Skip to content

Commit 0c9644d

Browse files
committed
Added usb commands to quickly interact with ECU B/C/D's UDS
1 parent acaea25 commit 0c9644d

1 file changed

Lines changed: 166 additions & 0 deletions

File tree

firmware/RAMNV1/Core/Src/ramn_cdc.c

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,41 @@ static int countElements(char* buffer, int length) {
5050
return count;
5151
}
5252

53+
static FDCAN_TxHeaderTypeDef USBTxHeader;
54+
static uint8_t USBTxData[8U];
55+
56+
// Function to send a UDS frame based on provided CAN ID and ascii string
57+
void sendUDSAsciiHex(uint16_t can_id, char *ascii_hex)
58+
{
59+
uint8_t data[8] = {0};
60+
uint8_t payload[7];
61+
uint8_t payload_len = 0;
62+
63+
while (*ascii_hex && *(ascii_hex + 1) && payload_len < 7)
64+
{
65+
payload[payload_len++] = ASCIItoUint8(ascii_hex);
66+
ascii_hex += 2;
67+
}
68+
69+
data[0] = payload_len;
70+
71+
for (uint8_t i = 0; i < payload_len; i++)
72+
{
73+
data[i + 1] = payload[i];
74+
}
75+
76+
/* Configure CAN header */
77+
USBTxHeader.BitRateSwitch = FDCAN_BRS_OFF;
78+
USBTxHeader.FDFormat = FDCAN_CLASSIC_CAN;
79+
USBTxHeader.TxFrameType = FDCAN_DATA_FRAME;
80+
USBTxHeader.IdType = FDCAN_STANDARD_ID;
81+
USBTxHeader.Identifier = can_id;
82+
USBTxHeader.DataLength = UINT8toDLC(8);
83+
84+
RAMN_memcpy((uint8_t*)USBTxData, data, 8);
85+
RAMN_FDCAN_SendMessage(&USBTxHeader, USBTxData);
86+
}
87+
5388
RAMN_Bool_t RAMN_CDC_ProcessCLIBuffer(uint8_t* USBRxBuffer, uint32_t commandLength)
5489
{
5590
// Command is in USBRxBuffer, length is in commandLength. There is no endline in buffer.
@@ -464,6 +499,137 @@ RAMN_Bool_t RAMN_CDC_ProcessCLIBuffer(uint8_t* USBRxBuffer, uint32_t commandLeng
464499
RAMN_FDCAN_ResetPeripheral();
465500
}
466501
}
502+
else if (strcmp(token, "uds") == 0) {
503+
if (elementCount != 3)
504+
{
505+
RAMN_USB_SendStringFromTask("Usage: uds <B|C|D|*> <hex_payload>. Use * for broadcast.\r");
506+
}
507+
else
508+
{
509+
uint16_t can_id = 0;
510+
511+
token = strtok(NULL, " ");
512+
can_id = 0;
513+
if (strcmp(token, "*") == 0)
514+
{
515+
can_id = 0x7DF;
516+
}
517+
else if (strcmp(token, "B") == 0)
518+
{
519+
can_id = 0x7E1;
520+
}
521+
else if (strcmp(token, "C") == 0)
522+
{
523+
can_id = 0x7E2;
524+
}
525+
else if (strcmp(token, "D") == 0)
526+
{
527+
can_id = 0x7E3;
528+
}
529+
else if (strcmp(token, "A") == 0)
530+
{
531+
RAMN_USB_SendStringFromTask("Error: Use slcan to send UDS commands to ECU A.\r");
532+
}
533+
else
534+
{
535+
RAMN_USB_SendStringFromTask("Invalid ECU. Use B, C, D, or *.\r");
536+
}
537+
if (0x7E1 != 0)
538+
{
539+
token = strtok(NULL, " ");
540+
541+
uint16_t len = RAMN_strlen(token);
542+
543+
if ((len == 0) || (len % 2 != 0) || (len > 14))
544+
{
545+
RAMN_USB_SendStringFromTask("Invalid payload. Must be 1-7 bytes hex.\r");
546+
}
547+
else
548+
{
549+
sendUDSAsciiHex(can_id, token);
550+
}
551+
}
552+
}
553+
}
554+
else if (strcmp(token, "silence") == 0) {
555+
556+
if (elementCount != 2)
557+
{
558+
RAMN_USB_SendStringFromTask("Usage: silence <B|C|D|*>\r");
559+
}
560+
else
561+
{
562+
token = strtok(NULL, " ");
563+
564+
for (uint8_t i = 0; ((token[i] != 0) && (i < 4)); i++)
565+
{
566+
switch(token[i])
567+
{
568+
case '*':
569+
RAMN_USB_SendStringFromTask("Silencing all ECUs (broadcast).\r");
570+
sendUDSAsciiHex(0x7DF, "31010200");
571+
break;
572+
case 'A':
573+
RAMN_USB_SendStringFromTask("ECU A does not support this command.\r");
574+
break;
575+
case 'B':
576+
RAMN_USB_SendStringFromTask("Silencing ECU B.\r");
577+
sendUDSAsciiHex(0x7E1, "31010200");
578+
break;
579+
case 'C':
580+
RAMN_USB_SendStringFromTask("Silencing ECU C.\r");
581+
sendUDSAsciiHex(0x7E2, "31010200");
582+
break;
583+
case 'D':
584+
RAMN_USB_SendStringFromTask("Silencing ECU D.\r");
585+
sendUDSAsciiHex(0x7E3, "31010200");
586+
break;
587+
default:
588+
RAMN_USB_SendStringFromTask("Invalid ECU. Use B, C, D, or *.\r");
589+
break;
590+
}
591+
}
592+
}
593+
}
594+
else if (strcmp(token, "talk") == 0) {
595+
if (elementCount != 2)
596+
{
597+
RAMN_USB_SendStringFromTask("Usage: talk <B|C|D|*>\r");
598+
}
599+
else
600+
{
601+
token = strtok(NULL, " ");
602+
603+
for (uint8_t i = 0; ((token[i] != 0) && (i < 4)); i++)
604+
{
605+
switch(token[i])
606+
{
607+
case '*':
608+
RAMN_USB_SendStringFromTask("Restoring communication for all ECUs.\r");
609+
sendUDSAsciiHex(0x7DF, "31020200");
610+
break;
611+
case 'A':
612+
RAMN_USB_SendStringFromTask("ECU A does not support this command.\r");
613+
break;
614+
case 'B':
615+
RAMN_USB_SendStringFromTask("Restoring ECU B communication.\r");
616+
sendUDSAsciiHex(0x7E1, "31020200");
617+
break;
618+
case 'C':
619+
RAMN_USB_SendStringFromTask("Restoring ECU C communication.\r");
620+
sendUDSAsciiHex(0x7E2, "31020200");
621+
break;
622+
case 'D':
623+
RAMN_USB_SendStringFromTask("Restoring ECU D communication.\r");
624+
sendUDSAsciiHex(0x7E3, "31020200");
625+
break;
626+
default:
627+
RAMN_USB_SendStringFromTask("Invalid ECU. Use B, C, D, or *.\r");
628+
break;
629+
}
630+
}
631+
}
632+
}
467633
#ifdef ENABLE_SCREEN
468634
else if ( strcmp(token, "theme") == 0) {
469635
if (elementCount != 2)

0 commit comments

Comments
 (0)