From b88b247058b6bb07bae9cf45a652249851794cdd Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Mon, 1 Jun 2026 20:56:39 -0700 Subject: [PATCH 01/36] Initial commit Co-authored-by: Thomas Xu --- Autogen/CAN/Doc/GRCAN.CANdo | 27 ++++++++++++++ Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h | 61 ++++++++++++++++--------------- ECU/Application/Inc/CANdler.h | 3 ++ ECU/Application/Inc/StateData.h | 2 + ECU/Application/Inc/StateUtils.h | 1 - ECU/Application/Src/CANdler.c | 34 +++++++++++++++++ ECU/Application/Src/StateTicks.c | 2 +- ECU/Application/Src/StateUtils.c | 6 --- ECU/Core/Src/main.c | 17 ++++++++- 9 files changed, 113 insertions(+), 40 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN.CANdo b/Autogen/CAN/Doc/GRCAN.CANdo index 2041234c9..be1dd6f3c 100644 --- a/Autogen/CAN/Doc/GRCAN.CANdo +++ b/Autogen/CAN/Doc/GRCAN.CANdo @@ -108,6 +108,8 @@ routing: can_id_override: 0x2316 - msg: DTI Data 5 can_id_override: 0x2416 + - msg: DTI Data 6 + can_id_override: 0x1F16 HV DC-DC: Primary: ECU: @@ -9319,6 +9321,31 @@ Custom CAN ID: - name: "CAN Version" bit_start: 56 comment: Indicates the CAN map version. For ex: 23 -> 2,3 (V2,3) + DTI Data 6: + CAN ID: 0x1F16 + Length: 8 + signals: + - name: "Control mode" + bit_start: 0 + comment: Describes the control mode of the inverter: + 1: CONTROL_MODE_SPEED + 2: CONTROL_MODE_CURRENT + 3: CONTROL_MODE_CURRENT_BRAKE + 4: CONTROL_MODE_POS + 7: CONTROL_MODE_NONE + 0, 5, 6: NOT USED + Mainly used in multi-controller configurations for internal communication. + - name: "Target Iq" + bit_start: 8 + comment: The value represent how much Iq current the inverter is targeted to reach. This value excludes limits. For ex. if the target Iq is 50 A and temperature limit is hit, the values keep 50 A in any case, not including the deration of the temp. limit. This is useful in multi-inverter configuration to let know the secondary inverter the target Iq. + - name: "Motor position" + bit_start: 24 + comment: Motor position expressed in degrees + - name: "isMotorStill" + bit_start: 40 + comment: Represents if the motor in still position or not. + 1: still + 0: rotating IMD general: CAN ID: 0x18FF01F4 Length: 8 diff --git a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h index 5a70891ac..5a2a69f6e 100644 --- a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h +++ b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h @@ -3,36 +3,37 @@ #define CUSTOM_CAN_ID_H typedef enum { - CHARGER_CONTROL_CAN_ID = 0x1806E5F4, - CHARGER_DATA_CAN_ID = 0x18FF50E5, - DTI_CONTROL_1_CAN_ID = 0x116, - DTI_CONTROL_10_CAN_ID = 0xA16, - DTI_CONTROL_11_CAN_ID = 0xB16, - DTI_CONTROL_12_CAN_ID = 0xC16, - DTI_CONTROL_2_CAN_ID = 0x216, - DTI_CONTROL_3_CAN_ID = 0x316, - DTI_CONTROL_4_CAN_ID = 0x416, - DTI_CONTROL_5_CAN_ID = 0x516, - DTI_CONTROL_6_CAN_ID = 0x616, - DTI_CONTROL_7_CAN_ID = 0x716, - DTI_CONTROL_8_CAN_ID = 0x816, - DTI_CONTROL_9_CAN_ID = 0x916, - DTI_DATA_1_CAN_ID = 0x2016, - DTI_DATA_2_CAN_ID = 0x2116, - DTI_DATA_3_CAN_ID = 0x2216, - DTI_DATA_4_CAN_ID = 0x2316, - DTI_DATA_5_CAN_ID = 0x2416, - EM_MEAS_CAN_ID = 0x10D, - EM_STATUS_CAN_ID = 0x40D, - EM_TEAM_DATA_1_CAN_ID = 0x30D, - EM_TEAM_DATA_2_CAN_ID = 0x30E, - EM_TEMP_CAN_ID = 0x60D, - IMD_IT_SYSTEM_CAN_ID = 0x18EFF4FE, - IMD_GENERAL_CAN_ID = 0x18FF01F4, - IMD_ISOLATION_INFO_CAN_ID = 0x18EFF4FE, - IMD_REQUEST_CAN_ID = 0x18EFF4FE, - IMD_RESPONSE_CAN_ID = 0x23, - IMD_VOLTAGE_CAN_ID = 0x18EFF4FE, + CHARGER_CONTROL_CAN_ID = 0x1806E5F4, + CHARGER_DATA_CAN_ID = 0x18FF50E5, + DTI_CONTROL_1_CAN_ID = 0x116, + DTI_CONTROL_10_CAN_ID = 0xA16, + DTI_CONTROL_11_CAN_ID = 0xB16, + DTI_CONTROL_12_CAN_ID = 0xC16, + DTI_CONTROL_2_CAN_ID = 0x216, + DTI_CONTROL_3_CAN_ID = 0x316, + DTI_CONTROL_4_CAN_ID = 0x416, + DTI_CONTROL_5_CAN_ID = 0x516, + DTI_CONTROL_6_CAN_ID = 0x616, + DTI_CONTROL_7_CAN_ID = 0x716, + DTI_CONTROL_8_CAN_ID = 0x816, + DTI_CONTROL_9_CAN_ID = 0x916, + DTI_DATA_1_CAN_ID = 0x2016, + DTI_DATA_2_CAN_ID = 0x2116, + DTI_DATA_3_CAN_ID = 0x2216, + DTI_DATA_4_CAN_ID = 0x2316, + DTI_DATA_5_CAN_ID = 0x2416, + DTI_DATA_6_CAN_ID = 0x1F16, + EM_MEAS_CAN_ID = 0x10D, + EM_STATUS_CAN_ID = 0x40D, + EM_TEAM_DATA_1_CAN_ID = 0x30D, + EM_TEAM_DATA_2_CAN_ID = 0x30E, + EM_TEMP_CAN_ID = 0x60D, + IMD_IT_SYSTEM_CAN_ID = 0x18EFF4FE, + IMD_GENERAL_CAN_ID = 0x18FF01F4, + IMD_ISOLATION_INFO_CAN_ID = 0x18EFF4FE, + IMD_REQUEST_CAN_ID = 0x18EFF4FE, + IMD_RESPONSE_CAN_ID = 0x23, + IMD_VOLTAGE_CAN_ID = 0x18EFF4FE, } GRCAN_CUSTOM_ID; #endif // CUSTOM_CAN_ID_H diff --git a/ECU/Application/Inc/CANdler.h b/ECU/Application/Inc/CANdler.h index 048243634..20f8db1fa 100644 --- a/ECU/Application/Inc/CANdler.h +++ b/ECU/Application/Inc/CANdler.h @@ -4,6 +4,7 @@ #include "GRCAN_BUS_ID.h" #include "GRCAN_MSG_ID.h" #include "GRCAN_NODE_ID.h" +#include "GRCAN_CUSTOM_ID.h" #include "StateData.h" #ifndef CANDLER_H @@ -11,4 +12,6 @@ void ECU_CAN_MessageHandler(ECU_StateData *state_data, GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id, uint8_t *data, uint32_t data_length); +void ECU_CAN_DTI_MessageHandler(ECU_StateData *state_data, GRCAN_CUSTOM_ID id, uint8_t *data, uint32_t data_length); + #endif diff --git a/ECU/Application/Inc/StateData.h b/ECU/Application/Inc/StateData.h index 97992394a..d6870a523 100644 --- a/ECU/Application/Inc/StateData.h +++ b/ECU/Application/Inc/StateData.h @@ -124,6 +124,8 @@ typedef volatile struct ECU_StateData { bool apps_bse_violation; + bool is_moving; + GR_ECU_State ecu_state; CANHandle *primary_can; diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index c258b6676..96ec2d3c3 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -74,7 +74,6 @@ bool PressingBrake(volatile const ECU_StateData *stateData); float CalcBrakePressure(volatile const ECU_StateData *stateData); float CalcAccPedalTravel(volatile const ECU_StateData *stateData); bool APPS_Plausible(volatile const ECU_StateData *stateData); -bool vehicle_is_moving(volatile const ECU_StateData *stateData); /* Disable inverter for both DTI and Custom */ void disable_inverter(void); void Send_VCP_APPS(const ECU_StateData *stateData, uint16_t apps1_raw, uint16_t apps2_raw); diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 0fb46ba4e..4721a434d 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -1,16 +1,20 @@ #include "CANdler.h" #include +#include #include "GRCAN_BUS_ID.h" #include "GRCAN_MSG_ID.h" #include "GRCAN_NODE_ID.h" +#include "GRCAN_CUSTOM_ID.h" #include "Logomatic.h" #include "Pinging.h" #include "StateData.h" #include "bitManipulations.h" #define WHEEL_RPM_TO_MPH_RATIO 0.0476f +#define NUM_MOTOR_POLE_PAIRS 10 +#define GEAR_RATIO 3.0f void ReportBadMessageLength(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id) { @@ -156,3 +160,33 @@ void ECU_CAN_MessageHandler(ECU_StateData *state_data, GRCAN_BUS_ID bus_id, GRCA break; } } + +void ECU_CAN_DTI_MessageHandler(ECU_StateData *state_data, GRCAN_CUSTOM_ID id, uint8_t *data, uint32_t data_length) +{ + switch (id) { + case DTI_DATA_1_CAN_ID: + if(data_length != 8) { + ReportBadMessageLength(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); + break; + } + int32_t erpm = (data[0] << 24) + | (data[1] << 16) + | (data[2] << 8) + | (data[3]); + state_data->vehicle_speed_mph = (float) erpm / NUM_MOTOR_POLE_PAIRS / GEAR_RATIO * WHEEL_RPM_TO_MPH_RATIO; + break; + + case DTI_DATA_6_CAN_ID: + if(data_length != 8) { + ReportBadMessageLength(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); + break; + } + state_data->is_moving = !data[5]; + break; + + default: + // don't really gaf + // ReportUnhandledMessage(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); + break; + } +} diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 18d3cf616..9280b4d59 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -238,7 +238,7 @@ void ECU_Drive_Active(ECU_StateData *stateData) if (stateData->rtd_button_pressed) { stateData->ecu_state = GR_PRECHARGE_COMPLETE; - if (vehicle_is_moving(stateData)) { + if (stateData->is_moving) { LOGOMATIC("Warning: Vehicle is moving during state transition.\n"); } return; diff --git a/ECU/Application/Src/StateUtils.c b/ECU/Application/Src/StateUtils.c index 8a2a17f8a..d5fbf593e 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -175,12 +175,6 @@ bool APPS_Plausible(volatile const ECU_StateData *stateData) return error < 0.1f; } -bool vehicle_is_moving(volatile const ECU_StateData *stateData) -{ - const float tolerance = 0.1f; // In MPH - return stateData->vehicle_speed_mph > tolerance; -} - void disable_inverter(void) { GRCAN_INV_CMD_MSG inverter_msg = {.drive_enable = 0, .field_weakening = 0, .rpm_limit = 0, .set_ac_current = 0, .set_dc_current = 0}; diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 9ad6a31bb..e582c1811 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -298,7 +298,11 @@ void ADC_Configure(void) void CAN1_rx_callback(uint32_t ID, void *data, uint32_t size) { - ECU_CAN_MessageHandler(&stateLump, GRCAN_BUS_PRIMARY, (0x000FFF00 & ID) >> 8, (0xFF00000 & ID) >> 20, data, size); + if ((ID & 0x1FFFC0FF) == 0x00000016) { + ECU_CAN_DTI_MessageHandler(&stateLump, ID, data, size); + } else { + ECU_CAN_MessageHandler(&stateLump, GRCAN_BUS_PRIMARY, (0x000FFF00 & ID) >> 8, (0xFF00000 & ID) >> 20, data, size); + } } void CAN2_rx_callback(uint32_t ID, void *data, uint32_t size) @@ -327,7 +331,7 @@ void CAN_Configure(void) canCfg.hal_fdcan_init.DataTimeSeg1 = 9; // Updated for 160MHz: 160 MHz/((1+9+10)*1) = 8 Mbps canCfg.hal_fdcan_init.DataTimeSeg2 = 10; canCfg.hal_fdcan_init.StdFiltersNbr = 0; - canCfg.hal_fdcan_init.ExtFiltersNbr = 1; + canCfg.hal_fdcan_init.ExtFiltersNbr = 3; canCfg.rx_callback = NULL; canCfg.rx_interrupt_priority = 15; // TODO: Maybe make these not hardcoded @@ -392,10 +396,19 @@ void CAN_Configure(void) fdcan_primary_filter_all.FilterID1 = GRCAN_ALL & 0xFF; fdcan_primary_filter_all.FilterID2 = 0x000000FF; + FDCAN_FilterTypeDef fdcan_primary_filter_dti = {0}; + fdcan_primary_filter_ecu.IdType = FDCAN_EXTENDED_ID; + fdcan_primary_filter_ecu.FilterIndex = 2; + fdcan_primary_filter_ecu.FilterType = FDCAN_FILTER_MASK; + fdcan_primary_filter_ecu.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + fdcan_primary_filter_ecu.FilterID1 = 0x00000016; + fdcan_primary_filter_ecu.FilterID2 = 0x1FFFC0FF; + stateLump.primary_can = can_init(&canCfg); can_add_filter(stateLump.primary_can, &fdcan_primary_filter_ecu); can_add_filter(stateLump.primary_can, &fdcan_primary_filter_all); + can_add_filter(stateLump.primary_can, &fdcan_primary_filter_dti); // CAN2 ====================================================== canCfg.fdcan_instance = FDCAN2; From d4718ddff5490f19d83e83447a56fe2d3c2c5cf7 Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Mon, 1 Jun 2026 21:01:16 -0700 Subject: [PATCH 02/36] current gear ratio --- ECU/Application/Src/CANdler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 4721a434d..28d1e24da 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -14,7 +14,7 @@ #define WHEEL_RPM_TO_MPH_RATIO 0.0476f #define NUM_MOTOR_POLE_PAIRS 10 -#define GEAR_RATIO 3.0f +#define GEAR_RATIO 3.92f // will be 3.0 when the sprocket is changed void ReportBadMessageLength(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id) { From 1b0b2c26cbafe83cd95cac720fb94cb691884626 Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Mon, 1 Jun 2026 21:06:03 -0700 Subject: [PATCH 03/36] use vehicle speed when deciding whether to regen brake --- ECU/Application/Src/StateTicks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 9280b4d59..9f27e4172 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -260,7 +260,7 @@ void ECU_Drive_Active(ECU_StateData *stateData) if (stateData->apps_bse_violation || !apps_plausible) { torque_request = 0; - } else if (stateData->enable_regen && PressingBrake(stateData) && 0 > REGEN_MIN_SPEED_MPH) { // stateData->vehicle_speed_mph + } else if (stateData->enable_regen && PressingBrake(stateData) && stateData->vehicle_speed_mph > REGEN_MIN_SPEED_MPH) { torque_request = -MIN_WITH_TYPES(CalcBrakePressure(stateData) / 5000.0f * stateData->regen_strength, 1.0f) * MAX_REVERSE_CURRENT_AMPS; } else { uint16_t max_current = 0; From d5c7e3e79a2ddeaa494d1bcaf63db79f4cdedd08 Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Mon, 1 Jun 2026 21:07:37 -0700 Subject: [PATCH 04/36] Note where min speed came from --- ECU/Application/Inc/StateUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index 96ec2d3c3..53372a66d 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -14,7 +14,7 @@ uint32_t MillisecondsSinceBoot(void); #define MAX_APPS_IMPLAUSIBLE_TIME_MS 100 #define MAX_BUZZER_TIME_MS 1000 -#define REGEN_MIN_SPEED_MPH 3.106856f // MPH +#define REGEN_MIN_SPEED_MPH 3.106856f // 5 KPH #define MAX_CURRENT_AMPS 300.0f // Determined by Ryan #define MAX_REVERSE_CURRENT_AMPS 20.0f // TODO: Change as appropriate From cbbb7d7d549dbcfda18cedefb6becb2c9bdbf0e5 Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Mon, 1 Jun 2026 21:20:45 -0700 Subject: [PATCH 05/36] explicitly promote integer just in case --- ECU/Application/Src/CANdler.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 28d1e24da..ab7a616b2 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -169,10 +169,10 @@ void ECU_CAN_DTI_MessageHandler(ECU_StateData *state_data, GRCAN_CUSTOM_ID id, u ReportBadMessageLength(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); break; } - int32_t erpm = (data[0] << 24) - | (data[1] << 16) - | (data[2] << 8) - | (data[3]); + int32_t erpm = ((uint32_t)data[0] << 24) + | ((uint32_t)data[1] << 16) + | ((uint32_t)data[2] << 8) + | ((uint32_t)data[3]); state_data->vehicle_speed_mph = (float) erpm / NUM_MOTOR_POLE_PAIRS / GEAR_RATIO * WHEEL_RPM_TO_MPH_RATIO; break; From c5344f92ecf096de424681679dd3d6e4175e4240 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 04:44:40 +0000 Subject: [PATCH 06/36] Automatic CANfigurator: Updated CAN files automatically --- Autogen/CAN/Doc/GRCAN_Primary.dbc | 11 ++++++ Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h | 62 +++++++++++++++---------------- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN_Primary.dbc b/Autogen/CAN/Doc/GRCAN_Primary.dbc index 5979cc4f0..eb030e765 100644 --- a/Autogen/CAN/Doc/GRCAN_Primary.dbc +++ b/Autogen/CAN/Doc/GRCAN_Primary.dbc @@ -169,6 +169,12 @@ BO_ 2147492886 DTI_Inv_DTI_Data_5_to_ECU: 8 DTI_Inv SG_ Power_limit : 42|1@1+ (1,0) [0|0] "" ECU SG_ CAN_Version : 56|8@1+ (1,0) [0|0] "" ECU +BO_ 2147491606 DTI_Inv_DTI_Data_6_to_ECU: 8 DTI_Inv + SG_ Control_mode : 0|8@1+ (1,0) [0|0] "" ECU + SG_ Target_Iq : 8|16@1+ (1,0) [0|0] "" ECU + SG_ Motor_position : 24|16@1+ (1,0) [0|0] "" ECU + SG_ isMotorStill : 40|16@1+ (1,0) [0|0] "" ECU + BO_ 2191528450 HV_DC_DC_Status_to_ECU: 7 HV_DC_DC SG_ Input_Voltage : 0|16@1+ (0.001,0) [0|65.535] "V" ECU SG_ Output_Voltage : 16|16@1+ (0.001,0) [0|65.535] "V" ECU @@ -458,6 +464,10 @@ CM_ SG_ 2147492886 RPM_min_limit "1: RPM min limit active 0: RPM min limit inact CM_ SG_ 2147492886 RPM_max_limit "1: RPM max limit active 0: RPM max limit inactive"; CM_ SG_ 2147492886 Power_limit "1: Power limit by Config active 0: Power limit by Config inactive"; CM_ SG_ 2147492886 CAN_Version "Indicates the CAN map version. For ex: 23 -> 2,3 (V2,3)"; +CM_ SG_ 2147491606 Control_mode "Describes the control mode of the inverter:"; +CM_ SG_ 2147491606 Target_Iq "The value represent how much Iq current the inverter is targeted to reach. This value excludes limits. For ex. if the target Iq is 50 A and temperature limit is hit, the values keep 50 A in any case, not including the deration of the temp. limit. This is useful in multi-inverter configuration to let know the secondary inverter the target Iq."; +CM_ SG_ 2147491606 Motor_position "Motor position expressed in degrees"; +CM_ SG_ 2147491606 isMotorStill "Represents if the motor in still position or not."; CM_ SG_ 2191528450 Input_Voltage "~20v for LV (LV only. Send 0 for HV)"; CM_ SG_ 2191528450 Output_Voltage "~12v for LV and ~20v for HV"; CM_ SG_ 2191528450 Input_Current "Input current (LV only. Send 0 for HV)"; @@ -603,6 +613,7 @@ BA_ "VFrameFormat" BO_ 2147492118 1; BA_ "VFrameFormat" BO_ 2147492374 1; BA_ "VFrameFormat" BO_ 2147492630 1; BA_ "VFrameFormat" BO_ 2147492886 1; +BA_ "VFrameFormat" BO_ 2147491606 1; BA_ "VFrameFormat" BO_ 2191528450 1; BA_ "VFrameFormat" BO_ 2191524354 1; BA_ "VFrameFormat" BO_ 2191524353 1; diff --git a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h index 5a2a69f6e..3d14fdae7 100644 --- a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h +++ b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h @@ -3,37 +3,37 @@ #define CUSTOM_CAN_ID_H typedef enum { - CHARGER_CONTROL_CAN_ID = 0x1806E5F4, - CHARGER_DATA_CAN_ID = 0x18FF50E5, - DTI_CONTROL_1_CAN_ID = 0x116, - DTI_CONTROL_10_CAN_ID = 0xA16, - DTI_CONTROL_11_CAN_ID = 0xB16, - DTI_CONTROL_12_CAN_ID = 0xC16, - DTI_CONTROL_2_CAN_ID = 0x216, - DTI_CONTROL_3_CAN_ID = 0x316, - DTI_CONTROL_4_CAN_ID = 0x416, - DTI_CONTROL_5_CAN_ID = 0x516, - DTI_CONTROL_6_CAN_ID = 0x616, - DTI_CONTROL_7_CAN_ID = 0x716, - DTI_CONTROL_8_CAN_ID = 0x816, - DTI_CONTROL_9_CAN_ID = 0x916, - DTI_DATA_1_CAN_ID = 0x2016, - DTI_DATA_2_CAN_ID = 0x2116, - DTI_DATA_3_CAN_ID = 0x2216, - DTI_DATA_4_CAN_ID = 0x2316, - DTI_DATA_5_CAN_ID = 0x2416, - DTI_DATA_6_CAN_ID = 0x1F16, - EM_MEAS_CAN_ID = 0x10D, - EM_STATUS_CAN_ID = 0x40D, - EM_TEAM_DATA_1_CAN_ID = 0x30D, - EM_TEAM_DATA_2_CAN_ID = 0x30E, - EM_TEMP_CAN_ID = 0x60D, - IMD_IT_SYSTEM_CAN_ID = 0x18EFF4FE, - IMD_GENERAL_CAN_ID = 0x18FF01F4, - IMD_ISOLATION_INFO_CAN_ID = 0x18EFF4FE, - IMD_REQUEST_CAN_ID = 0x18EFF4FE, - IMD_RESPONSE_CAN_ID = 0x23, - IMD_VOLTAGE_CAN_ID = 0x18EFF4FE, + CHARGER_CONTROL_CAN_ID = 0x1806E5F4, + CHARGER_DATA_CAN_ID = 0x18FF50E5, + DTI_CONTROL_1_CAN_ID = 0x116, + DTI_CONTROL_10_CAN_ID = 0xA16, + DTI_CONTROL_11_CAN_ID = 0xB16, + DTI_CONTROL_12_CAN_ID = 0xC16, + DTI_CONTROL_2_CAN_ID = 0x216, + DTI_CONTROL_3_CAN_ID = 0x316, + DTI_CONTROL_4_CAN_ID = 0x416, + DTI_CONTROL_5_CAN_ID = 0x516, + DTI_CONTROL_6_CAN_ID = 0x616, + DTI_CONTROL_7_CAN_ID = 0x716, + DTI_CONTROL_8_CAN_ID = 0x816, + DTI_CONTROL_9_CAN_ID = 0x916, + DTI_DATA_1_CAN_ID = 0x2016, + DTI_DATA_2_CAN_ID = 0x2116, + DTI_DATA_3_CAN_ID = 0x2216, + DTI_DATA_4_CAN_ID = 0x2316, + DTI_DATA_5_CAN_ID = 0x2416, + DTI_DATA_6_CAN_ID = 0x1F16, + EM_MEAS_CAN_ID = 0x10D, + EM_STATUS_CAN_ID = 0x40D, + EM_TEAM_DATA_1_CAN_ID = 0x30D, + EM_TEAM_DATA_2_CAN_ID = 0x30E, + EM_TEMP_CAN_ID = 0x60D, + IMD_IT_SYSTEM_CAN_ID = 0x18EFF4FE, + IMD_GENERAL_CAN_ID = 0x18FF01F4, + IMD_ISOLATION_INFO_CAN_ID = 0x18EFF4FE, + IMD_REQUEST_CAN_ID = 0x18EFF4FE, + IMD_RESPONSE_CAN_ID = 0x23, + IMD_VOLTAGE_CAN_ID = 0x18EFF4FE, } GRCAN_CUSTOM_ID; #endif // CUSTOM_CAN_ID_H From 4c9c5031aa1fe73737a399b270b11837d31b9aba Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 04:46:15 +0000 Subject: [PATCH 07/36] Automatic Clang-Format: Standardized formatting automatically --- ECU/Application/Inc/CANdler.h | 2 +- ECU/Application/Src/CANdler.c | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/ECU/Application/Inc/CANdler.h b/ECU/Application/Inc/CANdler.h index 20f8db1fa..47cb01326 100644 --- a/ECU/Application/Inc/CANdler.h +++ b/ECU/Application/Inc/CANdler.h @@ -2,9 +2,9 @@ #include #include "GRCAN_BUS_ID.h" +#include "GRCAN_CUSTOM_ID.h" #include "GRCAN_MSG_ID.h" #include "GRCAN_NODE_ID.h" -#include "GRCAN_CUSTOM_ID.h" #include "StateData.h" #ifndef CANDLER_H diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index ab7a616b2..72dc7ad45 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -1,12 +1,12 @@ #include "CANdler.h" -#include #include +#include #include "GRCAN_BUS_ID.h" +#include "GRCAN_CUSTOM_ID.h" #include "GRCAN_MSG_ID.h" #include "GRCAN_NODE_ID.h" -#include "GRCAN_CUSTOM_ID.h" #include "Logomatic.h" #include "Pinging.h" #include "StateData.h" @@ -165,19 +165,16 @@ void ECU_CAN_DTI_MessageHandler(ECU_StateData *state_data, GRCAN_CUSTOM_ID id, u { switch (id) { case DTI_DATA_1_CAN_ID: - if(data_length != 8) { + if (data_length != 8) { ReportBadMessageLength(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); break; } - int32_t erpm = ((uint32_t)data[0] << 24) - | ((uint32_t)data[1] << 16) - | ((uint32_t)data[2] << 8) - | ((uint32_t)data[3]); - state_data->vehicle_speed_mph = (float) erpm / NUM_MOTOR_POLE_PAIRS / GEAR_RATIO * WHEEL_RPM_TO_MPH_RATIO; + int32_t erpm = ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | ((uint32_t)data[3]); + state_data->vehicle_speed_mph = (float)erpm / NUM_MOTOR_POLE_PAIRS / GEAR_RATIO * WHEEL_RPM_TO_MPH_RATIO; break; case DTI_DATA_6_CAN_ID: - if(data_length != 8) { + if (data_length != 8) { ReportBadMessageLength(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); break; } From b4fda59ffa7bbc659e7071d0a4d48620f5c2b824 Mon Sep 17 00:00:00 2001 From: Thomas Xu Date: Thu, 4 Jun 2026 20:52:46 -0700 Subject: [PATCH 08/36] Adjust `disable_inverter` offset for current requests. --- ECU/Application/Src/StateUtils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/StateUtils.c b/ECU/Application/Src/StateUtils.c index d5fbf593e..be3d158a8 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -177,7 +177,7 @@ bool APPS_Plausible(volatile const ECU_StateData *stateData) void disable_inverter(void) { - GRCAN_INV_CMD_MSG inverter_msg = {.drive_enable = 0, .field_weakening = 0, .rpm_limit = 0, .set_ac_current = 0, .set_dc_current = 0}; + GRCAN_INV_CMD_MSG inverter_msg = {.drive_enable = 0, .field_weakening = 0, .rpm_limit = 0, .set_ac_current = 32768, .set_dc_current = 32768}; ECU_CAN_Send(GRCAN_BUS_PRIMARY, GRCAN_GR_Inv, GRCAN_INV_CMD, &inverter_msg, sizeof(inverter_msg)); ECU_CAN_Send_DTI(DTI_CONTROL_12_CAN_ID, &inverter_msg.drive_enable, 1); } From cb5e869434ded2f8a6807fd80eeb4bb123a5f98f Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 19:28:00 -0700 Subject: [PATCH 09/36] Data 6 does not exist in our version (v2.4 not v2.5) Signed-off-by: Daniel Hansen --- Autogen/CAN/Doc/GRCAN.CANdo | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN.CANdo b/Autogen/CAN/Doc/GRCAN.CANdo index be1dd6f3c..11c571064 100644 --- a/Autogen/CAN/Doc/GRCAN.CANdo +++ b/Autogen/CAN/Doc/GRCAN.CANdo @@ -9321,31 +9321,6 @@ Custom CAN ID: - name: "CAN Version" bit_start: 56 comment: Indicates the CAN map version. For ex: 23 -> 2,3 (V2,3) - DTI Data 6: - CAN ID: 0x1F16 - Length: 8 - signals: - - name: "Control mode" - bit_start: 0 - comment: Describes the control mode of the inverter: - 1: CONTROL_MODE_SPEED - 2: CONTROL_MODE_CURRENT - 3: CONTROL_MODE_CURRENT_BRAKE - 4: CONTROL_MODE_POS - 7: CONTROL_MODE_NONE - 0, 5, 6: NOT USED - Mainly used in multi-controller configurations for internal communication. - - name: "Target Iq" - bit_start: 8 - comment: The value represent how much Iq current the inverter is targeted to reach. This value excludes limits. For ex. if the target Iq is 50 A and temperature limit is hit, the values keep 50 A in any case, not including the deration of the temp. limit. This is useful in multi-inverter configuration to let know the secondary inverter the target Iq. - - name: "Motor position" - bit_start: 24 - comment: Motor position expressed in degrees - - name: "isMotorStill" - bit_start: 40 - comment: Represents if the motor in still position or not. - 1: still - 0: rotating IMD general: CAN ID: 0x18FF01F4 Length: 8 From 9379b40b62f821fd3e455bcfdf540d0d811919f1 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 19:28:21 -0700 Subject: [PATCH 10/36] Remove logic relating to not real dti data 6 Signed-off-by: Daniel Hansen --- ECU/Application/Inc/StateData.h | 2 -- ECU/Application/Src/CANdler.c | 8 -------- ECU/Application/Src/StateTicks.c | 2 +- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/ECU/Application/Inc/StateData.h b/ECU/Application/Inc/StateData.h index d6870a523..97992394a 100644 --- a/ECU/Application/Inc/StateData.h +++ b/ECU/Application/Inc/StateData.h @@ -124,8 +124,6 @@ typedef volatile struct ECU_StateData { bool apps_bse_violation; - bool is_moving; - GR_ECU_State ecu_state; CANHandle *primary_can; diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 72dc7ad45..fadfda906 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -173,14 +173,6 @@ void ECU_CAN_DTI_MessageHandler(ECU_StateData *state_data, GRCAN_CUSTOM_ID id, u state_data->vehicle_speed_mph = (float)erpm / NUM_MOTOR_POLE_PAIRS / GEAR_RATIO * WHEEL_RPM_TO_MPH_RATIO; break; - case DTI_DATA_6_CAN_ID: - if (data_length != 8) { - ReportBadMessageLength(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); - break; - } - state_data->is_moving = !data[5]; - break; - default: // don't really gaf // ReportUnhandledMessage(GRCAN_BUS_PRIMARY, (GRCAN_MSG_ID)id, GRCAN_DTI_Inv); diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 9f27e4172..c5226772b 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -238,7 +238,7 @@ void ECU_Drive_Active(ECU_StateData *stateData) if (stateData->rtd_button_pressed) { stateData->ecu_state = GR_PRECHARGE_COMPLETE; - if (stateData->is_moving) { + if (stateData->vehicle_speed_mph > 0) { LOGOMATIC("Warning: Vehicle is moving during state transition.\n"); } return; From d776c65989ad72136bb11c2b54baabf3cceffcb0 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 02:28:51 +0000 Subject: [PATCH 11/36] Automatic CANfigurator: Updated CAN files automatically --- Autogen/CAN/Doc/GRCAN_Primary.dbc | 11 ----------- Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h | 1 - 2 files changed, 12 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN_Primary.dbc b/Autogen/CAN/Doc/GRCAN_Primary.dbc index eb030e765..5979cc4f0 100644 --- a/Autogen/CAN/Doc/GRCAN_Primary.dbc +++ b/Autogen/CAN/Doc/GRCAN_Primary.dbc @@ -169,12 +169,6 @@ BO_ 2147492886 DTI_Inv_DTI_Data_5_to_ECU: 8 DTI_Inv SG_ Power_limit : 42|1@1+ (1,0) [0|0] "" ECU SG_ CAN_Version : 56|8@1+ (1,0) [0|0] "" ECU -BO_ 2147491606 DTI_Inv_DTI_Data_6_to_ECU: 8 DTI_Inv - SG_ Control_mode : 0|8@1+ (1,0) [0|0] "" ECU - SG_ Target_Iq : 8|16@1+ (1,0) [0|0] "" ECU - SG_ Motor_position : 24|16@1+ (1,0) [0|0] "" ECU - SG_ isMotorStill : 40|16@1+ (1,0) [0|0] "" ECU - BO_ 2191528450 HV_DC_DC_Status_to_ECU: 7 HV_DC_DC SG_ Input_Voltage : 0|16@1+ (0.001,0) [0|65.535] "V" ECU SG_ Output_Voltage : 16|16@1+ (0.001,0) [0|65.535] "V" ECU @@ -464,10 +458,6 @@ CM_ SG_ 2147492886 RPM_min_limit "1: RPM min limit active 0: RPM min limit inact CM_ SG_ 2147492886 RPM_max_limit "1: RPM max limit active 0: RPM max limit inactive"; CM_ SG_ 2147492886 Power_limit "1: Power limit by Config active 0: Power limit by Config inactive"; CM_ SG_ 2147492886 CAN_Version "Indicates the CAN map version. For ex: 23 -> 2,3 (V2,3)"; -CM_ SG_ 2147491606 Control_mode "Describes the control mode of the inverter:"; -CM_ SG_ 2147491606 Target_Iq "The value represent how much Iq current the inverter is targeted to reach. This value excludes limits. For ex. if the target Iq is 50 A and temperature limit is hit, the values keep 50 A in any case, not including the deration of the temp. limit. This is useful in multi-inverter configuration to let know the secondary inverter the target Iq."; -CM_ SG_ 2147491606 Motor_position "Motor position expressed in degrees"; -CM_ SG_ 2147491606 isMotorStill "Represents if the motor in still position or not."; CM_ SG_ 2191528450 Input_Voltage "~20v for LV (LV only. Send 0 for HV)"; CM_ SG_ 2191528450 Output_Voltage "~12v for LV and ~20v for HV"; CM_ SG_ 2191528450 Input_Current "Input current (LV only. Send 0 for HV)"; @@ -613,7 +603,6 @@ BA_ "VFrameFormat" BO_ 2147492118 1; BA_ "VFrameFormat" BO_ 2147492374 1; BA_ "VFrameFormat" BO_ 2147492630 1; BA_ "VFrameFormat" BO_ 2147492886 1; -BA_ "VFrameFormat" BO_ 2147491606 1; BA_ "VFrameFormat" BO_ 2191528450 1; BA_ "VFrameFormat" BO_ 2191524354 1; BA_ "VFrameFormat" BO_ 2191524353 1; diff --git a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h index 3d14fdae7..5a70891ac 100644 --- a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h +++ b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h @@ -22,7 +22,6 @@ typedef enum { DTI_DATA_3_CAN_ID = 0x2216, DTI_DATA_4_CAN_ID = 0x2316, DTI_DATA_5_CAN_ID = 0x2416, - DTI_DATA_6_CAN_ID = 0x1F16, EM_MEAS_CAN_ID = 0x10D, EM_STATUS_CAN_ID = 0x40D, EM_TEAM_DATA_1_CAN_ID = 0x30D, From 42774e4c4f743fa4c3f9d9346e98f2c44355f5e8 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 19:29:09 -0700 Subject: [PATCH 12/36] Nuke remaining dti data 6 ref Signed-off-by: Daniel Hansen --- Autogen/CAN/Doc/GRCAN.CANdo | 2 -- 1 file changed, 2 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN.CANdo b/Autogen/CAN/Doc/GRCAN.CANdo index 11c571064..2041234c9 100644 --- a/Autogen/CAN/Doc/GRCAN.CANdo +++ b/Autogen/CAN/Doc/GRCAN.CANdo @@ -108,8 +108,6 @@ routing: can_id_override: 0x2316 - msg: DTI Data 5 can_id_override: 0x2416 - - msg: DTI Data 6 - can_id_override: 0x1F16 HV DC-DC: Primary: ECU: From 8bcbd1a50871a15f17ec432e148461d4484f5bba Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 19:42:52 -0700 Subject: [PATCH 13/36] Enable regen on the branch to test regen Signed-off-by: Daniel Hansen --- ECU/Application/Src/StateTicks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index c5226772b..ae7608ee3 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -59,7 +59,7 @@ ECU_StateData stateLump = { .apps_2_max = 1926, // Regen .regen_strength = 2, - .enable_regen = false}; + .enable_regen = true }; static uint32_t millis_since_boot; void ECU_State_Tick(void) From 7e7f1a26c9891e1678e8412031f4a297b3e365af Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 02:44:07 +0000 Subject: [PATCH 14/36] Automatic Clang-Format: Standardized formatting automatically --- ECU/Application/Src/StateTicks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index ae7608ee3..db3970833 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -59,7 +59,7 @@ ECU_StateData stateLump = { .apps_2_max = 1926, // Regen .regen_strength = 2, - .enable_regen = true }; + .enable_regen = true}; static uint32_t millis_since_boot; void ECU_State_Tick(void) From 6d88e875ce705b627d6bbe95126d533c87b06581 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 21:39:31 -0700 Subject: [PATCH 15/36] Use more explicit math for `WHEEL_RPM_TO_MPH_RATIO` Signed-off-by: Daniel Hansen --- ECU/Application/Src/CANdler.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index fadfda906..187b57fba 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -12,9 +12,13 @@ #include "StateData.h" #include "bitManipulations.h" -#define WHEEL_RPM_TO_MPH_RATIO 0.0476f +#define WHEEL_RADIUS_INCHES 8.0f +#define WHEEL_CIRCUMFERENCE_INCHES (2.0f * M_PI * WHEEL_RADIUS_INCHES) +#define WHEEL_RPM_TO_MPH_RATIO (WHEEL_CIRCUMFERENCE_INCHES / 63360.0f * 60.0f) #define NUM_MOTOR_POLE_PAIRS 10 -#define GEAR_RATIO 3.92f // will be 3.0 when the sprocket is changed +#define DRIVEN_SPROCKET_TEETH 51.0f +#define DRIVING_SPROCKET_TEETH 19.0f +#define GEAR_RATIO (51.0f / 19.0f) void ReportBadMessageLength(GRCAN_BUS_ID bus_id, GRCAN_MSG_ID msg_id, GRCAN_NODE_ID sender_id) { From 136e5c21d3f36372819162d9a8440be2ee65f522 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 21:39:42 -0700 Subject: [PATCH 16/36] Cleanup actual calc Signed-off-by: Daniel Hansen --- ECU/Application/Src/CANdler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 187b57fba..6e9d62e08 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -174,7 +174,7 @@ void ECU_CAN_DTI_MessageHandler(ECU_StateData *state_data, GRCAN_CUSTOM_ID id, u break; } int32_t erpm = ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | ((uint32_t)data[3]); - state_data->vehicle_speed_mph = (float)erpm / NUM_MOTOR_POLE_PAIRS / GEAR_RATIO * WHEEL_RPM_TO_MPH_RATIO; + state_data->vehicle_speed_mph = (float)erpm * WHEEL_RPM_TO_MPH_RATIO / (NUM_MOTOR_POLE_PAIRS * GEAR_RATIO); break; default: From 6884d0e6d5ec77f2f0098c35cd5979219c0aca55 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 21:44:34 -0700 Subject: [PATCH 17/36] Never print buzz Signed-off-by: Daniel Hansen --- ECU/Application/Src/StateTicks.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index db3970833..e22114d11 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -233,7 +233,6 @@ void ECU_Drive_Active(ECU_StateData *stateData) LL_GPIO_ResetOutputPin(RTD_CONTROL_GPIO_Port, RTD_CONTROL_Pin); } else { LL_GPIO_SetOutputPin(RTD_CONTROL_GPIO_Port, RTD_CONTROL_Pin); - // LOGOMATIC("buzz!\n"); } if (stateData->rtd_button_pressed) { From 3f178c9e58dea4c74a0254b4f4e26e6d7f6bc49a Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sat, 6 Jun 2026 22:10:57 -0700 Subject: [PATCH 18/36] Pi floats! Signed-off-by: Daniel Hansen --- ECU/Application/Src/CANdler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 6e9d62e08..1478a8b76 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -13,7 +13,7 @@ #include "bitManipulations.h" #define WHEEL_RADIUS_INCHES 8.0f -#define WHEEL_CIRCUMFERENCE_INCHES (2.0f * M_PI * WHEEL_RADIUS_INCHES) +#define WHEEL_CIRCUMFERENCE_INCHES (2.0f * (float)M_PI * WHEEL_RADIUS_INCHES) #define WHEEL_RPM_TO_MPH_RATIO (WHEEL_CIRCUMFERENCE_INCHES / 63360.0f * 60.0f) #define NUM_MOTOR_POLE_PAIRS 10 #define DRIVEN_SPROCKET_TEETH 51.0f From ffd0865754d8fe246394a5982f4317b243baa864 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Mon, 8 Jun 2026 21:00:44 -0700 Subject: [PATCH 19/36] Ensure the brake lights stay on at least 100ms Copied from `dfb8fbc9f0e1928c02f05b7379796cb03bb8190f` Signed-off-by: Daniel Hansen --- ECU/Application/Src/Lights.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ECU/Application/Src/Lights.c b/ECU/Application/Src/Lights.c index 3e0e7c31d..ddd9eb07c 100644 --- a/ECU/Application/Src/Lights.c +++ b/ECU/Application/Src/Lights.c @@ -13,7 +13,13 @@ void BrakeLightControl(ECU_StateData *stateLump) { + static uint32_t brake_light_start_millis; + if (PressingBrake(stateLump)) { + brake_light_start_millis = MillisecondsSinceBoot(); + } + + if (MillisecondsSinceBoot() - brake_light_start_millis < 100) { LL_GPIO_SetOutputPin(BRAKE_LIGHT_GPIO_Port, BRAKE_LIGHT_Pin); } else { LL_GPIO_ResetOutputPin(BRAKE_LIGHT_GPIO_Port, BRAKE_LIGHT_Pin); From bc696e2998221683d031eac4c4fb2a69170ac3e3 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Mon, 8 Jun 2026 21:02:18 -0700 Subject: [PATCH 20/36] Run brake and dash lights during startup delay Co-authored-by: kzwicker Signed-off-by: Daniel Hansen --- ECU/Application/Inc/Lights.h | 2 ++ ECU/Core/Src/main.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ECU/Application/Inc/Lights.h b/ECU/Application/Inc/Lights.h index 37e3b6626..08fa9658c 100644 --- a/ECU/Application/Inc/Lights.h +++ b/ECU/Application/Inc/Lights.h @@ -12,6 +12,8 @@ * * @return void */ +void BrakeLightControl(ECU_StateData *stateLump); +void dashLights(ECU_StateData *stateLump); void lightControl(ECU_StateData *stateData); #endif diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index e582c1811..3e54fac46 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -498,6 +498,8 @@ int main(void) LOGOMATIC("Boot completed at %lu ms\n", MillisecondsSinceBoot()); while (MillisecondsSinceBoot() < 5000) { // Notes per Andrey and Ryan + BrakeLightControl(&stateLump); + dashLights(&stateLump); LL_mDelay(1); ADC_UpdateAnalogValues_EMA(ADC_buffers, NUM_SIGNALS, adc_alpha, ADC_outputs); write_adc_values_to_state_data(); From e04322a43723ee0248e0af588179056a6ecd151e Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Tue, 9 Jun 2026 10:53:09 -0700 Subject: [PATCH 21/36] Move driving critical decisions from brake f and brake r to just bse/f https://discord.com/channels/756738476887638107/1457989718741618788/1513853014874521680 Signed-off-by: Daniel Hansen --- ECU/Application/Src/StateUtils.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ECU/Application/Src/StateUtils.c b/ECU/Application/Src/StateUtils.c index be3d158a8..2297cb216 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -140,7 +140,7 @@ bool PressingBrake(volatile const ECU_StateData *stateData) } #endif - return (stateData->Brake_F_Signal > stateData->brake_f_min) || (stateData->Brake_R_Signal > stateData->brake_r_min); + return stateData->bse_signal > stateData->brake_bse_min; } float CalcBrakePressure(volatile const ECU_StateData *stateData) @@ -149,9 +149,7 @@ float CalcBrakePressure(volatile const ECU_StateData *stateData) return 0; #endif - float psi_front = stateData->Brake_F_Signal / 4096.0f * 5000.0f; - float psi_rear = stateData->Brake_R_Signal / 4096.0f * 5000.0f; - return fmaxf(psi_front, psi_rear); + return stateData->bse_signal / 4096.0f * 5000.0f; } // TODO: reconsider deadzone From acbbbb586cec1b1e7bdcf6ad90302d94aceffcff Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Tue, 9 Jun 2026 22:32:20 -0700 Subject: [PATCH 22/36] Send analog data (eg pedals) every 30 ms Signed-off-by: Daniel Hansen --- ECU/Application/Src/CANutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/CANutils.c b/ECU/Application/Src/CANutils.c index 5b1765cc9..0e340fee8 100644 --- a/ECU/Application/Src/CANutils.c +++ b/ECU/Application/Src/CANutils.c @@ -132,7 +132,7 @@ void SendECUAnalogDataOverCAN(const ECU_StateData *stateData) uint32_t millis_since_boot = MillisecondsSinceBoot(); static uint32_t last_can_tcm_request_millis = 0; - if (millis_since_boot - last_can_tcm_request_millis > 100) { + if (millis_since_boot - last_can_tcm_request_millis > 30) { GRCAN_ECU_ANALOG_DATA_MSG message = {.bspd_signal = stateData->bspd_signal, .bse_signal = stateData->bse_signal, .apps_1_signal = stateData->APPS1_Signal, From 7fbd756a8ed17dcc7ee8470e5bb3545c0c52a356 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Tue, 9 Jun 2026 22:47:04 -0700 Subject: [PATCH 23/36] Have hootl tests use bse instead of brake f Signed-off-by: Daniel Hansen --- ECU/Test/Src/StateTicksTest.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ECU/Test/Src/StateTicksTest.c b/ECU/Test/Src/StateTicksTest.c index 5fbedb3fc..75a3b4112 100644 --- a/ECU/Test/Src/StateTicksTest.c +++ b/ECU/Test/Src/StateTicksTest.c @@ -163,7 +163,7 @@ int main(void) stateLumpTest.APPS2_Signal = stateLumpTest.apps_2_min; LOGOMATIC("Press brake: STAY IN GLV ON\n"); - stateLumpTest.Brake_F_Signal = stateLumpTest.brake_f_min + 69; + stateLumpTest.bse_signal = stateLumpTest.brake_bse_min + 69; ECU_Pseudo_State_Tick(&stateLumpTest); if (stateLumpTest.ecu_state != GR_GLV_ON) { LOGOMATIC("0.2 Failure: ecu state not in GLV ON\n"); @@ -175,7 +175,7 @@ int main(void) } LOGOMATIC("Release brake: STAY IN GLV ON\n"); - stateLumpTest.Brake_F_Signal = 0; + stateLumpTest.bse_signal = 0; ECU_Pseudo_State_Tick(&stateLumpTest); if (stateLumpTest.ecu_state != GR_GLV_ON) { LOGOMATIC("0.2 Failure: ecu state not in GLV ON\n"); @@ -256,7 +256,7 @@ int main(void) // ## Step 0.7 ## // ########################## LOGOMATIC("Press and release the RTD button WHILE pressing the brake\n"); - stateLumpTest.Brake_F_Signal = stateLumpTest.brake_f_min + 69; + stateLumpTest.bse_signal = stateLumpTest.brake_bse_min + 69; LOGOMATIC("Press RTD\n"); stateLumpTest.rtd_button_press_interrupt = true; ECU_Pseudo_State_Tick(&stateLumpTest); @@ -275,7 +275,7 @@ int main(void) // ## Step 0.8 ## // ########################## LOGOMATIC("Release Brakes -> STAY IN DRIVE ACTIVE\n"); - stateLumpTest.Brake_F_Signal = 0; + stateLumpTest.bse_signal = 0; ECU_Pseudo_State_Tick(&stateLumpTest); if (stateLumpTest.ecu_state != GR_DRIVE_ACTIVE) { LOGOMATIC("0.8 Failure: ecu state not in drive active\n"); @@ -324,7 +324,7 @@ int main(void) LOGOMATIC("Press Throttle and Brake -> STAY IN DRIVE ACTIVE\n"); stateLumpTest.APPS1_Signal = stateLumpTest.apps_1_max; stateLumpTest.APPS2_Signal = stateLumpTest.apps_2_max; - stateLumpTest.Brake_F_Signal = stateLumpTest.brake_f_min + 69; + stateLumpTest.bse_signal = stateLumpTest.brake_bse_min + 69; ECU_Pseudo_State_Tick(&stateLumpTest); if (stateLumpTest.ecu_state != GR_DRIVE_ACTIVE) { LOGOMATIC("0.11 Failure: ecu state not in drive active\n"); @@ -341,7 +341,7 @@ int main(void) LOGOMATIC("Release Throttle and Brake-> STAY IN DRIVE ACTIVE\n"); stateLumpTest.APPS1_Signal = stateLumpTest.apps_1_min; stateLumpTest.APPS2_Signal = stateLumpTest.apps_2_min; - stateLumpTest.Brake_F_Signal = 0; + stateLumpTest.bse_signal = 0; ECU_Pseudo_State_Tick(&stateLumpTest); if (stateLumpTest.ecu_state != GR_DRIVE_ACTIVE) { LOGOMATIC("0.12 Failure: ecu state not in drive active\n"); From 06695128f77fa1a6c1d55b47bf2c412250c64cbe Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Thu, 11 Jun 2026 19:47:03 -0700 Subject: [PATCH 24/36] More power! Signed-off-by: Daniel Hansen --- Autogen/CAN/Doc/GRCAN.CANdo | 2 +- ECU/Application/Src/StateTicks.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN.CANdo b/Autogen/CAN/Doc/GRCAN.CANdo index 2041234c9..03bd7924a 100644 --- a/Autogen/CAN/Doc/GRCAN.CANdo +++ b/Autogen/CAN/Doc/GRCAN.CANdo @@ -560,7 +560,7 @@ Message ID: data type: u4 Torque Map: bit_start: 36 - comment: The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor. 0 is max current amps, 1 is 50 / 100 / 150 / 200 / 250 / 275, 2 and later is tbd + comment: The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor. 0 is max current amps, 1 is 100 / 200 / 250 / 300 / 325 / 350 Amps, 2 and later is tbd data type: u4 Max Cell Temp: bit_start: 40 diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index e22114d11..2c79efa41 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -31,8 +31,8 @@ ECU_StateData stateLump = { .ecu_state = GR_GLV_ON, // Assume ACU good at boot .acu_software_latch = 1, - // Startup at just above minimum power - .powerlevel = 1, + // Startup at minimum power + .powerlevel = 0, // See CANdo specification .torquemap = 1, // APPS Deadzone @@ -266,22 +266,22 @@ void ECU_Drive_Active(ECU_StateData *stateData) // Chosen max current for different power level / torque maps switch (stateData->powerlevel) { case 0: - max_current = 50; + max_current = 100; break; case 1: - max_current = 100; + max_current = 200; break; case 2: - max_current = 150; + max_current = 250; break; case 3: - max_current = 200; + max_current = 300; break; case 4: - max_current = 250; + max_current = 325; break; case 5: - max_current = 275; + max_current = 350; break; default: LOGOMATIC("Invalid power level: %d. Defaulting to no current.\n", stateData->powerlevel); From 7c56baa72874d042a7d58d8262e910bb0545392c Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 02:47:49 +0000 Subject: [PATCH 25/36] Automatic CANfigurator: Updated CAN files automatically --- Autogen/CAN/Doc/GRCAN_Primary.dbc | 2 +- Autogen/CAN/Inc/GRCAN_MSG_DATA.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN_Primary.dbc b/Autogen/CAN/Doc/GRCAN_Primary.dbc index 5979cc4f0..dc09b2400 100644 --- a/Autogen/CAN/Doc/GRCAN_Primary.dbc +++ b/Autogen/CAN/Doc/GRCAN_Primary.dbc @@ -515,7 +515,7 @@ CM_ SG_ 2149581568 Ping_Group_1 "[Byte 1 / Bits 8-15] ECU ping targets 8: ACU (1 CM_ SG_ 2149581568 Ping_Group_2 "[Byte 2 / Bits 16-23] ECU ping targets 16: Suspension FL (1: OK, 0: Timeout) 17: Suspension FR (1: OK, 0: Timeout) 18: Suspension RL (1: OK, 0: Timeout) 19: Suspension RR (1: OK, 0: Timeout) 20: InboardFloor FL (1: OK, 0: Timeout) 21: InboardFloor FR (1: OK, 0: Timeout) 22: InboardFloor RL (1: OK, 0: Timeout) 23: InboardFloor RR (1: OK, 0: Timeout)"; CM_ SG_ 2149581568 Ping_Group_3 "[Byte 3 / Bits 24-31] ECU ping targets 24: TireTemp FL (1: OK, 0: Timeout) 25: TireTemp FR (1: OK, 0: Timeout) 26: TireTemp RL (1: OK, 0: Timeout) 27: TireTemp RR (1: OK, 0: Timeout) 28: BrakeTemp FL (1: OK, 0: Timeout) 29: BrakeTemp FR (1: OK, 0: Timeout) 30: BrakeTemp RL (1: OK, 0: Timeout) 31: BrakeTemp RR (1: OK, 0: Timeout)"; CM_ SG_ 2149581568 Power_Level "Controls the AC current limits to each of the inverters Discrete Mapping, actual current values described by the torque map"; -CM_ SG_ 2149581568 Torque_Map "The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor. 0 is max current amps, 1 is 50 / 100 / 150 / 200 / 250 / 275, 2 and later is tbd"; +CM_ SG_ 2149581568 Torque_Map "The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor. 0 is max current amps, 1 is 100 / 200 / 250 / 300 / 325 / 350 Amps, 2 and later is tbd"; CM_ SG_ 2149581568 Max_Cell_Temp "the Temp of the hottest cell of the accumulator"; CM_ SG_ 2149581568 Accumulator_State_of_Chg "% charged of the Accumulator"; CM_ SG_ 2149581568 GLV_State_of_Chg "% charged of the Low Voltage Bat"; diff --git a/Autogen/CAN/Inc/GRCAN_MSG_DATA.h b/Autogen/CAN/Inc/GRCAN_MSG_DATA.h index c00113345..5d5b185d2 100644 --- a/Autogen/CAN/Inc/GRCAN_MSG_DATA.h +++ b/Autogen/CAN/Inc/GRCAN_MSG_DATA.h @@ -53,8 +53,8 @@ See diagram in StateMachine.h (Byte 0) */ 31: BrakeTemp RR (1: OK, 0: Timeout) (Byte 3) */ uint8_t ping_group_3; /** Controls the AC current limits to each of the inverters -Discrete Mapping, actual current values described by the torque map The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor. 0 is max current amps, 1 is 50 -/ 100 / 150 / 200 / 250 / 275, 2 and later is tbd (Byte 4) */ +Discrete Mapping, actual current values described by the torque map The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor. 0 is max current amps, 1 is 100 +/ 200 / 250 / 300 / 325 / 350 Amps, 2 and later is tbd (Byte 4) */ uint8_t power_level_torque_map; /** the Temp of the hottest cell of the accumulator (Byte 5) */ uint8_t max_cell_temp; From 7858fd54ab87fcd4bd35dbd8d831010c1d386b7b Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Thu, 11 Jun 2026 19:51:01 -0700 Subject: [PATCH 26/36] Adjust hard coded absolute non-configurable maximum Signed-off-by: Daniel Hansen --- ECU/Application/Inc/StateUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index 53372a66d..62d11d066 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -16,7 +16,7 @@ uint32_t MillisecondsSinceBoot(void); #define REGEN_MIN_SPEED_MPH 3.106856f // 5 KPH -#define MAX_CURRENT_AMPS 300.0f // Determined by Ryan +#define MAX_CURRENT_AMPS 375.0f // Determined by Ryan #define MAX_REVERSE_CURRENT_AMPS 20.0f // TODO: Change as appropriate #define ECU_STATUS_MSG_PERIOD_MILLIS (1000) From 424609c443b704b805807b60804daeaca9394e3d Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Thu, 11 Jun 2026 19:53:46 -0700 Subject: [PATCH 27/36] Incorporate brake pressure fix ```c float pressure_psi = ((float)adc_counts - 654.09f) * 5000.0f / 2614.73f; ``` https://discord.com/channels/@me/1339848701379612764/1514824425336340532 Signed-off-by: Daniel Hansen --- ECU/Application/Src/StateUtils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/StateUtils.c b/ECU/Application/Src/StateUtils.c index 2297cb216..85929bafb 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -149,7 +149,7 @@ float CalcBrakePressure(volatile const ECU_StateData *stateData) return 0; #endif - return stateData->bse_signal / 4096.0f * 5000.0f; + return ((float)stateData->bse_signal - 654.09f) * 5000.0f / 2614.73f; } // TODO: reconsider deadzone From 113c1b927a4de77a9baa4f4b63fd5230d9b33a92 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Thu, 11 Jun 2026 20:09:27 -0700 Subject: [PATCH 28/36] Temp disable regen Signed-off-by: Daniel Hansen --- ECU/Application/Src/StateTicks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 2c79efa41..e5e15e481 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -59,7 +59,7 @@ ECU_StateData stateLump = { .apps_2_max = 1926, // Regen .regen_strength = 2, - .enable_regen = true}; + .enable_regen = false}; static uint32_t millis_since_boot; void ECU_State_Tick(void) From 145ff2a1b30d739aa3838ec21065e1e8ee8c6c19 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Thu, 11 Jun 2026 20:19:03 -0700 Subject: [PATCH 29/36] Battery max reverse current at 30A Signed-off-by: Daniel Hansen --- ECU/Application/Inc/StateUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index 62d11d066..955b0a520 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -17,7 +17,7 @@ uint32_t MillisecondsSinceBoot(void); #define REGEN_MIN_SPEED_MPH 3.106856f // 5 KPH #define MAX_CURRENT_AMPS 375.0f // Determined by Ryan -#define MAX_REVERSE_CURRENT_AMPS 20.0f // TODO: Change as appropriate +#define MAX_REVERSE_CURRENT_AMPS 30.0f // TODO: Change as appropriate #define ECU_STATUS_MSG_PERIOD_MILLIS (1000) #define TRACTIVE_SYSTEM_MAX_PERMITTED_DISCHARGE_TIME_MILLIS (5000) From 1502edabbfde426338c576bc3c53e1658e1cf45e Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Wed, 17 Jun 2026 21:49:50 -0400 Subject: [PATCH 30/36] The Unwronging of the Dash Panel Lights --- ECU/Application/Inc/StateData.h | 4 +--- ECU/Application/Src/Lights.c | 17 +++++++++++------ ECU/Application/Src/StateTicks.c | 4 +++- ECU/Core/Src/main.c | 11 ++++++++++- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ECU/Application/Inc/StateData.h b/ECU/Application/Inc/StateData.h index 97992394a..0cd60783f 100644 --- a/ECU/Application/Inc/StateData.h +++ b/ECU/Application/Inc/StateData.h @@ -116,9 +116,7 @@ typedef volatile struct ECU_StateData { bool ir_minus; bool acu_software_latch; - bool bms_light; - bool imd_light; - bool tssi_fault; + bool SDC_startup_condition; bool enable_regen; diff --git a/ECU/Application/Src/Lights.c b/ECU/Application/Src/Lights.c index ddd9eb07c..6679df722 100644 --- a/ECU/Application/Src/Lights.c +++ b/ECU/Application/Src/Lights.c @@ -26,7 +26,6 @@ void BrakeLightControl(ECU_StateData *stateLump) } } -static bool SDCStartupCondition = true; // prevent false positive TSSI on startup // PRECONDITION: IMD assumed to give valid readings before this is run void TSSILightControl(ECU_StateData *stateLump) { @@ -36,16 +35,16 @@ void TSSILightControl(ECU_StateData *stateLump) bool redCar; // if we are before SDC is reset, don't red car unless there is an active failure - if (SDCStartupCondition) { + if (stateLump->SDC_startup_condition) { redCar = false; SDC_Level bms = bmsLevel(stateLump); SDC_Level imd = imdLevel(stateLump); if (bms == SDC_OK && imd == SDC_OK) { - SDCStartupCondition = false; + stateLump->SDC_startup_condition = false; } else if (bms == SDC_ONGOING_FAILURE || imd == SDC_ONGOING_FAILURE) { - SDCStartupCondition = false; + stateLump->SDC_startup_condition = false; redCar = true; } } else { @@ -149,8 +148,14 @@ void dashLights(ECU_StateData *stateLump) GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (bms_nonlatch << 5) | (imd_nonlatch << 4) | (bspd_nonlatch << 3) | (bms_latch << 2) | (imd_latch << 1) | (bspd_latch << 0)}; */ - GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (!bspdFailure(stateLump) << 5) | (!imdFailure(stateLump) << 4) | (!bmsFailure(stateLump) << 3) | (bspdFailure(stateLump) << 2) | - (imdFailure(stateLump) << 1) | (bmsFailure(stateLump) << 0)}; + GRCAN_DASH_CONFIG_MSG message; + if(stateLump->SDC_startup_condition) { + message = (GRCAN_DASH_CONFIG_MSG){.led_latch_flags = (true << 5) | (true << 4) | (true << 3) | (false << 2) | + (false << 1) | (false << 0)}; + } else { + message = (GRCAN_DASH_CONFIG_MSG){.led_latch_flags = (!bspdFailure(stateLump) << 5) | (!imdFailure(stateLump) << 4) | (!bmsFailure(stateLump) << 3) | (bspdFailure(stateLump) << 2) | + (imdFailure(stateLump) << 1) | (bmsFailure(stateLump) << 0)}; + } message.led_latch_flags = ~message.led_latch_flags; // not to spec, needed as of the current iteration of the dash panel code ECU_CAN_Send(GRCAN_BUS_PRIMARY, GRCAN_Dash_Panel, GRCAN_DASH_CONFIG, &message, sizeof(message)); diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index e5e15e481..41ff2da6e 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -59,7 +59,9 @@ ECU_StateData stateLump = { .apps_2_max = 1926, // Regen .regen_strength = 2, - .enable_regen = false}; + .enable_regen = false, + .SDC_startup_condition = true +}; static uint32_t millis_since_boot; void ECU_State_Tick(void) diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 3e54fac46..193c67178 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -499,7 +499,16 @@ int main(void) while (MillisecondsSinceBoot() < 5000) { // Notes per Andrey and Ryan BrakeLightControl(&stateLump); - dashLights(&stateLump); + //GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (!bspdFailure(stateLump) << 5) | (!imdFailure(stateLump) << 4) | (!bmsFailure(stateLump) << 3) | (bspdFailure(stateLump) << 2) | + // (imdFailure(stateLump) << 1) | (bmsFailure(stateLump) << 0)}; + + GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (true << 5) | (true << 4) | (true << 3) | (false << 2) | + (false << 1) | (false << 0)}; + + message.led_latch_flags = ~message.led_latch_flags; // not to spec, needed as of the current iteration of the dash panel code + + ECU_CAN_Send(GRCAN_BUS_PRIMARY, GRCAN_Dash_Panel, GRCAN_DASH_CONFIG, &message, sizeof(message)); + LL_mDelay(1); ADC_UpdateAnalogValues_EMA(ADC_buffers, NUM_SIGNALS, adc_alpha, ADC_outputs); write_adc_values_to_state_data(); From e7ae6bc6c3f4afe1ce793c1b77d4161b178355ec Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 01:53:14 +0000 Subject: [PATCH 31/36] Automatic Clang-Format: Standardized formatting automatically --- ECU/Application/Src/Lights.c | 7 +++---- ECU/Application/Src/StateTicks.c | 3 +-- ECU/Core/Src/main.c | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ECU/Application/Src/Lights.c b/ECU/Application/Src/Lights.c index 6679df722..c86bb1efe 100644 --- a/ECU/Application/Src/Lights.c +++ b/ECU/Application/Src/Lights.c @@ -149,12 +149,11 @@ void dashLights(ECU_StateData *stateLump) GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (bms_nonlatch << 5) | (imd_nonlatch << 4) | (bspd_nonlatch << 3) | (bms_latch << 2) | (imd_latch << 1) | (bspd_latch << 0)}; */ GRCAN_DASH_CONFIG_MSG message; - if(stateLump->SDC_startup_condition) { - message = (GRCAN_DASH_CONFIG_MSG){.led_latch_flags = (true << 5) | (true << 4) | (true << 3) | (false << 2) | - (false << 1) | (false << 0)}; + if (stateLump->SDC_startup_condition) { + message = (GRCAN_DASH_CONFIG_MSG){.led_latch_flags = (true << 5) | (true << 4) | (true << 3) | (false << 2) | (false << 1) | (false << 0)}; } else { message = (GRCAN_DASH_CONFIG_MSG){.led_latch_flags = (!bspdFailure(stateLump) << 5) | (!imdFailure(stateLump) << 4) | (!bmsFailure(stateLump) << 3) | (bspdFailure(stateLump) << 2) | - (imdFailure(stateLump) << 1) | (bmsFailure(stateLump) << 0)}; + (imdFailure(stateLump) << 1) | (bmsFailure(stateLump) << 0)}; } message.led_latch_flags = ~message.led_latch_flags; // not to spec, needed as of the current iteration of the dash panel code diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 41ff2da6e..2a78ae364 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -60,8 +60,7 @@ ECU_StateData stateLump = { // Regen .regen_strength = 2, .enable_regen = false, - .SDC_startup_condition = true -}; + .SDC_startup_condition = true}; static uint32_t millis_since_boot; void ECU_State_Tick(void) diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 193c67178..aa8f6f89b 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -499,11 +499,10 @@ int main(void) while (MillisecondsSinceBoot() < 5000) { // Notes per Andrey and Ryan BrakeLightControl(&stateLump); - //GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (!bspdFailure(stateLump) << 5) | (!imdFailure(stateLump) << 4) | (!bmsFailure(stateLump) << 3) | (bspdFailure(stateLump) << 2) | + // GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (!bspdFailure(stateLump) << 5) | (!imdFailure(stateLump) << 4) | (!bmsFailure(stateLump) << 3) | (bspdFailure(stateLump) << 2) | // (imdFailure(stateLump) << 1) | (bmsFailure(stateLump) << 0)}; - GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (true << 5) | (true << 4) | (true << 3) | (false << 2) | - (false << 1) | (false << 0)}; + GRCAN_DASH_CONFIG_MSG message = {.led_latch_flags = (true << 5) | (true << 4) | (true << 3) | (false << 2) | (false << 1) | (false << 0)}; message.led_latch_flags = ~message.led_latch_flags; // not to spec, needed as of the current iteration of the dash panel code From b0acb84e14f9934a2d06307c923f3e463ee6a0c8 Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Fri, 19 Jun 2026 17:28:41 -0400 Subject: [PATCH 32/36] Revised scaling of TS voltage --- ECU/Application/Src/CANdler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 1478a8b76..cd1bd97d7 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -71,7 +71,7 @@ void ECU_CAN_MessageHandler(ECU_StateData *state_data, GRCAN_BUS_ID bus_id, GRCA GRCAN_ACU_STATUS_1_MSG *acu_status_1 = (GRCAN_ACU_STATUS_1_MSG *)data; state_data->tractivebattery_soc = acu_status_1->accumulator_soc; state_data->glv_soc = acu_status_1->glv_soc; - state_data->ts_voltage = acu_status_1->ts_voltage * 0.01f; + state_data->ts_voltage = acu_status_1->ts_voltage * 0.1f; break; case GRCAN_ACU_STATUS_2: From e6919a464047dadee2b7d77a46be5eb7629ce0f9 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Fri, 19 Jun 2026 14:29:12 -0700 Subject: [PATCH 33/36] Switch to 10x scaling of the ACU Status 1 field for TS Voltage Signed-off-by: Daniel Hansen --- Autogen/CAN/Doc/GRCAN.CANdo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Autogen/CAN/Doc/GRCAN.CANdo b/Autogen/CAN/Doc/GRCAN.CANdo index 03bd7924a..fff052888 100644 --- a/Autogen/CAN/Doc/GRCAN.CANdo +++ b/Autogen/CAN/Doc/GRCAN.CANdo @@ -668,7 +668,7 @@ Message ID: units: Volts scaled min: 0 scaled max: 655.35 - map equation: "0.01x" + map equation: "0.1x" Accumulator Current: bit_start: 32 comment: Current output of accumulator From b70f0302a397d80030537b4bb554fcae9008444a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 21:29:36 +0000 Subject: [PATCH 34/36] Automatic CANfigurator: Updated CAN files automatically --- Autogen/CAN/Doc/GRCAN_Charger.dbc | 2 +- Autogen/CAN/Doc/GRCAN_Primary.dbc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Autogen/CAN/Doc/GRCAN_Charger.dbc b/Autogen/CAN/Doc/GRCAN_Charger.dbc index 5cef85a39..9d7f15ec7 100644 --- a/Autogen/CAN/Doc/GRCAN_Charger.dbc +++ b/Autogen/CAN/Doc/GRCAN_Charger.dbc @@ -41,7 +41,7 @@ BO_ 2550588916 ACU_Charger_Control_to_Charger: 5 ACU BO_ 2150631170 ACU_ACU_Status_1_to_CCU: 8 ACU SG_ Accumulator_Voltage : 0|16@1+ (0.01,0) [0|655.35] "Volts" CCU - SG_ TS_Voltage : 16|16@1+ (0.01,0) [0|655.35] "Volts" CCU + SG_ TS_Voltage : 16|16@1+ (0.1,0) [0|655.35] "Volts" CCU SG_ Accumulator_Current : 32|16@1- (0.01,0) [-327.68|327.67] "Amps" CCU SG_ Accumulator_SOC : 48|8@1+ (0.3921568627,0) [0|100] "%" CCU SG_ GLV_SOC : 56|8@1+ (0.3921568627,0) [0|100] "%" CCU diff --git a/Autogen/CAN/Doc/GRCAN_Primary.dbc b/Autogen/CAN/Doc/GRCAN_Primary.dbc index dc09b2400..c1ca89636 100644 --- a/Autogen/CAN/Doc/GRCAN_Primary.dbc +++ b/Autogen/CAN/Doc/GRCAN_Primary.dbc @@ -45,7 +45,7 @@ BO_ 2150629890 ACU_Ping_to_ECU: 4 ACU BO_ 2150631170 ACU_ACU_Status_1_to_ECU: 8 ACU SG_ Accumulator_Voltage : 0|16@1+ (0.01,0) [0|655.35] "Volts" ECU - SG_ TS_Voltage : 16|16@1+ (0.01,0) [0|655.35] "Volts" ECU + SG_ TS_Voltage : 16|16@1+ (0.1,0) [0|655.35] "Volts" ECU SG_ Accumulator_Current : 32|16@1- (0.01,0) [-327.68|327.67] "Amps" ECU SG_ Accumulator_SOC : 48|8@1+ (0.3921568627,0) [0|100] "%" ECU SG_ GLV_SOC : 56|8@1+ (0.3921568627,0) [0|100] "%" ECU From d7c83d85f5096be172017c3d0c68d2f58db7004e Mon Sep 17 00:00:00 2001 From: Casey Zwicker Date: Fri, 19 Jun 2026 17:36:07 -0400 Subject: [PATCH 35/36] fix ccu anyway --- CCU/Application/Src/StateUtils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CCU/Application/Src/StateUtils.c b/CCU/Application/Src/StateUtils.c index ecded1836..04ec028da 100644 --- a/CCU/Application/Src/StateUtils.c +++ b/CCU/Application/Src/StateUtils.c @@ -89,7 +89,7 @@ void VCP_Oneliner(const CCU_StateData *state_data) length = snprintf(buffer, sizeof(buffer), " | IR+ %s", state_data->IR_PLUS ? "Closed" : "Open"); VCP_Send(buffer, length); - length = snprintf(buffer, sizeof(buffer), " | %huV", state_data->Accumulator_Voltage / 100); + length = snprintf(buffer, sizeof(buffer), " | %huV", state_data->Accumulator_Voltage / 10); VCP_Send(buffer, length); length = snprintf(buffer, sizeof(buffer), " | SOC %hu%%", (uint8_t)(state_data->Accumulator_SOC * 20.0f / 51.0f)); From d1bd0f76deb33ba2e5680937a5299698c37da12b Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Fri, 19 Jun 2026 20:58:21 -0700 Subject: [PATCH 36/36] Make everything 325 A regardless of brightness Signed-off-by: Daniel Hansen --- ECU/Application/Src/StateTicks.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 2a78ae364..cc86939a4 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -267,22 +267,22 @@ void ECU_Drive_Active(ECU_StateData *stateData) // Chosen max current for different power level / torque maps switch (stateData->powerlevel) { case 0: - max_current = 100; + max_current = 325; break; case 1: - max_current = 200; + max_current = 325; break; case 2: - max_current = 250; + max_current = 325; break; case 3: - max_current = 300; + max_current = 325; break; case 4: max_current = 325; break; case 5: - max_current = 350; + max_current = 325; break; default: LOGOMATIC("Invalid power level: %d. Defaulting to no current.\n", stateData->powerlevel);