Battery-Emulator/Software/src/communication/can/obd.cpp
2025-08-29 23:16:36 +03:00

148 lines
4.1 KiB
C++

#include "obd.h"
#include "../../devboard/utils/logging.h"
#include "comm_can.h"
void show_dtc(uint8_t byte0, uint8_t byte1);
void show_dtc(uint8_t byte0, uint8_t byte1) {
char letter;
switch (byte0 >> 6) {
case 0:
letter = 'P';
break;
case 1:
letter = 'C';
break;
case 2:
letter = 'B';
break;
case 3:
letter = 'U';
break;
}
logging.printf("%c%d\n", letter, ((byte0 & 0x3F) << 8) | byte1);
}
void handle_obd_frame(CAN_frame& rx_frame) {
if (rx_frame.data.u8[1] == 0x7F) {
const char* error_str = "?";
switch (rx_frame.data.u8[3]) { // See https://automotive.wiki/index.php/ISO_14229
case 0x10:
error_str = "generalReject";
break;
case 0x11:
error_str = "serviceNotSupported";
break;
case 0x12:
error_str = "subFunctionNotSupported";
break;
case 0x13:
error_str = "incorrectMessageLengthOrInvalidFormat";
break;
case 0x14:
error_str = "responseTooLong";
break;
case 0x21:
error_str = "busyRepeatReques";
break;
case 0x22:
error_str = "conditionsNotCorrect";
break;
case 0x24:
error_str = "requestSequenceError";
break;
case 0x31:
error_str = "requestOutOfRange";
break;
case 0x33:
error_str = "securityAccessDenied";
break;
case 0x35:
error_str = "invalidKey";
break;
case 0x36:
error_str = "exceedNumberOfAttempts";
break;
case 0x37:
error_str = "requiredTimeDelayNotExpired";
break;
case 0x70:
error_str = "uploadDownloadNotAccepted";
break;
case 0x71:
error_str = "transferDataSuspended";
break;
case 0x72:
error_str = "generalProgrammingFailure";
break;
case 0x73:
error_str = "wrongBlockSequenceCounter";
break;
case 0x78:
error_str = "requestCorrectlyReceived-ResponsePending";
break;
case 0x7E:
error_str = "subFunctionNotSupportedInActiveSession";
break;
case 0x7F:
error_str = "serviceNotSupportedInActiveSession";
break;
}
logging.printf("ODB reply Request for service 0x%02X: %s\n", rx_frame.data.u8[2], error_str);
} else {
switch (rx_frame.data.u8[1] & 0x3F) {
case 3:
logging.printf("ODB reply service 03: Show stored DTCs, %d present:\n", rx_frame.data.u8[2]);
for (int i = 0; i < rx_frame.data.u8[2]; i++)
show_dtc(rx_frame.data.u8[3 + 2 * i], rx_frame.data.u8[4 + 2 * i]);
break;
case 7:
logging.printf("ODB reply service 07: Show pending DTCs, %d present:\n", rx_frame.data.u8[2]);
for (int i = 0; i < rx_frame.data.u8[2]; i++)
show_dtc(rx_frame.data.u8[3 + 2 * i], rx_frame.data.u8[4 + 2 * i]);
break;
default:
logging.printf("ODBx reply frame received:\n");
}
}
dump_can_frame(rx_frame, MSG_RX);
}
void transmit_obd_can_frame(unsigned int address, int interface, bool canFD) {
static CAN_frame OBD_frame;
OBD_frame.FD = canFD;
OBD_frame.ID = address;
OBD_frame.ext_ID = address > 0x7FF;
OBD_frame.DLC = 8;
OBD_frame.data.u8[0] = 0x01;
OBD_frame.data.u8[1] = 0x03;
OBD_frame.data.u8[2] = 0xAA;
OBD_frame.data.u8[3] = 0xAA;
OBD_frame.data.u8[4] = 0xAA;
OBD_frame.data.u8[5] = 0xAA;
OBD_frame.data.u8[6] = 0xAA;
OBD_frame.data.u8[7] = 0xAA;
static int cnt = 0;
switch (cnt) {
case 2:
transmit_can_frame_to_interface(&OBD_frame, interface); // DTC TP-ISO
break;
case 3:
OBD_frame.data.u8[1] = 0x07;
transmit_can_frame_to_interface(&OBD_frame, interface); // DTC TP-ISO
break;
case 4:
OBD_frame.data.u8[1] = 0x0A;
transmit_can_frame_to_interface(&OBD_frame, interface); // DTC TP-ISO
break;
case 5:
OBD_frame.data.u8[0] = 0x02;
OBD_frame.data.u8[1] = 0x01;
OBD_frame.data.u8[2] = 0x1C;
transmit_can_frame_to_interface(&OBD_frame, interface); // DTC TP-ISO
break;
}
cnt++;
if (cnt == 3600)
cnt = 0;
}