diff --git a/.vscode/launch.json b/.vscode/launch.json index 6ce25106f..4300ec903 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -50,7 +50,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -81,7 +81,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -112,7 +112,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -132,6 +132,7 @@ "request": "launch", "type": "cortex-debug", "servertype": "openocd", + "runToEntryPoint": "main", "configFiles": [ "interface/stlink.cfg", "target/stm32g4x.cfg" @@ -143,7 +144,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -267,7 +268,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 160000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -298,7 +299,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -329,7 +330,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -360,7 +361,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -422,7 +423,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 80000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -486,7 +487,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -517,7 +518,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -548,7 +549,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -579,7 +580,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -610,7 +611,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -641,7 +642,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -672,7 +673,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -703,7 +704,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -734,7 +735,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -765,7 +766,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { @@ -796,7 +797,7 @@ "swoConfig": { "enabled": true, "cpuFrequency": 170000000, - "swoFrequency": 2000000, + "swoFrequency": 500000, "source": "probe", "decoders": [ { diff --git a/.vscode/settings.json b/.vscode/settings.json index 2370caa0c..5e71e685a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,5 +23,6 @@ "files.trimFinalNewlines": true, "files.trimTrailingWhitespace": true, "files.eol": "\n", - "cmake.useCMakePresets": "always" + "cmake.useCMakePresets": "always", + "C_Cpp.errorSquiggles": "disabled" } diff --git a/CANine/Application/Inc/CANdler.h b/CANine/Application/Inc/CANdler.h new file mode 100644 index 000000000..2316ce77a --- /dev/null +++ b/CANine/Application/Inc/CANdler.h @@ -0,0 +1,15 @@ +#include +#include "GRCAN_MSG_DATA.h" +#include "GRCAN_MSG_ID.h" +#include "GRCAN_BUS_ID.h" +#include "GRCAN_NODE_ID.h" + +#ifndef CANDLER_H +#define CANDLER_H +void ReportBadMessageLength(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id); +void ReportUnhandledMessage(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id); +void LoopbackTest(uint32_t ID, void *data, uint32_t size); +void CAN_MessageHandler(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id, uint8_t *data, uint32_t data_length); + + +#endif diff --git a/CANine/Application/Src/CANdler.c b/CANine/Application/Src/CANdler.c new file mode 100644 index 000000000..e6aa0f538 --- /dev/null +++ b/CANine/Application/Src/CANdler.c @@ -0,0 +1,480 @@ +#include "CANdler.h" +#include "StateMachine.h" +#include +#include "GRCAN_MSG_DATA.h" +#include "GRCAN_BUS_ID.h" +#include "GRCAN_MSG_ID.h" +#include "GRCAN_NODE_ID.h" +#include "Logomatic.h" +#include "bitManipulations.h" + + + +void ReportBadMessageLength(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id) +{ + // TODO Ideally change some state data to note a bad message, ie if BCU + // that can be a comms error + LOGOMATIC("Bad CAN Message length! Bus: %d, Msg: %X, Sender: %X\n", bus_id, msg_id, sender_id); +} + +void ReportUnhandledMessage(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id) +{ + // Filtering likely needs to be adjusted if this is happening often + LOGOMATIC("Unhandled CANine CAN Rx msg! Bus: %d, Msg: %X, Sender: %X\n", bus_id, msg_id, sender_id); +} + + +void LoopbackTest(uint32_t ID, void *data, uint32_t size) +{ + uint8_t *bytes = (uint8_t *)data; + LOGOMATIC("Received CAN message with ID: 0x%lX, data: 0x", ID); + for (uint32_t i = 0; i < size; i++) { + LOGOMATIC("%02X", bytes[i]); + } + LOGOMATIC("\n"); +} + +void CAN_MessageHandler(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id, uint8_t *data, uint32_t data_length) { + switch (msg_id) { + case GRCAN_DEBUG_2_0: + if (data_length > sizeof(GRCAN_DEBUG_2_0_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + LOGOMATIC("Received from %02X on bus %d: %.*s\n", sender_id, bus_id, (int)data_length, data); + break; + case GRCAN_DEBUG_FD: + if (data_length > sizeof(GRCAN_DEBUG_FD_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + LOGOMATIC("Received from %02X on bus %d: %.*s\n", sender_id, bus_id, (int)data_length, data); + break; + case GRCAN_PING: + if (data_length > sizeof(GRCAN_PING_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_PING_MSG * grcan_ping_msg = (GRCAN_PING_MSG *) data; + + LOGOMATIC("Time in millis: %lu", grcan_ping_msg->timestamp); + break; + case GRCAN_ECU_STATUS_1: + if (data_length > sizeof(GRCAN_ECU_STATUS_1_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_ECU_STATUS_1_MSG * grcan_ecu_status_1_msg = (GRCAN_ECU_STATUS_1_MSG *) data; + switch (grcan_ecu_status_1_msg->ecu_state) { + case GR_GLV_OFF: + LOGOMATIC("Current ECU State: GR_GLV_OFF \n"); + break; + case GR_GLV_ON: + LOGOMATIC("Current ECU State: GR_GLV_ON \n"); + break; + case GR_PRECHARGE_ENGAGED: + LOGOMATIC("Current ECU State: GR_PRECHARGE_ENGAGED \n"); + break; + case GR_PRECHARGE_COMPLETE: + LOGOMATIC("Current ECU State: GR_PRECHARGE_COMPLETE \n"); + break; + case GR_DRIVE_ACTIVE: + LOGOMATIC("Current ECU State: GR_DRIVE_ACTIVE \n"); + break; + case GR_TS_DISCHARGE: + LOGOMATIC("Current ECU State: GR_TS_DISCHARGE \n"); + break; + default: + LOGOMATIC("Current ECU State: None found \n"); + break; + } + + LOGOMATIC("BCU Node Status: %s\n", GETBIT(grcan_ecu_status_1_msg->status_flags, 7) ? "OK" : "Timeout"); + LOGOMATIC("GR Inverter Status: %s\n", GETBIT(grcan_ecu_status_1_msg->status_flags, 6) ? "OK" : "Timeout"); + LOGOMATIC("Fan Controller 1 Status: %s\n", GETBIT(grcan_ecu_status_1_msg->status_flags, 5) ? "OK" : "Timeout"); + LOGOMATIC("Fan Controller 2 Status: %s\n", GETBIT(grcan_ecu_status_1_msg->status_flags, 4) ? "OK" : "Timeout"); + LOGOMATIC("Fan Controller 3 Status: %s\n", GETBIT(grcan_ecu_status_1_msg->status_flags, 3) ? "OK" : "Timeout"); + LOGOMATIC("Dash Panel Status: %s\n", GETBIT(grcan_ecu_status_1_msg->status_flags, 2) ? "OK" : "Timeout"); + LOGOMATIC("TCM Node Status: %s\n", GETBIT(grcan_ecu_status_1_msg->status_flags, 1) ? "OK" : "Timeout"); + + uint8_t torque_map = grcan_ecu_status_1_msg->power_level_torque_map & 0x0F; + uint8_t power_lvl = (grcan_ecu_status_1_msg->power_level_torque_map >> 4) & 0x0F; + + LOGOMATIC("Power Level (hex value, controls the AC current limits): 0x%X\n", power_lvl); + LOGOMATIC("Torque Map (hex value): 0x%X\n", torque_map); + + LOGOMATIC("Max Cell Temperature: %u\n", grcan_ecu_status_1_msg->max_cell_temp); + LOGOMATIC("Percent of accumlator charged: %u\n", grcan_ecu_status_1_msg->accumulator_state_of_charge); + LOGOMATIC("Percent of Low Voltage Bat charged: %u\n", grcan_ecu_status_1_msg->glv_state_of_charge); + LOGOMATIC("Output terminal voltage of accumulator: %u\n", grcan_ecu_status_1_msg->tractive_system_voltage); + break; + case GRCAN_ECU_STATUS_2: + if (data_length > sizeof(GRCAN_ECU_STATUS_2_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_ECU_STATUS_2_MSG * grcan_ecu_status_2_msg = (GRCAN_ECU_STATUS_2_MSG *)data; + LOGOMATIC("Absolute value of speed: %u\n", grcan_ecu_status_2_msg->vehicle_speed); + LOGOMATIC("FR Wheel RPM: %u\n", grcan_ecu_status_2_msg->fr_wheel_rpm); + LOGOMATIC("FL Wheel RPM: %u\n", grcan_ecu_status_2_msg->fl_wheel_rpm); + LOGOMATIC("RR Wheel RPM: %u\n", grcan_ecu_status_2_msg->rr_wheel_rpm); + break; + + + + + + + + case GRCAN_ECU_STATUS_3: + if (data_length > sizeof(GRCAN_ECU_STATUS_3_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_ECU_STATUS_3_MSG * grcan_ecu_status_3 = (GRCAN_ECU_STATUS_3_MSG *)data; + LOGOMATIC("Wheel RPM: %u\n", grcan_ecu_status_3->rl_wheel_rpm); + break; + case GRCAN_BCU_CELL_DATA_1: + if (data_length > sizeof(GRCAN_BCU_CELL_DATA_1_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_BCU_CELL_DATA_1_MSG * grcan_bcu_cell_data_1_msg = (GRCAN_BCU_CELL_DATA_1_MSG *)data; + for (int i = 0; i < 32; i++) { + LOGOMATIC("Cell %d - Voltage: %u, Temp: %u\n", i + 1, grcan_bcu_cell_data_1_msg->cells[i].voltage, grcan_bcu_cell_data_1_msg->cells[i].temperature); + } + break; + case GRCAN_BCU_CELL_DATA_2: + if (data_length > sizeof(GRCAN_BCU_CELL_DATA_2_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_BCU_CELL_DATA_2_MSG * grcan_bcu_cell_data_2_msg = (GRCAN_BCU_CELL_DATA_2_MSG *)data; + for (int i = 0; i < 32; i++) { + LOGOMATIC("Cell %d - Voltage: %u, Temp: %u\n", i + 33, grcan_bcu_cell_data_2_msg->cells[i].voltage, grcan_bcu_cell_data_2_msg->cells[i].temperature); + } + break; + + case GRCAN_BCU_CELL_DATA_3: + if (data_length > sizeof(GRCAN_BCU_CELL_DATA_3_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_BCU_CELL_DATA_3_MSG * grcan_bcu_cell_data_3_msg = (GRCAN_BCU_CELL_DATA_3_MSG *)data; + for (int i = 0; i < 32; i++) { + LOGOMATIC("Cell %d - Voltage: %u, Temp: %u\n", i + 65, grcan_bcu_cell_data_3_msg->cells[i].voltage, grcan_bcu_cell_data_3_msg->cells[i].temperature); + } + break; + + case GRCAN_BCU_CELL_DATA_4: + if (data_length > sizeof(GRCAN_BCU_CELL_DATA_4_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_BCU_CELL_DATA_4_MSG * grcan_bcu_cell_data_4_msg = (GRCAN_BCU_CELL_DATA_4_MSG *)data; + for (int i = 0; i < 32; i++) { + LOGOMATIC("Cell %d - Voltage: %u, Temp: %u\n", i + 97, grcan_bcu_cell_data_4_msg->cells[i].voltage, grcan_bcu_cell_data_4_msg->cells[i].temperature); + } + break; + + case GRCAN_BCU_CELL_DATA_5: + if (data_length > sizeof(GRCAN_BCU_CELL_DATA_5_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_BCU_CELL_DATA_5_MSG * grcan_bcu_cell_data_5_msg = (GRCAN_BCU_CELL_DATA_5_MSG *)data; + for (int i = 0; i < 32; i++) { + LOGOMATIC("Cell %d - Voltage: %u, Temp: %u\n", i + 129, grcan_bcu_cell_data_5_msg->cells[i].voltage, grcan_bcu_cell_data_5_msg->cells[i].temperature); + } + break; + //convert to celsius + case GRCAN_INVERTER_STATUS_1: + if (data_length > sizeof(GRCAN_INVERTER_STATUS_1_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_INVERTER_STATUS_1_MSG * grcan_inverter_status_1_msg = (GRCAN_INVERTER_STATUS_1_MSG *)data; + LOGOMATIC("AC Current: %u (0.01 * current)\n", grcan_inverter_status_1_msg->ac_current); + LOGOMATIC("DC Current: %u (0.01 * current)\n", grcan_inverter_status_1_msg->dc_current); + LOGOMATIC("Motor RPM: %u (RPM)\n", grcan_inverter_status_1_msg->motor_rpm); + break; + + case GRCAN_INVERTER_STATUS_2: + if (data_length > sizeof(GRCAN_INVERTER_STATUS_2_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_INVERTER_STATUS_2_MSG * grcan_inverter_status_2_msg = (GRCAN_INVERTER_STATUS_2_MSG *)data; + LOGOMATIC("U MOSFET Temp: %u (Celsius + 40)\n", grcan_inverter_status_2_msg->u_mosfet_temperature); + LOGOMATIC("V MOSFET Temp: %u (Celsius + 40)\n", grcan_inverter_status_2_msg->v_mosfet_temperature); + LOGOMATIC("W MOSFET Temp: %u (Celsius + 40)\n", grcan_inverter_status_2_msg->w_mosfet_temperature); + break; + + case GRCAN_INVERTER_STATUS_3: + if (data_length > sizeof(GRCAN_INVERTER_STATUS_3_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_INVERTER_STATUS_3_MSG * grcan_inverter_status_3_msg = (GRCAN_INVERTER_STATUS_3_MSG *)data; + int32_t motor_temp_c = (int32_t)grcan_inverter_status_3_msg->motor_temperature - 40; + LOGOMATIC("Motor Temp: %ld C\n", motor_temp_c); + + const char *fault_msgs[] = { + "TS Over Max", + "TS Under Min", + "Inverter Over Temp", + "Motor Over Temp", + "Mosfet Drive Error", + "Encoder Error", + "CAN Error/Timeout", + "Reserved/Unknown Fault" + }; + + if (grcan_inverter_status_3_msg->fault_bits == 0) { + LOGOMATIC("System Status: OK\n"); + } else { + for (int i = 0; i < 8; i++) { + if (GETBIT(grcan_inverter_status_3_msg->fault_bits, i)) { + LOGOMATIC("FAULT DETECTED: %s\n", fault_msgs[i]); + } + } + } + break; + + case GRCAN_INVERTER_CONFIG: + if (data_length > sizeof(GRCAN_INVERTER_CONFIG_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_INVERTER_CONFIG_MSG * grcan_inverter_config_msg = (GRCAN_INVERTER_CONFIG_MSG *)data; + LOGOMATIC("Max AC Current: %u\n", grcan_inverter_config_msg->max_ac_current); + LOGOMATIC("Max DC Current: %u\n", grcan_inverter_config_msg->max_dc_current); + LOGOMATIC("RPM Limit: %u (0: No limit)\n", grcan_inverter_config_msg->absolute_max_rpm_limit); + LOGOMATIC("Motor Direction: %s\n", (grcan_inverter_config_msg->motor_direction == 1) ? "Inverted" : "Normal"); + break; + + case GRCAN_INVERTER_COMMAND: + if (data_length > sizeof(GRCAN_INVERTER_COMMAND_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_INVERTER_COMMAND_MSG * grcan_inverter_command_msg = (GRCAN_INVERTER_COMMAND_MSG *)data; + LOGOMATIC("Set AC Current: %u\n", grcan_inverter_command_msg->set_ac_current); + LOGOMATIC("Set DC Current: %u\n", grcan_inverter_command_msg->set_dc_current); + LOGOMATIC("RPM Limit: %u\n", grcan_inverter_command_msg->rpm_limit); + LOGOMATIC("Field Weakening: %u\n", grcan_inverter_command_msg->field_weakening); + LOGOMATIC("Drive Enable: %s\n", (grcan_inverter_command_msg->drive_enable == 1) ? "ENABLED" : "DISABLED"); + break; + + case GRCAN_FAN_STATUS: + if (data_length > sizeof(GRCAN_FAN_STATUS_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_FAN_STATUS_MSG * grcan_fan_status_msg = (GRCAN_FAN_STATUS_MSG *)data; + LOGOMATIC("Fan Speed: %u RPM\n", grcan_fan_status_msg->fan_speed); + LOGOMATIC("Input Voltage: %u (0-22)\n", grcan_fan_status_msg->input_voltage); + LOGOMATIC("Input Current: %u (0-10)\n", grcan_fan_status_msg->input_current); + break; + + case GRCAN_FAN_COMMAND: + if (data_length > sizeof(GRCAN_FAN_COMMAND_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_FAN_COMMAND_MSG * grcan_fan_command_msg = (GRCAN_FAN_COMMAND_MSG *)data; + LOGOMATIC("Fan Command: %u Percent\n", grcan_fan_command_msg->fan_command); + break; + + //is this correct + case GRCAN_DASH_STATUS: + if (data_length > sizeof(GRCAN_DASH_STATUS_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_DASH_STATUS_MSG * grcan_dash_status_msg = (GRCAN_DASH_STATUS_MSG *)data; + LOGOMATIC("TS Active: %s\n", GETBIT(grcan_dash_status_msg->button_flags, 0) ? "YES" : "NO"); + LOGOMATIC("RTD: %s\n", GETBIT(grcan_dash_status_msg->button_flags, 1) ? "YES" : "NO"); + LOGOMATIC("LED BMS: %s\n", GETBIT(grcan_dash_status_msg->led_bits, 0) ? "ON" : "OFF"); + LOGOMATIC("LED IMD: %s\n", GETBIT(grcan_dash_status_msg->led_bits, 1) ? "ON" : "OFF"); + LOGOMATIC("LED BSPD: %s\n", GETBIT(grcan_dash_status_msg->led_bits, 2) ? "ON" : "OFF"); + break; + + + + + + + + + + + + + + case GRCAN_DASH_CONFIG: + if (data_length > sizeof(GRCAN_DASH_CONFIG_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_DASH_CONFIG_MSG * grcan_dash_config_msg = (GRCAN_DASH_CONFIG_MSG *) data; + LOGOMATIC("BMS: %s\n", GETBIT(grcan_dash_config_msg->led_bits, 0) ? "true" : "false"); + LOGOMATIC("IMD %s\n", GETBIT(grcan_dash_config_msg->led_bits, 1) ? "true" : "false"); + LOGOMATIC("BSPD %s\n", GETBIT(grcan_dash_config_msg->led_bits, 2) ? "true" : "false"); + break; + case GRCAN_TCM_STATUS: + if (data_length > sizeof(GRCAN_TCM_STATUS_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_TCM_STATUS_MSG * grcan_tcm_status_msg = (GRCAN_TCM_STATUS_MSG *)data; + LOGOMATIC("Connection Status: %s\n", GETBIT(grcan_tcm_status_msg->status_bits, 0) ? "OK" : "Timeout"); + LOGOMATIC("MQTT Status: %s\n", GETBIT(grcan_tcm_status_msg->status_bits, 1) ? "OK" : "Timeout"); + LOGOMATIC("Epic Shelter Status %s\n", GETBIT(grcan_tcm_status_msg->status_bits, 2) ? "In Progress" : "Idle"); + LOGOMATIC("Camera Status %s\n", GETBIT(grcan_tcm_status_msg->status_bits, 3) ? "Recording" : "Idle"); + + LOGOMATIC("Mapache Ping: %u ms\n", grcan_tcm_status_msg->mapache_ping); + LOGOMATIC("Cache Size: %lu \n", grcan_tcm_status_msg->cache_size); + + break; + case GRCAN_TCM_RESOURCE_UTILIZATION: + if (data_length > sizeof(GRCAN_TCM_RESOURCE_UTILIZATION_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_TCM_RESOURCE_UTILIZATION_MSG * grcan_tcm_resource_utilization_msg = (GRCAN_TCM_RESOURCE_UTILIZATION_MSG *)data; + LOGOMATIC("Core 0 Frequency: %u MHz\n", grcan_tcm_resource_utilization_msg->cpu_0_freq); + LOGOMATIC("Core 0 Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->cpu_0_util); + LOGOMATIC("Core 1 Frequency: %u MHz\n", grcan_tcm_resource_utilization_msg->cpu_1_freq); + LOGOMATIC("Core 1 Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->cpu_1_util); + LOGOMATIC("Core 2 Frequency: %u MHz\n", grcan_tcm_resource_utilization_msg->cpu_2_freq); + LOGOMATIC("Core 2 Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->cpu_2_util); + LOGOMATIC("Core 3 Frequency: %u MHz\n", grcan_tcm_resource_utilization_msg->cpu_3_freq); + LOGOMATIC("Core 3 Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->cpu_3_util); + LOGOMATIC("Core 4 Frequency: %u MHz\n", grcan_tcm_resource_utilization_msg->cpu_4_freq); + LOGOMATIC("Core 4 Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->cpu_4_util); + LOGOMATIC("Core 5 Frequency: %u MHz\n", grcan_tcm_resource_utilization_msg->cpu_5_freq); + LOGOMATIC("Core 5 Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->cpu_5_util); + LOGOMATIC("Total CPU Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->cpu_total_util); + LOGOMATIC("Total Memory: %u MB\n", grcan_tcm_resource_utilization_msg->ram_total); + LOGOMATIC("Used Memory: %u MB\n", grcan_tcm_resource_utilization_msg->ram_used); + LOGOMATIC("Memory Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->ram_util); + LOGOMATIC("GPU Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->gpu_util); + LOGOMATIC("GPU Frequency: %u MHz\n", grcan_tcm_resource_utilization_msg->gpu_freq); + LOGOMATIC("Total Disk Space: %lu MB\n", grcan_tcm_resource_utilization_msg->disk_total); + LOGOMATIC("Used Disk Space: %lu MB\n", grcan_tcm_resource_utilization_msg->disk_used); + LOGOMATIC("Disk Utilization: %u%%\n", grcan_tcm_resource_utilization_msg->disk_util); + LOGOMATIC("CPU Temp: %u ˚C\n", grcan_tcm_resource_utilization_msg->cpu_temp); + LOGOMATIC("GPU Temp: %u ˚C\n", grcan_tcm_resource_utilization_msg->gpu_temp); + LOGOMATIC("Voltage Draw: %u mV\n", grcan_tcm_resource_utilization_msg->voltage_draw); + LOGOMATIC("Current Draw: %u mA\n", grcan_tcm_resource_utilization_msg->current_draw); + LOGOMATIC("Power Draw: %u mW\n", grcan_tcm_resource_utilization_msg->power_draw); + + break; + case GRCAN_ECU_ANALOG_DATA: + if (data_length > sizeof(GRCAN_ECU_ANALOG_DATA_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_ECU_ANALOG_DATA_MSG * grcan_ecu_analog_data_msg = (GRCAN_ECU_ANALOG_DATA_MSG *)data; + + LOGOMATIC("All of the following ECU Analog Signals are in the range of 4-20 mA: "); + LOGOMATIC("BSPD Signal: %u mA\n", grcan_ecu_analog_data_msg->bspd_signal); + LOGOMATIC("BSE Signal: %u mA\n", grcan_ecu_analog_data_msg->bse_signal); + LOGOMATIC("Apps 1 Signal: %u mA\n", grcan_ecu_analog_data_msg->apps_1_signal); + LOGOMATIC("Apps 2 Signal: %u mA\n", grcan_ecu_analog_data_msg->apps_2_signal); + LOGOMATIC("Brakeline F Signal: %u mA\n", grcan_ecu_analog_data_msg->brakeline_f_signal); + LOGOMATIC("Brakeline R Signal: %u mA\n", grcan_ecu_analog_data_msg->brakeline_r_signal); + LOGOMATIC("Steering Angle Signal: %u mA\n", grcan_ecu_analog_data_msg->steering_angle_signal); + LOGOMATIC("Aux Signal: %u mA\n", grcan_ecu_analog_data_msg->aux_signal); + + break; + case GRCAN_GPS_LAT: + if (data_length > sizeof(GRCAN_GPS_LAT_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_GPS_LAT_MSG * grcan_gps_lat_msg = (GRCAN_GPS_LAT_MSG *)data; + + LOGOMATIC("Lattitude: %u \n", grcan_gps_lat_msg->lat); + break; + case GRCAN_GPS_LON: + if (data_length > sizeof(GRCAN_GPS_LON_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_GPS_LON_MSG * grcan_gps_lon_msg = (GRCAN_GPS_LON_MSG *)data; + LOGOMATIC("Longitude: %u \n", grcan_gps_lon_msg->lon); + break; + case GRCAN_GPS_ALT: + if (data_length > sizeof(GRCAN_GPS_ALT_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_GPS_ALT_MSG * grcan_gps_alt_msg = (GRCAN_GPS_ALT_MSG *)data; + + LOGOMATIC("Altitude: %u \n", grcan_gps_alt_msg->alt); + break; + case GRCAN_GPS_PX: + if (data_length > sizeof(GRCAN_GPS_PX_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_GPS_PX_MSG * grcan_gps_px_msg = (GRCAN_GPS_PX_MSG *)data; + + LOGOMATIC("Theta: %u \n", grcan_gps_px_msg->theta); + LOGOMATIC("Acc: %u \n", grcan_gps_px_msg->acc); + LOGOMATIC("Status: %lu \n", grcan_gps_px_msg->status); + + break; + case GRCAN_GPS_QY: + if (data_length > sizeof(GRCAN_GPS_QY_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_GPS_QY_MSG * grcan_gps_qy_msg = (GRCAN_GPS_QY_MSG *)data; + + LOGOMATIC("Theta: %u \n", grcan_gps_qy_msg->theta); + LOGOMATIC("Acc: %u \n", grcan_gps_qy_msg->acc); + LOGOMATIC("Status: %lu \n", grcan_gps_qy_msg->status); + + break; + case GRCAN_GPS_RZ: + if (data_length > sizeof(GRCAN_GPS_RZ_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_GPS_RZ_MSG * grcan_gps_rz_msg = (GRCAN_GPS_RZ_MSG *)data; + + LOGOMATIC("Theta: %u \n", grcan_gps_rz_msg->theta); + LOGOMATIC("Acc: %u \n", grcan_gps_rz_msg->acc); + LOGOMATIC("Status: %lu \n", grcan_gps_rz_msg->status); + + break; + case GRCAN_UVW_DGPS: + if (data_length > sizeof(GRCAN_UVW_DGPS_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_UVW_DGPS_MSG * grcan_uvw_dgps_msg = (GRCAN_UVW_DGPS_MSG *)data; + + LOGOMATIC("U: %u \n", grcan_uvw_dgps_msg->dgps_u); + LOGOMATIC("V: %u \n", grcan_uvw_dgps_msg->dgps_v); + LOGOMATIC("W: %u \n", grcan_uvw_dgps_msg->dgps_w); + + break; + case GRCAN_ECU_PERFORMANCE: + if (data_length > sizeof(GRCAN_ECU_PERFORMANCE_MSG)) { + ReportBadMessageLength(bus_id, msg_id, sender_id); + break; + } + GRCAN_ECU_PERFORMANCE_MSG * grcan_ecu_performance_msg = (GRCAN_ECU_PERFORMANCE_MSG *)data; + + LOGOMATIC("Total number of clock cycles elapsed for 10 iterations of the main loop: %lu \n", grcan_ecu_performance_msg->elapsed_cycles); + + break; + default: + ReportUnhandledMessage(bus_id, msg_id, sender_id); + break; + } +} diff --git a/CANine/CMakeLists.txt b/CANine/CMakeLists.txt index 3410dbbb7..3884f59f2 100644 --- a/CANine/CMakeLists.txt +++ b/CANine/CMakeLists.txt @@ -30,11 +30,24 @@ add_library(${GR_PROJECT_NAME}_USER_CODE INTERFACE) target_sources( ${GR_PROJECT_NAME}_USER_CODE INTERFACE + # Core Core/Src/main.c Core/Src/stm32g4xx_it.c - Core/Src/stm32g4xx_hal_msp.c + # Application + Application/Src/CANdler.c ) -target_link_libraries(${GR_PROJECT_NAME}_USER_CODE INTERFACE VCP_LIB) +target_link_libraries( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + PERIPHERAL_CAN_LIB + CANfigurator + BitManipulations_Lib +) -target_include_directories(${GR_PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) +target_include_directories( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + Core/Inc + Application/Inc +) diff --git a/CANine/Core/Inc/can_cfg.h b/CANine/Core/Inc/can_cfg.h new file mode 100644 index 000000000..0e987b82d --- /dev/null +++ b/CANine/Core/Inc/can_cfg.h @@ -0,0 +1,7 @@ +#ifndef CAN_CFG_H +#define CAN_CFG_H + +#define USECAN1 +#define TX_BUFFER_1_SIZE 10 + +#endif diff --git a/CANine/Core/Inc/stm32g4xx_hal_conf.h b/CANine/Core/Inc/stm32g4xx_hal_conf.h index 0888f0058..673034544 100644 --- a/CANine/Core/Inc/stm32g4xx_hal_conf.h +++ b/CANine/Core/Inc/stm32g4xx_hal_conf.h @@ -42,7 +42,7 @@ extern "C" { /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */ -/*#define HAL_FDCAN_MODULE_ENABLED */ +#define HAL_FDCAN_MODULE_ENABLED /*#define HAL_FMAC_MODULE_ENABLED */ /*#define HAL_HRTIM_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ diff --git a/CANine/Core/Src/main.c b/CANine/Core/Src/main.c index c487719e2..00be7408d 100644 --- a/CANine/Core/Src/main.c +++ b/CANine/Core/Src/main.c @@ -1,15 +1,5 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.c - * @brief : Main program body - ****************************************************************************** - * @attention - * - * Copyright (c) 2025 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file + + /* This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * @@ -21,8 +11,14 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#include +#include "StateMachine.h" +#include "CANdler.h" +#include "GRCAN_MSG_DATA.h" +#include "GRCAN_MSG_ID.h" +#include "GRCAN_NODE_ID.h" #include "Logomatic.h" -#include "vcp.h" +#include "can.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -33,11 +29,18 @@ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ +// TODO Comment and uncomment this line as relevant +#define EXTERNAL_LOOPBACK_TEST + /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ - +#ifdef EXTERNAL_LOOPBACK_TEST +#pragma message("Testing with external loopback") +#else +#pragma message("Testing with external CAN bus") +#endif /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ @@ -60,7 +63,7 @@ static void MX_GPIO_Init(void); LogomaticConfig logomaticConfig = {.clock_source = LOGOMATIC_PCLK1, .bus = LOGOMATIC_BUS, .gpio_port = LOGOMATIC_GPIOA, - .gpio_pin_rx_tx_mask = LL_GPIO_PIN_9 | LL_GPIO_PIN_10, + .gpio_pin_rx_tx_mask = LL_GPIO_PIN_2 | LL_GPIO_PIN_3, .baud_rate = 115200, .data_width = LOGOMATIC_DATAWIDTH_8B, .stop_bits = LOGOMATIC_STOPBITS_1, @@ -71,24 +74,240 @@ LogomaticConfig logomaticConfig = {.clock_source = LOGOMATIC_PCLK1, .tx_fifo_threshold = LOGOMATIC_FIFOTHRESHOLD_1_8, .rx_fifo_threshold = LOGOMATIC_FIFOTHRESHOLD_1_8}; -VCP_Config vcp_config = {.baud_rate = 4000000, - .clock_source = VCP_CLOCK_PCLK, - .gpio_tx_rx_pin_mask = LL_GPIO_PIN_2 | LL_GPIO_PIN_3, - .bus_port = VCP_Port_A, - .parity = VCP_Parity_None, - .prescaler = VCP_Prescalar_Div1, - .stop_bits = VCP_StopBits_1, - .oversampling = VCP_Oversampling_16, - .tx_fifo_threshold = VCP_Threshold_1_8, - .rx_fifo_threshold = VCP_Threshold_1_8, - .usart_instance = USART2, - .alternate_function = LL_GPIO_AF_7}; +static CANHandle *can1; + +void CAN1_rx_callback(uint32_t ID, void *data, uint32_t size) +{ +//#ifdef EXTERNAL_LOOPBACK_TEST +// LoopbackTest(ID, data, size); +//#else + CAN_MessageHandler(GRCAN_BUS_PRIMARY, (0x000FFF00 & ID) >> 8, (0xFF00000 & ID) >> 20, (uint8_t*)data, size); +//#endif +} + +void sendMSG(){ + + FDCANTxMessage sendBCUCellData1; + + sendBCUCellData1.tx_header.Identifier = (GRCAN_BCU << 20) | (GRCAN_BCU_CELL_DATA_1 << 8) | GRCAN_Debugger; + sendBCUCellData1.tx_header.IdType = FDCAN_EXTENDED_ID; + sendBCUCellData1.tx_header.TxFrameType = FDCAN_DATA_FRAME; + sendBCUCellData1.tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + sendBCUCellData1.tx_header.DataLength = FDCAN_DLC_BYTES_64; + sendBCUCellData1.tx_header.BitRateSwitch = FDCAN_BRS_OFF; + sendBCUCellData1.tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS; + sendBCUCellData1.tx_header.MessageMarker = 0; + + GRCAN_BCU_CELL_DATA_1_MSG grcan_bcu_cell_data_1_msg = { + .cells[0].voltage = 0xAF, + .cells[0].temperature = 45, + .cells[1].voltage = 0xBE, + .cells[1].temperature = 48, + .cells[2].voltage = 0xFF, + .cells[2].temperature = 60, + .cells[3].voltage = 0xAF, + .cells[3].temperature = 45, + .cells[4].voltage = 0xBE, + .cells[4].temperature = 48, + .cells[5].voltage = 0xFF, + .cells[5].temperature = 60, + .cells[6].voltage = 0xAF, + .cells[6].temperature = 45, + .cells[7].voltage = 0xBE, + .cells[7].temperature = 48, + .cells[8].voltage = 0xFF, + .cells[8].temperature = 60, + .cells[9].voltage = 0xAF, + .cells[9].temperature = 45, + .cells[10].voltage = 0xBE, + .cells[10].temperature = 48, + .cells[11].voltage = 0xFF, + .cells[11].temperature = 60 + }; + + for (int i = 12; i < 32; i++) { + grcan_bcu_cell_data_1_msg.cells[i].voltage = i * 2; + grcan_bcu_cell_data_1_msg.cells[i].temperature = i * 2 + 1; + } + + memcpy(sendBCUCellData1.data, &grcan_bcu_cell_data_1_msg, sizeof(grcan_bcu_cell_data_1_msg)); + + can_send(can1, &sendBCUCellData1); + + FDCANTxMessage sendInverterStatus3; + + sendInverterStatus3.tx_header.Identifier = (GRCAN_GR_Inverter << 20) | (GRCAN_INVERTER_STATUS_3 << 8) | GRCAN_Debugger; + sendInverterStatus3.tx_header.IdType = FDCAN_EXTENDED_ID; + sendInverterStatus3.tx_header.TxFrameType = FDCAN_DATA_FRAME; + sendInverterStatus3.tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + sendInverterStatus3.tx_header.DataLength = FDCAN_DLC_BYTES_2; + sendInverterStatus3.tx_header.BitRateSwitch = FDCAN_BRS_OFF; + sendInverterStatus3.tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS; + sendInverterStatus3.tx_header.MessageMarker = 0; + + GRCAN_INVERTER_STATUS_3_MSG sendInverterStatus3_msg = { + .motor_temperature = 105, + .fault_bits = 0x24 + }; + + memcpy(sendInverterStatus3.data, &sendInverterStatus3_msg, sizeof(sendInverterStatus3_msg)); + + can_send(can1, &sendInverterStatus3); + + + FDCANTxMessage sendECUStatus1; + + sendECUStatus1.tx_header.Identifier = (GRCAN_ECU << 20) | (GRCAN_ECU_STATUS_1 << 8) | GRCAN_Debugger; + sendECUStatus1.tx_header.IdType = FDCAN_EXTENDED_ID; + sendECUStatus1.tx_header.TxFrameType = FDCAN_DATA_FRAME; + sendECUStatus1.tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + sendECUStatus1.tx_header.DataLength = FDCAN_DLC_BYTES_8; + sendECUStatus1.tx_header.BitRateSwitch = FDCAN_BRS_OFF; + sendECUStatus1.tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS; + sendECUStatus1.tx_header.MessageMarker = 0; + + GRCAN_ECU_STATUS_1_MSG ecu_status1_msg = { + .ecu_state = GR_DRIVE_ACTIVE, + + .status_flags = 0x65, + + .power_level_torque_map = (0xA << 4) | 0x3, + .max_cell_temp = 35, + .accumulator_state_of_charge = 90, + .glv_state_of_charge = 95, + .tractive_system_voltage = 560 + }; + + memcpy(sendECUStatus1.data, &ecu_status1_msg, sizeof(ecu_status1_msg)); + + can_send(can1, &sendECUStatus1); + + + FDCANTxMessage sendECUMsg; + + sendECUMsg.tx_header.Identifier = (GRCAN_DGPS << 20) | (GRCAN_GPS_RZ << 8) | GRCAN_Debugger; + sendECUMsg.tx_header.IdType = FDCAN_EXTENDED_ID; + sendECUMsg.tx_header.TxFrameType = FDCAN_DATA_FRAME; + sendECUMsg.tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + sendECUMsg.tx_header.DataLength = FDCAN_DLC_BYTES_8; + sendECUMsg.tx_header.BitRateSwitch = FDCAN_BRS_OFF; + sendECUMsg.tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS; + sendECUMsg.tx_header.MessageMarker = 0; + + GRCAN_GPS_RZ_MSG message = {.theta = 0xABCD, .acc = 0x1234, .status = 0x12345678}; + + memcpy(sendECUMsg.data, &message, sizeof(message)); + + can_send(can1, &sendECUMsg); + } + +// CANConfig cfg1; +void CAN_Configure() +{ + + CANConfig canCfg; + + // SHARED config ddata for CAN1 and CAN2 + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; + canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; +#ifdef EXTERNAL_LOOPBACK_TEST + canCfg.hal_fdcan_init.Mode = FDCAN_MODE_EXTERNAL_LOOPBACK; +#else + canCfg.hal_fdcan_init.Mode = FDCAN_MODE_NORMAL; +#endif + canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; + canCfg.hal_fdcan_init.TransmitPause = DISABLE; + canCfg.hal_fdcan_init.ProtocolException = ENABLE; + canCfg.hal_fdcan_init.NominalPrescaler = 1; + canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; + canCfg.hal_fdcan_init.NominalTimeSeg1 = 127; // Updated for 170MHz: (1+127+42)*1 = 170 ticks -> 1 Mbps + canCfg.hal_fdcan_init.NominalTimeSeg2 = 42; + canCfg.hal_fdcan_init.DataPrescaler = 2; + canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; + canCfg.hal_fdcan_init.DataTimeSeg1 = 12; // Updated for 170MHz: 170 MHz/((1+12+4)*2) = 5 Mbps + canCfg.hal_fdcan_init.DataTimeSeg2 = 4; + canCfg.hal_fdcan_init.StdFiltersNbr = 1; + canCfg.hal_fdcan_init.ExtFiltersNbr = 0; + + canCfg.rx_callback = NULL; + canCfg.rx_interrupt_priority = 15; // TODO: Maybe make these not hardcoded + canCfg.tx_interrupt_priority = 15; + // canCfg.tx_buffer_length = CAN_TX_BUFFER_LENGTH; + + // RX shared settings + canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_rx_gpio.Pull = GPIO_PULLUP; + canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + // TX Shared settings + canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_tx_gpio.Pull = GPIO_NOPULL; + canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + /*FDCAN_TxHeaderTypeDef TxHeader = { + .Identifier = 1, + + .IdType = FDCAN_STANDARD_ID, + .TxFrameType = FDCAN_DATA_FRAME, + .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node + // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors + .DataLength = 1, + .BitRateSwitch = FDCAN_BRS_OFF, + .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages + .MessageMarker = 0 // also change this to a real address if you change fifo control + }; + + FDCANTxMessage msg = {.data = {0x80}, .tx_header = TxHeader}; + */ + + // PCLK1 from SYSCLK + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + + // CAN1 ===================================================================== + canCfg.fdcan_instance = FDCAN1; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_11; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; + + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_12; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; + + // RX Callback CAN1 + canCfg.rx_callback = CAN1_rx_callback; // TODO: Make sure the wrapper for this is defined correctly + + // primary_can = can_init(&canCfg); + + // // Filter 1 Definitions + // FDCAN_FilterTypeDef fdcan1_filter; + + // fdcan1_filter.IdType = FDCAN_EXTENDED_ID; + // fdcan1_filter.FilterIndex = 0; + // fdcan1_filter.FilterType = FDCAN_FILTER_MASK; + // fdcan1_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + // fdcan1_filter.FilterID1 = LOCAL_GR_ID; // filter messages with ECU destination + // fdcan1_filter.FilterID2 = 0x00000FF; + + // fdcan1_filter.FilterIndex = 1; + // fdcan1_filter.FilterID1 = 0xFF; // filter messages for all targets + // HAL_FDCAN_ConfigFilter(primary_can->hal_fdcanP, &fdcan1_filter); + + // data_can = can_init(&canCfg); + + // accept unmatched standard and extended frames into RXFIFO0 - default behaviour + can1 = can_init(&canCfg); + + can_start(can1); +} + /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ + int main(void) { @@ -112,14 +331,16 @@ int main(void) /* USER CODE BEGIN SysInit */ Setup_Logomatic(&logomaticConfig); - Setup_VCP(&vcp_config); + + // LOGOMATIC("Logomatic initialization complete\n"); + // VCP_Send((uint8_t *)"VCP initialization complete\n", 29); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ - LOGOMATIC("Logomatic initialization complete\n"); - VCP_Send("VCP initialization complete\n", 29); + + CAN_Configure(); /* USER CODE END 2 */ /* Infinite loop */ @@ -128,14 +349,38 @@ int main(void) /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ - LOGOMATIC("Hello, LOGOMATIC! Great to be here\n"); - VCP_Send("Hello, VCP! Great to be here\n", 30); + LOGOMATIC("Main loop iteration\n"); + sendMSG(); + +// #ifdef EXTERNAL_LOOPBACK_TEST +// LOGOMATIC("Sending CAN message in external loopback mode\n"); +// FDCANTxMessage sendECUMsg; + +// sendECUMsg.tx_header.Identifier = (0x000FFF00 & GRCAN_GPS_RZ) >> 8; +// sendECUMsg.tx_header.IdType = FDCAN_EXTENDED_ID; +// sendECUMsg.tx_header.TxFrameType = FDCAN_DATA_FRAME; +// sendECUMsg.tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE; +// sendECUMsg.tx_header.DataLength = FDCAN_DLC_BYTES_8; +// sendECUMsg.tx_header.BitRateSwitch = FDCAN_BRS_OFF; +// sendECUMsg.tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS; +// sendECUMsg.tx_header.MessageMarker = 0; + +// GRCAN_GPS_RZ_MSG message = {.theta = 0xABCD, .acc = 0x1234, .status = 0x12345678}; + +// memcpy(sendECUMsg.data, &message, sizeof(message)); + +// can_send(can1, &sendECUMsg); + +// #endif LL_mDelay(750); } + /* USER CODE END 3 */ } + + /** * @brief System Clock Configuration * @retval None diff --git a/CANine/Core/Src/stm32g4xx_hal_msp.c b/CANine/Core/Src/stm32g4xx_hal_msp.c deleted file mode 100644 index f266230dd..000000000 --- a/CANine/Core/Src/stm32g4xx_hal_msp.c +++ /dev/null @@ -1,86 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32g4xx_hal_msp.c - * @brief This file provides code for the MSP Initialization - * and de-Initialization codes. - ****************************************************************************** - * @attention - * - * Copyright (c) 2025 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN TD */ - -/* USER CODE END TD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN Define */ - -/* USER CODE END Define */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN Macro */ - -/* USER CODE END Macro */ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* External functions --------------------------------------------------------*/ -/* USER CODE BEGIN ExternalFunctions */ - -/* USER CODE END ExternalFunctions */ - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ -/** - * Initializes the Global MSP. - */ -void HAL_MspInit(void) -{ - - /* USER CODE BEGIN MspInit 0 */ - - /* USER CODE END MspInit 0 */ - - __HAL_RCC_SYSCFG_CLK_ENABLE(); - __HAL_RCC_PWR_CLK_ENABLE(); - - /* System interrupt init*/ - - /** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral - */ - HAL_PWREx_DisableUCPDDeadBattery(); - - /* USER CODE BEGIN MspInit 1 */ - - /* USER CODE END MspInit 1 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */