Addition of transmit_obd_can_frame and handle_obd_frame functions

- Addition of transmit_obd_can_frame and handle_obd_frame functions
- Use dump_can_frame function in comm_can.cpp as well.
- Fix code formatting of dump_can_frame function
This commit is contained in:
mvgalen 2025-01-11 13:58:27 +01:00
parent ce949b2162
commit 7b69f9e9a8
4 changed files with 194 additions and 63 deletions

View file

@ -282,38 +282,7 @@ void print_can_frame(CAN_frame frame, frameDirection msgDir) {
#endif // DEBUG_CAN_DATA
if (datalayer.system.info.can_logging_active) { // If user clicked on CAN Logging page in webserver, start recording
char* message_string = datalayer.system.info.logged_can_messages;
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
// Not enough space, reset and start from the beginning
offset = 0;
}
unsigned long currentTime = millis();
// Add timestamp
offset += snprintf(message_string + offset, message_string_size - offset, "(%lu.%03lu) ", currentTime / 1000,
currentTime % 1000);
// Add direction. The 0 and 1 after RX and TX ensures that SavvyCAN puts TX and RX in a different bus.
offset +=
snprintf(message_string + offset, message_string_size - offset, "%s ", (msgDir == MSG_RX) ? "RX0" : "TX1");
// Add ID and DLC
offset += snprintf(message_string + offset, message_string_size - offset, "%X [%u] ", frame.ID, frame.DLC);
// Add data bytes
for (uint8_t i = 0; i < frame.DLC; i++) {
if (i < frame.DLC - 1) {
offset += snprintf(message_string + offset, message_string_size - offset, "%02X ", frame.data.u8[i]);
} else {
offset += snprintf(message_string + offset, message_string_size - offset, "%02X", frame.data.u8[i]);
}
}
// Add linebreak
offset += snprintf(message_string + offset, message_string_size - offset, "\n");
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
dump_can_frame(frame, msgDir);
}
}
@ -351,37 +320,37 @@ void map_can_frame_to_variable(CAN_frame* rx_frame, int interface) {
#endif
}
}
void dump_frame(CAN_frame &frame, frameDirection msgDir){
char* message_string = datalayer.system.info.logged_can_messages;
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
void dump_can_frame(CAN_frame &frame, frameDirection msgDir) {
char* message_string = datalayer.system.info.logged_can_messages;
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
// Not enough space, reset and start from the beginning
offset = 0;
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
// Not enough space, reset and start from the beginning
offset = 0;
}
unsigned long currentTime = millis();
// Add timestamp
offset += snprintf(message_string + offset, message_string_size - offset, "(%lu.%03lu) ", currentTime / 1000,
currentTime % 1000);
// Add direction. The 0 and 1 after RX and TX ensures that SavvyCAN puts TX and RX in a different bus.
offset +=
snprintf(message_string + offset, message_string_size - offset, "%s ", (msgDir == MSG_RX) ? "RX0" : "TX1");
// Add ID and DLC
offset += snprintf(message_string + offset, message_string_size - offset, "%X [%u] ", frame.ID, frame.DLC);
// Add data bytes
for (uint8_t i = 0; i < frame.DLC; i++) {
if (i < frame.DLC - 1) {
offset += snprintf(message_string + offset, message_string_size - offset, "%02X ", frame.data.u8[i]);
} else {
offset += snprintf(message_string + offset, message_string_size - offset, "%02X", frame.data.u8[i]);
}
unsigned long currentTime = millis();
// Add timestamp
offset += snprintf(message_string + offset, message_string_size - offset, "(%lu.%03lu) ", currentTime / 1000,
currentTime % 1000);
}
// Add linebreak
offset += snprintf(message_string + offset, message_string_size - offset, "\n");
// Add direction. The 0 and 1 after RX and TX ensures that SavvyCAN puts TX and RX in a different bus.
offset +=
snprintf(message_string + offset, message_string_size - offset, "%s ", (msgDir == MSG_RX) ? "RX0" : "TX1");
// Add ID and DLC
offset += snprintf(message_string + offset, message_string_size - offset, "%X [%u] ", frame.ID, frame.DLC);
// Add data bytes
for (uint8_t i = 0; i < frame.DLC; i++) {
if (i < frame.DLC - 1) {
offset += snprintf(message_string + offset, message_string_size - offset, "%02X ", frame.data.u8[i]);
} else {
offset += snprintf(message_string + offset, message_string_size - offset, "%02X", frame.data.u8[i]);
}
}
// Add linebreak
offset += snprintf(message_string + offset, message_string_size - offset, "\n");
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
}

View file

@ -15,7 +15,7 @@
#include "../../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h"
#endif //CANFD_ADDON
void dump_frame(CAN_frame &frame, frameDirection msgDir);
void dump_can_frame(CAN_frame &frame, frameDirection msgDir);
/**
* @brief Initialization function for CAN.

View file

@ -0,0 +1,151 @@
#include "obd.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){
static CAN_frame OBD_frame = {.FD = true,
.ext_ID = false,
.DLC = 8,
.ID = 0x700,
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
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(&OBD_frame, interface); // DTC TP-ISO
break;
case 3:
OBD_frame.data.u8[1]=0x07;
transmit_can_frame(&OBD_frame, interface); // DTC TP-ISO
break;
case 4:
OBD_frame.data.u8[1]=0x0A;
transmit_can_frame(&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(&OBD_frame, interface); // DTC TP-ISO
break;
}
cnt++;
if (cnt == 3600)
cnt = 0;
}

View file

@ -0,0 +1,11 @@
#ifndef _OBD_H_
#define _OBD_H_
#include "../../include.h"
#include "../../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
void handle_obd_frame(CAN_frame &rx_frame);
void transmit_obd_can_frame(unsigned int address, int interface);
#endif // _OBD_H_