From 77f8bb5a41d57cd0c8d8a5ee081aff64fe62992d Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 11 Jun 2025 00:03:13 -0700 Subject: [PATCH 01/30] add base thermal files (simple if loop) --- fsae-vehicle-fw/src/peripherals/adc.cpp | 22 ++++++++---- fsae-vehicle-fw/src/peripherals/adc.h | 4 +-- fsae-vehicle-fw/src/vehicle/thermal.cpp | 48 +++++++++++++++++++++++++ fsae-vehicle-fw/src/vehicle/thermal.h | 5 +++ 4 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 fsae-vehicle-fw/src/vehicle/thermal.cpp create mode 100644 fsae-vehicle-fw/src/vehicle/thermal.h diff --git a/fsae-vehicle-fw/src/peripherals/adc.cpp b/fsae-vehicle-fw/src/peripherals/adc.cpp index c43b595..8f3999c 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.cpp +++ b/fsae-vehicle-fw/src/peripherals/adc.cpp @@ -12,16 +12,21 @@ #include "vehicle/faults.h" #include "vehicle/telemetry.h" #include "vehicle/motor.h" +#include "vehicle/thermal.h" enum SensorIndexesADC0 { // TODO: Update with real values - APPS_1_INDEX, - APPS_2_INDEX, - BSE_1_INDEX, - BSE_2_INDEX, + THERMISTOR_1_INDEX = 0, // A0 + APPS_1_INDEX = 5, + APPS_2_INDEX = 4, + BSE_1_INDEX = 3, + BSE_2_INDEX = 2, SUSP_TRAV_LINPOT1, SUSP_TRAV_LINPOT2, SUSP_TRAV_LINPOT3, - SUSP_TRAV_LINPOT4 + SUSP_TRAV_LINPOT4, + THERMISTOR_2_INDEX = 10, // A1 + THERMISTOR_3_INDEX = 9, // A2 + THERMISTOR_4_INDEX = 8// A3 }; enum SensorIndexesADC1 { // TODO: Update with real values @@ -35,10 +40,11 @@ enum SensorIndexesADC1 { // TODO: Update with real values SUSP_TRAV_LINPOT42 }; -uint16_t adc0Pins[SENSOR_PIN_AMT_ADC0] = {A0, A1, A2, A3, A4, A5, A6, A7}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, 24, 25, 19, 18, 14, 15, 17}; +uint16_t adc0Pins[SENSOR_PIN_AMT_ADC0] = {A0, A1, A2, A3, A4, A5, A6, A7, A15, A16, A17}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, 24, 25, 19, 18, 14, 15, 17}; uint16_t adc0Reads[SENSOR_PIN_AMT_ADC0]; -uint16_t adc1Pins[SENSOR_PIN_AMT_ADC1] = {A7, A6, A5, A4, A3, A2, A1, A0}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, 24, 25, 19, 18, 14, 15, 17}; + +uint16_t adc1Pins[SENSOR_PIN_AMT_ADC1] = {A17, A16, A15, A7, A6, A5, A4, A3, A2, A1, A0}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, 24, 25, 19, 18, 14, 15, 17}; uint16_t adc1Reads[SENSOR_PIN_AMT_ADC1]; static TickType_t lastWakeTime; @@ -87,6 +93,8 @@ void threadADC( void *pvParameters ){ APPS_UpdateData(adc0Reads[APPS_1_INDEX], adc0Reads[APPS_2_INDEX]); BSE_UpdateData(adc0Reads[BSE_1_INDEX], adc0Reads[BSE_2_INDEX]); + thermal_Update(adc0Reads[THERMISTOR_1_INDEX], adc0Reads[THERMISTOR_2_INDEX], adc0Reads[THERMISTOR_3_INDEX], adc0Reads[THERMISTOR_4_INDEX]); + // Handle any faults that were raised // Faults_HandleFaults(); // Motor_UpdateMotor(); diff --git a/fsae-vehicle-fw/src/peripherals/adc.h b/fsae-vehicle-fw/src/peripherals/adc.h index 1108ec9..2494ed7 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.h +++ b/fsae-vehicle-fw/src/peripherals/adc.h @@ -2,8 +2,8 @@ #pragma once #include -#define SENSOR_PIN_AMT_ADC0 8 -#define SENSOR_PIN_AMT_ADC1 8 +#define SENSOR_PIN_AMT_ADC0 11 +#define SENSOR_PIN_AMT_ADC1 11 extern uint16_t adc0Pins[SENSOR_PIN_AMT_ADC0]; extern uint16_t adc0Index; diff --git a/fsae-vehicle-fw/src/vehicle/thermal.cpp b/fsae-vehicle-fw/src/vehicle/thermal.cpp new file mode 100644 index 0000000..7bec868 --- /dev/null +++ b/fsae-vehicle-fw/src/vehicle/thermal.cpp @@ -0,0 +1,48 @@ +#include +#include "vehicle/telemetry.h" + +#define DUTY_CYCLE_MAX 255 +#define ANALOG_WRITE_FREQUENCY 25000 // 25 kHz for Koolance +#define ANALOG_WRITE_RESOLUTION 8 // 8-bit resolution (0-255) + +#define PUMP_PIN 12 // Define the PWM pin for the pump +#define FAN_PIN 7 + +#define TEMP_THRESHOLD 30 // Temperature threshold in degrees Celsius + +void setup() { + pinMode(PUMP_PIN, OUTPUT); + analogWriteFrequency(PUMP_PIN, ANALOG_WRITE_FREQUENCY); // 25 kHz for Koolance + analogWriteResolution(ANALOG_WRITE_RESOLUTION); // 0-255 + + pinMode(FAN_PIN, OUTPUT); + analogWriteFrequency(FAN_PIN, ANALOG_WRITE_FREQUENCY); // 25 kHz for Koolance + analogWriteResolution(ANALOG_WRITE_RESOLUTION); // 0-255 +} + +void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, uint32_t rawReading3, uint32_t rawReading4) { + // Assuming rawReading1 and rawReading2 are the temperature readings from the sensors + // Convert raw readings to temperature in degrees Celsius + int32_t temp1 = (rawReading1); + int32_t temp2 = (rawReading2); + int32_t temp3 = (rawReading1); + int32_t temp4 = (rawReading2); + // Check if the MCU temperature exceeds the threshold + if (temp1 > TEMP_THRESHOLD || temp2 > TEMP_THRESHOLD) { + // If the MCU temperature exceeds the threshold, turn on the pump and fan + analogWrite(PUMP_PIN, DUTY_CYCLE_MAX * 0.9); // Set pump to full duty cycle + analogWrite(FAN_PIN, DUTY_CYCLE_MAX * 0.9); // Set fan to full duty cycle + } else { + // If the MCU temperature is below the threshold, turn off the pump and fan + analogWrite(PUMP_PIN, 0); // Set pump to 0 duty cycle + analogWrite(FAN_PIN, 0); // Set fan to 0 duty cycle + } + // Debugging output + Serial.print("Temp1: "); + Serial.print(temp1); + Serial.print(" C | Temp2: "); + Serial.print(temp2); + Serial.println(" C"); + +} + diff --git a/fsae-vehicle-fw/src/vehicle/thermal.h b/fsae-vehicle-fw/src/vehicle/thermal.h new file mode 100644 index 0000000..2b3dfe6 --- /dev/null +++ b/fsae-vehicle-fw/src/vehicle/thermal.h @@ -0,0 +1,5 @@ + +#include + +void thermal_Init(); +void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, uint32_t rawReading3, uint32_t rawReading4); From e13b347c3b2b3bbdf6784e76c3d6b82aed68dd0a Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 11 Jun 2025 00:29:37 -0700 Subject: [PATCH 02/30] header file fix --- fsae-vehicle-fw/src/vehicle/thermal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsae-vehicle-fw/src/vehicle/thermal.cpp b/fsae-vehicle-fw/src/vehicle/thermal.cpp index 7bec868..a7a9b74 100644 --- a/fsae-vehicle-fw/src/vehicle/thermal.cpp +++ b/fsae-vehicle-fw/src/vehicle/thermal.cpp @@ -10,7 +10,7 @@ #define TEMP_THRESHOLD 30 // Temperature threshold in degrees Celsius -void setup() { +void thermal_Init() { pinMode(PUMP_PIN, OUTPUT); analogWriteFrequency(PUMP_PIN, ANALOG_WRITE_FREQUENCY); // 25 kHz for Koolance analogWriteResolution(ANALOG_WRITE_RESOLUTION); // 0-255 From ae4fce330c87fd9256298f69d38718c6e29a7653 Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 17 Oct 2025 10:17:09 -0700 Subject: [PATCH 03/30] telemtry updates --- fsae-vehicle-fw/file_list.txt | 0 fsae-vehicle-fw/src/peripherals/adc.cpp | 3 +- fsae-vehicle-fw/src/utils/utils.h | 2 +- fsae-vehicle-fw/src/vehicle/telemetry.cpp | 109 +++++++++++++--------- fsae-vehicle-fw/src/vehicle/telemetry.h | 23 +++-- fsae-vehicle-fw/src/vehicle/thermal.cpp | 4 +- 6 files changed, 86 insertions(+), 55 deletions(-) create mode 100644 fsae-vehicle-fw/file_list.txt diff --git a/fsae-vehicle-fw/file_list.txt b/fsae-vehicle-fw/file_list.txt new file mode 100644 index 0000000..e69de29 diff --git a/fsae-vehicle-fw/src/peripherals/adc.cpp b/fsae-vehicle-fw/src/peripherals/adc.cpp index 8f3999c..158428f 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.cpp +++ b/fsae-vehicle-fw/src/peripherals/adc.cpp @@ -93,7 +93,8 @@ void threadADC( void *pvParameters ){ APPS_UpdateData(adc0Reads[APPS_1_INDEX], adc0Reads[APPS_2_INDEX]); BSE_UpdateData(adc0Reads[BSE_1_INDEX], adc0Reads[BSE_2_INDEX]); - thermal_Update(adc0Reads[THERMISTOR_1_INDEX], adc0Reads[THERMISTOR_2_INDEX], adc0Reads[THERMISTOR_3_INDEX], adc0Reads[THERMISTOR_4_INDEX]); + thermal_Update(adc0Reads[THERMISTOR_1_INDEX], adc0Reads[THERMISTOR_2_INDEX], + adc0Reads[THERMISTOR_3_INDEX], adc0Reads[THERMISTOR_4_INDEX]); // Handle any faults that were raised // Faults_HandleFaults(); diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index 5233e7e..370cef4 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -2,7 +2,7 @@ #pragma once -#define DEBUG_FLAG 0 +#define DEBUG_FLAG 1 #define THREAD_MAIN_STACK_SIZE 128 #define THREAD_MAIN_PRIORITY 1 diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.cpp b/fsae-vehicle-fw/src/vehicle/telemetry.cpp index 1ab42c5..9fe95b7 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.cpp +++ b/fsae-vehicle-fw/src/vehicle/telemetry.cpp @@ -18,41 +18,55 @@ void Telemetry_Init() { // TODO: Update initialization telemetryData = { // Fill with reasonable dummy values .APPS_Travel = 0.0F, - .BSEFront_PSI = 0.0F, - .BSERear_PSI = 0.0F, - .accumulatorVoltage = 0.0F, - .accumulatorTemp_F = 25.0F, - .motorState = MOTOR_STATE_OFF, + // .BSEFront_PSI = 0.0F, + // .BSERear_PSI = 0.0F, + // .accumulatorVoltage = 0.0F, + // .accumulatorTemp_F = 25.0F, + //.motorState = MOTOR_STATE_OFF, + .motorSpeed = 0.0F, .motorTorque = 0.0F, .maxMotorTorque = 0.0F, - .maxMotorBrakeTorque = 0.0F, + //.maxMotorBrakeTorque = 0.0F, .motorDirection = DIRECTION_STANDBY, + .motorState = MOTOR_STATE_OFF, + .mcuMainState = STATE_STANDBY, .mcuWorkMode = WORK_MODE_STANDBY, + + .mcuVoltage = 0.0F, + .mcuCurrent = 0.0F, .motorTemp = 25, .mcuTemp = 25, + .dcMainWireOverVoltFault = false, - .motorPhaseCurrFault = false, - .mcuOverHotFault = false, - .resolverFault = false, - .phaseCurrSensorFault = false, - .motorOverSpdFault = false, - .drvMotorOverHotFault = false, .dcMainWireOverCurrFault = false, - .drvMotorOverCoolFault = false, - .mcuMotorSystemState = false, - .mcuTempSensorState = false, - .motorTempSensorState = false, - .dcVoltSensorState = false, - .dcLowVoltWarning = false, - .mcu12VLowVoltWarning = false, + .motorOverSpdFault = false, + .motorPhaseCurrFault = false, .motorStallFault = false, - .motorOpenPhaseFault = false, + .mcuWarningLevel = ERROR_NONE, - .mcuVoltage = 0.0F, - .mcuCurrent = 0.0F, - .motorPhaseCurr = 0.0F, + //.mcuOverHotFault = false, + // .resolverFault = false, + // .phaseCurrSensorFault = false, + + + + // .drvMotorOverHotFault = false, + // .dcMainWireOverCurrFault = false, + // .drvMotorOverCoolFault = false, + // .mcuMotorSystemState = false, + // .mcuTempSensorState = false, + // .motorTempSensorState = false, + // .dcVoltSensorState = false, + // .dcLowVoltWarning = false, + // .mcu12VLowVoltWarning = false, + + // .motorOpenPhaseFault = false, + + // .mcuVoltage = 0.0F, + // .mcuCurrent = 0.0F, + // .motorPhaseCurr = 0.0F, }; } @@ -62,44 +76,49 @@ void threadTelemetry(void *pvParameters){ taskENTER_CRITICAL(); // Enter critical section telemetryData = { .APPS_Travel = APPS_GetAPPSReading(), - .BSEFront_PSI = BSE_GetBSEReading()->bseFront_PSI, - .BSERear_PSI = BSE_GetBSEReading()->bseFront_PSI, - .accumulatorVoltage = 0.0F, // TODO: Replace with actual accumulator voltage reading - .accumulatorTemp_F = 0.0F, // TODO: Replace with actual accumulator temperature reading - .motorState = Motor_GetState(), + // .BSEFront_PSI = BSE_GetBSEReading()->bseFront_PSI, + // .BSERear_PSI = BSE_GetBSEReading()->bseFront_PSI, + // .accumulatorVoltage = 0.0F, // TODO: Replace with actual accumulator voltage reading + // .accumulatorTemp_F = 0.0F, // TODO: Replace with actual accumulator temperature reading + .motorSpeed = MCU_GetMCU1Data()->motorSpeed, .motorTorque = MCU_GetMCU1Data()->motorTorque, .maxMotorTorque = MCU_GetMCU1Data()->maxMotorTorque, .maxMotorBrakeTorque = MCU_GetMCU1Data()->maxMotorBrakeTorque, + .motorDirection = MCU_GetMCU1Data()->motorDirection, + .motorState = Motor_GetState(), .mcuMainState = MCU_GetMCU1Data()->mcuMainState, .mcuWorkMode = MCU_GetMCU1Data()->mcuWorkMode, + .mcuVoltage = MCU_GetMCU3Data()->mcuVoltage, + .mcuCurrent = MCU_GetMCU3Data()->mcuCurrent, .motorTemp = MCU_GetMCU2Data()->motorTemp, .mcuTemp = MCU_GetMCU2Data()->mcuTemp, + .dcMainWireOverVoltFault = MCU_GetMCU2Data()->dcMainWireOverVoltFault, - .motorPhaseCurrFault = MCU_GetMCU2Data()->motorPhaseCurrFault, - .mcuOverHotFault = MCU_GetMCU2Data()->mcuOverHotFault, - .resolverFault = MCU_GetMCU2Data()->resolverFault, - .phaseCurrSensorFault = MCU_GetMCU2Data()->phaseCurrSensorFault, - .motorOverSpdFault = MCU_GetMCU2Data()->motorOverSpdFault, - .drvMotorOverHotFault = MCU_GetMCU2Data()->drvMotorOverHotFault, .dcMainWireOverCurrFault = MCU_GetMCU2Data()->dcMainWireOverCurrFault, - .drvMotorOverCoolFault = MCU_GetMCU2Data()->drvMotorOverCoolFault, - .mcuMotorSystemState = MCU_GetMCU2Data()->mcuMotorSystemState, - .mcuTempSensorState = MCU_GetMCU2Data()->mcuTempSensorState, - .motorTempSensorState = MCU_GetMCU2Data()->motorTempSensorState, - .dcVoltSensorState = MCU_GetMCU2Data()->dcVoltSensorState, - .dcLowVoltWarning = MCU_GetMCU2Data()->dcLowVoltWarning, - .mcu12VLowVoltWarning = MCU_GetMCU2Data()->mcu12VLowVoltWarning, + .motorOverSpdFault = MCU_GetMCU2Data()->motorOverSpdFault, + .motorPhaseCurrFault = MCU_GetMCU2Data()->motorPhaseCurrFault, + +// .mcuOverHotFault = MCU_GetMCU2Data()->mcuOverHotFault, +// .resolverFault = MCU_GetMCU2Data()->resolverFault, + // .phaseCurrSensorFault = MCU_GetMCU2Data()->phaseCurrSensorFault, + // .drvMotorOverHotFault = MCU_GetMCU2Data()->drvMotorOverHotFault, + // .drvMotorOverCoolFault = MCU_GetMCU2Data()->drvMotorOverCoolFault, + // .mcuMotorSystemState = MCU_GetMCU2Data()->mcuMotorSystemState, + // .mcuTempSensorState = MCU_GetMCU2Data()->mcuTempSensorState, + // .motorTempSensorState = MCU_GetMCU2Data()->motorTempSensorState, + // .dcVoltSensorState = MCU_GetMCU2Data()->dcVoltSensorState, + // .dcLowVoltWarning = MCU_GetMCU2Data()->dcLowVoltWarning, + // .mcu12VLowVoltWarning = MCU_GetMCU2Data()->mcu12VLowVoltWarning, .motorStallFault = MCU_GetMCU2Data()->motorStallFault, - .motorOpenPhaseFault = MCU_GetMCU2Data()->motorOpenPhaseFault, + // .motorOpenPhaseFault = MCU_GetMCU2Data()->motorOpenPhaseFault, .mcuWarningLevel = MCU_GetMCU2Data()->mcuWarningLevel, - .mcuVoltage = MCU_GetMCU3Data()->mcuVoltage, - .mcuCurrent = MCU_GetMCU3Data()->mcuCurrent, - .motorPhaseCurr = MCU_GetMCU3Data()->motorPhaseCurr, + + // .motorPhaseCurr = MCU_GetMCU3Data()->motorPhaseCurr, }; taskEXIT_CRITICAL(); diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.h b/fsae-vehicle-fw/src/vehicle/telemetry.h index b1c595e..7e8c93f 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.h +++ b/fsae-vehicle-fw/src/vehicle/telemetry.h @@ -16,7 +16,7 @@ typedef struct __attribute__((packed)){ float accumulatorVoltage; float accumulatorTemp_F; - MotorState motorState; // Motor state + // Motor state // MCU1 data float motorSpeed; // Motor speed in RPM @@ -24,20 +24,31 @@ typedef struct __attribute__((packed)){ float maxMotorTorque; // Max motor torque in Nm float maxMotorBrakeTorque; // Max motor brake torque in Nm MotorRotateDirection motorDirection; // Motor direction + MotorState motorState; + MCUMainState mcuMainState; // Motor main state MCUWorkMode mcuWorkMode; // MCU work mode + float mcuVoltage; + float mcuCurrent; + // MCU2 data int32_t motorTemp; // Motor temperature in C int32_t mcuTemp; // Inverter temperature in C + bool dcMainWireOverVoltFault; // DC over voltage fault + bool dcMainWireOverCurrFault; // DC main wire over voltage fault + bool motorOverSpdFault; // MCU motor over speed fault + // bool phaseCurrSensorFault; // Phase current sensor fault + + bool motorPhaseCurrFault; // MCU motor phase current fault bool mcuOverHotFault; // MCU overheat fault bool resolverFault; // Resolver fault - bool phaseCurrSensorFault; // Phase current sensor fault - bool motorOverSpdFault; // MCU motor over speed fault +// bool phaseCurrSensorFault; // Phase current sensor fault +// bool motorOverSpdFault; // MCU motor over speed fault bool drvMotorOverHotFault; // Driver motor overheat fault - bool dcMainWireOverCurrFault; // DC main wire over voltage fault + // bool dcMainWireOverCurrFault; // DC main wire over voltage fault bool drvMotorOverCoolFault; // Driver motor overcool fault bool mcuMotorSystemState; // MCU motor system state bool mcuTempSensorState; // MCU temperature sensor state @@ -50,8 +61,8 @@ typedef struct __attribute__((packed)){ MCUWarningLevel mcuWarningLevel; // MCU warning level // MCU3 data - float mcuVoltage; // DC main wire voltage in V - float mcuCurrent; // DC main wire current in A + //float mcuVoltage; // DC main wire voltage in V + //float mcuCurrent; // DC main wire current in A float motorPhaseCurr; // Motor phase current in A float debug[4]; // Debug data diff --git a/fsae-vehicle-fw/src/vehicle/thermal.cpp b/fsae-vehicle-fw/src/vehicle/thermal.cpp index a7a9b74..acfc761 100644 --- a/fsae-vehicle-fw/src/vehicle/thermal.cpp +++ b/fsae-vehicle-fw/src/vehicle/thermal.cpp @@ -25,8 +25,8 @@ void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, uint32_t rawRead // Convert raw readings to temperature in degrees Celsius int32_t temp1 = (rawReading1); int32_t temp2 = (rawReading2); - int32_t temp3 = (rawReading1); - int32_t temp4 = (rawReading2); + // int32_t temp3 = (rawReading3); + // int32_t temp4 = (rawReading4); // Check if the MCU temperature exceeds the threshold if (temp1 > TEMP_THRESHOLD || temp2 > TEMP_THRESHOLD) { // If the MCU temperature exceeds the threshold, turn on the pump and fan From 237fb9c079e6743046114e14ace8300aeb64f11a Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 17 Oct 2025 10:19:51 -0700 Subject: [PATCH 04/30] clean up telemetry packets, only needed data for himac --- fsae-vehicle-fw/src/vehicle/telemetry.cpp | 42 ++--------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.cpp b/fsae-vehicle-fw/src/vehicle/telemetry.cpp index 9fe95b7..ab7cb35 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.cpp +++ b/fsae-vehicle-fw/src/vehicle/telemetry.cpp @@ -18,16 +18,12 @@ void Telemetry_Init() { // TODO: Update initialization telemetryData = { // Fill with reasonable dummy values .APPS_Travel = 0.0F, - // .BSEFront_PSI = 0.0F, - // .BSERear_PSI = 0.0F, - // .accumulatorVoltage = 0.0F, - // .accumulatorTemp_F = 25.0F, - //.motorState = MOTOR_STATE_OFF, + .motorSpeed = 0.0F, .motorTorque = 0.0F, .maxMotorTorque = 0.0F, - //.maxMotorBrakeTorque = 0.0F, + .motorDirection = DIRECTION_STANDBY, .motorState = MOTOR_STATE_OFF, @@ -46,27 +42,7 @@ void Telemetry_Init() { .motorStallFault = false, .mcuWarningLevel = ERROR_NONE, - //.mcuOverHotFault = false, - // .resolverFault = false, - // .phaseCurrSensorFault = false, - - - // .drvMotorOverHotFault = false, - // .dcMainWireOverCurrFault = false, - // .drvMotorOverCoolFault = false, - // .mcuMotorSystemState = false, - // .mcuTempSensorState = false, - // .motorTempSensorState = false, - // .dcVoltSensorState = false, - // .dcLowVoltWarning = false, - // .mcu12VLowVoltWarning = false, - - // .motorOpenPhaseFault = false, - - // .mcuVoltage = 0.0F, - // .mcuCurrent = 0.0F, - // .motorPhaseCurr = 0.0F, }; } @@ -102,23 +78,9 @@ void threadTelemetry(void *pvParameters){ .motorOverSpdFault = MCU_GetMCU2Data()->motorOverSpdFault, .motorPhaseCurrFault = MCU_GetMCU2Data()->motorPhaseCurrFault, -// .mcuOverHotFault = MCU_GetMCU2Data()->mcuOverHotFault, -// .resolverFault = MCU_GetMCU2Data()->resolverFault, - // .phaseCurrSensorFault = MCU_GetMCU2Data()->phaseCurrSensorFault, - // .drvMotorOverHotFault = MCU_GetMCU2Data()->drvMotorOverHotFault, - // .drvMotorOverCoolFault = MCU_GetMCU2Data()->drvMotorOverCoolFault, - // .mcuMotorSystemState = MCU_GetMCU2Data()->mcuMotorSystemState, - // .mcuTempSensorState = MCU_GetMCU2Data()->mcuTempSensorState, - // .motorTempSensorState = MCU_GetMCU2Data()->motorTempSensorState, - // .dcVoltSensorState = MCU_GetMCU2Data()->dcVoltSensorState, - // .dcLowVoltWarning = MCU_GetMCU2Data()->dcLowVoltWarning, - // .mcu12VLowVoltWarning = MCU_GetMCU2Data()->mcu12VLowVoltWarning, .motorStallFault = MCU_GetMCU2Data()->motorStallFault, - // .motorOpenPhaseFault = MCU_GetMCU2Data()->motorOpenPhaseFault, .mcuWarningLevel = MCU_GetMCU2Data()->mcuWarningLevel, - - // .motorPhaseCurr = MCU_GetMCU3Data()->motorPhaseCurr, }; taskEXIT_CRITICAL(); From b4560f77fa4eb1aba87ec91b00e67de2bb826097 Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 17 Oct 2025 10:44:37 -0700 Subject: [PATCH 05/30] add potential can loss dection --- fsae-vehicle-fw/src/peripherals/can.cpp | 31 +++++++++++++++++++++++ fsae-vehicle-fw/src/peripherals/can.h | 3 +++ fsae-vehicle-fw/src/vehicle/motor.cpp | 12 +++++++++ fsae-vehicle-fw/src/vehicle/telemetry.cpp | 6 ----- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index 473deea..00596bd 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -23,6 +23,15 @@ isotp tp; CAN_message_t motorMsg; CAN_message_t rx_msg; +// CAN loss detection +static uint32_t lastCAN2MsgTime = 0; +static uint32_t lastCAN3MsgTime = 0; +static bool can2Healthy = false; +static bool can3Healthy = false; + +#define CAN_TIMEOUT_MS 100 + + void CAN_Init() { // Initialize CAN bus can2.begin(); @@ -55,12 +64,27 @@ void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data) { if (can2.read(rx_msg)) { *rx_id = rx_msg.id; memcpy(rx_data, rx_msg.buf, sizeof(*rx_data)); + + lastCAN2MsgTime = millis(); + can2Healthy = true; } else { // No message received, assign default values *rx_id = 0; *rx_data = 0; } } +void CAN_CheckHealth() { + uint32_t now = millis(); + if (now - lastCAN2MsgTime > CAN_TIMEOUT_MS) { + can2Healthy = false; + } + + if (now - lastCAN3MsgTime > CAN_TIMEOUT_MS) { + can3Healthy = false; + } +} + + void CAN_ISOTP_Send(uint32_t id, uint8_t* msg, uint16_t size) { ISOTP_data config; config.id = id; @@ -68,3 +92,10 @@ void CAN_ISOTP_Send(uint32_t id, uint8_t* msg, uint16_t size) { config.separation_time = 1; // Time between back-to-back frames in milliseconds tp.write(config, msg, size); } + + +bool CAN_IsBusHealthy(uint8_t bus) { + if (bus == 2) return can2Healthy; + if (bus == 3) return can3Healthy; + return false; +} diff --git a/fsae-vehicle-fw/src/peripherals/can.h b/fsae-vehicle-fw/src/peripherals/can.h index cf71aac..34e7297 100644 --- a/fsae-vehicle-fw/src/peripherals/can.h +++ b/fsae-vehicle-fw/src/peripherals/can.h @@ -7,3 +7,6 @@ void CAN_Send(uint32_t id, uint64_t msg); void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data); void CAN_ISOTP_Send(uint32_t id, uint8_t* msg, uint16_t size); + +bool CAN_IsBusHealthy(uint8_t bus); +void CAN_CheckHealth(); diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 6c42ae8..853e92b 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -39,6 +39,18 @@ void threadMotor(void *pvParameters){ vcu1 = {0}; bms1 = {0}; bms2 = {0}; + + /* + if (!CAN_IsBusHealthy(2) || !CAN_IsBusHealthy(3)) { + // CAN is lost, enter fault mode immediately + motorData.state = MOTOR_STATE_FAULT; + motorData.desiredTorque = 0.0F; + + #if DEBUG_FLAG + Serial.println("CAN fault detected — entering FAULT state"); + #endif + }*/ + switch (motorData.state){ case MOTOR_STATE_OFF: { diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.cpp b/fsae-vehicle-fw/src/vehicle/telemetry.cpp index ab7cb35..1b78da8 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.cpp +++ b/fsae-vehicle-fw/src/vehicle/telemetry.cpp @@ -15,7 +15,6 @@ TelemetryData telemetryData; void Telemetry_Init() { - // TODO: Update initialization telemetryData = { // Fill with reasonable dummy values .APPS_Travel = 0.0F, @@ -52,11 +51,6 @@ void threadTelemetry(void *pvParameters){ taskENTER_CRITICAL(); // Enter critical section telemetryData = { .APPS_Travel = APPS_GetAPPSReading(), - // .BSEFront_PSI = BSE_GetBSEReading()->bseFront_PSI, - // .BSERear_PSI = BSE_GetBSEReading()->bseFront_PSI, - // .accumulatorVoltage = 0.0F, // TODO: Replace with actual accumulator voltage reading - // .accumulatorTemp_F = 0.0F, // TODO: Replace with actual accumulator temperature reading - .motorSpeed = MCU_GetMCU1Data()->motorSpeed, .motorTorque = MCU_GetMCU1Data()->motorTorque, From 851def152933390daf8a6916d23880f6274b6d28 Mon Sep 17 00:00:00 2001 From: Natalie Perrochon Date: Fri, 17 Oct 2025 15:33:38 -0700 Subject: [PATCH 06/30] Updated mainline prints to be behind himac flag so we don't have all the debug statements when trying to do himac testing --- fsae-vehicle-fw/src/main.cpp | 2 +- fsae-vehicle-fw/src/utils/utils.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index bd4137b..7d0293e 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -65,7 +65,7 @@ void threadMain(void *pvParameters) { * Telemetry: battery current, phase current, motor speed, temperature(s) */ - # if DEBUG_FLAG + # if HIMAC_FLAG if (Serial.available()) { char input = Serial.read(); diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index 370cef4..dd5e9b5 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -3,6 +3,7 @@ #pragma once #define DEBUG_FLAG 1 +#define HIMAC_FLAG 1 #define THREAD_MAIN_STACK_SIZE 128 #define THREAD_MAIN_PRIORITY 1 From 93ac93d7451562e924e1d2a71c974c4cd01d0934 Mon Sep 17 00:00:00 2001 From: Karan Date: Tue, 21 Oct 2025 20:08:45 -0700 Subject: [PATCH 07/30] Can 2 to can3 and fixed HiMaC flag --- fsae-vehicle-fw/src/main.cpp | 37 +++++++++++++------------ fsae-vehicle-fw/src/peripherals/can.cpp | 25 ++++++++++------- fsae-vehicle-fw/src/utils/utils.h | 3 +- fsae-vehicle-fw/src/vehicle/thermal.cpp | 10 +++---- 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index bd4137b..a9571b5 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -45,7 +45,7 @@ void threadMain(void *pvParameters) { Serial.begin(9600); xLastWakeTime = xTaskGetTickCount(); // Initialize the last wake time - # if DEBUG_FLAG + # if HIMAC_FLAG float torqueDemand = 0; bool enablePrecharge = false; bool enablePower = false; @@ -60,12 +60,13 @@ void threadMain(void *pvParameters) { * 'p' or 'P' to enter precharging state from standby, * 'o' or 'O' to enter run state, * ' ' (space) to stop all torque. + * R to toggle regen * The torque demand is limited between 0 and TORQUE_MAX_NM. * * Telemetry: battery current, phase current, motor speed, temperature(s) */ - # if DEBUG_FLAG + # if HIMAC_FLAG if (Serial.available()) { char input = Serial.read(); @@ -186,6 +187,7 @@ void threadMain(void *pvParameters) { Serial.print(" | "); Serial.print("Regen: "); Serial.print(enableRegen); + Serial.print(" \r"); // Serial.print("Battery Current: "); @@ -204,22 +206,21 @@ void threadMain(void *pvParameters) { // Serial.print(MCU_GetMCU2Data().motorTemp); // Serial.print(" \n"); - // print all errors if they are true in one line - // Serial.print(" | "); - // if (MCU_GetMCU2Data().dcMainWireOverVoltFault) Serial.print("DC Over Volt Fault, "); - // if (MCU_GetMCU2Data().motorPhaseCurrFault) Serial.print("Motor Phase Curr Fault, "); - // if (MCU_GetMCU2Data().mcuOverHotFault) Serial.print("MCU Over Hot Fault, "); - // if (MCU_GetMCU2Data().resolverFault) Serial.print("Resolver Fault, "); - // if (MCU_GetMCU2Data().phaseCurrSensorFault) Serial.print("Phase Curr Sensor Fault, "); - // if (MCU_GetMCU2Data().motorOverSpdFault) Serial.print("Motor Over Spd Fault, "); - // if (MCU_GetMCU2Data().drvMotorOverHotFault) Serial.print("Driver Motor Over Hot Fault, "); - // if (MCU_GetMCU2Data().dcMainWireOverCurrFault) Serial.print("DC Main Wire Over Curr Fault, "); - // if (MCU_GetMCU2Data().drvMotorOverCoolFault) Serial.print("Driver Motor Over Cool Fault, "); - // if (MCU_GetMCU2Data().dcLowVoltWarning) Serial.print("DC Low Volt Warning, "); - // if (MCU_GetMCU2Data().mcu12VLowVoltWarning) Serial.print("MCU 12V Low Volt Warning, "); - // if (MCU_GetMCU2Data().motorStallFault) Serial.print("Motor Stall Fault, "); - // if (MCU_GetMCU2Data().motorOpenPhaseFault) Serial.print("Motor Open Phase Fault, "); - + //print all errors if they are true in one line + Serial.print(" | "); + if (MCU_GetMCU2Data()->dcMainWireOverVoltFault) Serial.print("DC Over Volt Fault, "); + if (MCU_GetMCU2Data()->motorPhaseCurrFault) Serial.print("Motor Phase Curr Fault, "); + if (MCU_GetMCU2Data()->mcuOverHotFault) Serial.print("MCU Over Hot Fault, "); + if (MCU_GetMCU2Data()->resolverFault) Serial.print("Resolver Fault, "); + if (MCU_GetMCU2Data()->phaseCurrSensorFault) Serial.print("Phase Curr Sensor Fault, "); + if (MCU_GetMCU2Data()->motorOverSpdFault) Serial.print("Motor Over Spd Fault, "); + if (MCU_GetMCU2Data()->drvMotorOverHotFault) Serial.print("Driver Motor Over Hot Fault, "); + if (MCU_GetMCU2Data()->dcMainWireOverCurrFault) Serial.print("DC Main Wire Over Curr Fault, "); + if (MCU_GetMCU2Data()->drvMotorOverCoolFault) Serial.print("Driver Motor Over Cool Fault, "); + if (MCU_GetMCU2Data()->dcLowVoltWarning) Serial.print("DC Low Volt Warning, "); + if (MCU_GetMCU2Data()->mcu12VLowVoltWarning) Serial.print("MCU 12V Low Volt Warning, "); + if (MCU_GetMCU2Data()->motorStallFault) Serial.print("Motor Stall Fault, "); + if (MCU_GetMCU2Data()->motorOpenPhaseFault) Serial.print("Motor Open Phase Fault, "); Motor_UpdateMotor(torqueDemand, enablePrecharge, enablePower, enableRun, enableRegen); // Update motor with the current torque demand # endif vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10)); // Delay for 100ms diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index 00596bd..8952fda 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -55,9 +55,13 @@ void CAN_Init() { void CAN_Send(uint32_t id, uint64_t msg) { motorMsg.id = id; + // msg.id = 0x100; memcpy(motorMsg.buf, &msg, sizeof(msg)); can2.write(motorMsg); + + Serial.println("| Sending CAN... "); + Serial.print(""); } void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data) { @@ -65,8 +69,9 @@ void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data) { *rx_id = rx_msg.id; memcpy(rx_data, rx_msg.buf, sizeof(*rx_data)); - lastCAN2MsgTime = millis(); - can2Healthy = true; + Serial.println("--> CAN Message recieved"); + // lastCAN2MsgTime = millis(); + // can2Healthy = true; } else { // No message received, assign default values *rx_id = 0; *rx_data = 0; @@ -74,14 +79,14 @@ void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data) { } void CAN_CheckHealth() { - uint32_t now = millis(); - if (now - lastCAN2MsgTime > CAN_TIMEOUT_MS) { - can2Healthy = false; - } - - if (now - lastCAN3MsgTime > CAN_TIMEOUT_MS) { - can3Healthy = false; - } + // uint32_t now = millis(); + // if (now - lastCAN2MsgTime > CAN_TIMEOUT_MS) { + // can2Healthy = false; + // } + + // if (now - lastCAN3MsgTime > CAN_TIMEOUT_MS) { + // can3Healthy = false; + // } } diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index 370cef4..0331a93 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -2,7 +2,8 @@ #pragma once -#define DEBUG_FLAG 1 +#define DEBUG_FLAG 0 +#define HIMAC_FLAG 1 #define THREAD_MAIN_STACK_SIZE 128 #define THREAD_MAIN_PRIORITY 1 diff --git a/fsae-vehicle-fw/src/vehicle/thermal.cpp b/fsae-vehicle-fw/src/vehicle/thermal.cpp index acfc761..e177a49 100644 --- a/fsae-vehicle-fw/src/vehicle/thermal.cpp +++ b/fsae-vehicle-fw/src/vehicle/thermal.cpp @@ -38,11 +38,11 @@ void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, uint32_t rawRead analogWrite(FAN_PIN, 0); // Set fan to 0 duty cycle } // Debugging output - Serial.print("Temp1: "); - Serial.print(temp1); - Serial.print(" C | Temp2: "); - Serial.print(temp2); - Serial.println(" C"); + // Serial.print("Temp1: "); + // Serial.print(temp1); + // Serial.print(" C | Temp2: "); + // Serial.print(temp2); + // Serial.println(" C"); } From 96beabbbae473b151c360128c86ce6f63ad54662 Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 24 Oct 2025 01:36:19 -0700 Subject: [PATCH 08/30] corrected state machine to match inverter docs --- fsae-vehicle-fw/src/main.cpp | 252 +++++++++++++++----------- fsae-vehicle-fw/src/vehicle/motor.cpp | 94 ++++++++-- fsae-vehicle-fw/src/vehicle/motor.h | 6 +- 3 files changed, 227 insertions(+), 125 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index a9571b5..01454f6 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -9,13 +9,13 @@ #include "vehicle/apps.h" #include "vehicle/bse.h" #include "vehicle/faults.h" +#include "vehicle/ifl100-36.h" #include "vehicle/motor.h" #include "vehicle/telemetry.h" -#include "vehicle/ifl100-36.h" +#include "utils/utils.h" #include #include -#include "utils/utils.h" #define TORQUE_STEP 1 #define TORQUE_MAX_NM 20 // Maximum torque demand in Nm @@ -34,10 +34,15 @@ void setup() { // runs once on bootup Motor_Init(); MCU_Init(); - xTaskCreate(threadADC, "threadADC", THREAD_ADC_STACK_SIZE, NULL, THREAD_ADC_PRIORITY, NULL); - xTaskCreate(threadMotor, "threadMotor", THREAD_MOTOR_STACK_SIZE, NULL, THREAD_MOTOR_PRIORITY, NULL); - xTaskCreate(threadTelemetry, "threadTelemetryCAN", THREAD_CAN_TELEMETRY_STACK_SIZE, NULL, THREAD_CAN_TELEMETRY_PRIORITY, NULL); - xTaskCreate(threadMain, "threadMain", THREAD_MAIN_STACK_SIZE, NULL, THREAD_MAIN_PRIORITY, NULL); + xTaskCreate(threadADC, "threadADC", THREAD_ADC_STACK_SIZE, NULL, + THREAD_ADC_PRIORITY, NULL); + xTaskCreate(threadMotor, "threadMotor", THREAD_MOTOR_STACK_SIZE, NULL, + THREAD_MOTOR_PRIORITY, NULL); + xTaskCreate(threadTelemetry, "threadTelemetryCAN", + THREAD_CAN_TELEMETRY_STACK_SIZE, NULL, + THREAD_CAN_TELEMETRY_PRIORITY, NULL); + xTaskCreate(threadMain, "threadMain", THREAD_MAIN_STACK_SIZE, NULL, + THREAD_MAIN_PRIORITY, NULL); vTaskStartScheduler(); } @@ -45,112 +50,137 @@ void threadMain(void *pvParameters) { Serial.begin(9600); xLastWakeTime = xTaskGetTickCount(); // Initialize the last wake time - # if HIMAC_FLAG +#if HIMAC_FLAG float torqueDemand = 0; + bool enableStandby = false; bool enablePrecharge = false; bool enablePower = false; bool enableRun = false; + bool enableFault = false; + bool enableRegen = false; - # endif + + + bool enablebackToRun = false; +#endif while (true) { /* - * Read user input from Serial to control torque demand. - * 'w' or 'W' to increase torque demand, - * 's' or 'S' to decrease torque demand, - * 'p' or 'P' to enter precharging state from standby, - * 'o' or 'O' to enter run state, - * ' ' (space) to stop all torque. - * R to toggle regen - * The torque demand is limited between 0 and TORQUE_MAX_NM. - * - * Telemetry: battery current, phase current, motor speed, temperature(s) - */ - - # if HIMAC_FLAG + * Read user input from Serial to control torque demand. + * 'w' or 'W' to increase torque demand, + * 's' or 'S' to decrease torque demand, + * + * 'p' or 'P' to enter precharging state from standby, + * 'l' or 'L' to enter standby from precharging + * + * 'o' or 'O' to enter run state, + * 'k' or 'K' to go back to idle from run + * + * ' ' (space) to stop all torque. (reset w/s to 0) + * + * + * R to toggle regen + * The torque demand is limited between 0 and TORQUE_MAX_NM. + * + * + * + * + * + * Telemetry: battery current, phase current, motor speed, + * temperature(s) + */ + +#if HIMAC_FLAG if (Serial.available()) { char input = Serial.read(); switch (input) { - case 'w': // Increase torque demand - case 'W': - { - if (torqueDemand < TORQUE_MAX_NM) { - torqueDemand += TORQUE_STEP; // Increment torque demand - } - break; - } - case 's': // Decrease torque demand - case 'S': - { - if( torqueDemand > 0) { - torqueDemand -= TORQUE_STEP; // Decrement torque demand - } - break; + case 'w': // Increase torque demand + case 'W': { + if (torqueDemand < TORQUE_MAX_NM) { + torqueDemand += TORQUE_STEP; // Increment torque demand } - case 'p': // Precharge state - case 'P': - { - enablePrecharge = true; // Set flag to enable precharging - enablePower = false; // Disable run state - enableRun = false; // Disable run state - torqueDemand = 0; // Reset torque demand - // Serial.println("Entering precharge state..."); - } - break; - case 'o': // Power Ready state - case 'O': - { - enablePrecharge = false; // Disable precharging - enablePower = true; // Set flag to enable power ready state - enableRun = false; // Set flag to enable run state - } break; - - case 'i': - case 'I': // Run state - { - enablePrecharge = false; // Disable precharging - enablePower = false; // Set flag to enable power ready state - enableRun = true; // Set flag to enable run state - } - break; - - case ' ': // Stop all torque - torqueDemand = 0; - enableRun = false; // Disable run state - enablePrecharge = false; // Disable precharging - break; - case 'f': // Fault state - case 'F': { - Serial.println("Entering fault state"); - enableRun = false; // Disable run state - enablePrecharge = false; // Disable precharging - torqueDemand = 0; // Reset torque demand - Motor_SetFaultState(); // Set motor to fault state - break; + } + case 's': // Decrease torque demand + case 'S': { + if (torqueDemand > 0) { + torqueDemand -= TORQUE_STEP; // Decrement torque demand } - case 'r': - case 'R': - enableRegen = !enableRegen; - default: - break; + break; + } + case 'l': + case 'L': { // Standby state + enableStandby = true; + enablePrecharge = false; // Disable Precharge + enablePower = false; // Disable run state + enableRun = false; // Disable run state + break; + } + case 'p': // Precharge state + case 'P': { + enableStandby = false; + enablePrecharge = true; // Set flag to enable precharging + enablePower = false; // Disable run state + enableRun = false; // Disable run state + torqueDemand = 0; // Reset torque demand + // Serial.println("Entering precharge state..."); + break; + } + case 'o': // IDLE: Power Ready state + case 'O': { + enableStandby = false; + enablePrecharge = false; // Disable precharging + enablePower = true; // Set flag to enable power ready state + enableRun = false; // Set flag to enable run state + break; + } + case 'i': + case 'I': { // Run state + enableStandby = false; + enablePrecharge = false; // Disable precharging + enablePower = false; // Set flag to enable power ready state + enableRun = true; // Set flag to enable run state + break; + } + case ' ': { // Stop all torque + torqueDemand = 0; + enableRun = false; // Disable run state + enablePrecharge = false; // Disable precharging + break; + } + case 'f': // Fault state + case 'F': { + Serial.println("Entering fault state"); + enableRun = false; // Disable run state + enablePrecharge = false; // Disable precharging + enableStandby = false; + torqueDemand = 0; // Reset torque demand + Motor_SetFaultState(); // Set motor to fault state + break; + } + case 'r': + case 'R': { + enableRegen = !enableRegen; + break; + } + default: + break; } } - // Serial.print("State: "); // Serial.print(MCU_GetMCU1Data().mcuMainState); // Serial.print(" | "); // Serial.print("Internal State: "); // Serial.print(Motor_GetState()); - //Serial.print(" \n"); - + // Serial.print(" \n"); // Serial.print("Torque - "); // Serial.print(torqueDemand); // Serial.print(" \n"); - // Telemetry: Read battery current, phase current, motor speed, temperature(s) + // Telemetry: Read battery current, phase current, motor speed, + // temperature(s) Serial.print("C State: "); Serial.print(MCU_GetMCU1Data()->mcuMainState); Serial.print(" | "); @@ -164,7 +194,8 @@ void threadMain(void *pvParameters) { Serial.print("RPM: "); Serial.print(MCU_GetMCU1Data()->motorSpeed); - // Telemetry: Read battery current, phase current, motor speed, temperature(s) + // Telemetry: Read battery current, phase current, motor speed, + // temperature(s) Serial.print(" | "); Serial.print("B Volt: "); Serial.print(MCU_GetMCU3Data()->mcuVoltage); @@ -189,7 +220,6 @@ void threadMain(void *pvParameters) { Serial.print(enableRegen); Serial.print(" \r"); - // Serial.print("Battery Current: "); // Serial.print(MCU_GetMCU3Data().mcuCurrent); // Serial.print(" \n"); @@ -206,26 +236,40 @@ void threadMain(void *pvParameters) { // Serial.print(MCU_GetMCU2Data().motorTemp); // Serial.print(" \n"); - //print all errors if they are true in one line + // print all errors if they are true in one line Serial.print(" | "); - if (MCU_GetMCU2Data()->dcMainWireOverVoltFault) Serial.print("DC Over Volt Fault, "); - if (MCU_GetMCU2Data()->motorPhaseCurrFault) Serial.print("Motor Phase Curr Fault, "); - if (MCU_GetMCU2Data()->mcuOverHotFault) Serial.print("MCU Over Hot Fault, "); - if (MCU_GetMCU2Data()->resolverFault) Serial.print("Resolver Fault, "); - if (MCU_GetMCU2Data()->phaseCurrSensorFault) Serial.print("Phase Curr Sensor Fault, "); - if (MCU_GetMCU2Data()->motorOverSpdFault) Serial.print("Motor Over Spd Fault, "); - if (MCU_GetMCU2Data()->drvMotorOverHotFault) Serial.print("Driver Motor Over Hot Fault, "); - if (MCU_GetMCU2Data()->dcMainWireOverCurrFault) Serial.print("DC Main Wire Over Curr Fault, "); - if (MCU_GetMCU2Data()->drvMotorOverCoolFault) Serial.print("Driver Motor Over Cool Fault, "); - if (MCU_GetMCU2Data()->dcLowVoltWarning) Serial.print("DC Low Volt Warning, "); - if (MCU_GetMCU2Data()->mcu12VLowVoltWarning) Serial.print("MCU 12V Low Volt Warning, "); - if (MCU_GetMCU2Data()->motorStallFault) Serial.print("Motor Stall Fault, "); - if (MCU_GetMCU2Data()->motorOpenPhaseFault) Serial.print("Motor Open Phase Fault, "); - Motor_UpdateMotor(torqueDemand, enablePrecharge, enablePower, enableRun, enableRegen); // Update motor with the current torque demand - # endif + if (MCU_GetMCU2Data()->dcMainWireOverVoltFault) + Serial.print("DC Over Volt Fault, "); + if (MCU_GetMCU2Data()->motorPhaseCurrFault) + Serial.print("Motor Phase Curr Fault, "); + if (MCU_GetMCU2Data()->mcuOverHotFault) + Serial.print("MCU Over Hot Fault, "); + if (MCU_GetMCU2Data()->resolverFault) + Serial.print("Resolver Fault, "); + if (MCU_GetMCU2Data()->phaseCurrSensorFault) + Serial.print("Phase Curr Sensor Fault, "); + if (MCU_GetMCU2Data()->motorOverSpdFault) + Serial.print("Motor Over Spd Fault, "); + if (MCU_GetMCU2Data()->drvMotorOverHotFault) + Serial.print("Driver Motor Over Hot Fault, "); + if (MCU_GetMCU2Data()->dcMainWireOverCurrFault) + Serial.print("DC Main Wire Over Curr Fault, "); + if (MCU_GetMCU2Data()->drvMotorOverCoolFault) + Serial.print("Driver Motor Over Cool Fault, "); + if (MCU_GetMCU2Data()->dcLowVoltWarning) + Serial.print("DC Low Volt Warning, "); + if (MCU_GetMCU2Data()->mcu12VLowVoltWarning) + Serial.print("MCU 12V Low Volt Warning, "); + if (MCU_GetMCU2Data()->motorStallFault) + Serial.print("Motor Stall Fault, "); + if (MCU_GetMCU2Data()->motorOpenPhaseFault) + Serial.print("Motor Open Phase Fault, "); + Motor_UpdateMotor( + torqueDemand, enablePrecharge, enablePower, enableRun, + enableRegen, enableStandby); // Update motor with the current torque demand +#endif vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10)); // Delay for 100ms } } void loop() {} - diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 853e92b..e597a42 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -28,6 +28,17 @@ static VCU1 vcu1 = {0}; static BMS1 bms1 = {0}; static BMS2 bms2 = {0}; +/** + * + * TODO 10/24/25 + * + * Match State Machine of Inverter with Program + * Check thread priorities --GOOD + * Make sure fault state can be read and matched -- GOOD + * CAN Communication from PCC (like ifl100-36) + * + */ + void Motor_Init(){ motorData.state = MOTOR_STATE_OFF; // TODO Check if we want this motorData.desiredTorque = 0.0F; // No torque demand at start @@ -52,12 +63,25 @@ void threadMotor(void *pvParameters){ }*/ switch (motorData.state){ - case MOTOR_STATE_OFF: - { + case MOTOR_STATE_OFF:{ + //T8 + vcu1.KeyPosition = 0; + break; + } + case MOTOR_STATE_STANDBY:{ + //T1 + vcu1.KeyPosition = 2; + + //T3 + vcu1.BMS_Main_Relay_Cmd = 0; + bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Finish_Sts = 0; + break; } case MOTOR_STATE_PRECHARGING: { + vcu1.KeyPosition = 2; // T2 State transition: BMS_Main_Relay_Cmd == 1 && Pre_charge_Relay_FB == 1 vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF @@ -69,6 +93,10 @@ void threadMotor(void *pvParameters){ vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF + + //T6 + vcu1.VCU_MotorMode = 0; + vcu1.VCU_TorqueReq = 0; break; } case MOTOR_STATE_DRIVING: @@ -97,11 +125,11 @@ void threadMotor(void *pvParameters){ case MOTOR_STATE_FAULT: { // T7 MCU_Warning_Level == 3 - vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit - bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF - vcu1.VCU_Warning_Level = 1; // 0 = No Warning, 1 = Warning, 2 = Fault, 3 = Critical Fault - vcu1.VCU_MotorMode = 0; // 0 = Standby, 1 = Drive, 2 = Generate Electricy, 3 = Reserved + vcu1.BMS_Main_Relay_Cmd = 0; // 1 = ON, 0 = OFF + bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Finish_Sts = 0; // 1 = ON, 0 = OFF + vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, 2 = Fault, 3 = Critical Fault + vcu1.VCU_MotorMode = 0; // 0 = Standby, 1 = Drive, 2 = Generate Electricy, 3 = Reserved break; } default: @@ -130,17 +158,30 @@ void threadMotor(void *pvParameters){ } } -void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen){ +void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen, bool enableStandy){ // Update the motor state based on the RTM button state - // float throttleCommand = APPS_GetAPPSReading(); // 0; //TODO Get APPS_travel + + + //off --> standby --> precharge --> run --> fault -->standy + //no kl15 then off switch(motorData.state){ // LV on, HV off case MOTOR_STATE_OFF:{ + if (enableStandy){ + // # if HIMAC_FLAG + // Serial.println("Standby Mode"); + // #endif + motorData.state = MOTOR_STATE_STANDBY; + } + motorData.desiredTorque = 0.0F; + break; + } + case MOTOR_STATE_STANDBY:{ if (enablePrecharge){ - # if DEBUG_FLAG - Serial.println("Precharging..."); - #endif + // # if HIMAC_FLAG + // Serial.println("Precharging..."); + // #endif motorData.state = MOTOR_STATE_PRECHARGING; } motorData.desiredTorque = 0.0F; @@ -150,11 +191,14 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe case MOTOR_STATE_PRECHARGING: { if(enablePower){ - # if DEBUG_FLAG - Serial.println("Precharge finished"); - # endif + // # if HIMAC_FLAG + // Serial.println("Precharge finished"); + // # endif motorData.state = MOTOR_STATE_IDLE; + } else if (enableStandy){ + motorData.state = MOTOR_STATE_STANDBY; } + motorData.desiredTorque = 0.0F; break; } @@ -162,7 +206,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe case MOTOR_STATE_IDLE: { if(enableRun){ - # if DEBUG_FLAG + # if HIMAC_FLAG Serial.println("Ready to drive..."); # endif motorData.state = MOTOR_STATE_DRIVING; @@ -177,16 +221,21 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe // motorData.state = MOTOR_STATE_IDLE; // } + if (enablePower){ + motorData.state = MOTOR_STATE_IDLE; + } // torque is communicated as a percentage #if !SPEED_CONTROL_ENABLED - if (enableRegen && torqueDemand <= 0.0F && MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { + else if (enableRegen && torqueDemand <= 0.0F && MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { // If regen is enabled and the torque demand is zero, we need to set the torque demand to 0 // to prevent the motor from applying torque in the wrong direction motorData.desiredTorque = MAX_REGEN_TORQUE * REGEN_BIAS; } else { motorData.desiredTorque = torqueDemand; } + + #else // Speed control is enabled, we need to set the torque demand to 0 vcu1.VCU_TorqueReq = 0; // 0 = No torque @@ -196,10 +245,15 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe } case MOTOR_STATE_FAULT: { - // TODO Implement RTM Button - if(RTMButton_GetState() == false){ - motorData.state = MOTOR_STATE_IDLE; + + if (enableStandy){ + motorData.state = MOTOR_STATE_STANDBY; } +//GOES BACK TO HV ON + // TODO Implement RTM Button + // if(RTMButton_GetState() == false){ + // motorData.state = MOTOR_STATE_IDLE; + // } motorData.desiredTorque = 0.0F; break; } diff --git a/fsae-vehicle-fw/src/vehicle/motor.h b/fsae-vehicle-fw/src/vehicle/motor.h index 78108d1..02e5e50 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.h +++ b/fsae-vehicle-fw/src/vehicle/motor.h @@ -6,16 +6,20 @@ typedef enum { MOTOR_STATE_OFF, + MOTOR_STATE_STANDBY, MOTOR_STATE_PRECHARGING, MOTOR_STATE_IDLE, MOTOR_STATE_DRIVING, MOTOR_STATE_FAULT, + MOTOR_PRECHARGE_TO_STANDBY, + MOTOR_RUN_TO_IDLE, + } MotorState; void threadMotor(void *pvParameters); void Motor_Init(); -void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen); +void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen, bool enableStandby); float Motor_GetTorqueDemand(); MotorState Motor_GetState(); From d44faa9b1fd968e65937c02fa6e92bc8a0f8fd4e Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 24 Oct 2025 01:42:36 -0700 Subject: [PATCH 09/30] add debugging comments for himac 10-24 --- fsae-vehicle-fw/src/main.cpp | 7 +------ fsae-vehicle-fw/src/vehicle/motor.cpp | 8 +++++--- fsae-vehicle-fw/src/vehicle/motor.h | 5 +---- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 01454f6..4cf8f6b 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -76,14 +76,9 @@ void threadMain(void *pvParameters) { * 'k' or 'K' to go back to idle from run * * ' ' (space) to stop all torque. (reset w/s to 0) - * - * * R to toggle regen - * The torque demand is limited between 0 and TORQUE_MAX_NM. - * - * - * * + * The torque demand is limited between 0 and TORQUE_MAX_NM. * * Telemetry: battery current, phase current, motor speed, * temperature(s) diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index e597a42..1f6f917 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -62,6 +62,8 @@ void threadMotor(void *pvParameters){ #endif }*/ + + //TODO: Check if keyposition does anything --> if not then manually switch kl15, and provision a gpio pin to control a 3.3v switch or mosfet switch (motorData.state){ case MOTOR_STATE_OFF:{ //T8 @@ -76,7 +78,6 @@ void threadMotor(void *pvParameters){ vcu1.BMS_Main_Relay_Cmd = 0; bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 0; - break; } case MOTOR_STATE_PRECHARGING: @@ -162,7 +163,6 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe // Update the motor state based on the RTM button state // float throttleCommand = APPS_GetAPPSReading(); // 0; //TODO Get APPS_travel - //off --> standby --> precharge --> run --> fault -->standy //no kl15 then off switch(motorData.state){ @@ -248,8 +248,10 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe if (enableStandy){ motorData.state = MOTOR_STATE_STANDBY; + } else if (enableRun) { + Motor_ClearFaultState(); } -//GOES BACK TO HV ON + //GOES BACK TO HV ON // TODO Implement RTM Button // if(RTMButton_GetState() == false){ // motorData.state = MOTOR_STATE_IDLE; diff --git a/fsae-vehicle-fw/src/vehicle/motor.h b/fsae-vehicle-fw/src/vehicle/motor.h index 02e5e50..137624a 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.h +++ b/fsae-vehicle-fw/src/vehicle/motor.h @@ -10,10 +10,7 @@ typedef enum { MOTOR_STATE_PRECHARGING, MOTOR_STATE_IDLE, MOTOR_STATE_DRIVING, - MOTOR_STATE_FAULT, - MOTOR_PRECHARGE_TO_STANDBY, - MOTOR_RUN_TO_IDLE, - + MOTOR_STATE_FAULT } MotorState; void threadMotor(void *pvParameters); From ff710a8e3c828be4ccd0c838e2d0900c553935ce Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 24 Oct 2025 02:22:53 -0700 Subject: [PATCH 10/30] before adding pcc can defintions --- fsae-vehicle-fw/src/peripherals/can.cpp | 10 ++++++++++ fsae-vehicle-fw/src/vehicle/motor.cpp | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index 8952fda..e32eb4e 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -32,6 +32,14 @@ static bool can3Healthy = false; #define CAN_TIMEOUT_MS 100 +//CAN SETUP +/** + * CAN2 (CAN2 on diagram) --> ORION, CCM, RASPI, PCC + * CAN3 (CAN1 on diagram) --> CCM, OMNI, RASPI + * + */ + + void CAN_Init() { // Initialize CAN bus can2.begin(); @@ -52,6 +60,8 @@ void CAN_Init() { tp.setWriteBus(&can3); // Set the bus to write to can3 } +//TODO @ksthakkar: make can_send general function to select both CANbuses or make seperate CAN_send functions +//can2 void CAN_Send(uint32_t id, uint64_t msg) { motorMsg.id = id; diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 1f6f917..03f600b 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -32,11 +32,13 @@ static BMS2 bms2 = {0}; * * TODO 10/24/25 * - * Match State Machine of Inverter with Program + * Match State Machine of Inverter with Program --GOOD * Check thread priorities --GOOD * Make sure fault state can be read and matched -- GOOD * CAN Communication from PCC (like ifl100-36) * + * TODO Future: Enums for VCU transitions or abstracted T1-T8 transitions + * */ void Motor_Init(){ @@ -167,6 +169,8 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe //no kl15 then off switch(motorData.state){ // LV on, HV off + + //no kl15 case MOTOR_STATE_OFF:{ if (enableStandy){ // # if HIMAC_FLAG @@ -177,6 +181,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe motorData.desiredTorque = 0.0F; break; } + //kl15 on and ready to go into precharge case MOTOR_STATE_STANDBY:{ if (enablePrecharge){ // # if HIMAC_FLAG @@ -243,6 +248,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe break; } + //Any fault error occurs case MOTOR_STATE_FAULT: { From ca59357fe81a8841bb07aef99b0742d771e77696 Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 24 Oct 2025 02:35:23 -0700 Subject: [PATCH 11/30] try to correct formatting and add correct spacings --- fsae-vehicle-fw/src/main.cpp | 3 --- fsae-vehicle-fw/src/peripherals/can.cpp | 4 ++-- fsae-vehicle-fw/src/vehicle/motor.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 4cf8f6b..307ab36 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -56,12 +56,9 @@ void threadMain(void *pvParameters) { bool enablePrecharge = false; bool enablePower = false; bool enableRun = false; - bool enableFault = false; bool enableRegen = false; - - bool enablebackToRun = false; #endif while (true) { /* diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index e32eb4e..ccbd0f7 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -24,8 +24,8 @@ CAN_message_t motorMsg; CAN_message_t rx_msg; // CAN loss detection -static uint32_t lastCAN2MsgTime = 0; -static uint32_t lastCAN3MsgTime = 0; +// static uint32_t lastCAN2MsgTime = 0; +// static uint32_t lastCAN3MsgTime = 0; static bool can2Healthy = false; static bool can3Healthy = false; diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 03f600b..caf86ab 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -161,7 +161,7 @@ void threadMotor(void *pvParameters){ } } -void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen, bool enableStandy){ +void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen, bool enableStandby){ // Update the motor state based on the RTM button state // float throttleCommand = APPS_GetAPPSReading(); // 0; //TODO Get APPS_travel @@ -172,7 +172,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe //no kl15 case MOTOR_STATE_OFF:{ - if (enableStandy){ + if (enableStandby){ // # if HIMAC_FLAG // Serial.println("Standby Mode"); // #endif @@ -200,7 +200,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe // Serial.println("Precharge finished"); // # endif motorData.state = MOTOR_STATE_IDLE; - } else if (enableStandy){ + } else if (enableStandby){ motorData.state = MOTOR_STATE_STANDBY; } @@ -252,7 +252,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePowe case MOTOR_STATE_FAULT: { - if (enableStandy){ + if (enableStandby){ motorData.state = MOTOR_STATE_STANDBY; } else if (enableRun) { Motor_ClearFaultState(); From c0efa4cefbfd3e54f504e98d0c06c66d792de319 Mon Sep 17 00:00:00 2001 From: Karan Date: Thu, 30 Oct 2025 11:35:31 -0700 Subject: [PATCH 12/30] state machine fully verified, issues with motor phase leads --- fsae-vehicle-fw/src/main.cpp | 42 ++- fsae-vehicle-fw/src/peripherals/can.cpp | 10 +- fsae-vehicle-fw/src/vehicle/ifl100-36.cpp | 12 +- fsae-vehicle-fw/src/vehicle/ifl100-36.h | 5 +- fsae-vehicle-fw/src/vehicle/motor.cpp | 414 +++++++++++----------- 5 files changed, 255 insertions(+), 228 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 307ab36..247ab7a 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -138,6 +138,8 @@ void threadMain(void *pvParameters) { torqueDemand = 0; enableRun = false; // Disable run state enablePrecharge = false; // Disable precharging + enablePower = false; + enableRun = false; break; } case 'f': // Fault state @@ -207,10 +209,16 @@ void threadMain(void *pvParameters) { Serial.print("Mtr Temp: "); Serial.print(MCU_GetMCU2Data()->motorTemp); + Serial.print(" | "); + Serial.print(" "); + Serial.print(" | "); Serial.print("Regen: "); Serial.print(enableRegen); - Serial.print(" \r"); + Serial.print("\r"); + + + // Serial.print("Battery Current: "); // Serial.print(MCU_GetMCU3Data().mcuCurrent); @@ -231,34 +239,40 @@ void threadMain(void *pvParameters) { // print all errors if they are true in one line Serial.print(" | "); if (MCU_GetMCU2Data()->dcMainWireOverVoltFault) - Serial.print("DC Over Volt Fault, "); + Serial.println("DC Over Volt Fault, "); if (MCU_GetMCU2Data()->motorPhaseCurrFault) - Serial.print("Motor Phase Curr Fault, "); + Serial.println("Motor Phase Curr Fault, "); if (MCU_GetMCU2Data()->mcuOverHotFault) - Serial.print("MCU Over Hot Fault, "); + Serial.println("MCU Over Hot Fault, "); if (MCU_GetMCU2Data()->resolverFault) - Serial.print("Resolver Fault, "); + Serial.println("Resolver Fault, "); if (MCU_GetMCU2Data()->phaseCurrSensorFault) - Serial.print("Phase Curr Sensor Fault, "); + Serial.println("Phase Curr Sensor Fault, "); if (MCU_GetMCU2Data()->motorOverSpdFault) - Serial.print("Motor Over Spd Fault, "); + Serial.println("Motor Over Spd Fault, "); if (MCU_GetMCU2Data()->drvMotorOverHotFault) - Serial.print("Driver Motor Over Hot Fault, "); + Serial.println("Driver Motor Over Hot Fault, "); if (MCU_GetMCU2Data()->dcMainWireOverCurrFault) - Serial.print("DC Main Wire Over Curr Fault, "); + Serial.println("DC Main Wire Over Curr Fault, "); if (MCU_GetMCU2Data()->drvMotorOverCoolFault) - Serial.print("Driver Motor Over Cool Fault, "); + Serial.println("Driver Motor Over Cool Fault, "); if (MCU_GetMCU2Data()->dcLowVoltWarning) - Serial.print("DC Low Volt Warning, "); + Serial.println("DC Low Volt Warning, "); if (MCU_GetMCU2Data()->mcu12VLowVoltWarning) - Serial.print("MCU 12V Low Volt Warning, "); + Serial.println("MCU 12V Low Volt Warning, "); if (MCU_GetMCU2Data()->motorStallFault) - Serial.print("Motor Stall Fault, "); + Serial.println("Motor Stall Fault, "); if (MCU_GetMCU2Data()->motorOpenPhaseFault) - Serial.print("Motor Open Phase Fault, "); + Serial.println("Motor Open Phase Fault, "); + + + + Motor_UpdateMotor( torqueDemand, enablePrecharge, enablePower, enableRun, enableRegen, enableStandby); // Update motor with the current torque demand + + #endif vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10)); // Delay for 100ms } diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index ccbd0f7..349a128 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -68,18 +68,18 @@ void CAN_Send(uint32_t id, uint64_t msg) // msg.id = 0x100; memcpy(motorMsg.buf, &msg, sizeof(msg)); - can2.write(motorMsg); + can3.write(motorMsg); - Serial.println("| Sending CAN... "); - Serial.print(""); + // Serial.println("| Sending CAN... "); + // Serial.print(""); } void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data) { - if (can2.read(rx_msg)) { + if (can3.read(rx_msg)) { *rx_id = rx_msg.id; memcpy(rx_data, rx_msg.buf, sizeof(*rx_data)); - Serial.println("--> CAN Message recieved"); + // Serial.println("--> CAN Message recieved"); // lastCAN2MsgTime = millis(); // can2Healthy = true; } else { // No message received, assign default values diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp index f6ff8f0..d47ed50 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp @@ -58,8 +58,8 @@ void MCU_Init() { mcu3Data = { .mcuVoltage = 0.0F, // Default voltage in V - .mcuCurrent = 0.0F, // Default current in A - .motorPhaseCurr = 0.0F // Default phase current in A + .mcuCurrent = 16.0F, // Default current in A + .motorPhaseCurr = 3.0F // Default phase current in A }; // Initialize the motor thread @@ -130,11 +130,13 @@ static void threadMCU(void *pvParameters) { memcpy(&mcu3, &rx_data, sizeof(mcu3)); taskENTER_CRITICAL(); // Enter critical section + mcu3Data = { - .mcuVoltage = CHANGE_ENDIANESS_16(mcu3.MCU_DC_MainWireVolt) * 0.01F, // convert to V - .mcuCurrent = CHANGE_ENDIANESS_16(mcu3.MCU_DC_MainWireCurr) * 0.01F, // convert to A - .motorPhaseCurr = CHANGE_ENDIANESS_16(mcu3.MCU_MotorPhaseCurr) * 0.01F, // convert to A + .mcuVoltage = (((mcu3.MCU_DC_MainWireVolt & 0xFF) << 8) | (mcu3.MCU_DC_MainWireVolt >> 8)) * 0.01F, // convert to V + .mcuCurrent = (((mcu3.MCU_DC_MainWireCurr & 0xFF) << 8) | (mcu3.MCU_DC_MainWireCurr >> 8)) * 0.01F, // convert to A + .motorPhaseCurr = (((mcu3.MCU_MotorPhaseCurr & 0xFF) << 8) | (mcu3.MCU_MotorPhaseCurr >> 8)) * 0.01F, // convert to A }; + taskEXIT_CRITICAL(); // Exit critical section break; } diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.h b/fsae-vehicle-fw/src/vehicle/ifl100-36.h index b6fcc07..fe37847 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.h +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.h @@ -120,8 +120,9 @@ typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) { uint64_t MCU_DC_MainWireVolt : 16; // end of byte 0 and byte 1 - uint64_t MCU_DC_MainWireCurr: 16; // end of byte 2 and byte 3 - uint64_t MCU_MotorPhaseCurr : 16; // end of byte 4 and byte 5 + //uint64_t dummystop : 8; + uint64_t MCU_DC_MainWireCurr: 16; // end of byte 2 and byte 3 --> should be byte 3 and 4 + uint64_t MCU_MotorPhaseCurr : 16; // end of byte 4 and byte 5 ---> 6 and 7? or 5 and 6 uint64_t Reserved : 16; // end of byte 6 and byte 7 } MCU3; // bit order verified diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index caf86ab..5869b7f 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -1,9 +1,8 @@ // Anteater Electric Racing, 2025 - #define SPEED_CONTROL_ENABLED 0 #define SPEED_P_GAIN 0.01F // Proportional gain for speed control -#define SPEED_I_GAIN 0.1F // Integral gain for speed control +#define SPEED_I_GAIN 0.1F // Integral gain for speed control #include @@ -11,13 +10,13 @@ #include "peripherals/can.h" -#include "vehicle/motor.h" -#include "vehicle/telemetry.h" -#include "vehicle/rtm_button.h" #include "apps.h" #include "vehicle/ifl100-36.h" +#include "vehicle/motor.h" +#include "vehicle/rtm_button.h" +#include "vehicle/telemetry.h" -typedef struct{ +typedef struct { MotorState state; float desiredTorque; // Torque demand in Nm; } MotorData; @@ -32,22 +31,19 @@ static BMS2 bms2 = {0}; * * TODO 10/24/25 * - * Match State Machine of Inverter with Program --GOOD - * Check thread priorities --GOOD - * Make sure fault state can be read and matched -- GOOD * CAN Communication from PCC (like ifl100-36) * * TODO Future: Enums for VCU transitions or abstracted T1-T8 transitions * */ -void Motor_Init(){ +void Motor_Init() { motorData.state = MOTOR_STATE_OFF; // TODO Check if we want this - motorData.desiredTorque = 0.0F; // No torque demand at start + motorData.desiredTorque = 0.0F; // No torque demand at start } -void threadMotor(void *pvParameters){ - while(true){ +void threadMotor(void *pvParameters) { + while (true) { // Clear packet contents vcu1 = {0}; bms1 = {0}; @@ -64,86 +60,110 @@ void threadMotor(void *pvParameters){ #endif }*/ + // TODO: Check if keyposition does anything --> if not then manually + // switch kl15, and provision a gpio pin to control a 3.3v switch or + // mosfet + switch (motorData.state) { - //TODO: Check if keyposition does anything --> if not then manually switch kl15, and provision a gpio pin to control a 3.3v switch or mosfet - switch (motorData.state){ - case MOTOR_STATE_OFF:{ - //T8 - vcu1.KeyPosition = 0; - break; - } - case MOTOR_STATE_STANDBY:{ - //T1 - vcu1.KeyPosition = 2; - - //T3 - vcu1.BMS_Main_Relay_Cmd = 0; - bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit - bms1.Pre_charge_Finish_Sts = 0; - break; - } - case MOTOR_STATE_PRECHARGING: - { - vcu1.KeyPosition = 2; - // T2 State transition: BMS_Main_Relay_Cmd == 1 && Pre_charge_Relay_FB == 1 - vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF - break; - } - case MOTOR_STATE_IDLE: - { - // T4 BMS_Main_Relay_Cmd == 1 && Pre_charge_Finish_Sts == 1 && Ubat>=200V - vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit - bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF - - //T6 - vcu1.VCU_MotorMode = 0; - vcu1.VCU_TorqueReq = 0; - break; - } - case MOTOR_STATE_DRIVING: - { - uint16_t maxDischarge = (uint16_t) (BATTERY_MAX_CURRENT_A + 500) * 10; - uint16_t maxRegen = (uint16_t) (BATTERY_MAX_REGEN_A + 500) * 10; - - bms2.sAllowMaxDischarge = CHANGE_ENDIANESS_16(maxDischarge); // Convert to little-endian format - bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16(maxRegen); // Convert to little-endian format - - // T5 BMS_Main_Relay_Cmd == 1 && VCU_MotorMode = 1/2 - vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit - bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF - - vcu1.VehicleState = 1; // 0 = Not ready, 1 = Ready - vcu1.GearLeverPos_Sts = 3; // 0 = Default, 1 = R, 2 = N, 3 = D, 4 = P - vcu1.AC_Control_Cmd = 1; // 0 = Not active, 1 = Active - vcu1.BMS_Aux_Relay_Cmd = 1; // 0 = not work, 1 = work - vcu1.KeyPosition = 2; // 0 = Off, 1 = ACC, 2 = ON, 2 = Crank+On - - vcu1.VCU_TorqueReq = (uint8_t) ((fabsf(motorData.desiredTorque) / MOTOR_MAX_TORQUE) * 100); // Torque demand in percentage (0-99.6) 350Nm - vcu1.VCU_MotorMode = motorData.desiredTorque >= 0 ? 1 : 2; // 0 = Standby, 1 = Drive, 2 = Generate Electricy, 3 = Reserved - break; - } - case MOTOR_STATE_FAULT: - { - // T7 MCU_Warning_Level == 3 - vcu1.BMS_Main_Relay_Cmd = 0; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit - bms1.Pre_charge_Finish_Sts = 0; // 1 = ON, 0 = OFF - vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, 2 = Fault, 3 = Critical Fault - vcu1.VCU_MotorMode = 0; // 0 = Standby, 1 = Drive, 2 = Generate Electricy, 3 = Reserved - break; - } - default: - { - break; - } + // TODO: MAKE this state 4? --> matches with inverter state machine + case MOTOR_STATE_OFF: { + // T8 + // vcu1.KeyPosition = 0; + break; + } + case MOTOR_STATE_STANDBY: { + // T1 + // vcu1.KeyPosition = 2; + + // T3 + vcu1.BMS_Main_Relay_Cmd = 0; + bms1.Pre_charge_Relay_FB = + 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Finish_Sts = 0; + break; } + case MOTOR_STATE_PRECHARGING: { + // vcu1.KeyPosition = 2; + // T2 State transition: BMS_Main_Relay_Cmd == 1 && + // Pre_charge_Relay_FB == 1 + vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF + bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF + vcu1.VCU_TorqueReq = 0; - vcu1.CheckSum = ComputeChecksum((uint8_t*) &vcu1); - bms1.CheckSum = ComputeChecksum((uint8_t*) &bms1); - bms2.CheckSum = ComputeChecksum((uint8_t*) &bms2); + break; + } + case MOTOR_STATE_IDLE: { + // T4 BMS_Main_Relay_Cmd == 1 && Pre_charge_Finish_Sts == 1 && + // Ubat>=200V + vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF + bms1.Pre_charge_Relay_FB = + 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF + + // T6 + // vcu1.VCU_MotorMode = 0; + // vcu1.VCU_TorqueReq = 0; + + // Convert to little-endian format + // bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16(maxRegen); // + // Convert to little-endian format + + break; + } + case MOTOR_STATE_DRIVING: { + uint16_t maxDischarge = + (uint16_t)(BATTERY_MAX_CURRENT_A + 500) * 10; + uint16_t maxRegen = (uint16_t)(BATTERY_MAX_REGEN_A + 500) * 10; + + bms2.sAllowMaxDischarge = CHANGE_ENDIANESS_16(maxDischarge); + bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16( + maxRegen); // Convert to little-endian format + + // T5 BMS_Main_Relay_Cmd == 1 && VCU_MotorMode = 1/2 + vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF + bms1.Pre_charge_Relay_FB = + 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF + + vcu1.VehicleState = 1; // 0 = Not ready, 1 = Ready + vcu1.GearLeverPos_Sts = + 3; // 0 = Default, 1 = R, 2 = N, 3 = D, 4 = P + vcu1.AC_Control_Cmd = 1; // 0 = Not active, 1 = Active + vcu1.BMS_Aux_Relay_Cmd = 1; // 0 = not work, 1 = work + vcu1.VCU_WorkMode = 0; + + // vcu1.KeyPosition = 2; // 0 = Off, 1 = ACC, 2 = ON, 3 = Crank+On + + vcu1.VCU_TorqueReq = + (uint8_t)((fabsf(motorData.desiredTorque) / MOTOR_MAX_TORQUE) * + 100); // Torque demand in percentage (0-99.6) 350Nm + vcu1.VCU_MotorMode = motorData.desiredTorque >= 0 + ? 1 + : 2; // 0 = Standby, 1 = Drive, 2 = + // Generate Electricy, 3 = Reserved + break; + } + case MOTOR_STATE_FAULT: { + // T7 MCU_Warning_Level == 3 + vcu1.BMS_Main_Relay_Cmd = 0; // 1 = ON, 0 = OFF + bms1.Pre_charge_Relay_FB = + 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Finish_Sts = 0; // 1 = ON, 0 = OFF + vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, + // 2 = Fault, 3 = Critical Fault + vcu1.VCU_MotorMode = + 0; // 0 = Standby, 1 = Drive, 2 = Generate + // Electricy, 3 = Reserved + break; + } + default: { + break; + } + } + + vcu1.CheckSum = ComputeChecksum((uint8_t *)&vcu1); + bms1.CheckSum = ComputeChecksum((uint8_t *)&bms1); + bms2.CheckSum = ComputeChecksum((uint8_t *)&bms2); uint64_t vcu1_msg; memcpy(&vcu1_msg, &vcu1, sizeof(vcu1_msg)); @@ -161,130 +181,120 @@ void threadMotor(void *pvParameters){ } } -void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen, bool enableStandby){ +void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, + bool enablePower, bool enableRun, bool enableRegen, + bool enableStandby) { // Update the motor state based on the RTM button state - // float throttleCommand = APPS_GetAPPSReading(); // 0; //TODO Get APPS_travel - - //off --> standby --> precharge --> run --> fault -->standy - //no kl15 then off - switch(motorData.state){ - // LV on, HV off - - //no kl15 - case MOTOR_STATE_OFF:{ - if (enableStandby){ - // # if HIMAC_FLAG - // Serial.println("Standby Mode"); - // #endif - motorData.state = MOTOR_STATE_STANDBY; - } - motorData.desiredTorque = 0.0F; - break; - } - //kl15 on and ready to go into precharge - case MOTOR_STATE_STANDBY:{ - if (enablePrecharge){ - // # if HIMAC_FLAG - // Serial.println("Precharging..."); - // #endif - motorData.state = MOTOR_STATE_PRECHARGING; - } - motorData.desiredTorque = 0.0F; - break; + // float throttleCommand = APPS_GetAPPSReading(); // 0; //TODO Get + // APPS_travel + + // off --> standby --> precharge --> run --> fault -->standy + // no kl15 then off + switch (motorData.state) { + // LV on, HV off + + // no kl15 + case MOTOR_STATE_OFF: { + if (enableStandby) { + // # if HIMAC_FLAG + // Serial.println("Standby Mode"); + // #endif + motorData.state = MOTOR_STATE_STANDBY; } - // HV switch on (PCC CAN message) - case MOTOR_STATE_PRECHARGING: - { - if(enablePower){ - // # if HIMAC_FLAG - // Serial.println("Precharge finished"); - // # endif - motorData.state = MOTOR_STATE_IDLE; - } else if (enableStandby){ - motorData.state = MOTOR_STATE_STANDBY; - } - - motorData.desiredTorque = 0.0F; - break; + motorData.desiredTorque = 0.0F; + break; + } + // kl15 on and ready to go into precharge + case MOTOR_STATE_STANDBY: { + if (enablePrecharge) { + // # if HIMAC_FLAG + // Serial.println("Precharging..."); + // #endif + motorData.state = MOTOR_STATE_PRECHARGING; } - // PCC CAN message finished - case MOTOR_STATE_IDLE: - { - if(enableRun){ - # if HIMAC_FLAG - Serial.println("Ready to drive..."); - # endif - motorData.state = MOTOR_STATE_DRIVING; - } - motorData.desiredTorque = 0.0F; - break; + motorData.desiredTorque = 0.0F; + break; + } + // HV switch on (PCC CAN message) + case MOTOR_STATE_PRECHARGING: { + if (enablePower) { + // # if HIMAC_FLAG + // Serial.println("Precharge finished"); + // # endif + motorData.state = MOTOR_STATE_IDLE; + } else if (enableStandby) { + motorData.state = MOTOR_STATE_STANDBY; } - // Ready to drive button pressed - case MOTOR_STATE_DRIVING: - { - // if(!enableRun){ - // motorData.state = MOTOR_STATE_IDLE; - // } - - if (enablePower){ - motorData.state = MOTOR_STATE_IDLE; - } - // torque is communicated as a percentage - #if !SPEED_CONTROL_ENABLED - - else if (enableRegen && torqueDemand <= 0.0F && MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { - // If regen is enabled and the torque demand is zero, we need to set the torque demand to 0 - // to prevent the motor from applying torque in the wrong direction - motorData.desiredTorque = MAX_REGEN_TORQUE * REGEN_BIAS; - } else { - motorData.desiredTorque = torqueDemand; - } - - - #else - // Speed control is enabled, we need to set the torque demand to 0 - vcu1.VCU_TorqueReq = 0; // 0 = No torque - #endif - break; + motorData.desiredTorque = 0.0F; + break; + } + // PCC CAN message finished + case MOTOR_STATE_IDLE: { + if (enableRun) { + #if HIMAC_FLAG + Serial.println("Ready to drive..."); + #endif + motorData.state = MOTOR_STATE_DRIVING; } - //Any fault error occurs - case MOTOR_STATE_FAULT: - { - - if (enableStandby){ - motorData.state = MOTOR_STATE_STANDBY; - } else if (enableRun) { - Motor_ClearFaultState(); - } - //GOES BACK TO HV ON - // TODO Implement RTM Button - // if(RTMButton_GetState() == false){ - // motorData.state = MOTOR_STATE_IDLE; - // } - motorData.desiredTorque = 0.0F; - break; + motorData.desiredTorque = 0.0F; + break; + } + // Ready to drive button pressed + case MOTOR_STATE_DRIVING: { + // if(!enableRun){ + // motorData.state = MOTOR_STATE_IDLE; + // } + + if (enablePower) { + motorData.state = MOTOR_STATE_IDLE; } - default: - { - break; + // torque is communicated as a percentage + #if !SPEED_CONTROL_ENABLED + + else if (enableRegen && torqueDemand <= 0.0F && + MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { + // If regen is enabled and the torque demand is zero, we need to set + // the torque demand to 0 to prevent the motor from applying torque + // in the wrong direction + motorData.desiredTorque = MAX_REGEN_TORQUE * REGEN_BIAS; + } else { + motorData.desiredTorque = torqueDemand; } + + #else + // Speed control is enabled, we need to set the torque demand to 0 + vcu1.VCU_TorqueReq = 0; // 0 = No torque + #endif + + break; } -} + // Any fault error occurs + case MOTOR_STATE_FAULT: { -float Motor_GetTorqueDemand(){ - return motorData.desiredTorque; + if (enableStandby) { + motorData.state = MOTOR_STATE_STANDBY; + } else if (enableRun) { + Motor_ClearFaultState(); + } + // GOES BACK TO HV ON + // TODO Implement RTM Button + // if(RTMButton_GetState() == false){ + // motorData.state = MOTOR_STATE_IDLE; + // } + motorData.desiredTorque = 0.0F; + break; + } + default: { + break; + } + } } -void Motor_SetFaultState(){ - motorData.state = MOTOR_STATE_FAULT; -} +float Motor_GetTorqueDemand() { return motorData.desiredTorque; } -void Motor_ClearFaultState(){ - motorData.state = MOTOR_STATE_DRIVING; -} +void Motor_SetFaultState() { motorData.state = MOTOR_STATE_FAULT; } -MotorState Motor_GetState(){ - return motorData.state; -} +void Motor_ClearFaultState() { motorData.state = MOTOR_STATE_DRIVING; } +MotorState Motor_GetState() { return motorData.state; } From 5af7a4715f4103ac6dc7b21a7c93d3e7d4735dc2 Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 5 Nov 2025 11:54:44 -0800 Subject: [PATCH 13/30] MOTOR SPINNING v2 --- fsae-vehicle-fw/src/main.cpp | 28 +++++++------ fsae-vehicle-fw/src/vehicle/motor.cpp | 57 +++++++++++++-------------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 247ab7a..abe7c6d 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -136,18 +136,18 @@ void threadMain(void *pvParameters) { } case ' ': { // Stop all torque torqueDemand = 0; - enableRun = false; // Disable run state - enablePrecharge = false; // Disable precharging - enablePower = false; - enableRun = false; + // enableRun = false; // Disable run state + // enablePrecharge = false; // Disable precharging + // enablePower = false; + // enableRun = false; break; } case 'f': // Fault state case 'F': { - Serial.println("Entering fault state"); + //Serial.println("Entering fault state"); enableRun = false; // Disable run state enablePrecharge = false; // Disable precharging - enableStandby = false; + // enablePower = false; torqueDemand = 0; // Reset torque demand Motor_SetFaultState(); // Set motor to fault state break; @@ -184,10 +184,18 @@ void threadMain(void *pvParameters) { Serial.print("Torque: "); Serial.print(torqueDemand); + // Serial.print(" | "); + // Serial.print("M: "); + // Serial.print(MCU_GetMCU1Data()->motorTorque); Serial.print(" | "); Serial.print("RPM: "); Serial.print(MCU_GetMCU1Data()->motorSpeed); + + //Serial.print(" | "); + // Serial.print("maxtorq "); + // Serial.print(MCU_GetMCU1Data()->maxMotorTorque); + // Telemetry: Read battery current, phase current, motor speed, // temperature(s) Serial.print(" | "); @@ -209,12 +217,10 @@ void threadMain(void *pvParameters) { Serial.print("Mtr Temp: "); Serial.print(MCU_GetMCU2Data()->motorTemp); - Serial.print(" | "); - Serial.print(" "); - Serial.print(" | "); - Serial.print("Regen: "); - Serial.print(enableRegen); + // Serial.print(" | "); + // Serial.print("Regen: "); + // Serial.print(enableRegen); Serial.print("\r"); diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 5869b7f..4c9034c 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -71,17 +71,18 @@ void threadMotor(void *pvParameters) { // vcu1.KeyPosition = 0; break; } + case MOTOR_STATE_STANDBY: { // T1 // vcu1.KeyPosition = 2; // T3 vcu1.BMS_Main_Relay_Cmd = 0; - bms1.Pre_charge_Relay_FB = - 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 0; break; } + case MOTOR_STATE_PRECHARGING: { // vcu1.KeyPosition = 2; // T2 State transition: BMS_Main_Relay_Cmd == 1 && @@ -89,20 +90,19 @@ void threadMotor(void *pvParameters) { vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF vcu1.VCU_TorqueReq = 0; - break; } + case MOTOR_STATE_IDLE: { // T4 BMS_Main_Relay_Cmd == 1 && Pre_charge_Finish_Sts == 1 && // Ubat>=200V vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = - 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF // T6 - // vcu1.VCU_MotorMode = 0; - // vcu1.VCU_TorqueReq = 0; + vcu1.VCU_MotorMode = 0; + vcu1.VCU_TorqueReq = 0; // Convert to little-endian format // bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16(maxRegen); // @@ -110,24 +110,23 @@ void threadMotor(void *pvParameters) { break; } + case MOTOR_STATE_DRIVING: { - uint16_t maxDischarge = - (uint16_t)(BATTERY_MAX_CURRENT_A + 500) * 10; - uint16_t maxRegen = (uint16_t)(BATTERY_MAX_REGEN_A + 500) * 10; + + uint16_t maxDischarge = (uint16_t)(BATTERY_MAX_CURRENT_A + 500) * 10; + // uint16_t maxRegen = (uint16_t)(BATTERY_MAX_REGEN_A + 500) * 10; bms2.sAllowMaxDischarge = CHANGE_ENDIANESS_16(maxDischarge); - bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16( - maxRegen); // Convert to little-endian format + // bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16( + // maxRegen); // Convert to little-endian format // T5 BMS_Main_Relay_Cmd == 1 && VCU_MotorMode = 1/2 vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = - 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF vcu1.VehicleState = 1; // 0 = Not ready, 1 = Ready - vcu1.GearLeverPos_Sts = - 3; // 0 = Default, 1 = R, 2 = N, 3 = D, 4 = P + vcu1.GearLeverPos_Sts = 3; // 0 = Default, 1 = R, 2 = N, 3 = D, 4 = P vcu1.AC_Control_Cmd = 1; // 0 = Not active, 1 = Active vcu1.BMS_Aux_Relay_Cmd = 1; // 0 = not work, 1 = work vcu1.VCU_WorkMode = 0; @@ -141,24 +140,24 @@ void threadMotor(void *pvParameters) { ? 1 : 2; // 0 = Standby, 1 = Drive, 2 = // Generate Electricy, 3 = Reserved + break; } + case MOTOR_STATE_FAULT: { // T7 MCU_Warning_Level == 3 - vcu1.BMS_Main_Relay_Cmd = 0; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = - 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + vcu1.BMS_Main_Relay_Cmd = 0; // 1 = ON, 0 = OFF + bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 0; // 1 = ON, 0 = OFF - vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, - // 2 = Fault, 3 = Critical Fault - vcu1.VCU_MotorMode = - 0; // 0 = Standby, 1 = Drive, 2 = Generate - // Electricy, 3 = Reserved + // vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, 2 = Fault, 3 = Critical Fault + vcu1.VCU_MotorMode = 0; // 1 0 = Standby, 1 = Drive, 2 = Generate// Electricy, 3 = Reserved break; } + default: { break; } + } vcu1.CheckSum = ComputeChecksum((uint8_t *)&vcu1); @@ -233,7 +232,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, case MOTOR_STATE_IDLE: { if (enableRun) { #if HIMAC_FLAG - Serial.println("Ready to drive..."); + // Serial.println("Ready to drive..."); #endif motorData.state = MOTOR_STATE_DRIVING; } @@ -246,13 +245,13 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, // motorData.state = MOTOR_STATE_IDLE; // } - if (enablePower) { - motorData.state = MOTOR_STATE_IDLE; - } + // if (enablePower) { + // motorData.state = MOTOR_STATE_IDLE; + // } // torque is communicated as a percentage #if !SPEED_CONTROL_ENABLED - else if (enableRegen && torqueDemand <= 0.0F && + if (enableRegen && torqueDemand <= 0.0F && MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { // If regen is enabled and the torque demand is zero, we need to set // the torque demand to 0 to prevent the motor from applying torque From ce410ae9fc49031d29d815b993599c0a69f58153 Mon Sep 17 00:00:00 2001 From: Karan Date: Fri, 7 Nov 2025 11:27:48 -0800 Subject: [PATCH 14/30] post motor testing 11/5 --- fsae-vehicle-fw/src/main.cpp | 2 +- fsae-vehicle-fw/src/vehicle/motor.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index abe7c6d..6ea0e13 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -147,7 +147,7 @@ void threadMain(void *pvParameters) { //Serial.println("Entering fault state"); enableRun = false; // Disable run state enablePrecharge = false; // Disable precharging - // enablePower = false; + enablePower = false; torqueDemand = 0; // Reset torque demand Motor_SetFaultState(); // Set motor to fault state break; diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 4c9034c..516d50c 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -103,7 +103,6 @@ void threadMotor(void *pvParameters) { // T6 vcu1.VCU_MotorMode = 0; vcu1.VCU_TorqueReq = 0; - // Convert to little-endian format // bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16(maxRegen); // // Convert to little-endian format @@ -140,7 +139,6 @@ void threadMotor(void *pvParameters) { ? 1 : 2; // 0 = Standby, 1 = Drive, 2 = // Generate Electricy, 3 = Reserved - break; } From 6cc5aa595b3ab346bcd2acffd37dba96a02e4263 Mon Sep 17 00:00:00 2001 From: PranavKocharlakota Date: Fri, 7 Nov 2025 11:28:41 -0800 Subject: [PATCH 15/30] Add pcc_receive.cpp Receive can data from PCC on CCM --- fsae-pcc/src/can.cpp | 18 +++++++++--------- fsae-vehicle-fw/src/vehicle/ifl100-36.cpp | 6 ++++++ fsae-vehicle-fw/src/vehicle/ifl100-36.h | 1 + fsae-vehicle-fw/src/vehicle/pcc_receive.cpp | 19 +++++++++++++++++++ fsae-vehicle-fw/src/vehicle/pcc_receive.h | 16 ++++++++++++++++ 5 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 fsae-vehicle-fw/src/vehicle/pcc_receive.cpp create mode 100644 fsae-vehicle-fw/src/vehicle/pcc_receive.h diff --git a/fsae-pcc/src/can.cpp b/fsae-pcc/src/can.cpp index b2fc4d1..5943305 100644 --- a/fsae-pcc/src/can.cpp +++ b/fsae-pcc/src/can.cpp @@ -11,11 +11,11 @@ #define PCC_CAN_ID 0x123 typedef struct __attribute__((packed)) { - uint32_t timestamp; // Timestamp in milliseconds + //uint32_t timestamp; // Timestamp in milliseconds uint8_t state; // Precharge state uint8_t errorCode; // Error code - float accumulatorVoltage; // Accumulator voltage in volts - float tsVoltage; // Transmission side voltage in volts + //float accumulatorVoltage; // Accumulator voltage in volts + //float tsVoltage; // Transmission side voltage in volts float prechargeProgress; // Precharge progress in percent } PCC; @@ -36,12 +36,12 @@ void CAN_Init() { void CAN_SendPCCMessage(uint32_t timestamp, uint8_t state, uint8_t errorCode, float accumulatorVoltage, float tsVoltage, float prechargeProgress) { pccData = { - .timestamp = timestamp, - .state = state, - .errorCode = errorCode, - .accumulatorVoltage = accumulatorVoltage, - .tsVoltage = tsVoltage, - .prechargeProgress = prechargeProgress + //.timestamp = timestamp, 4 bytes + .state = state, // 1 bytes + .errorCode = errorCode, // 1 bytes + //.accumulatorVoltage = accumulatorVoltage, 4 bytes + //.tsVoltage = tsVoltage, 4 bytes + .prechargeProgress = prechargeProgress // 4 bytes }; // Serial.print("PCC Message: "); diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp index f6ff8f0..8f0f7a3 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp @@ -10,6 +10,8 @@ #include "utils/utils.h" +#include "pcc_receive.h" + #define THREAD_MCU_STACK_SIZE 128 #define THREAD_MCU_PRIORITY 1 @@ -138,6 +140,10 @@ static void threadMCU(void *pvParameters) { taskEXIT_CRITICAL(); // Exit critical section break; } + case pcc_ID: + { + processPCCMessage(rx_data); + } default: { break; diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.h b/fsae-vehicle-fw/src/vehicle/ifl100-36.h index b6fcc07..2f7a538 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.h +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.h @@ -10,6 +10,7 @@ #define mMCU1_ID 0x105 #define mMCU2_ID 0x106 #define mMCU3_ID 0x107 +#define pcc_ID 0x123 #define mBMS1_ID 0x1A0 #define mBMS2_ID 0x1A1 diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp new file mode 100644 index 0000000..1fcd1de --- /dev/null +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp @@ -0,0 +1,19 @@ +#define THREAD_CAN_STACK_SIZE 128 +#define THREAD_CAN_PRIORITY 1 + + + +#include "arduino_freertos.h" +#include "pcc_receive.h" + +void processPCCMessage(uint64_t rx_data){ + taskENTER_CRITICAL(); + memcpy(&pccData, &rx_data, sizeof(PCC)); + taskEXIT_CRITICAL(); + + Serial.print("Precharge Progress: "); + Serial.println(pccData.prechargeProgress); +} + + + diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.h b/fsae-vehicle-fw/src/vehicle/pcc_receive.h new file mode 100644 index 0000000..d96af08 --- /dev/null +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +typedef struct __attribute__((packed)) { + //uint32_t timestamp; + uint8_t state; + uint8_t errorCode; + //float accumulatorVoltage; + //float tsVoltage; + float prechargeProgress; +} PCC; + +static PCC pccData; + +void processPCCMessage(uint64_t); From 8da6d3360eedf5b0f066739231f0c5af0e64a64e Mon Sep 17 00:00:00 2001 From: Karan Date: Mon, 10 Nov 2025 12:26:29 -0800 Subject: [PATCH 16/30] pcc can recieve testing --- fsae-vehicle-fw/src/main.cpp | 6 ++++++ fsae-vehicle-fw/src/peripherals/can.cpp | 8 +++++--- fsae-vehicle-fw/src/utils/utils.h | 2 +- fsae-vehicle-fw/src/vehicle/ifl100-36.cpp | 2 ++ fsae-vehicle-fw/src/vehicle/pcc_receive.cpp | 2 ++ fsae-vehicle-fw/src/vehicle/pcc_receive.h | 8 ++++---- fsae-vehicle-fw/src/vehicle/telemetry.cpp | 3 --- 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 6ea0e13..b60d6ff 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -178,6 +178,11 @@ void threadMain(void *pvParameters) { Serial.print("C State: "); Serial.print(MCU_GetMCU1Data()->mcuMainState); Serial.print(" | "); + // Serial.print("APPS: "); + // Serial.print(APPS_GetAPPSReading1()); + // Serial.print(" | "); + // Serial.print(APPS_GetAPPSReading2()); + // Serial.print(" | "); Serial.print("T State: "); Serial.print(Motor_GetState()); Serial.print(" | "); @@ -244,6 +249,7 @@ void threadMain(void *pvParameters) { // print all errors if they are true in one line Serial.print(" | "); + if (MCU_GetMCU2Data()->dcMainWireOverVoltFault) Serial.println("DC Over Volt Fault, "); if (MCU_GetMCU2Data()->motorPhaseCurrFault) diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index 349a128..63464f5 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -32,14 +32,16 @@ static bool can3Healthy = false; #define CAN_TIMEOUT_MS 100 -//CAN SETUP +// /** + * CANBus Setup: KZ + * * CAN2 (CAN2 on diagram) --> ORION, CCM, RASPI, PCC * CAN3 (CAN1 on diagram) --> CCM, OMNI, RASPI * + * TODO: CAN recieve and send for each bus + * */ - - void CAN_Init() { // Initialize CAN bus can2.begin(); diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index 0331a93..dd5e9b5 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -2,7 +2,7 @@ #pragma once -#define DEBUG_FLAG 0 +#define DEBUG_FLAG 1 #define HIMAC_FLAG 1 #define THREAD_MAIN_STACK_SIZE 128 diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp index eb95832..7f642d0 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp @@ -144,7 +144,9 @@ static void threadMCU(void *pvParameters) { } case pcc_ID: { + Serial.print("PCC OK?"); processPCCMessage(rx_data); + break; } default: { diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp index 1fcd1de..6dd7f56 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp @@ -6,6 +6,8 @@ #include "arduino_freertos.h" #include "pcc_receive.h" +static PCC pccData; + void processPCCMessage(uint64_t rx_data){ taskENTER_CRITICAL(); memcpy(&pccData, &rx_data, sizeof(PCC)); diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.h b/fsae-vehicle-fw/src/vehicle/pcc_receive.h index d96af08..229b702 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.h +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.h @@ -6,11 +6,11 @@ typedef struct __attribute__((packed)) { //uint32_t timestamp; uint8_t state; uint8_t errorCode; - //float accumulatorVoltage; - //float tsVoltage; - float prechargeProgress; + uint16_t accumulatorVoltage; + uint16_t tsVoltage; + uint16_t prechargeProgress; } PCC; -static PCC pccData; +//static PCC pccData; void processPCCMessage(uint64_t); diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.cpp b/fsae-vehicle-fw/src/vehicle/telemetry.cpp index 1b78da8..900e613 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.cpp +++ b/fsae-vehicle-fw/src/vehicle/telemetry.cpp @@ -17,12 +17,9 @@ TelemetryData telemetryData; void Telemetry_Init() { telemetryData = { // Fill with reasonable dummy values .APPS_Travel = 0.0F, - - .motorSpeed = 0.0F, .motorTorque = 0.0F, .maxMotorTorque = 0.0F, - .motorDirection = DIRECTION_STANDBY, .motorState = MOTOR_STATE_OFF, From f5a593a83e153f94f5d6440fc70d86e76bd2f110 Mon Sep 17 00:00:00 2001 From: Karan Date: Mon, 10 Nov 2025 17:09:42 -0800 Subject: [PATCH 17/30] himac testing 10/11 --- fsae-vehicle-fw/src/main.cpp | 5 +++ fsae-vehicle-fw/src/peripherals/adc.cpp | 2 +- fsae-vehicle-fw/src/peripherals/gpio.cpp | 10 ++++++ fsae-vehicle-fw/src/peripherals/gpio.h | 6 ++++ fsae-vehicle-fw/src/utils/utils.h | 2 +- fsae-vehicle-fw/src/vehicle/motor.cpp | 2 ++ fsae-vehicle-fw/src/vehicle/rtm_button.cpp | 2 +- fsae-vehicle-fw/src/vehicle/telemetry.cpp | 4 +-- fsae-vehicle-fw/src/vehicle/telemetry.h | 36 +++++++++++----------- 9 files changed, 46 insertions(+), 23 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index b60d6ff..ef88b2d 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -12,6 +12,8 @@ #include "vehicle/ifl100-36.h" #include "vehicle/motor.h" #include "vehicle/telemetry.h" +#include "peripherals/gpio.h" +#include "vehicle/rtm_button.h" #include "utils/utils.h" #include @@ -33,6 +35,7 @@ void setup() { // runs once on bootup Telemetry_Init(); Motor_Init(); MCU_Init(); + GPIO_Init(); xTaskCreate(threadADC, "threadADC", THREAD_ADC_STACK_SIZE, NULL, THREAD_ADC_PRIORITY, NULL); @@ -61,6 +64,7 @@ void threadMain(void *pvParameters) { #endif while (true) { + digitalWrite(13, 1); /* * Read user input from Serial to control torque demand. * 'w' or 'W' to increase torque demand, @@ -286,6 +290,7 @@ void threadMain(void *pvParameters) { #endif + Serial.print(RTMButton_GetState()); vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10)); // Delay for 100ms } } diff --git a/fsae-vehicle-fw/src/peripherals/adc.cpp b/fsae-vehicle-fw/src/peripherals/adc.cpp index 158428f..9e8ed8a 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.cpp +++ b/fsae-vehicle-fw/src/peripherals/adc.cpp @@ -17,7 +17,7 @@ enum SensorIndexesADC0 { // TODO: Update with real values THERMISTOR_1_INDEX = 0, // A0 APPS_1_INDEX = 5, - APPS_2_INDEX = 4, + APPS_2_INDEX = 6, //A6 BSE_1_INDEX = 3, BSE_2_INDEX = 2, SUSP_TRAV_LINPOT1, diff --git a/fsae-vehicle-fw/src/peripherals/gpio.cpp b/fsae-vehicle-fw/src/peripherals/gpio.cpp index 8f12bf1..3279555 100644 --- a/fsae-vehicle-fw/src/peripherals/gpio.cpp +++ b/fsae-vehicle-fw/src/peripherals/gpio.cpp @@ -12,3 +12,13 @@ void GPIO_Init() { pinMode(3, INPUT_PULLUP); // wheel speed 2 pinMode(4, INPUT_PULLDOWN); // rtm button } + +// Read the current logical level of a GPIO pin. +// Uses digitalReadFast when available on the platform for better performance. +int GPIO_Read(int pin) { +#ifdef digitalReadFast + return digitalReadFast(pin); +#else + return digitalRead(pin); +#endif +} diff --git a/fsae-vehicle-fw/src/peripherals/gpio.h b/fsae-vehicle-fw/src/peripherals/gpio.h index d7b381a..75f0d63 100644 --- a/fsae-vehicle-fw/src/peripherals/gpio.h +++ b/fsae-vehicle-fw/src/peripherals/gpio.h @@ -2,4 +2,10 @@ #pragma once +#include + void GPIO_Init(); + +// Read the current logical level of a GPIO pin. +// Returns 0 for LOW, non-zero for HIGH. +int GPIO_Read(int pin); diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index dd5e9b5..0331a93 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -2,7 +2,7 @@ #pragma once -#define DEBUG_FLAG 1 +#define DEBUG_FLAG 0 #define HIMAC_FLAG 1 #define THREAD_MAIN_STACK_SIZE 128 diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 516d50c..b030cf2 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -9,6 +9,7 @@ #include "utils/utils.h" #include "peripherals/can.h" +#include "peripherals/gpio.h" #include "apps.h" #include "vehicle/ifl100-36.h" @@ -185,6 +186,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, // float throttleCommand = APPS_GetAPPSReading(); // 0; //TODO Get // APPS_travel + RTMButton_Update(GPIO_Read(RTM_BUTTON_PIN)); // off --> standby --> precharge --> run --> fault -->standy // no kl15 then off switch (motorData.state) { diff --git a/fsae-vehicle-fw/src/vehicle/rtm_button.cpp b/fsae-vehicle-fw/src/vehicle/rtm_button.cpp index be0a938..943f6ef 100644 --- a/fsae-vehicle-fw/src/vehicle/rtm_button.cpp +++ b/fsae-vehicle-fw/src/vehicle/rtm_button.cpp @@ -1,6 +1,6 @@ // Anteater Electric Racing, 2025 -#define BUTTON_DEBOUNCE_MS 100 +#define BUTTON_DEBOUNCE_MS 500 #include #include diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.cpp b/fsae-vehicle-fw/src/vehicle/telemetry.cpp index 900e613..e2ea558 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.cpp +++ b/fsae-vehicle-fw/src/vehicle/telemetry.cpp @@ -52,9 +52,9 @@ void threadTelemetry(void *pvParameters){ .motorSpeed = MCU_GetMCU1Data()->motorSpeed, .motorTorque = MCU_GetMCU1Data()->motorTorque, .maxMotorTorque = MCU_GetMCU1Data()->maxMotorTorque, - .maxMotorBrakeTorque = MCU_GetMCU1Data()->maxMotorBrakeTorque, + // .maxMotorBrakeTorque = MCU_GetMCU1Data()->maxMotorBrakeTorque, - .motorDirection = MCU_GetMCU1Data()->motorDirection, + // .motorDirection = MCU_GetMCU1Data()->motorDirection, .motorState = Motor_GetState(), .mcuMainState = MCU_GetMCU1Data()->mcuMainState, .mcuWorkMode = MCU_GetMCU1Data()->mcuWorkMode, diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.h b/fsae-vehicle-fw/src/vehicle/telemetry.h index 7e8c93f..1584c30 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.h +++ b/fsae-vehicle-fw/src/vehicle/telemetry.h @@ -10,11 +10,11 @@ typedef struct __attribute__((packed)){ float APPS_Travel; // APPS travel in % - float BSEFront_PSI; // front brake pressure in PSI - float BSERear_PSI; // rear brake pressure in PSI + // float BSEFront_PSI; // front brake pressure in PSI + // float BSERear_PSI; // rear brake pressure in PSI - float accumulatorVoltage; - float accumulatorTemp_F; + // float accumulatorVoltage; + // float accumulatorTemp_F; // Motor state @@ -22,7 +22,7 @@ typedef struct __attribute__((packed)){ float motorSpeed; // Motor speed in RPM float motorTorque; // Motor torque in Nm float maxMotorTorque; // Max motor torque in Nm - float maxMotorBrakeTorque; // Max motor brake torque in Nm + // float maxMotorBrakeTorque; // Max motor brake torque in Nm MotorRotateDirection motorDirection; // Motor direction MotorState motorState; @@ -43,27 +43,27 @@ typedef struct __attribute__((packed)){ bool motorPhaseCurrFault; // MCU motor phase current fault - bool mcuOverHotFault; // MCU overheat fault - bool resolverFault; // Resolver fault + // bool mcuOverHotFault; // MCU overheat fault + // bool resolverFault; // Resolver fault // bool phaseCurrSensorFault; // Phase current sensor fault // bool motorOverSpdFault; // MCU motor over speed fault - bool drvMotorOverHotFault; // Driver motor overheat fault - // bool dcMainWireOverCurrFault; // DC main wire over voltage fault - bool drvMotorOverCoolFault; // Driver motor overcool fault - bool mcuMotorSystemState; // MCU motor system state - bool mcuTempSensorState; // MCU temperature sensor state - bool motorTempSensorState; // MCU motor temperature sensor state - bool dcVoltSensorState; // MCU DC voltage sensor state - bool dcLowVoltWarning; // MCU DC low voltage warning - bool mcu12VLowVoltWarning; // MCU 12V low voltage warning +// bool drvMotorOverHotFault; // Driver motor overheat fault +// // bool dcMainWireOverCurrFault; // DC main wire over voltage fault +// bool drvMotorOverCoolFault; // Driver motor overcool fault +// bool mcuMotorSystemState; // MCU motor system state +// bool mcuTempSensorState; // MCU temperature sensor state +// bool motorTempSensorState; // MCU motor temperature sensor state +// bool dcVoltSensorState; // MCU DC voltage sensor state +// bool dcLowVoltWarning; // MCU DC low voltage warning +// bool mcu12VLowVoltWarning; // MCU 12V low voltage warning bool motorStallFault; // MCU motor stall fault - bool motorOpenPhaseFault; // MCU motor open phase fault +// bool motorOpenPhaseFault; // MCU motor open phase fault MCUWarningLevel mcuWarningLevel; // MCU warning level // MCU3 data //float mcuVoltage; // DC main wire voltage in V //float mcuCurrent; // DC main wire current in A - float motorPhaseCurr; // Motor phase current in A + // float motorPhaseCurr; // Motor phase current in A float debug[4]; // Debug data } TelemetryData; From c5b55f8d2ffc2373dccbce6ecc82c4f3502a2c32 Mon Sep 17 00:00:00 2001 From: Karan Date: Mon, 10 Nov 2025 20:46:21 -0800 Subject: [PATCH 18/30] working pcc recieve --- fsae-vehicle-fw/src/main.cpp | 6 +++++- fsae-vehicle-fw/src/vehicle/ifl100-36.cpp | 2 +- fsae-vehicle-fw/src/vehicle/ifl100-36.h | 2 +- fsae-vehicle-fw/src/vehicle/pcc_receive.cpp | 8 ++++++-- fsae-vehicle-fw/src/vehicle/pcc_receive.h | 2 ++ 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index ef88b2d..30e42c9 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -14,6 +14,7 @@ #include "vehicle/telemetry.h" #include "peripherals/gpio.h" #include "vehicle/rtm_button.h" +#include "vehicle/pcc_receive.h" #include "utils/utils.h" #include @@ -179,6 +180,9 @@ void threadMain(void *pvParameters) { // Telemetry: Read battery current, phase current, motor speed, // temperature(s) + Serial.print("PP:" ); + Serial.print(PCC_GetData()->accumulatorVoltage); + Serial.print(" | "); Serial.print("C State: "); Serial.print(MCU_GetMCU1Data()->mcuMainState); Serial.print(" | "); @@ -290,7 +294,7 @@ void threadMain(void *pvParameters) { #endif - Serial.print(RTMButton_GetState()); + //Serial.print(RTMButton_GetState()); vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10)); // Delay for 100ms } } diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp index 7f642d0..8f11500 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp @@ -144,7 +144,7 @@ static void threadMCU(void *pvParameters) { } case pcc_ID: { - Serial.print("PCC OK?"); + //Serial.print("PCC OK?"); processPCCMessage(rx_data); break; } diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.h b/fsae-vehicle-fw/src/vehicle/ifl100-36.h index 1b7cd86..1546fe3 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.h +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.h @@ -10,7 +10,7 @@ #define mMCU1_ID 0x105 #define mMCU2_ID 0x106 #define mMCU3_ID 0x107 -#define pcc_ID 0x123 +#define pcc_ID 0x222 #define mBMS1_ID 0x1A0 #define mBMS2_ID 0x1A1 diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp index 6dd7f56..af1ec38 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp @@ -13,8 +13,12 @@ void processPCCMessage(uint64_t rx_data){ memcpy(&pccData, &rx_data, sizeof(PCC)); taskEXIT_CRITICAL(); - Serial.print("Precharge Progress: "); - Serial.println(pccData.prechargeProgress); + // Serial.print("Precharge Progress: "); + // Serial.println(pccData.prechargeProgress); +} + +PCC* PCC_GetData(){ + return &pccData; } diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.h b/fsae-vehicle-fw/src/vehicle/pcc_receive.h index 229b702..dce9ea4 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.h +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.h @@ -14,3 +14,5 @@ typedef struct __attribute__((packed)) { //static PCC pccData; void processPCCMessage(uint64_t); + +PCC* PCC_GetData(); From 25ac7cbe52dc242d443c9f0a6dce95ff4da67bf3 Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 12 Nov 2025 11:36:08 -0800 Subject: [PATCH 19/30] pcc init added --- fsae-vehicle-fw/src/main.cpp | 3 +-- fsae-vehicle-fw/src/vehicle/pcc_receive.cpp | 10 ++++++++++ fsae-vehicle-fw/src/vehicle/pcc_receive.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 30e42c9..bc60f0c 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -37,6 +37,7 @@ void setup() { // runs once on bootup Motor_Init(); MCU_Init(); GPIO_Init(); + PCC_Init(); xTaskCreate(threadADC, "threadADC", THREAD_ADC_STACK_SIZE, NULL, THREAD_ADC_PRIORITY, NULL); @@ -204,11 +205,9 @@ void threadMain(void *pvParameters) { Serial.print("RPM: "); Serial.print(MCU_GetMCU1Data()->motorSpeed); - //Serial.print(" | "); // Serial.print("maxtorq "); // Serial.print(MCU_GetMCU1Data()->maxMotorTorque); - // Telemetry: Read battery current, phase current, motor speed, // temperature(s) Serial.print(" | "); diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp index af1ec38..60b600e 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp @@ -8,6 +8,16 @@ static PCC pccData; +void PCC_Init(){ + pccData = { + .state = 0, + .errorCode = 0, + .accumulatorVoltage = 0, + .tsVoltage = 0, + .prechargeProgress = 404 + }; +} + void processPCCMessage(uint64_t rx_data){ taskENTER_CRITICAL(); memcpy(&pccData, &rx_data, sizeof(PCC)); diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.h b/fsae-vehicle-fw/src/vehicle/pcc_receive.h index dce9ea4..abedfb5 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.h +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.h @@ -13,6 +13,7 @@ typedef struct __attribute__((packed)) { //static PCC pccData; +void PCC_Init(); void processPCCMessage(uint64_t); PCC* PCC_GetData(); From c09357bfbeb69cf60175e0cc8867f498443c8afd Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 12 Nov 2025 14:09:18 -0800 Subject: [PATCH 20/30] working integratoin test HIMAC, inverter faults tested and verified --- fsae-vehicle-fw/src/main.cpp | 4 ++-- fsae-vehicle-fw/src/vehicle/motor.cpp | 29 ++++++++++++++++++--------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index bc60f0c..0cb7f62 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -58,7 +58,7 @@ void threadMain(void *pvParameters) { #if HIMAC_FLAG float torqueDemand = 0; bool enableStandby = false; - bool enablePrecharge = false; + bool enablePrecharge = true; bool enablePower = false; bool enableRun = false; @@ -182,7 +182,7 @@ void threadMain(void *pvParameters) { // Telemetry: Read battery current, phase current, motor speed, // temperature(s) Serial.print("PP:" ); - Serial.print(PCC_GetData()->accumulatorVoltage); + Serial.print(PCC_GetData()->prechargeProgress); Serial.print(" | "); Serial.print("C State: "); Serial.print(MCU_GetMCU1Data()->mcuMainState); diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index b030cf2..b0b8496 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -16,6 +16,7 @@ #include "vehicle/motor.h" #include "vehicle/rtm_button.h" #include "vehicle/telemetry.h" +#include "vehicle/pcc_receive.h" typedef struct { MotorState state; @@ -39,7 +40,7 @@ static BMS2 bms2 = {0}; */ void Motor_Init() { - motorData.state = MOTOR_STATE_OFF; // TODO Check if we want this + motorData.state = MOTOR_STATE_PRECHARGING; // TODO Check if we want this motorData.desiredTorque = 0.0F; // No torque demand at start } @@ -187,6 +188,9 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, // APPS_travel RTMButton_Update(GPIO_Read(RTM_BUTTON_PIN)); + + uint8_t prechargeState = PCC_GetData()->state; + uint16_t prechargeProg = PCC_GetData()->prechargeProgress; // off --> standby --> precharge --> run --> fault -->standy // no kl15 then off switch (motorData.state) { @@ -216,7 +220,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, } // HV switch on (PCC CAN message) case MOTOR_STATE_PRECHARGING: { - if (enablePower) { + if (prechargeProg >= 94 && prechargeState == 3) { // # if HIMAC_FLAG // Serial.println("Precharge finished"); // # endif @@ -230,7 +234,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, } // PCC CAN message finished case MOTOR_STATE_IDLE: { - if (enableRun) { + if (RTMButton_GetState()) { #if HIMAC_FLAG // Serial.println("Ready to drive..."); #endif @@ -250,15 +254,20 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, // } // torque is communicated as a percentage #if !SPEED_CONTROL_ENABLED + if (RTMButton_GetState()){ + + if (enableRegen && torqueDemand <= 0.0F && + MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { + // If regen is enabled and the torque demand is zero, we need to set + // the torque demand to 0 to prevent the motor from applying torque + // in the wrong direction + motorData.desiredTorque = MAX_REGEN_TORQUE * REGEN_BIAS; + } else { + motorData.desiredTorque = torqueDemand; + } - if (enableRegen && torqueDemand <= 0.0F && - MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { - // If regen is enabled and the torque demand is zero, we need to set - // the torque demand to 0 to prevent the motor from applying torque - // in the wrong direction - motorData.desiredTorque = MAX_REGEN_TORQUE * REGEN_BIAS; } else { - motorData.desiredTorque = torqueDemand; + motorData.state = MOTOR_STATE_IDLE; } #else From 0b657ca65cf84175b1fa8dad52991b2126f8f250 Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 12 Nov 2025 14:13:32 -0800 Subject: [PATCH 21/30] reset torque to 0 when RTM is pressed. --- fsae-vehicle-fw/src/vehicle/motor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index b0b8496..1bcd725 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -268,6 +268,8 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, } else { motorData.state = MOTOR_STATE_IDLE; + torqueDemand = 0; + } #else From 5b376727f9be771c0b6a11bce6227c8295ee710e Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 12 Nov 2025 17:12:13 -0800 Subject: [PATCH 22/30] try to format on save --- fsae-vehicle-fw/src/vehicle/motor.cpp | 78 ++++++++++++++------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 1bcd725..9ffb0c4 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -14,9 +14,9 @@ #include "apps.h" #include "vehicle/ifl100-36.h" #include "vehicle/motor.h" +#include "vehicle/pcc_receive.h" #include "vehicle/rtm_button.h" #include "vehicle/telemetry.h" -#include "vehicle/pcc_receive.h" typedef struct { MotorState state; @@ -41,7 +41,7 @@ static BMS2 bms2 = {0}; void Motor_Init() { motorData.state = MOTOR_STATE_PRECHARGING; // TODO Check if we want this - motorData.desiredTorque = 0.0F; // No torque demand at start + motorData.desiredTorque = 0.0F; // No torque demand at start } void threadMotor(void *pvParameters) { @@ -80,7 +80,8 @@ void threadMotor(void *pvParameters) { // T3 vcu1.BMS_Main_Relay_Cmd = 0; - bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Relay_FB = + 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 0; break; } @@ -99,7 +100,8 @@ void threadMotor(void *pvParameters) { // T4 BMS_Main_Relay_Cmd == 1 && Pre_charge_Finish_Sts == 1 && // Ubat>=200V vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Relay_FB = + 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF // T6 @@ -114,8 +116,8 @@ void threadMotor(void *pvParameters) { case MOTOR_STATE_DRIVING: { - - uint16_t maxDischarge = (uint16_t)(BATTERY_MAX_CURRENT_A + 500) * 10; + uint16_t maxDischarge = + (uint16_t)(BATTERY_MAX_CURRENT_A + 500) * 10; // uint16_t maxRegen = (uint16_t)(BATTERY_MAX_REGEN_A + 500) * 10; bms2.sAllowMaxDischarge = CHANGE_ENDIANESS_16(maxDischarge); // bms2.sAllowMaxRegenCharge = CHANGE_ENDIANESS_16( @@ -123,11 +125,13 @@ void threadMotor(void *pvParameters) { // T5 BMS_Main_Relay_Cmd == 1 && VCU_MotorMode = 1/2 vcu1.BMS_Main_Relay_Cmd = 1; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Relay_FB = + 1; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 1; // 1 = ON, 0 = OFF vcu1.VehicleState = 1; // 0 = Not ready, 1 = Ready - vcu1.GearLeverPos_Sts = 3; // 0 = Default, 1 = R, 2 = N, 3 = D, 4 = P + vcu1.GearLeverPos_Sts = + 3; // 0 = Default, 1 = R, 2 = N, 3 = D, 4 = P vcu1.AC_Control_Cmd = 1; // 0 = Not active, 1 = Active vcu1.BMS_Aux_Relay_Cmd = 1; // 0 = not work, 1 = work vcu1.VCU_WorkMode = 0; @@ -147,17 +151,20 @@ void threadMotor(void *pvParameters) { case MOTOR_STATE_FAULT: { // T7 MCU_Warning_Level == 3 vcu1.BMS_Main_Relay_Cmd = 0; // 1 = ON, 0 = OFF - bms1.Pre_charge_Relay_FB = 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit + bms1.Pre_charge_Relay_FB = + 0; // 1 = ON, 0 = OFF NOTE: see if we can omit this bit bms1.Pre_charge_Finish_Sts = 0; // 1 = ON, 0 = OFF - // vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, 2 = Fault, 3 = Critical Fault - vcu1.VCU_MotorMode = 0; // 1 0 = Standby, 1 = Drive, 2 = Generate// Electricy, 3 = Reserved + // vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, + // 2 = Fault, 3 = Critical Fault + vcu1.VCU_MotorMode = + 0; // 1 0 = Standby, 1 = Drive, 2 = Generate// Electricy, + // 3 = Reserved break; } default: { break; } - } vcu1.CheckSum = ComputeChecksum((uint8_t *)&vcu1); @@ -210,9 +217,7 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, // kl15 on and ready to go into precharge case MOTOR_STATE_STANDBY: { if (enablePrecharge) { - // # if HIMAC_FLAG - // Serial.println("Precharging..."); - // #endif + motorData.state = MOTOR_STATE_PRECHARGING; } motorData.desiredTorque = 0.0F; @@ -235,9 +240,9 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, // PCC CAN message finished case MOTOR_STATE_IDLE: { if (RTMButton_GetState()) { - #if HIMAC_FLAG - // Serial.println("Ready to drive..."); - #endif +#if HIMAC_FLAG + // Serial.println("Ready to drive..."); +#endif motorData.state = MOTOR_STATE_DRIVING; } motorData.desiredTorque = 0.0F; @@ -245,22 +250,22 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, } // Ready to drive button pressed case MOTOR_STATE_DRIVING: { - // if(!enableRun){ - // motorData.state = MOTOR_STATE_IDLE; - // } - - // if (enablePower) { - // motorData.state = MOTOR_STATE_IDLE; - // } - // torque is communicated as a percentage - #if !SPEED_CONTROL_ENABLED - if (RTMButton_GetState()){ +// if(!enableRun){ +// motorData.state = MOTOR_STATE_IDLE; +// } + +// if (enablePower) { +// motorData.state = MOTOR_STATE_IDLE; +// } +// torque is communicated as a percentage +#if !SPEED_CONTROL_ENABLED + if (RTMButton_GetState()) { if (enableRegen && torqueDemand <= 0.0F && - MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { - // If regen is enabled and the torque demand is zero, we need to set - // the torque demand to 0 to prevent the motor from applying torque - // in the wrong direction + MCU_GetMCU1Data()->motorDirection == MOTOR_DIRECTION_FORWARD) { + // If regen is enabled and the torque demand is zero, we need to + // set the torque demand to 0 to prevent the motor from applying + // torque in the wrong direction motorData.desiredTorque = MAX_REGEN_TORQUE * REGEN_BIAS; } else { motorData.desiredTorque = torqueDemand; @@ -269,13 +274,12 @@ void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, } else { motorData.state = MOTOR_STATE_IDLE; torqueDemand = 0; - } - #else - // Speed control is enabled, we need to set the torque demand to 0 - vcu1.VCU_TorqueReq = 0; // 0 = No torque - #endif +#else + // Speed control is enabled, we need to set the torque demand to 0 + vcu1.VCU_TorqueReq = 0; // 0 = No torque +#endif break; } From fe43d3958dc6d44c1b8a7e7ad364d37b29528975 Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 12 Nov 2025 17:14:34 -0800 Subject: [PATCH 23/30] autosave clang --- fsae-vehicle-fw/src/main.cpp | 38 +-- fsae-vehicle-fw/src/peripherals/adc.cpp | 74 ++--- fsae-vehicle-fw/src/peripherals/adc.h | 2 +- fsae-vehicle-fw/src/peripherals/can.cpp | 31 +-- fsae-vehicle-fw/src/peripherals/can.h | 4 +- fsae-vehicle-fw/src/peripherals/gpio.cpp | 6 +- .../src/peripherals/peripherals.cpp | 2 +- fsae-vehicle-fw/src/utils/utils.h | 22 +- fsae-vehicle-fw/src/vehicle/apps.cpp | 101 +++---- fsae-vehicle-fw/src/vehicle/bse.cpp | 39 ++- fsae-vehicle-fw/src/vehicle/bse.h | 5 +- fsae-vehicle-fw/src/vehicle/faults.cpp | 124 +++++---- fsae-vehicle-fw/src/vehicle/faults.h | 1 - fsae-vehicle-fw/src/vehicle/ifl100-36.cpp | 258 +++++++++--------- fsae-vehicle-fw/src/vehicle/ifl100-36.h | 125 ++++----- fsae-vehicle-fw/src/vehicle/motor.cpp | 5 +- fsae-vehicle-fw/src/vehicle/motor.h | 4 +- fsae-vehicle-fw/src/vehicle/pcc_receive.cpp | 27 +- fsae-vehicle-fw/src/vehicle/pcc_receive.h | 6 +- fsae-vehicle-fw/src/vehicle/rtm_button.cpp | 9 +- fsae-vehicle-fw/src/vehicle/telemetry.cpp | 27 +- fsae-vehicle-fw/src/vehicle/telemetry.h | 53 ++-- fsae-vehicle-fw/src/vehicle/thermal.cpp | 43 +-- fsae-vehicle-fw/src/vehicle/thermal.h | 3 +- 24 files changed, 511 insertions(+), 498 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 0cb7f62..128a533 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -6,15 +6,15 @@ #include "peripherals/adc.h" #include "peripherals/can.h" +#include "peripherals/gpio.h" #include "vehicle/apps.h" #include "vehicle/bse.h" #include "vehicle/faults.h" #include "vehicle/ifl100-36.h" #include "vehicle/motor.h" -#include "vehicle/telemetry.h" -#include "peripherals/gpio.h" -#include "vehicle/rtm_button.h" #include "vehicle/pcc_receive.h" +#include "vehicle/rtm_button.h" +#include "vehicle/telemetry.h" #include "utils/utils.h" #include @@ -150,12 +150,12 @@ void threadMain(void *pvParameters) { } case 'f': // Fault state case 'F': { - //Serial.println("Entering fault state"); + // Serial.println("Entering fault state"); enableRun = false; // Disable run state enablePrecharge = false; // Disable precharging enablePower = false; - torqueDemand = 0; // Reset torque demand - Motor_SetFaultState(); // Set motor to fault state + torqueDemand = 0; // Reset torque demand + Motor_SetFaultState(); // Set motor to fault state break; } case 'r': @@ -181,7 +181,7 @@ void threadMain(void *pvParameters) { // Telemetry: Read battery current, phase current, motor speed, // temperature(s) - Serial.print("PP:" ); + Serial.print("PP:"); Serial.print(PCC_GetData()->prechargeProgress); Serial.print(" | "); Serial.print("C State: "); @@ -205,11 +205,11 @@ void threadMain(void *pvParameters) { Serial.print("RPM: "); Serial.print(MCU_GetMCU1Data()->motorSpeed); - //Serial.print(" | "); - // Serial.print("maxtorq "); - // Serial.print(MCU_GetMCU1Data()->maxMotorTorque); - // Telemetry: Read battery current, phase current, motor speed, - // temperature(s) + // Serial.print(" | "); + // Serial.print("maxtorq "); + // Serial.print(MCU_GetMCU1Data()->maxMotorTorque); + // Telemetry: Read battery current, phase current, motor speed, + // temperature(s) Serial.print(" | "); Serial.print("B Volt: "); Serial.print(MCU_GetMCU3Data()->mcuVoltage); @@ -229,15 +229,11 @@ void threadMain(void *pvParameters) { Serial.print("Mtr Temp: "); Serial.print(MCU_GetMCU2Data()->motorTemp); - // Serial.print(" | "); // Serial.print("Regen: "); // Serial.print(enableRegen); Serial.print("\r"); - - - // Serial.print("Battery Current: "); // Serial.print(MCU_GetMCU3Data().mcuCurrent); // Serial.print(" \n"); @@ -284,16 +280,12 @@ void threadMain(void *pvParameters) { if (MCU_GetMCU2Data()->motorOpenPhaseFault) Serial.println("Motor Open Phase Fault, "); - - - Motor_UpdateMotor( - torqueDemand, enablePrecharge, enablePower, enableRun, - enableRegen, enableStandby); // Update motor with the current torque demand - + torqueDemand, enablePrecharge, enablePower, enableRun, enableRegen, + enableStandby); // Update motor with the current torque demand #endif - //Serial.print(RTMButton_GetState()); + // Serial.print(RTMButton_GetState()); vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10)); // Delay for 100ms } } diff --git a/fsae-vehicle-fw/src/peripherals/adc.cpp b/fsae-vehicle-fw/src/peripherals/adc.cpp index 9e8ed8a..5148208 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.cpp +++ b/fsae-vehicle-fw/src/peripherals/adc.cpp @@ -1,23 +1,23 @@ // Anteater Electric Racing, 2025 -#include -#include #include "adc.h" #include "./vehicle/telemetry.h" -#include -#include #include "utils/utils.h" -#include "vehicle/bse.h" #include "vehicle/apps.h" +#include "vehicle/bse.h" #include "vehicle/faults.h" -#include "vehicle/telemetry.h" #include "vehicle/motor.h" +#include "vehicle/telemetry.h" #include "vehicle/thermal.h" +#include +#include +#include +#include -enum SensorIndexesADC0 { // TODO: Update with real values +enum SensorIndexesADC0 { // TODO: Update with real values THERMISTOR_1_INDEX = 0, // A0 APPS_1_INDEX = 5, - APPS_2_INDEX = 6, //A6 + APPS_2_INDEX = 6, // A6 BSE_1_INDEX = 3, BSE_2_INDEX = 2, SUSP_TRAV_LINPOT1, @@ -25,8 +25,8 @@ enum SensorIndexesADC0 { // TODO: Update with real values SUSP_TRAV_LINPOT3, SUSP_TRAV_LINPOT4, THERMISTOR_2_INDEX = 10, // A1 - THERMISTOR_3_INDEX = 9, // A2 - THERMISTOR_4_INDEX = 8// A3 + THERMISTOR_3_INDEX = 9, // A2 + THERMISTOR_4_INDEX = 8 // A3 }; enum SensorIndexesADC1 { // TODO: Update with real values @@ -40,11 +40,16 @@ enum SensorIndexesADC1 { // TODO: Update with real values SUSP_TRAV_LINPOT42 }; -uint16_t adc0Pins[SENSOR_PIN_AMT_ADC0] = {A0, A1, A2, A3, A4, A5, A6, A7, A15, A16, A17}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, 24, 25, 19, 18, 14, 15, 17}; +uint16_t adc0Pins[SENSOR_PIN_AMT_ADC0] = { + A0, A1, A2, A3, A4, A5, + A6, A7, A15, A16, A17}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, + // 24, 25, 19, 18, 14, 15, 17}; uint16_t adc0Reads[SENSOR_PIN_AMT_ADC0]; - -uint16_t adc1Pins[SENSOR_PIN_AMT_ADC1] = {A17, A16, A15, A7, A6, A5, A4, A3, A2, A1, A0}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, 24, 25, 19, 18, 14, 15, 17}; +uint16_t adc1Pins[SENSOR_PIN_AMT_ADC1] = { + A17, A16, A15, A7, A6, A5, + A4, A3, A2, A1, A0}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, + // 24, 25, 19, 18, 14, 15, 17}; uint16_t adc1Reads[SENSOR_PIN_AMT_ADC1]; static TickType_t lastWakeTime; @@ -53,37 +58,43 @@ ADC *adc = new ADC(); void ADC_Init() { // ADC 0 - adc->adc0->setAveraging(ADC_AVERAGING); // set number of averages + adc->adc0->setAveraging(ADC_AVERAGING); // set number of averages adc->adc0->setResolution(ADC_RESOLUTION); // set bits of resolution - adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::LOW_SPEED); // change the conversion speed - adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED); // change the sampling speed + adc->adc0->setConversionSpeed( + ADC_CONVERSION_SPEED::LOW_SPEED); // change the conversion speed + adc->adc0->setSamplingSpeed( + ADC_SAMPLING_SPEED::LOW_SPEED); // change the sampling speed // ADC 1 - adc->adc1->setAveraging(ADC_AVERAGING); // set number of averages + adc->adc1->setAveraging(ADC_AVERAGING); // set number of averages adc->adc1->setResolution(ADC_RESOLUTION); // set bits of resolution - adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::LOW_SPEED); // change the conversion speed - adc->adc1->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED); // change the sampling speed - - # if DEBUG_FLAG - Serial.println("Done initializing ADCs"); - # endif + adc->adc1->setConversionSpeed( + ADC_CONVERSION_SPEED::LOW_SPEED); // change the conversion speed + adc->adc1->setSamplingSpeed( + ADC_SAMPLING_SPEED::LOW_SPEED); // change the sampling speed + +#if DEBUG_FLAG + Serial.println("Done initializing ADCs"); +#endif } -void threadADC( void *pvParameters ){ - # if DEBUG_FLAG - Serial.print("Beginning adc thread"); - # endif +void threadADC(void *pvParameters) { +#if DEBUG_FLAG + Serial.print("Beginning adc thread"); +#endif lastWakeTime = xTaskGetTickCount(); - while(true){ + while (true) { vTaskDelayUntil(&lastWakeTime, TICKTYPE_FREQUENCY); - for(uint16_t currentIndexADC0 = 0; currentIndexADC0 < SENSOR_PIN_AMT_ADC0; ++currentIndexADC0){ + for (uint16_t currentIndexADC0 = 0; + currentIndexADC0 < SENSOR_PIN_AMT_ADC0; ++currentIndexADC0) { uint16_t currentPinADC0 = adc0Pins[currentIndexADC0]; uint16_t adcRead = adc->adc1->analogRead(currentPinADC0); adc0Reads[currentIndexADC0] = adcRead; } - for(uint16_t currentIndexADC1 = 0; currentIndexADC1 < SENSOR_PIN_AMT_ADC1; ++currentIndexADC1){ + for (uint16_t currentIndexADC1 = 0; + currentIndexADC1 < SENSOR_PIN_AMT_ADC1; ++currentIndexADC1) { uint16_t currentPinADC1 = adc1Pins[currentIndexADC1]; uint16_t adcRead = adc->adc1->analogRead(currentPinADC1); adc1Reads[currentIndexADC1] = adcRead; @@ -93,7 +104,8 @@ void threadADC( void *pvParameters ){ APPS_UpdateData(adc0Reads[APPS_1_INDEX], adc0Reads[APPS_2_INDEX]); BSE_UpdateData(adc0Reads[BSE_1_INDEX], adc0Reads[BSE_2_INDEX]); - thermal_Update(adc0Reads[THERMISTOR_1_INDEX], adc0Reads[THERMISTOR_2_INDEX], + thermal_Update( + adc0Reads[THERMISTOR_1_INDEX], adc0Reads[THERMISTOR_2_INDEX], adc0Reads[THERMISTOR_3_INDEX], adc0Reads[THERMISTOR_4_INDEX]); // Handle any faults that were raised diff --git a/fsae-vehicle-fw/src/peripherals/adc.h b/fsae-vehicle-fw/src/peripherals/adc.h index 2494ed7..9a2f8f6 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.h +++ b/fsae-vehicle-fw/src/peripherals/adc.h @@ -16,4 +16,4 @@ extern uint16_t adc1Reads[SENSOR_PIN_AMT_ADC1]; extern ADC *adc; void ADC_Init(); -void threadADC( void *pvParameters ); +void threadADC(void *pvParameters); diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index 63464f5..6e6f79b 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -3,15 +3,15 @@ #define THREAD_CAN_STACK_SIZE 128 #define THREAD_CAN_PRIORITY 1 -#include -#include #include #include +#include +#include #include "peripherals/can.h" #include "utils/utils.h" -#include "vehicle/motor.h" #include "vehicle/ifl100-36.h" +#include "vehicle/motor.h" #define CAN_INSTANCE CAN1 #define CAN_BAUD_RATE 500000 @@ -31,7 +31,6 @@ static bool can3Healthy = false; #define CAN_TIMEOUT_MS 100 - // /** * CANBus Setup: KZ @@ -62,12 +61,11 @@ void CAN_Init() { tp.setWriteBus(&can3); // Set the bus to write to can3 } -//TODO @ksthakkar: make can_send general function to select both CANbuses or make seperate CAN_send functions -//can2 -void CAN_Send(uint32_t id, uint64_t msg) -{ +// TODO @ksthakkar: make can_send general function to select both CANbuses or +// make seperate CAN_send functions can2 +void CAN_Send(uint32_t id, uint64_t msg) { motorMsg.id = id; - // msg.id = 0x100; + // msg.id = 0x100; memcpy(motorMsg.buf, &msg, sizeof(msg)); can3.write(motorMsg); @@ -76,7 +74,7 @@ void CAN_Send(uint32_t id, uint64_t msg) // Serial.print(""); } -void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data) { +void CAN_Receive(uint32_t *rx_id, uint64_t *rx_data) { if (can3.read(rx_msg)) { *rx_id = rx_msg.id; memcpy(rx_data, rx_msg.buf, sizeof(*rx_data)); @@ -101,18 +99,19 @@ void CAN_CheckHealth() { // } } - -void CAN_ISOTP_Send(uint32_t id, uint8_t* msg, uint16_t size) { +void CAN_ISOTP_Send(uint32_t id, uint8_t *msg, uint16_t size) { ISOTP_data config; config.id = id; config.flags.extended = 0; // Standard frame - config.separation_time = 1; // Time between back-to-back frames in milliseconds + config.separation_time = + 1; // Time between back-to-back frames in milliseconds tp.write(config, msg, size); } - bool CAN_IsBusHealthy(uint8_t bus) { - if (bus == 2) return can2Healthy; - if (bus == 3) return can3Healthy; + if (bus == 2) + return can2Healthy; + if (bus == 3) + return can3Healthy; return false; } diff --git a/fsae-vehicle-fw/src/peripherals/can.h b/fsae-vehicle-fw/src/peripherals/can.h index 34e7297..203a94e 100644 --- a/fsae-vehicle-fw/src/peripherals/can.h +++ b/fsae-vehicle-fw/src/peripherals/can.h @@ -4,9 +4,9 @@ void CAN_Init(); void CAN_Send(uint32_t id, uint64_t msg); -void CAN_Receive(uint32_t* rx_id, uint64_t* rx_data); +void CAN_Receive(uint32_t *rx_id, uint64_t *rx_data); -void CAN_ISOTP_Send(uint32_t id, uint8_t* msg, uint16_t size); +void CAN_ISOTP_Send(uint32_t id, uint8_t *msg, uint16_t size); bool CAN_IsBusHealthy(uint8_t bus); void CAN_CheckHealth(); diff --git a/fsae-vehicle-fw/src/peripherals/gpio.cpp b/fsae-vehicle-fw/src/peripherals/gpio.cpp index 3279555..275e125 100644 --- a/fsae-vehicle-fw/src/peripherals/gpio.cpp +++ b/fsae-vehicle-fw/src/peripherals/gpio.cpp @@ -1,15 +1,15 @@ // Anteater Electric Racing, 2025 -#include #include "peripherals/gpio.h" +#include // rtm button: 4 // wheel speed 1: 2, wheel speed 2: 3 // using can1 and can2 void GPIO_Init() { - pinMode(2, INPUT_PULLUP); // wheel speed 1 - pinMode(3, INPUT_PULLUP); // wheel speed 2 + pinMode(2, INPUT_PULLUP); // wheel speed 1 + pinMode(3, INPUT_PULLUP); // wheel speed 2 pinMode(4, INPUT_PULLDOWN); // rtm button } diff --git a/fsae-vehicle-fw/src/peripherals/peripherals.cpp b/fsae-vehicle-fw/src/peripherals/peripherals.cpp index 83e168b..bd9bfeb 100644 --- a/fsae-vehicle-fw/src/peripherals/peripherals.cpp +++ b/fsae-vehicle-fw/src/peripherals/peripherals.cpp @@ -1,8 +1,8 @@ // Anteater Electric Racing, 2025 +#include "peripherals/peripherals.h" #include "peripherals/adc.h" #include "peripherals/can.h" #include "peripherals/gpio.h" -#include "peripherals/peripherals.h" void Peripherals_Init() { ADC_Init(); diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index 0331a93..b648f7d 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -27,7 +27,8 @@ #define TICKTYPE_FREQUENCY 1 #define ADC_VOLTAGE_DIVIDER 2.0F -#define ADC_VALUE_TO_VOLTAGE(x) ((x) * (LOGIC_LEVEL_V / ADC_MAX_VALUE)) * ADC_VOLTAGE_DIVIDER +#define ADC_VALUE_TO_VOLTAGE(x) \ + ((x) * (LOGIC_LEVEL_V / ADC_MAX_VALUE)) * ADC_VOLTAGE_DIVIDER #define APPS_FAULT_PERCENT_MIN .1 #define APPS_FAULT_PERCENT_MAX .9 @@ -54,11 +55,14 @@ #define APPS_IMPLAUSABILITY_THRESHOLD 0.1 // 10% #define APPS_BSE_PLAUSABILITY_TROTTLE_THRESHOLD 0.25 // 25% -#define APPS_BSE_PLAUSABILITY_BRAKE_THRESHOLD 1.5 // TODO: change back to PSI200 // PSI +#define APPS_BSE_PLAUSABILITY_BRAKE_THRESHOLD \ + 1.5 // TODO: change back to PSI200 // PSI #define APPS_BSE_PLAUSIBILITY_RESET_THRESHOLD 0.05 // 5% #define BSE_VOLTAGE_DIVIDER 2.0F // TODO: Update with real value -#define BSE_ADC_VALUE_TO_VOLTAGE(x) (x * (LOGIC_LEVEL_V / ADC_MAX_VALUE)) * BSE_VOLTAGE_DIVIDER // ADC value to voltage conversion +#define BSE_ADC_VALUE_TO_VOLTAGE(x) \ + (x * (LOGIC_LEVEL_V / ADC_MAX_VALUE)) * \ + BSE_VOLTAGE_DIVIDER // ADC value to voltage conversion #define BSE_VOLTAGE_TO_PSI(x) x // Voltage to PSI conversion @@ -75,17 +79,15 @@ #define BATTERY_MAX_CURRENT_A 1.0F #define BATTERY_MAX_REGEN_A 1.0F -#define COMPUTE_ALPHA(CUTOFF_HZ) \ +#define COMPUTE_ALPHA(CUTOFF_HZ) \ (1.0F / (1.0F + (1.0F / (2.0F * M_PI * CUTOFF_HZ)) / TIME_STEP)) -#define LOWPASS_FILTER(NEW, OLD, ALPHA) \ - OLD = ALPHA * NEW + (1.0F - ALPHA) * OLD +#define LOWPASS_FILTER(NEW, OLD, ALPHA) OLD = ALPHA * NEW + (1.0F - ALPHA) * OLD -#define LINEAR_MAP(x, in_min, in_max, out_min, out_max) \ +#define LINEAR_MAP(x, in_min, in_max, out_min, out_max) \ ((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min) -#define CHANGE_ENDIANESS_16(x) \ - (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) +#define CHANGE_ENDIANESS_16(x) (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) #define MOTOR_DIRECTION_STANDBY 0 #define MOTOR_DIRECTION_FORWARD 1 @@ -93,4 +95,4 @@ #define MOTOR_DIRECTION_ERROR 3 #define MAX_REGEN_TORQUE -9.0F // TODO: test with higher value regen -#define REGEN_BIAS 1 // Scale 0-1 of max regen torque +#define REGEN_BIAS 1 // Scale 0-1 of max regen torque diff --git a/fsae-vehicle-fw/src/vehicle/apps.cpp b/fsae-vehicle-fw/src/vehicle/apps.cpp index fac83e8..cac3fea 100644 --- a/fsae-vehicle-fw/src/vehicle/apps.cpp +++ b/fsae-vehicle-fw/src/vehicle/apps.cpp @@ -1,18 +1,18 @@ // Anteater Electric Racing, 2025 -#include -#include "utils/utils.h" #include "apps.h" +#include "utils/utils.h" #include "vehicle/faults.h" #include "vehicle/telemetry.h" #include +#include typedef struct { float appsReading1_Percentage; // Percentage of pedal travel (0 to 1) float appsReading2_Percentage; // Percentage of pedal travel (0 to 1) - float appsReading1_Voltage; // Voltage reading from the pedal (0 to 3.3V) - float appsReading2_Voltage; // Voltage reading from the pedal (0 to 3.3V) + float appsReading1_Voltage; // Voltage reading from the pedal (0 to 3.3V) + float appsReading2_Voltage; // Voltage reading from the pedal (0 to 3.3V) float apps1RawReading; float apps2RawReading; @@ -20,8 +20,8 @@ typedef struct { static APPSData appsData; static float appsAlpha; -static TickType_t appsLatestHealthyStateTime = 0; // Set to 0 when fault not detected - +static TickType_t appsLatestHealthyStateTime = + 0; // Set to 0 when fault not detected static void checkAndHandleAPPSFault(); static void checkAndHandlePlausibilityFault(); @@ -45,22 +45,26 @@ void APPS_UpdateData(uint32_t rawReading1, uint32_t rawReading2) { LOWPASS_FILTER(rawReading2, appsData.apps2RawReading, appsAlpha); // Convert ADC values to voltage - appsData.appsReading1_Voltage = ADC_VALUE_TO_VOLTAGE(appsData.apps1RawReading); - appsData.appsReading2_Voltage = ADC_VALUE_TO_VOLTAGE(appsData.apps2RawReading); + appsData.appsReading1_Voltage = + ADC_VALUE_TO_VOLTAGE(appsData.apps1RawReading); + appsData.appsReading2_Voltage = + ADC_VALUE_TO_VOLTAGE(appsData.apps2RawReading); // Map voltage to percentage of throttle travel, limiting to 0-1 range - appsData.appsReading1_Percentage = LINEAR_MAP(appsData.appsReading1_Voltage, APPS_3V3_MIN, APPS_3V3_MAX, 0.0F, 1.0F); - appsData.appsReading2_Percentage = LINEAR_MAP(appsData.appsReading2_Voltage, APPS_5V_MIN, APPS_5V_MAX, 0.0F, 1.0F); + appsData.appsReading1_Percentage = LINEAR_MAP( + appsData.appsReading1_Voltage, APPS_3V3_MIN, APPS_3V3_MAX, 0.0F, 1.0F); + appsData.appsReading2_Percentage = LINEAR_MAP( + appsData.appsReading2_Voltage, APPS_5V_MIN, APPS_5V_MAX, 0.0F, 1.0F); - if(appsData.appsReading1_Percentage < 0.0F) { + if (appsData.appsReading1_Percentage < 0.0F) { appsData.appsReading1_Percentage = 0.0F; - } else if(appsData.appsReading1_Percentage > 1.0F) { + } else if (appsData.appsReading1_Percentage > 1.0F) { appsData.appsReading1_Percentage = 1.0F; } - if(appsData.appsReading2_Percentage < 0.0F) { + if (appsData.appsReading2_Percentage < 0.0F) { appsData.appsReading2_Percentage = 0.0F; - } else if(appsData.appsReading2_Percentage > 1.0F) { + } else if (appsData.appsReading2_Percentage > 1.0F) { appsData.appsReading2_Percentage = 1.0F; } @@ -69,41 +73,40 @@ void APPS_UpdateData(uint32_t rawReading1, uint32_t rawReading2) { } float APPS_GetAPPSReading() { - return (appsData.appsReading1_Percentage + appsData.appsReading2_Percentage) / 2; + return (appsData.appsReading1_Percentage + + appsData.appsReading2_Percentage) / + 2; } -float APPS_GetAPPSReading1() { - return appsData.appsReading1_Percentage; -} +float APPS_GetAPPSReading1() { return appsData.appsReading1_Percentage; } -float APPS_GetAPPSReading2() { - return appsData.appsReading2_Percentage; -} +float APPS_GetAPPSReading2() { return appsData.appsReading2_Percentage; } static void checkAndHandleAPPSFault() { // Check for open/short circuit - float difference = abs(appsData.appsReading1_Percentage - appsData.appsReading2_Percentage); - - # if DEBUG_FLAG - Serial.print("Difference is: "); - Serial.println(difference); - Serial.print("Percent APPS1: "); - Serial.println(appsData.appsReading1_Percentage); - Serial.print("Percent APPS2: "); - Serial.println(appsData.appsReading2_Percentage); - # endif - - if(appsData.appsReading1_Voltage < APPS_3V3_FAULT_MIN || - appsData.appsReading1_Voltage > APPS_3V3_FAULT_MAX || - appsData.appsReading2_Voltage < APPS_5V_FAULT_MIN || - appsData.appsReading2_Voltage > APPS_5V_FAULT_MAX) { + float difference = abs(appsData.appsReading1_Percentage - + appsData.appsReading2_Percentage); + +#if DEBUG_FLAG + Serial.print("Difference is: "); + Serial.println(difference); + Serial.print("Percent APPS1: "); + Serial.println(appsData.appsReading1_Percentage); + Serial.print("Percent APPS2: "); + Serial.println(appsData.appsReading2_Percentage); +#endif + + if (appsData.appsReading1_Voltage < APPS_3V3_FAULT_MIN || + appsData.appsReading1_Voltage > APPS_3V3_FAULT_MAX || + appsData.appsReading2_Voltage < APPS_5V_FAULT_MIN || + appsData.appsReading2_Voltage > APPS_5V_FAULT_MAX) { TickType_t now = xTaskGetTickCount(); TickType_t elapsedTicks = now - appsLatestHealthyStateTime; TickType_t elapsedMs = elapsedTicks * portTICK_PERIOD_MS; - if (elapsedMs > APPS_FAULT_TIME_THRESHOLD_MS){ - # if DEBUG_FLAG - Serial.println("Setting APPS fault"); - # endif + if (elapsedMs > APPS_FAULT_TIME_THRESHOLD_MS) { +#if DEBUG_FLAG + Serial.println("Setting APPS fault"); +#endif Faults_SetFault(FAULT_APPS); return; } @@ -116,9 +119,9 @@ static void checkAndHandleAPPSFault() { Faults_SetFault(FAULT_APPS); return; } else { - # if DEBUG_FLAG - Serial.println("Clearing fault in handle"); - # endif +#if DEBUG_FLAG + Serial.println("Clearing fault in handle"); +#endif Faults_ClearFault(FAULT_APPS); } } @@ -128,20 +131,20 @@ static void checkAndHandlePlausibilityFault() { float BSEReading_Rear = BSE_GetBSEReading()->bseRear_PSI; float BSEReading = BSEReading_Front; - if (BSEReading_Rear > BSEReading_Front){ + if (BSEReading_Rear > BSEReading_Front) { BSEReading = BSEReading_Rear; } - # if DEBUG_FLAG - Serial.print("BSE Reading: "); - Serial.println(BSEReading); - # endif +#if DEBUG_FLAG + Serial.print("BSE Reading: "); + Serial.println(BSEReading); +#endif if (APPS_GetAPPSReading() > APPS_BSE_PLAUSABILITY_TROTTLE_THRESHOLD && BSEReading > APPS_BSE_PLAUSABILITY_BRAKE_THRESHOLD) { Faults_SetFault(FAULT_APPS_BRAKE_PLAUSIBILITY); } else { - if (APPS_GetAPPSReading() < APPS_BSE_PLAUSIBILITY_RESET_THRESHOLD){ + if (APPS_GetAPPSReading() < APPS_BSE_PLAUSIBILITY_RESET_THRESHOLD) { Faults_ClearFault(FAULT_APPS_BRAKE_PLAUSIBILITY); } } diff --git a/fsae-vehicle-fw/src/vehicle/bse.cpp b/fsae-vehicle-fw/src/vehicle/bse.cpp index 637d5ec..7c78980 100644 --- a/fsae-vehicle-fw/src/vehicle/bse.cpp +++ b/fsae-vehicle-fw/src/vehicle/bse.cpp @@ -9,7 +9,7 @@ #include "vehicle/faults.h" #include -typedef struct{ +typedef struct { float bseRawFront; float bseRawRear; } BSERawData; @@ -17,8 +17,8 @@ typedef struct{ static BSEData bseData; static BSERawData bseRawData; static float bseAlpha; -static TickType_t bseLatestHealthyStateTime = 0; // Set to 0 when fault not detected - +static TickType_t bseLatestHealthyStateTime = + 0; // Set to 0 when fault not detected void BSE_Init() { bseData.bseFront_PSI = 0; @@ -27,10 +27,11 @@ void BSE_Init() { bseRawData.bseRawFront = 0; bseRawData.bseRawRear = 0; - bseAlpha = COMPUTE_ALPHA(BSE_CUTOFF_HZ); // 10Hz cutoff frequency, 0.01s sample time + bseAlpha = COMPUTE_ALPHA( + BSE_CUTOFF_HZ); // 10Hz cutoff frequency, 0.01s sample time } -void BSE_UpdateData(uint32_t bseReading1, uint32_t bseReading2){ +void BSE_UpdateData(uint32_t bseReading1, uint32_t bseReading2) { // Filter incoming values LOWPASS_FILTER(bseReading1, bseRawData.bseRawFront, bseAlpha); LOWPASS_FILTER(bseReading2, bseRawData.bseRawRear, bseAlpha); @@ -38,23 +39,23 @@ void BSE_UpdateData(uint32_t bseReading1, uint32_t bseReading2){ float bseVoltage1 = ADC_VALUE_TO_VOLTAGE(bseRawData.bseRawFront); float bseVoltage2 = ADC_VALUE_TO_VOLTAGE(bseRawData.bseRawRear); - # if DEBUG_FLAG - Serial.print("BSE Voltage: "); - Serial.println(bseVoltage1); - # endif +#if DEBUG_FLAG + Serial.print("BSE Voltage: "); + Serial.println(bseVoltage1); +#endif // Check BSE open/short circuit - if(bseVoltage1 < BSE_LOWER_THRESHOLD || - bseVoltage1 > BSE_UPPER_THRESHOLD || - bseVoltage2 < BSE_LOWER_THRESHOLD || - bseVoltage2 > BSE_UPPER_THRESHOLD) { + if (bseVoltage1 < BSE_LOWER_THRESHOLD || + bseVoltage1 > BSE_UPPER_THRESHOLD || + bseVoltage2 < BSE_LOWER_THRESHOLD || + bseVoltage2 > BSE_UPPER_THRESHOLD) { TickType_t now = xTaskGetTickCount(); TickType_t elapsedTicks = now - bseLatestHealthyStateTime; TickType_t elapsedMs = elapsedTicks * portTICK_PERIOD_MS; - if (elapsedMs > BSE_FAULT_TIME_THRESHOLD_MS){ - # if DEBUG_FLAG - Serial.println("Setting BSE fault"); - # endif + if (elapsedMs > BSE_FAULT_TIME_THRESHOLD_MS) { +#if DEBUG_FLAG + Serial.println("Setting BSE fault"); +#endif Faults_SetFault(FAULT_BSE); } @@ -67,6 +68,4 @@ void BSE_UpdateData(uint32_t bseReading1, uint32_t bseReading2){ bseData.bseRear_PSI = BSE_VOLTAGE_TO_PSI(bseVoltage2); } -BSEData* BSE_GetBSEReading() { - return &bseData; -} +BSEData *BSE_GetBSEReading() { return &bseData; } diff --git a/fsae-vehicle-fw/src/vehicle/bse.h b/fsae-vehicle-fw/src/vehicle/bse.h index 0a343e7..66444ba 100644 --- a/fsae-vehicle-fw/src/vehicle/bse.h +++ b/fsae-vehicle-fw/src/vehicle/bse.h @@ -5,10 +5,9 @@ typedef struct { float bseFront_PSI; // front brake pressure in PSI - float bseRear_PSI; // rear brake pressure in PSI + float bseRear_PSI; // rear brake pressure in PSI } BSEData; void BSE_Init(); void BSE_UpdateData(uint32_t bseReading1, uint32_t bseReading2); -BSEData* BSE_GetBSEReading(); - +BSEData *BSE_GetBSEReading(); diff --git a/fsae-vehicle-fw/src/vehicle/faults.cpp b/fsae-vehicle-fw/src/vehicle/faults.cpp index 83a8d05..4cf212b 100644 --- a/fsae-vehicle-fw/src/vehicle/faults.cpp +++ b/fsae-vehicle-fw/src/vehicle/faults.cpp @@ -9,64 +9,62 @@ #define FAULT_APPS_BRAKE_PLAUSIBILITY_MASK (0x1 << 6) #include "vehicle/faults.h" -#include "vehicle/motor.h" #include "utils/utils.h" +#include "vehicle/motor.h" -# if DEBUG_FLAG - #include -# endif +#if DEBUG_FLAG +#include +#endif static uint32_t faultBitMap; -void Faults_Init() { - faultBitMap = 0; - } +void Faults_Init() { faultBitMap = 0; } void Faults_SetFault(FaultType fault) { switch (fault) { - case FAULT_NONE: { - break; - } - case FAULT_OVER_CURRENT: { - faultBitMap |= FAULT_OVER_CURRENT_MASK; - break; - } - case FAULT_UNDER_VOLTAGE: { - faultBitMap |= FAULT_UNDER_VOLTAGE_MASK; - break; - } - case FAULT_OVER_TEMP: { - faultBitMap |= FAULT_OVER_TEMP_MASK; - break; - } - case FAULT_APPS: { - # if DEBUG_FLAG - Serial.println("Setting APPS fault"); - # endif - faultBitMap |= FAULT_APPS_MASK; - break; - } - case FAULT_BSE: { - # if DEBUG_FLAG - Serial.println("Setting BSE fault"); - # endif - faultBitMap |= FAULT_BSE_MASK; - break; - } - case FAULT_BPPS: { - faultBitMap |= FAULT_BPPS_MASK; - break; - } - case FAULT_APPS_BRAKE_PLAUSIBILITY: { - # if DEBUG_FLAG - Serial.println("Setting APPS Plausibility fault"); - # endif - faultBitMap |= FAULT_APPS_BRAKE_PLAUSIBILITY_MASK; - break; - } - default: { - break; - } + case FAULT_NONE: { + break; + } + case FAULT_OVER_CURRENT: { + faultBitMap |= FAULT_OVER_CURRENT_MASK; + break; + } + case FAULT_UNDER_VOLTAGE: { + faultBitMap |= FAULT_UNDER_VOLTAGE_MASK; + break; + } + case FAULT_OVER_TEMP: { + faultBitMap |= FAULT_OVER_TEMP_MASK; + break; + } + case FAULT_APPS: { +#if DEBUG_FLAG + Serial.println("Setting APPS fault"); +#endif + faultBitMap |= FAULT_APPS_MASK; + break; + } + case FAULT_BSE: { +#if DEBUG_FLAG + Serial.println("Setting BSE fault"); +#endif + faultBitMap |= FAULT_BSE_MASK; + break; + } + case FAULT_BPPS: { + faultBitMap |= FAULT_BPPS_MASK; + break; + } + case FAULT_APPS_BRAKE_PLAUSIBILITY: { +#if DEBUG_FLAG + Serial.println("Setting APPS Plausibility fault"); +#endif + faultBitMap |= FAULT_APPS_BRAKE_PLAUSIBILITY_MASK; + break; + } + default: { + break; + } } } @@ -88,9 +86,9 @@ void Faults_ClearFault(FaultType fault) { break; } case FAULT_APPS: { - # if DEBUG_FLAG - Serial.println("Clearing APPS fault"); - # endif +#if DEBUG_FLAG + Serial.println("Clearing APPS fault"); +#endif faultBitMap &= ~FAULT_APPS_MASK; break; } @@ -103,9 +101,9 @@ void Faults_ClearFault(FaultType fault) { break; } case FAULT_APPS_BRAKE_PLAUSIBILITY: { - # if DEBUG_FLAG - Serial.println("Clearing APPS BSE plausibility fault"); - # endif +#if DEBUG_FLAG + Serial.println("Clearing APPS BSE plausibility fault"); +#endif faultBitMap &= ~FAULT_APPS_BRAKE_PLAUSIBILITY_MASK; break; } @@ -118,15 +116,15 @@ void Faults_ClearFault(FaultType fault) { // currently having all faults being handled the same but leaving room for // future customization void Faults_HandleFaults() { - # if DEBUG_FLAG - Serial.print("Fault bitmap: "); - Serial.println(faultBitMap); - # endif +#if DEBUG_FLAG + Serial.print("Fault bitmap: "); + Serial.println(faultBitMap); +#endif if (faultBitMap == 0) { - # if DEBUG_FLAG - Serial.println("Clearing all faults in handle faults"); - # endif +#if DEBUG_FLAG + Serial.println("Clearing all faults in handle faults"); +#endif Motor_ClearFaultState(); return; diff --git a/fsae-vehicle-fw/src/vehicle/faults.h b/fsae-vehicle-fw/src/vehicle/faults.h index 7536742..bd77ccb 100644 --- a/fsae-vehicle-fw/src/vehicle/faults.h +++ b/fsae-vehicle-fw/src/vehicle/faults.h @@ -22,4 +22,3 @@ uint32_t Faults_GetFaults(); void Faults_ClearFault(FaultType fault); void Faults_HandleFaults(); bool Faults_CheckAllClear(); - diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp index 8f11500..1b7da1c 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.cpp @@ -25,151 +25,159 @@ static MCU3Data mcu3Data; void MCU_Init() { // Fill with reasonable dummy values - mcu1Data = { - .motorSpeed = 0.0F, - .motorTorque = 0.0F, - .maxMotorTorque = MOTOR_MAX_TORQUE, // Max torque in Nm - .maxMotorBrakeTorque = MOTOR_MAX_TORQUE, // Max brake torque in Nm - .motorDirection = DIRECTION_STANDBY, - .mcuMainState = STATE_STANDBY, - .mcuWorkMode = WORK_MODE_STANDBY - }; - - mcu2Data = { - .motorTemp = 25, // Default temperature in C - .mcuTemp = 25, // Default temperature in C - .dcMainWireOverVoltFault = false, - .motorPhaseCurrFault = false, - .mcuOverHotFault = false, - .resolverFault = false, - .phaseCurrSensorFault = false, - .motorOverSpdFault = false, - .drvMotorOverHotFault = false, - .dcMainWireOverCurrFault = false, - .drvMotorOverCoolFault = false, - .mcuMotorSystemState = false, - .mcuTempSensorState = false, - .motorTempSensorState = false, - .dcVoltSensorState = false, - .dcLowVoltWarning = false, - .mcu12VLowVoltWarning = false, - .motorStallFault = false, - .motorOpenPhaseFault = false, - .mcuWarningLevel = ERROR_NONE - }; + mcu1Data = {.motorSpeed = 0.0F, + .motorTorque = 0.0F, + .maxMotorTorque = MOTOR_MAX_TORQUE, // Max torque in Nm + .maxMotorBrakeTorque = + MOTOR_MAX_TORQUE, // Max brake torque in Nm + .motorDirection = DIRECTION_STANDBY, + .mcuMainState = STATE_STANDBY, + .mcuWorkMode = WORK_MODE_STANDBY}; + + mcu2Data = {.motorTemp = 25, // Default temperature in C + .mcuTemp = 25, // Default temperature in C + .dcMainWireOverVoltFault = false, + .motorPhaseCurrFault = false, + .mcuOverHotFault = false, + .resolverFault = false, + .phaseCurrSensorFault = false, + .motorOverSpdFault = false, + .drvMotorOverHotFault = false, + .dcMainWireOverCurrFault = false, + .drvMotorOverCoolFault = false, + .mcuMotorSystemState = false, + .mcuTempSensorState = false, + .motorTempSensorState = false, + .dcVoltSensorState = false, + .dcLowVoltWarning = false, + .mcu12VLowVoltWarning = false, + .motorStallFault = false, + .motorOpenPhaseFault = false, + .mcuWarningLevel = ERROR_NONE}; mcu3Data = { - .mcuVoltage = 0.0F, // Default voltage in V - .mcuCurrent = 16.0F, // Default current in A + .mcuVoltage = 0.0F, // Default voltage in V + .mcuCurrent = 16.0F, // Default current in A .motorPhaseCurr = 3.0F // Default phase current in A }; // Initialize the motor thread - xTaskCreate(threadMCU, "threadMCU", THREAD_MCU_STACK_SIZE, NULL, THREAD_MCU_PRIORITY, NULL); + xTaskCreate(threadMCU, "threadMCU", THREAD_MCU_STACK_SIZE, NULL, + THREAD_MCU_PRIORITY, NULL); } static void threadMCU(void *pvParameters) { while (true) { // Read the CAN messages CAN_Receive(&rx_id, &rx_data); - switch(rx_id) { - case mMCU1_ID: - { - MCU1 mcu1 = {0}; - memcpy(&mcu1, &rx_data, sizeof(mcu1)); - - int8_t torqueDirection = 0; // 1 if power drive state, -1 if generate electricity state - if (mcu1.MCU_MotorState == 1) torqueDirection = 1; - else if (mcu1.MCU_MotorState == 2) torqueDirection = -1; - - taskENTER_CRITICAL(); // Enter critical section - mcu1Data = { - .motorSpeed = CHANGE_ENDIANESS_16(mcu1.MCU_ActMotorSpd) * 0.25F, // convert to RPM - .motorTorque = mcu1.MCU_ActMotorTq * 0.392F * torqueDirection * MOTOR_MAX_TORQUE, // convert to Nm - .maxMotorTorque = mcu1.MCU_MaxMotorTq * 0.392F * MOTOR_MAX_TORQUE, // convert to Nm - .maxMotorBrakeTorque = mcu1.MCU_MaxMotorBrakeTq * 0.392F * MOTOR_MAX_TORQUE, // convert to Nm - .motorDirection = (MotorRotateDirection) mcu1.MCU_MotorRotateDirection, - .mcuMainState = (MCUMainState) mcu1.MCU_MotorMainState, - .mcuWorkMode = (MCUWorkMode) mcu1.MCU_MotorWorkMode - }; - taskEXIT_CRITICAL(); // Exit critical section - break; - } - case mMCU2_ID: - { - MCU2 mcu2 = {0}; - memcpy(&mcu2, &rx_data, sizeof(mcu2)); - - taskENTER_CRITICAL(); // Enter critical section - mcu2Data = { - .motorTemp = mcu2.MCU_Motor_Temp - 40, // convert to C - .mcuTemp = mcu2.MCU_hardwareTemp - 40, // convert to C - .dcMainWireOverVoltFault = mcu2.MCU_DCMainWireOverVoltFault ? true : false, - .motorPhaseCurrFault = mcu2.MCU_MotorPhaseCurrFault ? true : false, - .mcuOverHotFault = mcu2.MCU_OverHotFault ? true : false, - .resolverFault = mcu2.MCU_MotorResolver_Fault ? true : false, - .phaseCurrSensorFault = mcu2.MCU_PhaseCurrSensorState ? true : false, - .motorOverSpdFault = mcu2.MCU_MotorOverSpdFault ? true : false, - .drvMotorOverHotFault = mcu2.Drv_MotorOverHotFault ? true : false, - .dcMainWireOverCurrFault = mcu2.MCU_DCMainWireOverCurrFault ? true : false, - .drvMotorOverCoolFault = mcu2.Drv_MotorOverCoolFault ? true : false, - .mcuMotorSystemState = mcu2.MCU_MotorSystemState ? true : false, - .mcuTempSensorState = mcu2.MCU_TempSensorState ? true : false, - .motorTempSensorState = mcu2.MCU_MotorTempSensorState ? true : false, - .dcVoltSensorState = mcu2.MCU_DC_VoltSensorState ? true : false, - .dcLowVoltWarning = mcu2.MCU_DC_LowVoltWarning ? true : false, - .mcu12VLowVoltWarning = mcu2.MCU_12V_LowVoltWarning ? true : false, - .motorStallFault = mcu2.MCU_MotorStallFault ? true : false, - .motorOpenPhaseFault = mcu2.MCU_MotorOpenPhaseFault ? true : false, - .mcuWarningLevel = (MCUWarningLevel) mcu2.MCU_Warning_Level - }; - taskEXIT_CRITICAL(); // Exit critical section - break; - } - case mMCU3_ID: - { - MCU3 mcu3 = {0}; - memcpy(&mcu3, &rx_data, sizeof(mcu3)); - - taskENTER_CRITICAL(); // Enter critical section - - mcu3Data = { - .mcuVoltage = (((mcu3.MCU_DC_MainWireVolt & 0xFF) << 8) | (mcu3.MCU_DC_MainWireVolt >> 8)) * 0.01F, // convert to V - .mcuCurrent = (((mcu3.MCU_DC_MainWireCurr & 0xFF) << 8) | (mcu3.MCU_DC_MainWireCurr >> 8)) * 0.01F, // convert to A - .motorPhaseCurr = (((mcu3.MCU_MotorPhaseCurr & 0xFF) << 8) | (mcu3.MCU_MotorPhaseCurr >> 8)) * 0.01F, // convert to A - }; - - taskEXIT_CRITICAL(); // Exit critical section - break; - } - case pcc_ID: - { - //Serial.print("PCC OK?"); - processPCCMessage(rx_data); - break; - } - default: - { - break; - } + switch (rx_id) { + case mMCU1_ID: { + MCU1 mcu1 = {0}; + memcpy(&mcu1, &rx_data, sizeof(mcu1)); + + int8_t torqueDirection = + 0; // 1 if power drive state, -1 if generate electricity state + if (mcu1.MCU_MotorState == 1) + torqueDirection = 1; + else if (mcu1.MCU_MotorState == 2) + torqueDirection = -1; + + taskENTER_CRITICAL(); // Enter critical section + mcu1Data = { + .motorSpeed = CHANGE_ENDIANESS_16(mcu1.MCU_ActMotorSpd) * + 0.25F, // convert to RPM + .motorTorque = mcu1.MCU_ActMotorTq * 0.392F * torqueDirection * + MOTOR_MAX_TORQUE, // convert to Nm + .maxMotorTorque = mcu1.MCU_MaxMotorTq * 0.392F * + MOTOR_MAX_TORQUE, // convert to Nm + .maxMotorBrakeTorque = mcu1.MCU_MaxMotorBrakeTq * 0.392F * + MOTOR_MAX_TORQUE, // convert to Nm + .motorDirection = + (MotorRotateDirection)mcu1.MCU_MotorRotateDirection, + .mcuMainState = (MCUMainState)mcu1.MCU_MotorMainState, + .mcuWorkMode = (MCUWorkMode)mcu1.MCU_MotorWorkMode}; + taskEXIT_CRITICAL(); // Exit critical section + break; + } + case mMCU2_ID: { + MCU2 mcu2 = {0}; + memcpy(&mcu2, &rx_data, sizeof(mcu2)); + + taskENTER_CRITICAL(); // Enter critical section + mcu2Data = { + .motorTemp = mcu2.MCU_Motor_Temp - 40, // convert to C + .mcuTemp = mcu2.MCU_hardwareTemp - 40, // convert to C + .dcMainWireOverVoltFault = + mcu2.MCU_DCMainWireOverVoltFault ? true : false, + .motorPhaseCurrFault = + mcu2.MCU_MotorPhaseCurrFault ? true : false, + .mcuOverHotFault = mcu2.MCU_OverHotFault ? true : false, + .resolverFault = mcu2.MCU_MotorResolver_Fault ? true : false, + .phaseCurrSensorFault = + mcu2.MCU_PhaseCurrSensorState ? true : false, + .motorOverSpdFault = mcu2.MCU_MotorOverSpdFault ? true : false, + .drvMotorOverHotFault = + mcu2.Drv_MotorOverHotFault ? true : false, + .dcMainWireOverCurrFault = + mcu2.MCU_DCMainWireOverCurrFault ? true : false, + .drvMotorOverCoolFault = + mcu2.Drv_MotorOverCoolFault ? true : false, + .mcuMotorSystemState = mcu2.MCU_MotorSystemState ? true : false, + .mcuTempSensorState = mcu2.MCU_TempSensorState ? true : false, + .motorTempSensorState = + mcu2.MCU_MotorTempSensorState ? true : false, + .dcVoltSensorState = mcu2.MCU_DC_VoltSensorState ? true : false, + .dcLowVoltWarning = mcu2.MCU_DC_LowVoltWarning ? true : false, + .mcu12VLowVoltWarning = + mcu2.MCU_12V_LowVoltWarning ? true : false, + .motorStallFault = mcu2.MCU_MotorStallFault ? true : false, + .motorOpenPhaseFault = + mcu2.MCU_MotorOpenPhaseFault ? true : false, + .mcuWarningLevel = (MCUWarningLevel)mcu2.MCU_Warning_Level}; + taskEXIT_CRITICAL(); // Exit critical section + break; + } + case mMCU3_ID: { + MCU3 mcu3 = {0}; + memcpy(&mcu3, &rx_data, sizeof(mcu3)); + + taskENTER_CRITICAL(); // Enter critical section + + mcu3Data = { + .mcuVoltage = (((mcu3.MCU_DC_MainWireVolt & 0xFF) << 8) | + (mcu3.MCU_DC_MainWireVolt >> 8)) * + 0.01F, // convert to V + .mcuCurrent = (((mcu3.MCU_DC_MainWireCurr & 0xFF) << 8) | + (mcu3.MCU_DC_MainWireCurr >> 8)) * + 0.01F, // convert to A + .motorPhaseCurr = (((mcu3.MCU_MotorPhaseCurr & 0xFF) << 8) | + (mcu3.MCU_MotorPhaseCurr >> 8)) * + 0.01F, // convert to A + }; + + taskEXIT_CRITICAL(); // Exit critical section + break; + } + case pcc_ID: { + // Serial.print("PCC OK?"); + processPCCMessage(rx_data); + break; + } + default: { + break; + } } } } -MCU1Data* MCU_GetMCU1Data() { - return &mcu1Data; -} +MCU1Data *MCU_GetMCU1Data() { return &mcu1Data; } -MCU2Data* MCU_GetMCU2Data() { - return& mcu2Data; -} +MCU2Data *MCU_GetMCU2Data() { return &mcu2Data; } -MCU3Data* MCU_GetMCU3Data() { - return& mcu3Data; -} +MCU3Data *MCU_GetMCU3Data() { return &mcu3Data; } // checksum = (byte0 + byte1 + byte2 + byte3 + byte4 + byte5 + byte6) XOR 0xFF -uint8_t ComputeChecksum(uint8_t* data) { +uint8_t ComputeChecksum(uint8_t *data) { uint8_t sum = 0; for (uint8_t i = 0; i < 7; i++) { sum += data[i]; diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.h b/fsae-vehicle-fw/src/vehicle/ifl100-36.h index 1546fe3..450a1e9 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.h +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.h @@ -50,11 +50,11 @@ typedef struct __attribute__((packed)) { uint64_t Reserved : 5; uint64_t VCUAuthenticationStatus : 2; - uint64_t ChangeGearAlarm: 1; // end of byte 3 + uint64_t ChangeGearAlarm : 1; // end of byte 3 - uint64_t VehicleState: 1; - uint64_t Brake_Pedal_Sts: 2; - uint64_t BMS_Main_Relay_Cmd: 1; + uint64_t VehicleState : 1; + uint64_t Brake_Pedal_Sts : 2; + uint64_t BMS_Main_Relay_Cmd : 1; uint64_t GearLeverPos_Sts : 3; uint64_t GearLeverPos_Sts_F : 1; // end of byte 4 @@ -65,38 +65,38 @@ typedef struct __attribute__((packed)) { uint64_t KeyPosition : 2; // end of byte 5 uint64_t RollingCounter : 4; - uint64_t BMS_Aux_Relay_Cmd: 1; + uint64_t BMS_Aux_Relay_Cmd : 1; uint64_t PowerReduceReq : 3; // end of byte 6 uint64_t CheckSum : 8; // end of byte 7 -} VCU1; // bit order verified +} VCU1; // bit order verified typedef struct __attribute__((packed)) { - uint64_t MCU_ActMotorSpd : 16; // end of byte 0 and byte 1 - uint64_t MCU_ActMotorTq: 8; // end of byte 2 - uint64_t MCU_MaxMotorTq : 8; // end of byte 3 + uint64_t MCU_ActMotorSpd : 16; // end of byte 0 and byte 1 + uint64_t MCU_ActMotorTq : 8; // end of byte 2 + uint64_t MCU_MaxMotorTq : 8; // end of byte 3 uint64_t MCU_MaxMotorBrakeTq : 8; // end of byte 4 // flipped - uint64_t Reserved: 3; + uint64_t Reserved : 3; uint64_t MCU_MotorMainState : 3; uint64_t MCU_MotorRotateDirection : 2; // end of byte 5 uint64_t RollingCounter : 4; // end of byte 6 uint64_t MCU_MotorState : 2; - uint64_t MCU_MotorWorkMode: 2; + uint64_t MCU_MotorWorkMode : 2; uint64_t CheckSum : 8; // end of byte 7 -} MCU1; // order fixed, needs to be verified +} MCU1; // order fixed, needs to be verified typedef struct __attribute__((packed)) { - uint64_t MCU_Motor_Temp : 8; // end of byte 0 - uint64_t MCU_hardwareTemp: 8; // end of byte 1 + uint64_t MCU_Motor_Temp : 8; // end of byte 0 + uint64_t MCU_hardwareTemp : 8; // end of byte 1 uint64_t MCU_DCMainWireOverCurrFault : 1; uint64_t MCU_MotorPhaseCurrFault : 1; - uint64_t MCU_OverHotFault: 1; - uint64_t MCU_MotorResolver_Fault: 1; + uint64_t MCU_OverHotFault : 1; + uint64_t MCU_MotorResolver_Fault : 1; uint64_t MCU_PhaseCurrSensorState : 1; uint64_t MCU_MotorOverSpdFault : 1; uint64_t Drv_MotorOverHotFault : 1; @@ -117,26 +117,28 @@ typedef struct __attribute__((packed)) { uint64_t MCU_MotorStallFault : 1; // end of byte 6 uint64_t CheckSum : 8; // end of byte 7 -} MCU2; // fixed order, needs to be verified +} MCU2; // fixed order, needs to be verified typedef struct __attribute__((packed)) { uint64_t MCU_DC_MainWireVolt : 16; // end of byte 0 and byte 1 - //uint64_t dummystop : 8; - uint64_t MCU_DC_MainWireCurr: 16; // end of byte 2 and byte 3 --> should be byte 3 and 4 - uint64_t MCU_MotorPhaseCurr : 16; // end of byte 4 and byte 5 ---> 6 and 7? or 5 and 6 + // uint64_t dummystop : 8; + uint64_t MCU_DC_MainWireCurr + : 16; // end of byte 2 and byte 3 --> should be byte 3 and 4 + uint64_t MCU_MotorPhaseCurr + : 16; // end of byte 4 and byte 5 ---> 6 and 7? or 5 and 6 uint64_t Reserved : 16; // end of byte 6 and byte 7 -} MCU3; // bit order verified +} MCU3; // bit order verified typedef struct __attribute__((packed)) { uint64_t BMS_Warning_Level : 2; uint64_t Batt_charge_Sts : 2; uint64_t Negative_Relay_FB : 1; uint64_t Positive_Relay_FB : 1; - uint64_t HighVoltLoopLockSts: 1; + uint64_t HighVoltLoopLockSts : 1; uint64_t Batt_Charge_Sts_F : 1; // end of byte 0 - uint64_t Batt_SOC_Value: 8; // end of byte 1 - uint64_t Batt_SOH_Value: 8; // end of byte 2 + uint64_t Batt_SOC_Value : 8; // end of byte 1 + uint64_t Batt_SOH_Value : 8; // end of byte 2 uint64_t BMS_Cmd_AC_DC : 2; uint64_t Pre_charge_Relay_FB : 1; @@ -149,7 +151,7 @@ typedef struct __attribute__((packed)) { uint64_t Batt_Pack_Coincidence_Alarm : 1; uint64_t Batt_Pack_Matching_Alarm : 1; uint64_t Insulation_Resistance_Low_F : 1; - uint64_t HighVoltLoopLockSts_F: 1; + uint64_t HighVoltLoopLockSts_F : 1; uint64_t ChargeRelayAdhereDetectionSts : 1; uint64_t RelayAdhereDetectionSts : 1; // end of byte 4 @@ -159,62 +161,61 @@ typedef struct __attribute__((packed)) { uint64_t Reserved3 : 4; // end of byte 6 uint64_t CheckSum : 8; // end of byte 7 -} BMS1; // bit order verified +} BMS1; // bit order verified typedef struct __attribute__((packed)) { - uint64_t sAllowMaxDischarge : 16; // end of byte 1 and byte 2 - uint64_t sAllowMaxRegenCharge: 16; // end of byte 3 and byte 4 + uint64_t sAllowMaxDischarge : 16; // end of byte 1 and byte 2 + uint64_t sAllowMaxRegenCharge : 16; // end of byte 3 and byte 4 - uint64_t Reserved : 20; // end of byte 5 + uint64_t Reserved : 20; // end of byte 5 uint64_t RollingCounter : 4; // end of byte 6 uint64_t CheckSum : 8; // end of byte 7 -} BMS2; // bit order verified +} BMS2; // bit order verified typedef struct { // MCU1 data - float motorSpeed; // Motor speed in RPM - float motorTorque; // Motor torque in Nm - float maxMotorTorque; // Max motor torque in Nm - float maxMotorBrakeTorque; // Max motor brake torque in Nm + float motorSpeed; // Motor speed in RPM + float motorTorque; // Motor torque in Nm + float maxMotorTorque; // Max motor torque in Nm + float maxMotorBrakeTorque; // Max motor brake torque in Nm MotorRotateDirection motorDirection; // Motor direction - MCUMainState mcuMainState; // Motor main state - MCUWorkMode mcuWorkMode; // MCU work mode + MCUMainState mcuMainState; // Motor main state + MCUWorkMode mcuWorkMode; // MCU work mode } MCU1Data; typedef struct { - int32_t motorTemp; // Motor temperature in C - int32_t mcuTemp; // Hardware temperature in C - bool dcMainWireOverVoltFault; // DC over voltage fault - bool motorPhaseCurrFault; // MCU motor phase current fault - bool mcuOverHotFault; // MCU overheat fault - bool resolverFault; // Resolver fault - bool phaseCurrSensorFault; // Phase current sensor fault - bool motorOverSpdFault; // MCU motor over speed fault - bool drvMotorOverHotFault; // Driver motor overheat fault - bool dcMainWireOverCurrFault; // DC main wire over voltage fault - bool drvMotorOverCoolFault; // Driver motor overcool fault - bool mcuMotorSystemState; // MCU motor system state - bool mcuTempSensorState; // MCU temperature sensor state - bool motorTempSensorState; // MCU motor temperature sensor state - bool dcVoltSensorState; // MCU DC voltage sensor state - bool dcLowVoltWarning; // MCU DC low voltage warning - bool mcu12VLowVoltWarning; // MCU 12V low voltage warning - bool motorStallFault; // MCU motor stall fault - bool motorOpenPhaseFault; // MCU motor open phase fault + int32_t motorTemp; // Motor temperature in C + int32_t mcuTemp; // Hardware temperature in C + bool dcMainWireOverVoltFault; // DC over voltage fault + bool motorPhaseCurrFault; // MCU motor phase current fault + bool mcuOverHotFault; // MCU overheat fault + bool resolverFault; // Resolver fault + bool phaseCurrSensorFault; // Phase current sensor fault + bool motorOverSpdFault; // MCU motor over speed fault + bool drvMotorOverHotFault; // Driver motor overheat fault + bool dcMainWireOverCurrFault; // DC main wire over voltage fault + bool drvMotorOverCoolFault; // Driver motor overcool fault + bool mcuMotorSystemState; // MCU motor system state + bool mcuTempSensorState; // MCU temperature sensor state + bool motorTempSensorState; // MCU motor temperature sensor state + bool dcVoltSensorState; // MCU DC voltage sensor state + bool dcLowVoltWarning; // MCU DC low voltage warning + bool mcu12VLowVoltWarning; // MCU 12V low voltage warning + bool motorStallFault; // MCU motor stall fault + bool motorOpenPhaseFault; // MCU motor open phase fault MCUWarningLevel mcuWarningLevel; // MCU warning level } MCU2Data; typedef struct { - float mcuVoltage; // DC main wire voltage in V - float mcuCurrent; // DC main wire current in A + float mcuVoltage; // DC main wire voltage in V + float mcuCurrent; // DC main wire current in A float motorPhaseCurr; // Motor phase current in A } MCU3Data; void MCU_Init(); -uint8_t ComputeChecksum(uint8_t* data); +uint8_t ComputeChecksum(uint8_t *data); - -MCU1Data* MCU_GetMCU1Data(); -MCU2Data* MCU_GetMCU2Data(); -MCU3Data* MCU_GetMCU3Data(); +MCU1Data *MCU_GetMCU1Data(); +MCU2Data *MCU_GetMCU2Data(); +MCU3Data *MCU_GetMCU3Data(); diff --git a/fsae-vehicle-fw/src/vehicle/motor.cpp b/fsae-vehicle-fw/src/vehicle/motor.cpp index 9ffb0c4..cf04ab4 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.cpp +++ b/fsae-vehicle-fw/src/vehicle/motor.cpp @@ -156,9 +156,8 @@ void threadMotor(void *pvParameters) { bms1.Pre_charge_Finish_Sts = 0; // 1 = ON, 0 = OFF // vcu1.VCU_Warning_Level = 3; // 1 0 = No Warning, 1 = Warning, // 2 = Fault, 3 = Critical Fault - vcu1.VCU_MotorMode = - 0; // 1 0 = Standby, 1 = Drive, 2 = Generate// Electricy, - // 3 = Reserved + vcu1.VCU_MotorMode = 0; // 1 0 = Standby, 1 = Drive, 2 = + // Generate// Electricy, 3 = Reserved break; } diff --git a/fsae-vehicle-fw/src/vehicle/motor.h b/fsae-vehicle-fw/src/vehicle/motor.h index 137624a..c94a0ef 100644 --- a/fsae-vehicle-fw/src/vehicle/motor.h +++ b/fsae-vehicle-fw/src/vehicle/motor.h @@ -16,7 +16,9 @@ typedef enum { void threadMotor(void *pvParameters); void Motor_Init(); -void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, bool enablePower, bool enableRun, bool enableRegen, bool enableStandby); +void Motor_UpdateMotor(float torqueDemand, bool enablePrecharge, + bool enablePower, bool enableRun, bool enableRegen, + bool enableStandby); float Motor_GetTorqueDemand(); MotorState Motor_GetState(); diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp index 60b600e..289821f 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.cpp @@ -1,24 +1,20 @@ #define THREAD_CAN_STACK_SIZE 128 #define THREAD_CAN_PRIORITY 1 - - -#include "arduino_freertos.h" #include "pcc_receive.h" +#include "arduino_freertos.h" static PCC pccData; -void PCC_Init(){ - pccData = { - .state = 0, - .errorCode = 0, - .accumulatorVoltage = 0, - .tsVoltage = 0, - .prechargeProgress = 404 - }; +void PCC_Init() { + pccData = {.state = 0, + .errorCode = 0, + .accumulatorVoltage = 0, + .tsVoltage = 0, + .prechargeProgress = 404}; } -void processPCCMessage(uint64_t rx_data){ +void processPCCMessage(uint64_t rx_data) { taskENTER_CRITICAL(); memcpy(&pccData, &rx_data, sizeof(PCC)); taskEXIT_CRITICAL(); @@ -27,9 +23,4 @@ void processPCCMessage(uint64_t rx_data){ // Serial.println(pccData.prechargeProgress); } -PCC* PCC_GetData(){ - return &pccData; -} - - - +PCC *PCC_GetData() { return &pccData; } diff --git a/fsae-vehicle-fw/src/vehicle/pcc_receive.h b/fsae-vehicle-fw/src/vehicle/pcc_receive.h index abedfb5..1e2dd97 100644 --- a/fsae-vehicle-fw/src/vehicle/pcc_receive.h +++ b/fsae-vehicle-fw/src/vehicle/pcc_receive.h @@ -3,7 +3,7 @@ #include typedef struct __attribute__((packed)) { - //uint32_t timestamp; + // uint32_t timestamp; uint8_t state; uint8_t errorCode; uint16_t accumulatorVoltage; @@ -11,9 +11,9 @@ typedef struct __attribute__((packed)) { uint16_t prechargeProgress; } PCC; -//static PCC pccData; +// static PCC pccData; void PCC_Init(); void processPCCMessage(uint64_t); -PCC* PCC_GetData(); +PCC *PCC_GetData(); diff --git a/fsae-vehicle-fw/src/vehicle/rtm_button.cpp b/fsae-vehicle-fw/src/vehicle/rtm_button.cpp index 943f6ef..3784a50 100644 --- a/fsae-vehicle-fw/src/vehicle/rtm_button.cpp +++ b/fsae-vehicle-fw/src/vehicle/rtm_button.cpp @@ -7,16 +7,15 @@ #include "rtm_button.h" -static bool rtmState = false; // Latching state of RTM based on momentary button press. True - driving state, false - idle state +static bool rtmState = false; // Latching state of RTM based on momentary button + // press. True - driving state, false - idle state static uint32_t lastDebounceTime = 0; void RTMButton_Update(bool rtmButton) { - if(rtmButton == 1 && millis() - lastDebounceTime > BUTTON_DEBOUNCE_MS) { + if (rtmButton == 1 && millis() - lastDebounceTime > BUTTON_DEBOUNCE_MS) { rtmState = !rtmState; // Toggle the state lastDebounceTime = millis(); } } -bool RTMButton_GetState() { - return rtmState; -} +bool RTMButton_GetState() { return rtmState; } diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.cpp b/fsae-vehicle-fw/src/vehicle/telemetry.cpp index e2ea558..171e871 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.cpp +++ b/fsae-vehicle-fw/src/vehicle/telemetry.cpp @@ -15,7 +15,8 @@ TelemetryData telemetryData; void Telemetry_Init() { - telemetryData = { // Fill with reasonable dummy values + telemetryData = { + // Fill with reasonable dummy values .APPS_Travel = 0.0F, .motorSpeed = 0.0F, .motorTorque = 0.0F, @@ -42,9 +43,10 @@ void Telemetry_Init() { }; } -void threadTelemetry(void *pvParameters){ - static TickType_t lastWakeTime = xTaskGetTickCount(); // Initialize the last wake time - while(true){ +void threadTelemetry(void *pvParameters) { + static TickType_t lastWakeTime = + xTaskGetTickCount(); // Initialize the last wake time + while (true) { taskENTER_CRITICAL(); // Enter critical section telemetryData = { .APPS_Travel = APPS_GetAPPSReading(), @@ -64,8 +66,10 @@ void threadTelemetry(void *pvParameters){ .motorTemp = MCU_GetMCU2Data()->motorTemp, .mcuTemp = MCU_GetMCU2Data()->mcuTemp, - .dcMainWireOverVoltFault = MCU_GetMCU2Data()->dcMainWireOverVoltFault, - .dcMainWireOverCurrFault = MCU_GetMCU2Data()->dcMainWireOverCurrFault, + .dcMainWireOverVoltFault = + MCU_GetMCU2Data()->dcMainWireOverVoltFault, + .dcMainWireOverCurrFault = + MCU_GetMCU2Data()->dcMainWireOverCurrFault, .motorOverSpdFault = MCU_GetMCU2Data()->motorOverSpdFault, .motorPhaseCurrFault = MCU_GetMCU2Data()->motorPhaseCurrFault, @@ -75,13 +79,14 @@ void threadTelemetry(void *pvParameters){ }; taskEXIT_CRITICAL(); - uint8_t* serializedData = (uint8_t*) &telemetryData; + uint8_t *serializedData = (uint8_t *)&telemetryData; CAN_ISOTP_Send(TELEMETRY_CAN_ID, serializedData, sizeof(TelemetryData)); - vTaskDelayUntil(&lastWakeTime, pdMS_TO_TICKS(TELEMETRY_PERIOD_MS)); // Delay until the next telemetry update + vTaskDelayUntil( + &lastWakeTime, + pdMS_TO_TICKS( + TELEMETRY_PERIOD_MS)); // Delay until the next telemetry update } } -TelemetryData const* Telemetry_GetData() { - return &telemetryData; -} +TelemetryData const *Telemetry_GetData() { return &telemetryData; } diff --git a/fsae-vehicle-fw/src/vehicle/telemetry.h b/fsae-vehicle-fw/src/vehicle/telemetry.h index 1584c30..9617d15 100644 --- a/fsae-vehicle-fw/src/vehicle/telemetry.h +++ b/fsae-vehicle-fw/src/vehicle/telemetry.h @@ -3,11 +3,11 @@ #include -#include "vehicle/motor.h" #include "peripherals/adc.h" #include "vehicle/ifl100-36.h" +#include "vehicle/motor.h" -typedef struct __attribute__((packed)){ +typedef struct __attribute__((packed)) { float APPS_Travel; // APPS travel in % // float BSEFront_PSI; // front brake pressure in PSI @@ -16,58 +16,57 @@ typedef struct __attribute__((packed)){ // float accumulatorVoltage; // float accumulatorTemp_F; - // Motor state + // Motor state // MCU1 data - float motorSpeed; // Motor speed in RPM - float motorTorque; // Motor torque in Nm + float motorSpeed; // Motor speed in RPM + float motorTorque; // Motor torque in Nm float maxMotorTorque; // Max motor torque in Nm - // float maxMotorBrakeTorque; // Max motor brake torque in Nm + // float maxMotorBrakeTorque; // Max motor brake torque in Nm MotorRotateDirection motorDirection; // Motor direction MotorState motorState; MCUMainState mcuMainState; // Motor main state - MCUWorkMode mcuWorkMode; // MCU work mode + MCUWorkMode mcuWorkMode; // MCU work mode float mcuVoltage; float mcuCurrent; // MCU2 data int32_t motorTemp; // Motor temperature in C - int32_t mcuTemp; // Inverter temperature in C + int32_t mcuTemp; // Inverter temperature in C bool dcMainWireOverVoltFault; // DC over voltage fault bool dcMainWireOverCurrFault; // DC main wire over voltage fault - bool motorOverSpdFault; // MCU motor over speed fault - // bool phaseCurrSensorFault; // Phase current sensor fault - + bool motorOverSpdFault; // MCU motor over speed fault + // bool phaseCurrSensorFault; // Phase current sensor fault bool motorPhaseCurrFault; // MCU motor phase current fault // bool mcuOverHotFault; // MCU overheat fault // bool resolverFault; // Resolver fault -// bool phaseCurrSensorFault; // Phase current sensor fault -// bool motorOverSpdFault; // MCU motor over speed fault -// bool drvMotorOverHotFault; // Driver motor overheat fault -// // bool dcMainWireOverCurrFault; // DC main wire over voltage fault -// bool drvMotorOverCoolFault; // Driver motor overcool fault -// bool mcuMotorSystemState; // MCU motor system state -// bool mcuTempSensorState; // MCU temperature sensor state -// bool motorTempSensorState; // MCU motor temperature sensor state -// bool dcVoltSensorState; // MCU DC voltage sensor state -// bool dcLowVoltWarning; // MCU DC low voltage warning -// bool mcu12VLowVoltWarning; // MCU 12V low voltage warning + // bool phaseCurrSensorFault; // Phase current sensor fault + // bool motorOverSpdFault; // MCU motor over speed fault + // bool drvMotorOverHotFault; // Driver motor overheat fault + // // bool dcMainWireOverCurrFault; // DC main wire over voltage fault + // bool drvMotorOverCoolFault; // Driver motor overcool fault + // bool mcuMotorSystemState; // MCU motor system state + // bool mcuTempSensorState; // MCU temperature sensor state + // bool motorTempSensorState; // MCU motor temperature sensor state + // bool dcVoltSensorState; // MCU DC voltage sensor state + // bool dcLowVoltWarning; // MCU DC low voltage warning + // bool mcu12VLowVoltWarning; // MCU 12V low voltage warning bool motorStallFault; // MCU motor stall fault -// bool motorOpenPhaseFault; // MCU motor open phase fault + // bool motorOpenPhaseFault; // MCU motor open phase fault MCUWarningLevel mcuWarningLevel; // MCU warning level // MCU3 data - //float mcuVoltage; // DC main wire voltage in V - //float mcuCurrent; // DC main wire current in A - // float motorPhaseCurr; // Motor phase current in A + // float mcuVoltage; // DC main wire voltage in V + // float mcuCurrent; // DC main wire current in A + // float motorPhaseCurr; // Motor phase current in A float debug[4]; // Debug data } TelemetryData; void Telemetry_Init(); void threadTelemetry(void *pvParameters); -TelemetryData const* Telemetry_GetData(); +TelemetryData const *Telemetry_GetData(); diff --git a/fsae-vehicle-fw/src/vehicle/thermal.cpp b/fsae-vehicle-fw/src/vehicle/thermal.cpp index e177a49..1c78873 100644 --- a/fsae-vehicle-fw/src/vehicle/thermal.cpp +++ b/fsae-vehicle-fw/src/vehicle/thermal.cpp @@ -1,9 +1,9 @@ -#include #include "vehicle/telemetry.h" +#include #define DUTY_CYCLE_MAX 255 #define ANALOG_WRITE_FREQUENCY 25000 // 25 kHz for Koolance -#define ANALOG_WRITE_RESOLUTION 8 // 8-bit resolution (0-255) +#define ANALOG_WRITE_RESOLUTION 8 // 8-bit resolution (0-255) #define PUMP_PIN 12 // Define the PWM pin for the pump #define FAN_PIN 7 @@ -11,31 +11,38 @@ #define TEMP_THRESHOLD 30 // Temperature threshold in degrees Celsius void thermal_Init() { - pinMode(PUMP_PIN, OUTPUT); - analogWriteFrequency(PUMP_PIN, ANALOG_WRITE_FREQUENCY); // 25 kHz for Koolance - analogWriteResolution(ANALOG_WRITE_RESOLUTION); // 0-255 - - pinMode(FAN_PIN, OUTPUT); - analogWriteFrequency(FAN_PIN, ANALOG_WRITE_FREQUENCY); // 25 kHz for Koolance - analogWriteResolution(ANALOG_WRITE_RESOLUTION); // 0-255 + pinMode(PUMP_PIN, OUTPUT); + analogWriteFrequency(PUMP_PIN, + ANALOG_WRITE_FREQUENCY); // 25 kHz for Koolance + analogWriteResolution(ANALOG_WRITE_RESOLUTION); // 0-255 + + pinMode(FAN_PIN, OUTPUT); + analogWriteFrequency(FAN_PIN, + ANALOG_WRITE_FREQUENCY); // 25 kHz for Koolance + analogWriteResolution(ANALOG_WRITE_RESOLUTION); // 0-255 } -void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, uint32_t rawReading3, uint32_t rawReading4) { - // Assuming rawReading1 and rawReading2 are the temperature readings from the sensors - // Convert raw readings to temperature in degrees Celsius +void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, + uint32_t rawReading3, uint32_t rawReading4) { + // Assuming rawReading1 and rawReading2 are the temperature readings from + // the sensors Convert raw readings to temperature in degrees Celsius int32_t temp1 = (rawReading1); int32_t temp2 = (rawReading2); // int32_t temp3 = (rawReading3); // int32_t temp4 = (rawReading4); // Check if the MCU temperature exceeds the threshold if (temp1 > TEMP_THRESHOLD || temp2 > TEMP_THRESHOLD) { - // If the MCU temperature exceeds the threshold, turn on the pump and fan - analogWrite(PUMP_PIN, DUTY_CYCLE_MAX * 0.9); // Set pump to full duty cycle - analogWrite(FAN_PIN, DUTY_CYCLE_MAX * 0.9); // Set fan to full duty cycle + // If the MCU temperature exceeds the threshold, turn on the pump and + // fan + analogWrite(PUMP_PIN, + DUTY_CYCLE_MAX * 0.9); // Set pump to full duty cycle + analogWrite(FAN_PIN, + DUTY_CYCLE_MAX * 0.9); // Set fan to full duty cycle } else { - // If the MCU temperature is below the threshold, turn off the pump and fan + // If the MCU temperature is below the threshold, turn off the pump and + // fan analogWrite(PUMP_PIN, 0); // Set pump to 0 duty cycle - analogWrite(FAN_PIN, 0); // Set fan to 0 duty cycle + analogWrite(FAN_PIN, 0); // Set fan to 0 duty cycle } // Debugging output // Serial.print("Temp1: "); @@ -43,6 +50,4 @@ void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, uint32_t rawRead // Serial.print(" C | Temp2: "); // Serial.print(temp2); // Serial.println(" C"); - } - diff --git a/fsae-vehicle-fw/src/vehicle/thermal.h b/fsae-vehicle-fw/src/vehicle/thermal.h index 2b3dfe6..88d95be 100644 --- a/fsae-vehicle-fw/src/vehicle/thermal.h +++ b/fsae-vehicle-fw/src/vehicle/thermal.h @@ -2,4 +2,5 @@ #include void thermal_Init(); -void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, uint32_t rawReading3, uint32_t rawReading4); +void thermal_Update(uint32_t rawReading1, uint32_t rawReading2, + uint32_t rawReading3, uint32_t rawReading4); From 79e1f6f9ccbf30a6d5bf9c803c571097de2af5dd Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 12 Nov 2025 17:20:47 -0800 Subject: [PATCH 24/30] fix pcc formatting --- fsae-pcc/src/can.cpp | 16 ++-- fsae-pcc/src/can.h | 4 +- fsae-pcc/src/gpio.cpp | 6 +- fsae-pcc/src/gpio.h | 2 +- fsae-pcc/src/main.cpp | 41 +++++---- fsae-pcc/src/precharge.cpp | 184 ++++++++++++++++++++----------------- fsae-pcc/src/precharge.h | 10 +- fsae-pcc/src/utils.h | 3 +- 8 files changed, 144 insertions(+), 122 deletions(-) diff --git a/fsae-pcc/src/can.cpp b/fsae-pcc/src/can.cpp index 5943305..26788f5 100644 --- a/fsae-pcc/src/can.cpp +++ b/fsae-pcc/src/can.cpp @@ -11,11 +11,11 @@ #define PCC_CAN_ID 0x123 typedef struct __attribute__((packed)) { - //uint32_t timestamp; // Timestamp in milliseconds - uint8_t state; // Precharge state + // uint32_t timestamp; // Timestamp in milliseconds + uint8_t state; // Precharge state uint8_t errorCode; // Error code - //float accumulatorVoltage; // Accumulator voltage in volts - //float tsVoltage; // Transmission side voltage in volts + // float accumulatorVoltage; // Accumulator voltage in volts + // float tsVoltage; // Transmission side voltage in volts float prechargeProgress; // Precharge progress in percent } PCC; @@ -34,10 +34,12 @@ void CAN_Init() { pccMsg.id = PCC_CAN_ID; // can change ID } -void CAN_SendPCCMessage(uint32_t timestamp, uint8_t state, uint8_t errorCode, float accumulatorVoltage, float tsVoltage, float prechargeProgress) { +void CAN_SendPCCMessage(uint32_t timestamp, uint8_t state, uint8_t errorCode, + float accumulatorVoltage, float tsVoltage, + float prechargeProgress) { pccData = { //.timestamp = timestamp, 4 bytes - .state = state, // 1 bytes + .state = state, // 1 bytes .errorCode = errorCode, // 1 bytes //.accumulatorVoltage = accumulatorVoltage, 4 bytes //.tsVoltage = tsVoltage, 4 bytes @@ -60,4 +62,4 @@ void CAN_SendPCCMessage(uint32_t timestamp, uint8_t state, uint8_t errorCode, fl memcpy(pccMsg.buf, &pccData, sizeof(PCC)); can1.write(pccMsg); -} \ No newline at end of file +} diff --git a/fsae-pcc/src/can.h b/fsae-pcc/src/can.h index 1ebff2a..c08f824 100644 --- a/fsae-pcc/src/can.h +++ b/fsae-pcc/src/can.h @@ -5,4 +5,6 @@ #include void CAN_Init(); -void CAN_SendPCCMessage(uint32_t timestamp, uint8_t state, uint8_t errorCode, float accumulatorVoltage, float tsVoltage, float prechargeProgress); \ No newline at end of file +void CAN_SendPCCMessage(uint32_t timestamp, uint8_t state, uint8_t errorCode, + float accumulatorVoltage, float tsVoltage, + float prechargeProgress); diff --git a/fsae-pcc/src/gpio.cpp b/fsae-pcc/src/gpio.cpp index d0533f4..dad0059 100644 --- a/fsae-pcc/src/gpio.cpp +++ b/fsae-pcc/src/gpio.cpp @@ -1,11 +1,11 @@ // Anteater Electric Racing, 2025 -#include #include "gpio.h" #include "utils.h" +#include -void gpioInit(void){ +void gpioInit(void) { pinMode(SHUTDOWN_CTRL_PIN, INPUT); pinMode(FREQ_ACCU_PIN, INPUT); pinMode(FREQ_TS_PIN, INPUT); -} \ No newline at end of file +} diff --git a/fsae-pcc/src/gpio.h b/fsae-pcc/src/gpio.h index 9931ddb..220f717 100644 --- a/fsae-pcc/src/gpio.h +++ b/fsae-pcc/src/gpio.h @@ -2,4 +2,4 @@ #pragma once -void gpioInit(void); \ No newline at end of file +void gpioInit(void); diff --git a/fsae-pcc/src/main.cpp b/fsae-pcc/src/main.cpp index 8c8571e..70d61e4 100644 --- a/fsae-pcc/src/main.cpp +++ b/fsae-pcc/src/main.cpp @@ -11,17 +11,19 @@ #include #include -#include "precharge.h" + +#include "can.h" #include "gpio.h" +#include "precharge.h" #include "utils.h" -#include "can.h" static void threadMain(void *pvParameters); void setup() { Serial.begin(9600); - xTaskCreate(threadMain, "threadMain", THREAD_MAIN_STACK_SIZE, NULL, THREAD_MAIN_PRIORITY, NULL); + xTaskCreate(threadMain, "threadMain", THREAD_MAIN_STACK_SIZE, NULL, + THREAD_MAIN_PRIORITY, NULL); gpioInit(); // Initialize GPIO pins @@ -48,21 +50,21 @@ void threadMain(void *pvParameters) { Serial.print("State: "); switch (state) { - case STATE_STANDBY: - Serial.print("STANDBY"); - break; - case STATE_PRECHARGE: - Serial.print("PRECHARGE"); - break; - case STATE_ONLINE: - Serial.print("ONLINE"); - break; - case STATE_ERROR: - Serial.print("ERROR"); - break; - default: - Serial.print("UNDEFINED"); - break; + case STATE_STANDBY: + Serial.print("STANDBY"); + break; + case STATE_PRECHARGE: + Serial.print("PRECHARGE"); + break; + case STATE_ONLINE: + Serial.print("ONLINE"); + break; + case STATE_ERROR: + Serial.print("ERROR"); + break; + default: + Serial.print("UNDEFINED"); + break; } Serial.print(" | Accumulator Voltage: "); Serial.print(accumulator_voltage, 4); @@ -76,5 +78,4 @@ void threadMain(void *pvParameters) { } } -void loop() { -} +void loop() {} diff --git a/fsae-pcc/src/precharge.cpp b/fsae-pcc/src/precharge.cpp index 448c43d..fdca64c 100644 --- a/fsae-pcc/src/precharge.cpp +++ b/fsae-pcc/src/precharge.cpp @@ -3,10 +3,11 @@ #include #include #include -#include "semphr.h" + +#include "can.h" #include "precharge.h" +#include "semphr.h" #include "utils.h" -#include "can.h" #define PRECHARGE_STACK_SIZE 512 #define PRECHARGE_PRIORITY 1 @@ -25,65 +26,72 @@ static double prechargeProgress = 0.0F; typedef struct { float tsAlpha; float accumAlpha; - float filtered_TSF; // filtered tractive system Frequency - float filtered_ACF; // filtered Accumulator Frequency + float filtered_TSF; // filtered tractive system Frequency + float filtered_ACF; // filtered Accumulator Frequency } LowPassFilter; static LowPassFilter lpfValues = {0.0F, 0.0F, 0.0F}; static void prechargeTask(void *pvParameters); -float getFrequency(int pin){ +float getFrequency(int pin) { const unsigned int TIMEOUT = 700; - unsigned int tHigh = pulseIn(pin, 1, TIMEOUT); // microseconds + unsigned int tHigh = pulseIn(pin, 1, TIMEOUT); // microseconds unsigned int tLow = pulseIn(pin, 0, TIMEOUT); - if (tHigh == 0 || tLow == 0){ + if (tHigh == 0 || tLow == 0) { return 0; // timed out } - return ( 1000000.0 / (float)(tHigh + tLow) ); // f = 1/T + return (1000000.0 / (float)(tHigh + tLow)); // f = 1/T } -float getVoltage(int pin){ +float getVoltage(int pin) { float rawFreq = getFrequency(pin); float voltage = 0.0F; switch (pin) { - case ACCUMULATOR_VOLTAGE_PIN: - if (lpfValues.filtered_ACF == 0.0 && rawFreq != 0.0){ - lpfValues.filtered_ACF = FREQ_TO_VOLTAGE(rawFreq); - break; - } - if(rawFreq == 0.0F) rawFreq = lpfValues.filtered_ACF; - LOWPASS_FILTER(rawFreq, lpfValues.filtered_ACF, lpfValues.accumAlpha); - voltage = FREQ_TO_VOLTAGE(lpfValues.filtered_ACF); // Convert frequency to voltage - break; - case TS_VOLTAGE_PIN: - if(rawFreq == 0.0F) rawFreq = lpfValues.filtered_TSF; - LOWPASS_FILTER(rawFreq, lpfValues.filtered_TSF, lpfValues.tsAlpha); - voltage = FREQ_TO_VOLTAGE(lpfValues.filtered_TSF); // Convert frequency to voltage + case ACCUMULATOR_VOLTAGE_PIN: + if (lpfValues.filtered_ACF == 0.0 && rawFreq != 0.0) { + lpfValues.filtered_ACF = FREQ_TO_VOLTAGE(rawFreq); break; - default: - Serial.println("Error: Invalid pin for voltage measurement."); - return 0.0F; // Handle error + } + if (rawFreq == 0.0F) + rawFreq = lpfValues.filtered_ACF; + LOWPASS_FILTER(rawFreq, lpfValues.filtered_ACF, lpfValues.accumAlpha); + voltage = FREQ_TO_VOLTAGE( + lpfValues.filtered_ACF); // Convert frequency to voltage + break; + case TS_VOLTAGE_PIN: + if (rawFreq == 0.0F) + rawFreq = lpfValues.filtered_TSF; + LOWPASS_FILTER(rawFreq, lpfValues.filtered_TSF, lpfValues.tsAlpha); + voltage = FREQ_TO_VOLTAGE( + lpfValues.filtered_TSF); // Convert frequency to voltage + break; + default: + Serial.println("Error: Invalid pin for voltage measurement."); + return 0.0F; // Handle error } return voltage; } // Initialize mutex and precharge task -void prechargeInit(){ +void prechargeInit() { - lpfValues.tsAlpha = COMPUTE_ALPHA(100.0F); // 100Hz cutoff frequency for lowpass filter - lpfValues.accumAlpha = COMPUTE_ALPHA(1.0F); // 1Hz cutoff frequency for lowpass filter + lpfValues.tsAlpha = + COMPUTE_ALPHA(100.0F); // 100Hz cutoff frequency for lowpass filter + lpfValues.accumAlpha = + COMPUTE_ALPHA(1.0F); // 1Hz cutoff frequency for lowpass filter // Create precharge task - xTaskCreate(prechargeTask, "PrechargeTask", PRECHARGE_STACK_SIZE, NULL, PRECHARGE_PRIORITY, NULL); + xTaskCreate(prechargeTask, "PrechargeTask", PRECHARGE_STACK_SIZE, NULL, + PRECHARGE_PRIORITY, NULL); Serial.println("Precharge initialized"); } // Main precharge task: handles state machine and status updates -void prechargeTask(void *pvParameters){ +void prechargeTask(void *pvParameters) { // Stores the last time the last time task was ran TickType_t xLastWakeTime; @@ -92,48 +100,50 @@ void prechargeTask(void *pvParameters){ // Get current time xLastWakeTime = xTaskGetTickCount(); - - while (true){ - accVoltage = getVoltage(ACCUMULATOR_VOLTAGE_PIN); // Get raw accumulator voltage - tsVoltage = getVoltage(TS_VOLTAGE_PIN); // Get raw tractive system voltage + while (true) { + accVoltage = + getVoltage(ACCUMULATOR_VOLTAGE_PIN); // Get raw accumulator voltage + tsVoltage = + getVoltage(TS_VOLTAGE_PIN); // Get raw tractive system voltage // taskENTER_CRITICAL(); // Ensure atomic access to state - switch(state){ - case STATE_STANDBY: - standby(); - break; - - case STATE_PRECHARGE: - precharge(); - break; + switch (state) { + case STATE_STANDBY: + standby(); + break; - case STATE_ONLINE: - running(); - break; + case STATE_PRECHARGE: + precharge(); + break; - case STATE_ERROR: - errorState(); - break; + case STATE_ONLINE: + running(); + break; - default: // Undefined state - state = STATE_ERROR; - errorCode |= ERR_STATE_UNDEFINED; - errorState(); + case STATE_ERROR: + errorState(); + break; + default: // Undefined state + state = STATE_ERROR; + errorCode |= ERR_STATE_UNDEFINED; + errorState(); } // taskEXIT_CRITICAL(); // Exit critical section // Send CAN message of current PCC state - // CAN_SendPCCMessage(millis(), state, errorCode, accVoltage, tsVoltage, prechargeProgress); + // CAN_SendPCCMessage(millis(), state, errorCode, accVoltage, tsVoltage, + // prechargeProgress); // Wait for next cycle vTaskDelayUntil(&xLastWakeTime, xFrequency); } } -// STANDBY STATE: Open AIRs, Open Precharge, indicate status, wait for stable SDC -void standby(){ -static unsigned long epoch; +// STANDBY STATE: Open AIRs, Open Precharge, indicate status, wait for stable +// SDC +void standby() { + static unsigned long epoch; if (lastState != STATE_STANDBY) { lastState = STATE_STANDBY; Serial.println(" === STANDBY "); @@ -148,15 +158,14 @@ static unsigned long epoch; // Disable AIR, Disable Precharge digitalWrite(SHUTDOWN_CTRL_PIN, LOW); - // accVoltage = getVoltage(ACCUMULATOR_VOLTAGE_PIN); // Get raw accumulator voltage - // tsVoltage = getVoltage(TS_VOLTAGE_PIN); // Get raw tractive system voltage - // Serial.print("Accumulator Voltage: "); - // Serial.print(acv); + // accVoltage = getVoltage(ACCUMULATOR_VOLTAGE_PIN); // Get raw accumulator + // voltage tsVoltage = getVoltage(TS_VOLTAGE_PIN); // Get raw tractive + // system voltage Serial.print("Accumulator Voltage: "); Serial.print(acv); // Serial.println(" V"); // Check for stable shutdown circuit if (accVoltage >= PCC_MIN_ACC_VOLTAGE) { - if (millis() > epoch + PCC_WAIT_TIME){ - state = STATE_PRECHARGE; + if (millis() > epoch + PCC_WAIT_TIME) { + state = STATE_PRECHARGE; } } else { epoch = millis(); // reset timer @@ -164,7 +173,7 @@ static unsigned long epoch; } // PRECHARGE STATE: Close AIR- and precharge relay, monitor precharge voltage -void precharge(){ +void precharge() { unsigned long now = millis(); static unsigned long epoch; static unsigned long lastTimeBelowThreshold; @@ -173,7 +182,8 @@ void precharge(){ if (lastState != STATE_PRECHARGE) { lastState = STATE_PRECHARGE; - Serial.printf(" === PRECHARGE Target precharge %4.1f%%\n", PCC_TARGET_PERCENT); + Serial.printf(" === PRECHARGE Target precharge %4.1f%%\n", + PCC_TARGET_PERCENT); epoch = now; timePrechargeStart = now; } @@ -195,9 +205,11 @@ void precharge(){ } // Check if precharge complete - if ( prechargeProgress >= PCC_TARGET_PERCENT ) { - if ((now - lastTimeBelowThreshold) > hyst){ - if (now < timePrechargeStart + PCC_MIN_TIME_MS) { // Precharge too fast - something's wrong! + if (prechargeProgress >= PCC_TARGET_PERCENT) { + if ((now - lastTimeBelowThreshold) > hyst) { + if (now < + timePrechargeStart + PCC_MIN_TIME_MS) { // Precharge too fast - + // something's wrong! state = STATE_ERROR; errorCode |= ERR_PRECHARGE_TOO_FAST; } @@ -211,13 +223,13 @@ void precharge(){ Serial.print("% "); Serial.print(tsVoltage, 1); Serial.print("V\n"); - } - - + } } } else { - if (now > timePrechargeStart + PCC_MAX_TIME_MS) { // Precharge too slow - something's wrong! + if (now > + timePrechargeStart + + PCC_MAX_TIME_MS) { // Precharge too slow - something's wrong! Serial.print(" * Precharge time: "); Serial.print(now - timePrechargeStart); Serial.print("\n"); @@ -229,8 +241,9 @@ void precharge(){ } } -// ONLINE STATE: Close AIR+ to connect ACC to TS, Open Precharge relay, indicate status -void running(){ +// ONLINE STATE: Close AIR+ to connect ACC to TS, Open Precharge relay, indicate +// status +void running() { if (lastState != STATE_ONLINE) { lastState = STATE_ONLINE; Serial.println(" === ONLINE"); @@ -242,41 +255,44 @@ void running(){ } // ERROR STATE: Indicate error, open AIRs and precharge relay -void errorState(){ +void errorState() { digitalWrite(SHUTDOWN_CTRL_PIN, LOW); - if (lastState != STATE_ERROR){ + if (lastState != STATE_ERROR) { lastState = STATE_ERROR; Serial.println(" === ERROR"); // Display errors: Serial and Status LEDs - if (errorCode == ERR_NONE){ - Serial.println(" *Error state, but no error code logged..."); + if (errorCode == ERR_NONE) { + Serial.println(" *Error state, but no error code logged..."); } if (errorCode & ERR_PRECHARGE_TOO_FAST) { - Serial.println(" *Precharge too fast. Suspect wiring fault / chatter in shutdown circuit."); + Serial.println(" *Precharge too fast. Suspect wiring fault / " + "chatter in shutdown circuit."); } if (errorCode & ERR_PRECHARGE_TOO_SLOW) { - Serial.println(" *Precharge too slow. Potential causes:\n - Wiring fault\n - Discharge is stuck-on\n - Target precharge percent is too high"); + Serial.println(" *Precharge too slow. Potential causes:\n - " + "Wiring fault\n - Discharge is stuck-on\n - " + "Target precharge percent is too high"); } if (errorCode & ERR_STATE_UNDEFINED) { - Serial.println(" *State not defined in The State Machine."); + Serial.println(" *State not defined in The State Machine."); } } } -float getTSVoltage(){ +float getTSVoltage() { // Get the tractive system voltage return tsVoltage; } -float getAccumulatorVoltage(){ +float getAccumulatorVoltage() { // Get the accumulator voltage return accVoltage; } // Return current precharge state -PrechargeState getPrechargeState(){ +PrechargeState getPrechargeState() { PrechargeState currentPrechargeState; taskENTER_CRITICAL(); // Ensure atomic access to state @@ -287,7 +303,7 @@ PrechargeState getPrechargeState(){ } // Obtain current error information -int getPrechargeError(){ +int getPrechargeError() { int currentPrechargeError; taskENTER_CRITICAL(); // Ensure atomic access to error code diff --git a/fsae-pcc/src/precharge.h b/fsae-pcc/src/precharge.h index c78714d..646c67f 100644 --- a/fsae-pcc/src/precharge.h +++ b/fsae-pcc/src/precharge.h @@ -7,13 +7,14 @@ #define TS_VOLTAGE_PIN 15 #define PCC_RATIO .9 - -#define PCC_MIN_TIME_MS 8200U // [ms] Minimum time to wait for precharge to complete -#define PCC_MAX_TIME_MS 9200U // [ms] Maximum time to wait for precharge to complete +#define PCC_MIN_TIME_MS \ + 8200U // [ms] Minimum time to wait for precharge to complete +#define PCC_MAX_TIME_MS \ + 9200U // [ms] Maximum time to wait for precharge to complete #define PCC_TARGET_PERCENT 90U // Target precharge percent #define PCC_SETTLING_TIME 200U // [ms] Time to wait for precharge to settle #define PCC_MIN_ACC_VOLTAGE 1U // [V] Minimum voltage for shutdown circuit -#define PCC_WAIT_TIME 200U // [ms] Time to wait for stable voltage +#define PCC_WAIT_TIME 200U // [ms] Time to wait for stable voltage enum PrechargeState { STATE_STANDBY, @@ -28,7 +29,6 @@ enum { ERR_PRECHARGE_TOO_FAST = 0b00000001, ERR_PRECHARGE_TOO_SLOW = 0b00000010, - ERR_STATE_UNDEFINED = 0b10000000, }; diff --git a/fsae-pcc/src/utils.h b/fsae-pcc/src/utils.h index 5e18a2e..6a438a7 100644 --- a/fsae-pcc/src/utils.h +++ b/fsae-pcc/src/utils.h @@ -17,7 +17,8 @@ // Lowpass filter #define TIME_STEP 0.001F // 1ms time step -#define COMPUTE_ALPHA(CUTOFF_HZ) (1.0F / (1.0F + (1.0F / (2.0F * M_PI * CUTOFF_HZ)) / TIME_STEP)) +#define COMPUTE_ALPHA(CUTOFF_HZ) \ + (1.0F / (1.0F + (1.0F / (2.0F * M_PI * CUTOFF_HZ)) / TIME_STEP)) #define LOWPASS_FILTER(NEW, OLD, ALPHA) OLD = ALPHA * NEW + (1.0F - ALPHA) * OLD #define Rs 12000 From a8d810f6dbc6c23d672196fc98a630bb231bfba5 Mon Sep 17 00:00:00 2001 From: Karan Date: Wed, 12 Nov 2025 17:24:08 -0800 Subject: [PATCH 25/30] ifl100-36.h file formatted correctly --- fsae-vehicle-fw/src/vehicle/ifl100-36.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/fsae-vehicle-fw/src/vehicle/ifl100-36.h b/fsae-vehicle-fw/src/vehicle/ifl100-36.h index 450a1e9..8fb681b 100644 --- a/fsae-vehicle-fw/src/vehicle/ifl100-36.h +++ b/fsae-vehicle-fw/src/vehicle/ifl100-36.h @@ -121,13 +121,10 @@ typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) { uint64_t MCU_DC_MainWireVolt : 16; // end of byte 0 and byte 1 - // uint64_t dummystop : 8; - uint64_t MCU_DC_MainWireCurr - : 16; // end of byte 2 and byte 3 --> should be byte 3 and 4 - uint64_t MCU_MotorPhaseCurr - : 16; // end of byte 4 and byte 5 ---> 6 and 7? or 5 and 6 - uint64_t Reserved : 16; // end of byte 6 and byte 7 -} MCU3; // bit order verified + uint64_t MCU_DC_MainWireCurr : 16; // end of byte 2 and byte 3 + uint64_t MCU_MotorPhaseCurr : 16; // end of byte 4 and byte 5 + uint64_t Reserved : 16; // end of byte 6 and byte 7 +} MCU3; // bit order verified typedef struct __attribute__((packed)) { uint64_t BMS_Warning_Level : 2; From 25559bf79a12213537c540b50531ece41718f5a4 Mon Sep 17 00:00:00 2001 From: Natalie Perrochon Date: Mon, 17 Nov 2025 20:28:18 -0800 Subject: [PATCH 26/30] BUGFIX: Reverted include order to compile correctly The previous order was resulting in "constrain not defined" error, this should fix that issue --- fsae-vehicle-fw/src/peripherals/can.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsae-vehicle-fw/src/peripherals/can.cpp b/fsae-vehicle-fw/src/peripherals/can.cpp index 6e6f79b..b5d77b5 100644 --- a/fsae-vehicle-fw/src/peripherals/can.cpp +++ b/fsae-vehicle-fw/src/peripherals/can.cpp @@ -3,9 +3,9 @@ #define THREAD_CAN_STACK_SIZE 128 #define THREAD_CAN_PRIORITY 1 +#include #include #include -#include #include #include "peripherals/can.h" From 24983e79d6f53cbec67d08c06b32ae9adeb57a38 Mon Sep 17 00:00:00 2001 From: Anoop Koganti Date: Fri, 26 Dec 2025 16:46:22 -0800 Subject: [PATCH 27/30] Debugging APPS Added some lines to Utils.h and tinkered around with APPS code aswell. Slight fixes towards adc code as well as APPS header. Comments written where changes were implemented. (Anoop && Dylan) --- fsae-vehicle-fw/src/peripherals/adc.cpp | 20 ++- fsae-vehicle-fw/src/utils/utils.h | 36 +++++- fsae-vehicle-fw/src/vehicle/apps.cpp | 160 ++++++++++++++++-------- fsae-vehicle-fw/src/vehicle/apps.h | 2 +- 4 files changed, 156 insertions(+), 62 deletions(-) diff --git a/fsae-vehicle-fw/src/peripherals/adc.cpp b/fsae-vehicle-fw/src/peripherals/adc.cpp index 5148208..46ee2ea 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.cpp +++ b/fsae-vehicle-fw/src/peripherals/adc.cpp @@ -16,8 +16,8 @@ enum SensorIndexesADC0 { // TODO: Update with real values THERMISTOR_1_INDEX = 0, // A0 - APPS_1_INDEX = 5, - APPS_2_INDEX = 6, // A6 + APPS_1_INDEX = 4, + APPS_2_INDEX = 5, // A5 BSE_1_INDEX = 3, BSE_2_INDEX = 2, SUSP_TRAV_LINPOT1, @@ -42,7 +42,7 @@ enum SensorIndexesADC1 { // TODO: Update with real values uint16_t adc0Pins[SENSOR_PIN_AMT_ADC0] = { A0, A1, A2, A3, A4, A5, - A6, A7, A15, A16, A17}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, + A6, A7, A9, A16, A17}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, // 24, 25, 19, 18, 14, 15, 17}; uint16_t adc0Reads[SENSOR_PIN_AMT_ADC0]; @@ -89,7 +89,7 @@ void threadADC(void *pvParameters) { for (uint16_t currentIndexADC0 = 0; currentIndexADC0 < SENSOR_PIN_AMT_ADC0; ++currentIndexADC0) { uint16_t currentPinADC0 = adc0Pins[currentIndexADC0]; - uint16_t adcRead = adc->adc1->analogRead(currentPinADC0); + uint16_t adcRead = adc->adc0->analogRead(currentPinADC0); adc0Reads[currentIndexADC0] = adcRead; } @@ -100,6 +100,18 @@ void threadADC(void *pvParameters) { adc1Reads[currentIndexADC1] = adcRead; } + // Serial.print("ADC0 Reads: "); + // for (int i = 0; i < SENSOR_PIN_AMT_ADC0; i++) { + // Serial.print(adc0Reads[i]); + // Serial.print(" "); + // } + // Serial.println(); + // Serial.print("ADC1 Reads: "); + // for (int i = 0; i < SENSOR_PIN_AMT_ADC1; i++) { + // Serial.print(adc1Reads[i]); + // Serial.print(" "); + // } + // Serial.println(); // Update each sensors data APPS_UpdateData(adc0Reads[APPS_1_INDEX], adc0Reads[APPS_2_INDEX]); BSE_UpdateData(adc0Reads[BSE_1_INDEX], adc0Reads[BSE_2_INDEX]); diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index b648f7d..f1a62c3 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -3,7 +3,7 @@ #pragma once #define DEBUG_FLAG 0 -#define HIMAC_FLAG 1 +#define HIMAC_FLAG 0 #define THREAD_MAIN_STACK_SIZE 128 #define THREAD_MAIN_PRIORITY 1 @@ -26,9 +26,10 @@ #define ADC_MAX_VALUE ((1 << ADC_RESOLUTION) - 1) #define TICKTYPE_FREQUENCY 1 -#define ADC_VOLTAGE_DIVIDER 2.0F +#define ADC_VOLTAGE_DIVIDER 1.515151F + #define ADC_VALUE_TO_VOLTAGE(x) \ - ((x) * (LOGIC_LEVEL_V / ADC_MAX_VALUE)) * ADC_VOLTAGE_DIVIDER + ((x) * (LOGIC_LEVEL_V * ADC_VOLTAGE_DIVIDER / ADC_MAX_VALUE)) #define APPS_FAULT_PERCENT_MIN .1 #define APPS_FAULT_PERCENT_MAX .9 @@ -45,6 +46,35 @@ #define APPS_5V_MIN (APPS2_VOLTAGE_LEVEL * APPS_RANGE_MIN_PERCENT) #define APPS_5V_MAX (APPS2_VOLTAGE_LEVEL * APPS_RANGE_MAX_PERCENT) + +/* ANOOP TESTING FOR 20% HERE */ + +// --- APPS 0-20% -> 0-100% scaling --- + +// ADC values corresponding to physical 20% pedal (your "new max") +#define APPS1_20PCT_ADC 784.0F +#define APPS2_20PCT_ADC 1150.0F + +// Measured resting ADC (change these once you log them) +#define APPS1_REST_ADC 117.75F +#define APPS2_REST_ADC 172.5F + +// Clamp helper (if you don't already have it) +#define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : ((x) > (hi) ? (hi) : (x))) +#define CLAMP01(x) CLAMP((x), 0.0F, 1.0F) + +// Convert raw ADC -> commanded percent using only 0-20% physical range +#define APPS_ADC_TO_CMD_PERCENT(adc, rest_adc, adc_20) \ + CLAMP01( ((float)(adc) - (float)(rest_adc)) / ((float)(adc_20) - (float)(rest_adc)) ) + + + + +/* END ANOOP TESTING FOR 20% HERE */ + + + + #define APPS_3V3_FAULT_MIN (APPS1_VOLTAGE_LEVEL * APPS_FAULT_PERCENT_MIN) #define APPS_3V3_FAULT_MAX (APPS1_VOLTAGE_LEVEL * APPS_FAULT_PERCENT_MAX) diff --git a/fsae-vehicle-fw/src/vehicle/apps.cpp b/fsae-vehicle-fw/src/vehicle/apps.cpp index cac3fea..9ec3bd2 100644 --- a/fsae-vehicle-fw/src/vehicle/apps.cpp +++ b/fsae-vehicle-fw/src/vehicle/apps.cpp @@ -1,18 +1,18 @@ // Anteater Electric Racing, 2025 -#include "apps.h" +#include #include "utils/utils.h" +#include "apps.h" #include "vehicle/faults.h" #include "vehicle/telemetry.h" #include -#include typedef struct { float appsReading1_Percentage; // Percentage of pedal travel (0 to 1) float appsReading2_Percentage; // Percentage of pedal travel (0 to 1) - float appsReading1_Voltage; // Voltage reading from the pedal (0 to 3.3V) - float appsReading2_Voltage; // Voltage reading from the pedal (0 to 3.3V) + float appsReading1_Voltage; // Voltage reading from the pedal (0 to 3.3V) + float appsReading2_Voltage; // Voltage reading from the pedal (0 to 5V) float apps1RawReading; float apps2RawReading; @@ -20,8 +20,7 @@ typedef struct { static APPSData appsData; static float appsAlpha; -static TickType_t appsLatestHealthyStateTime = - 0; // Set to 0 when fault not detected +static TickType_t appsLatestHealthyStateTime = 0; // Set to 0 when fault not detected static void checkAndHandleAPPSFault(); static void checkAndHandlePlausibilityFault(); @@ -39,32 +38,82 @@ void APPS_Init() { appsAlpha = COMPUTE_ALPHA(100.0F); } -void APPS_UpdateData(uint32_t rawReading1, uint32_t rawReading2) { - // Filter incoming values +void APPS_UpdateData(uint16_t rawReading1, uint16_t rawReading2) { //changed uint16 from 32 + // Serial.print("Raw APPS1: "); + // Serial.println(rawReading1); + // Serial.print("Raw APPS2: "); + // Serial.println(rawReading2); + + if (rawReading1 > APPS1_20PCT_ADC) rawReading1 = APPS1_20PCT_ADC; + if (rawReading2 > APPS2_20PCT_ADC) rawReading2 = APPS2_20PCT_ADC; + LOWPASS_FILTER(rawReading1, appsData.apps1RawReading, appsAlpha); LOWPASS_FILTER(rawReading2, appsData.apps2RawReading, appsAlpha); + + Serial.print("Raw APPS1: "); + Serial.println(appsData.apps1RawReading); + Serial.print("Raw APPS2: "); + Serial.println(appsData.apps2RawReading); + + // after LOWPASS_FILTER + appsData.appsReading1_Percentage = + LINEAR_MAP(appsData.apps1RawReading, (float)APPS1_REST_ADC, (float)APPS1_20PCT_ADC, 0.0F, 1.0F); + + appsData.appsReading2_Percentage = + LINEAR_MAP(appsData.apps2RawReading, (float)APPS2_REST_ADC, (float)APPS2_20PCT_ADC, 0.0F, 1.0F); + + // clamp since LINEAR_MAP doesn't clamp + appsData.appsReading1_Percentage = CLAMP01(appsData.appsReading1_Percentage); + appsData.appsReading2_Percentage = CLAMP01(appsData.appsReading2_Percentage); + + + // Convert ADC values to voltage - appsData.appsReading1_Voltage = - ADC_VALUE_TO_VOLTAGE(appsData.apps1RawReading); - appsData.appsReading2_Voltage = - ADC_VALUE_TO_VOLTAGE(appsData.apps2RawReading); + appsData.appsReading1_Voltage = ADC_VALUE_TO_VOLTAGE(appsData.apps1RawReading); + appsData.appsReading2_Voltage = ADC_VALUE_TO_VOLTAGE(appsData.apps2RawReading); + + Serial.print("APPS1 RAW Voltage: "); + Serial.println(appsData.appsReading1_Voltage); + Serial.print("APPS2 RAW Voltage: "); + Serial.println(appsData.appsReading2_Voltage); + + if(appsData.appsReading1_Voltage < APPS_3V3_MIN) { + appsData.appsReading1_Voltage = APPS_3V3_MIN; + } else if(appsData.appsReading1_Voltage > APPS_3V3_MAX) { + appsData.appsReading1_Voltage = APPS_3V3_MAX; + } + + if(appsData.appsReading2_Voltage < APPS_5V_MIN) { + appsData.appsReading2_Voltage = APPS_5V_MIN; + } else if(appsData.appsReading2_Voltage > APPS_5V_MAX) { + appsData.appsReading2_Voltage = APPS_5V_MAX; + } + + // Map voltage to percentage of throttle travel, limiting to 0-1 range - appsData.appsReading1_Percentage = LINEAR_MAP( - appsData.appsReading1_Voltage, APPS_3V3_MIN, APPS_3V3_MAX, 0.0F, 1.0F); - appsData.appsReading2_Percentage = LINEAR_MAP( - appsData.appsReading2_Voltage, APPS_5V_MIN, APPS_5V_MAX, 0.0F, 1.0F); + // appsData.appsReading1_Percentage = + // LINEAR_MAP(appsData.apps1RawReading, 0.0F, (float)APPS1_20PCT_ADC, 0.0F, 1.0F); + + // appsData.appsReading2_Percentage = + // LINEAR_MAP(appsData.apps2RawReading, 0.0F, (float)APPS2_20PCT_ADC, 0.0F, 1.0F); - if (appsData.appsReading1_Percentage < 0.0F) { + + // Serial.print("APPS1 raw Perc: "); + // Serial.println(appsData.appsReading1_Percentage); + // Serial.print("APPS2 raw Perc: "); + // Serial.println(appsData.appsReading2_Percentage); + + if(appsData.appsReading1_Percentage < 0.0F) { appsData.appsReading1_Percentage = 0.0F; - } else if (appsData.appsReading1_Percentage > 1.0F) { + } else if(appsData.appsReading1_Percentage > 1.0F) { appsData.appsReading1_Percentage = 1.0F; } - if (appsData.appsReading2_Percentage < 0.0F) { + if(appsData.appsReading2_Percentage < 0.0F) { appsData.appsReading2_Percentage = 0.0F; - } else if (appsData.appsReading2_Percentage > 1.0F) { + } else if(appsData.appsReading2_Percentage > 1.0F) { appsData.appsReading2_Percentage = 1.0F; } @@ -73,40 +122,43 @@ void APPS_UpdateData(uint32_t rawReading1, uint32_t rawReading2) { } float APPS_GetAPPSReading() { - return (appsData.appsReading1_Percentage + - appsData.appsReading2_Percentage) / - 2; + return (appsData.appsReading1_Percentage + appsData.appsReading2_Percentage) / 2.0; } -float APPS_GetAPPSReading1() { return appsData.appsReading1_Percentage; } +float APPS_GetAPPSReading1() { + return appsData.appsReading1_Percentage; +} -float APPS_GetAPPSReading2() { return appsData.appsReading2_Percentage; } +float APPS_GetAPPSReading2() { + return appsData.appsReading2_Percentage; +} static void checkAndHandleAPPSFault() { // Check for open/short circuit - float difference = abs(appsData.appsReading1_Percentage - - appsData.appsReading2_Percentage); - -#if DEBUG_FLAG - Serial.print("Difference is: "); - Serial.println(difference); - Serial.print("Percent APPS1: "); - Serial.println(appsData.appsReading1_Percentage); - Serial.print("Percent APPS2: "); - Serial.println(appsData.appsReading2_Percentage); -#endif - - if (appsData.appsReading1_Voltage < APPS_3V3_FAULT_MIN || - appsData.appsReading1_Voltage > APPS_3V3_FAULT_MAX || - appsData.appsReading2_Voltage < APPS_5V_FAULT_MIN || - appsData.appsReading2_Voltage > APPS_5V_FAULT_MAX) { + float difference = abs(appsData.appsReading1_Percentage - appsData.appsReading2_Percentage); + + //# if DEBUG_FLAG + Serial.print("Difference is: "); + Serial.println(difference); + Serial.print("Percent APPS1: "); + Serial.println(appsData.appsReading1_Percentage); + Serial.print("Percent APPS2: "); + Serial.println(appsData.appsReading2_Percentage); + //# endif + + if(appsData.appsReading1_Voltage < APPS_3V3_FAULT_MIN || + appsData.appsReading1_Voltage > APPS_3V3_FAULT_MAX || + appsData.appsReading2_Voltage < APPS_5V_FAULT_MIN || + appsData.appsReading2_Voltage > APPS_5V_FAULT_MAX) { + TickType_t now = xTaskGetTickCount(); TickType_t elapsedTicks = now - appsLatestHealthyStateTime; TickType_t elapsedMs = elapsedTicks * portTICK_PERIOD_MS; - if (elapsedMs > APPS_FAULT_TIME_THRESHOLD_MS) { -#if DEBUG_FLAG - Serial.println("Setting APPS fault"); -#endif + + if (elapsedMs > APPS_FAULT_TIME_THRESHOLD_MS){ + # if DEBUG_FLAG + Serial.println("Setting APPS fault"); + # endif Faults_SetFault(FAULT_APPS); return; } @@ -119,9 +171,9 @@ static void checkAndHandleAPPSFault() { Faults_SetFault(FAULT_APPS); return; } else { -#if DEBUG_FLAG - Serial.println("Clearing fault in handle"); -#endif + # if DEBUG_FLAG + Serial.println("Clearing fault in handle"); + # endif Faults_ClearFault(FAULT_APPS); } } @@ -131,20 +183,20 @@ static void checkAndHandlePlausibilityFault() { float BSEReading_Rear = BSE_GetBSEReading()->bseRear_PSI; float BSEReading = BSEReading_Front; - if (BSEReading_Rear > BSEReading_Front) { + if (BSEReading_Rear > BSEReading_Front){ BSEReading = BSEReading_Rear; } -#if DEBUG_FLAG - Serial.print("BSE Reading: "); - Serial.println(BSEReading); -#endif + # if DEBUG_FLAG + Serial.print("BSE Reading: "); + Serial.println(BSEReading); + # endif if (APPS_GetAPPSReading() > APPS_BSE_PLAUSABILITY_TROTTLE_THRESHOLD && BSEReading > APPS_BSE_PLAUSABILITY_BRAKE_THRESHOLD) { Faults_SetFault(FAULT_APPS_BRAKE_PLAUSIBILITY); } else { - if (APPS_GetAPPSReading() < APPS_BSE_PLAUSIBILITY_RESET_THRESHOLD) { + if (APPS_GetAPPSReading() < APPS_BSE_PLAUSIBILITY_RESET_THRESHOLD){ Faults_ClearFault(FAULT_APPS_BRAKE_PLAUSIBILITY); } } diff --git a/fsae-vehicle-fw/src/vehicle/apps.h b/fsae-vehicle-fw/src/vehicle/apps.h index aad7e58..5f69b02 100644 --- a/fsae-vehicle-fw/src/vehicle/apps.h +++ b/fsae-vehicle-fw/src/vehicle/apps.h @@ -3,7 +3,7 @@ #include "bse.h" void APPS_Init(); -void APPS_UpdateData(uint32_t rawReading1, uint32_t rawReading2); +void APPS_UpdateData(uint16_t rawReading1, uint16_t rawReading2); float APPS_GetAPPSReading(); float APPS_GetAPPSReading1(); float APPS_GetAPPSReading2(); From c5efb393490598d5409ce09222747c3543bd57a6 Mon Sep 17 00:00:00 2001 From: Anoop Koganti Date: Fri, 26 Dec 2025 16:49:10 -0800 Subject: [PATCH 28/30] format code --- fsae-vehicle-fw/src/peripherals/adc.cpp | 4 +- fsae-vehicle-fw/src/utils/utils.h | 14 +-- fsae-vehicle-fw/src/vehicle/apps.cpp | 135 ++++++++++++------------ 3 files changed, 76 insertions(+), 77 deletions(-) diff --git a/fsae-vehicle-fw/src/peripherals/adc.cpp b/fsae-vehicle-fw/src/peripherals/adc.cpp index 46ee2ea..bb8b49f 100644 --- a/fsae-vehicle-fw/src/peripherals/adc.cpp +++ b/fsae-vehicle-fw/src/peripherals/adc.cpp @@ -41,9 +41,9 @@ enum SensorIndexesADC1 { // TODO: Update with real values }; uint16_t adc0Pins[SENSOR_PIN_AMT_ADC0] = { - A0, A1, A2, A3, A4, A5, + A0, A1, A2, A3, A4, A5, A6, A7, A9, A16, A17}; // A4, A4, 18, 17, 17, 17, 17}; // real values: {21, - // 24, 25, 19, 18, 14, 15, 17}; + // 24, 25, 19, 18, 14, 15, 17}; uint16_t adc0Reads[SENSOR_PIN_AMT_ADC0]; uint16_t adc1Pins[SENSOR_PIN_AMT_ADC1] = { diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index f1a62c3..e43ec7c 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -26,7 +26,7 @@ #define ADC_MAX_VALUE ((1 << ADC_RESOLUTION) - 1) #define TICKTYPE_FREQUENCY 1 -#define ADC_VOLTAGE_DIVIDER 1.515151F +#define ADC_VOLTAGE_DIVIDER 1.515151F #define ADC_VALUE_TO_VOLTAGE(x) \ ((x) * (LOGIC_LEVEL_V * ADC_VOLTAGE_DIVIDER / ADC_MAX_VALUE)) @@ -46,7 +46,6 @@ #define APPS_5V_MIN (APPS2_VOLTAGE_LEVEL * APPS_RANGE_MIN_PERCENT) #define APPS_5V_MAX (APPS2_VOLTAGE_LEVEL * APPS_RANGE_MAX_PERCENT) - /* ANOOP TESTING FOR 20% HERE */ // --- APPS 0-20% -> 0-100% scaling --- @@ -64,17 +63,12 @@ #define CLAMP01(x) CLAMP((x), 0.0F, 1.0F) // Convert raw ADC -> commanded percent using only 0-20% physical range -#define APPS_ADC_TO_CMD_PERCENT(adc, rest_adc, adc_20) \ - CLAMP01( ((float)(adc) - (float)(rest_adc)) / ((float)(adc_20) - (float)(rest_adc)) ) - - - +#define APPS_ADC_TO_CMD_PERCENT(adc, rest_adc, adc_20) \ + CLAMP01(((float)(adc) - (float)(rest_adc)) / \ + ((float)(adc_20) - (float)(rest_adc))) /* END ANOOP TESTING FOR 20% HERE */ - - - #define APPS_3V3_FAULT_MIN (APPS1_VOLTAGE_LEVEL * APPS_FAULT_PERCENT_MIN) #define APPS_3V3_FAULT_MAX (APPS1_VOLTAGE_LEVEL * APPS_FAULT_PERCENT_MAX) diff --git a/fsae-vehicle-fw/src/vehicle/apps.cpp b/fsae-vehicle-fw/src/vehicle/apps.cpp index 9ec3bd2..fd3cd83 100644 --- a/fsae-vehicle-fw/src/vehicle/apps.cpp +++ b/fsae-vehicle-fw/src/vehicle/apps.cpp @@ -1,18 +1,18 @@ // Anteater Electric Racing, 2025 -#include -#include "utils/utils.h" #include "apps.h" +#include "utils/utils.h" #include "vehicle/faults.h" #include "vehicle/telemetry.h" #include +#include typedef struct { float appsReading1_Percentage; // Percentage of pedal travel (0 to 1) float appsReading2_Percentage; // Percentage of pedal travel (0 to 1) - float appsReading1_Voltage; // Voltage reading from the pedal (0 to 3.3V) - float appsReading2_Voltage; // Voltage reading from the pedal (0 to 5V) + float appsReading1_Voltage; // Voltage reading from the pedal (0 to 3.3V) + float appsReading2_Voltage; // Voltage reading from the pedal (0 to 5V) float apps1RawReading; float apps2RawReading; @@ -20,7 +20,8 @@ typedef struct { static APPSData appsData; static float appsAlpha; -static TickType_t appsLatestHealthyStateTime = 0; // Set to 0 when fault not detected +static TickType_t appsLatestHealthyStateTime = + 0; // Set to 0 when fault not detected static void checkAndHandleAPPSFault(); static void checkAndHandlePlausibilityFault(); @@ -38,19 +39,21 @@ void APPS_Init() { appsAlpha = COMPUTE_ALPHA(100.0F); } -void APPS_UpdateData(uint16_t rawReading1, uint16_t rawReading2) { //changed uint16 from 32 +void APPS_UpdateData(uint16_t rawReading1, + uint16_t rawReading2) { // changed uint16 from 32 // Serial.print("Raw APPS1: "); // Serial.println(rawReading1); // Serial.print("Raw APPS2: "); // Serial.println(rawReading2); - if (rawReading1 > APPS1_20PCT_ADC) rawReading1 = APPS1_20PCT_ADC; - if (rawReading2 > APPS2_20PCT_ADC) rawReading2 = APPS2_20PCT_ADC; + if (rawReading1 > APPS1_20PCT_ADC) + rawReading1 = APPS1_20PCT_ADC; + if (rawReading2 > APPS2_20PCT_ADC) + rawReading2 = APPS2_20PCT_ADC; LOWPASS_FILTER(rawReading1, appsData.apps1RawReading, appsAlpha); LOWPASS_FILTER(rawReading2, appsData.apps2RawReading, appsAlpha); - Serial.print("Raw APPS1: "); Serial.println(appsData.apps1RawReading); Serial.print("Raw APPS2: "); @@ -58,62 +61,65 @@ void APPS_UpdateData(uint16_t rawReading1, uint16_t rawReading2) { //changed ui // after LOWPASS_FILTER appsData.appsReading1_Percentage = - LINEAR_MAP(appsData.apps1RawReading, (float)APPS1_REST_ADC, (float)APPS1_20PCT_ADC, 0.0F, 1.0F); + LINEAR_MAP(appsData.apps1RawReading, (float)APPS1_REST_ADC, + (float)APPS1_20PCT_ADC, 0.0F, 1.0F); appsData.appsReading2_Percentage = - LINEAR_MAP(appsData.apps2RawReading, (float)APPS2_REST_ADC, (float)APPS2_20PCT_ADC, 0.0F, 1.0F); + LINEAR_MAP(appsData.apps2RawReading, (float)APPS2_REST_ADC, + (float)APPS2_20PCT_ADC, 0.0F, 1.0F); // clamp since LINEAR_MAP doesn't clamp - appsData.appsReading1_Percentage = CLAMP01(appsData.appsReading1_Percentage); - appsData.appsReading2_Percentage = CLAMP01(appsData.appsReading2_Percentage); - - + appsData.appsReading1_Percentage = + CLAMP01(appsData.appsReading1_Percentage); + appsData.appsReading2_Percentage = + CLAMP01(appsData.appsReading2_Percentage); // Convert ADC values to voltage - appsData.appsReading1_Voltage = ADC_VALUE_TO_VOLTAGE(appsData.apps1RawReading); - appsData.appsReading2_Voltage = ADC_VALUE_TO_VOLTAGE(appsData.apps2RawReading); + appsData.appsReading1_Voltage = + ADC_VALUE_TO_VOLTAGE(appsData.apps1RawReading); + appsData.appsReading2_Voltage = + ADC_VALUE_TO_VOLTAGE(appsData.apps2RawReading); Serial.print("APPS1 RAW Voltage: "); Serial.println(appsData.appsReading1_Voltage); Serial.print("APPS2 RAW Voltage: "); Serial.println(appsData.appsReading2_Voltage); - if(appsData.appsReading1_Voltage < APPS_3V3_MIN) { + if (appsData.appsReading1_Voltage < APPS_3V3_MIN) { appsData.appsReading1_Voltage = APPS_3V3_MIN; - } else if(appsData.appsReading1_Voltage > APPS_3V3_MAX) { + } else if (appsData.appsReading1_Voltage > APPS_3V3_MAX) { appsData.appsReading1_Voltage = APPS_3V3_MAX; } - if(appsData.appsReading2_Voltage < APPS_5V_MIN) { + if (appsData.appsReading2_Voltage < APPS_5V_MIN) { appsData.appsReading2_Voltage = APPS_5V_MIN; - } else if(appsData.appsReading2_Voltage > APPS_5V_MAX) { + } else if (appsData.appsReading2_Voltage > APPS_5V_MAX) { appsData.appsReading2_Voltage = APPS_5V_MAX; } - - // Map voltage to percentage of throttle travel, limiting to 0-1 range // appsData.appsReading1_Percentage = - // LINEAR_MAP(appsData.apps1RawReading, 0.0F, (float)APPS1_20PCT_ADC, 0.0F, 1.0F); + // LINEAR_MAP(appsData.apps1RawReading, 0.0F, (float)APPS1_20PCT_ADC, + // 0.0F, 1.0F); // appsData.appsReading2_Percentage = - // LINEAR_MAP(appsData.apps2RawReading, 0.0F, (float)APPS2_20PCT_ADC, 0.0F, 1.0F); - + // LINEAR_MAP(appsData.apps2RawReading, 0.0F, (float)APPS2_20PCT_ADC, + // 0.0F, 1.0F); // Serial.print("APPS1 raw Perc: "); // Serial.println(appsData.appsReading1_Percentage); // Serial.print("APPS2 raw Perc: "); // Serial.println(appsData.appsReading2_Percentage); - if(appsData.appsReading1_Percentage < 0.0F) { + if (appsData.appsReading1_Percentage < 0.0F) { appsData.appsReading1_Percentage = 0.0F; - } else if(appsData.appsReading1_Percentage > 1.0F) { + } else if (appsData.appsReading1_Percentage > 1.0F) { appsData.appsReading1_Percentage = 1.0F; } - if(appsData.appsReading2_Percentage < 0.0F) { + if (appsData.appsReading2_Percentage < 0.0F) { appsData.appsReading2_Percentage = 0.0F; - } else if(appsData.appsReading2_Percentage > 1.0F) { + } else if (appsData.appsReading2_Percentage > 1.0F) { appsData.appsReading2_Percentage = 1.0F; } @@ -122,43 +128,42 @@ void APPS_UpdateData(uint16_t rawReading1, uint16_t rawReading2) { //changed ui } float APPS_GetAPPSReading() { - return (appsData.appsReading1_Percentage + appsData.appsReading2_Percentage) / 2.0; + return (appsData.appsReading1_Percentage + + appsData.appsReading2_Percentage) / + 2.0; } -float APPS_GetAPPSReading1() { - return appsData.appsReading1_Percentage; -} +float APPS_GetAPPSReading1() { return appsData.appsReading1_Percentage; } -float APPS_GetAPPSReading2() { - return appsData.appsReading2_Percentage; -} +float APPS_GetAPPSReading2() { return appsData.appsReading2_Percentage; } static void checkAndHandleAPPSFault() { // Check for open/short circuit - float difference = abs(appsData.appsReading1_Percentage - appsData.appsReading2_Percentage); - - //# if DEBUG_FLAG - Serial.print("Difference is: "); - Serial.println(difference); - Serial.print("Percent APPS1: "); - Serial.println(appsData.appsReading1_Percentage); - Serial.print("Percent APPS2: "); - Serial.println(appsData.appsReading2_Percentage); - //# endif - - if(appsData.appsReading1_Voltage < APPS_3V3_FAULT_MIN || - appsData.appsReading1_Voltage > APPS_3V3_FAULT_MAX || - appsData.appsReading2_Voltage < APPS_5V_FAULT_MIN || - appsData.appsReading2_Voltage > APPS_5V_FAULT_MAX) { + float difference = abs(appsData.appsReading1_Percentage - + appsData.appsReading2_Percentage); + + // # if DEBUG_FLAG + Serial.print("Difference is: "); + Serial.println(difference); + Serial.print("Percent APPS1: "); + Serial.println(appsData.appsReading1_Percentage); + Serial.print("Percent APPS2: "); + Serial.println(appsData.appsReading2_Percentage); + // # endif + + if (appsData.appsReading1_Voltage < APPS_3V3_FAULT_MIN || + appsData.appsReading1_Voltage > APPS_3V3_FAULT_MAX || + appsData.appsReading2_Voltage < APPS_5V_FAULT_MIN || + appsData.appsReading2_Voltage > APPS_5V_FAULT_MAX) { TickType_t now = xTaskGetTickCount(); TickType_t elapsedTicks = now - appsLatestHealthyStateTime; TickType_t elapsedMs = elapsedTicks * portTICK_PERIOD_MS; - if (elapsedMs > APPS_FAULT_TIME_THRESHOLD_MS){ - # if DEBUG_FLAG - Serial.println("Setting APPS fault"); - # endif + if (elapsedMs > APPS_FAULT_TIME_THRESHOLD_MS) { +#if DEBUG_FLAG + Serial.println("Setting APPS fault"); +#endif Faults_SetFault(FAULT_APPS); return; } @@ -171,9 +176,9 @@ static void checkAndHandleAPPSFault() { Faults_SetFault(FAULT_APPS); return; } else { - # if DEBUG_FLAG - Serial.println("Clearing fault in handle"); - # endif +#if DEBUG_FLAG + Serial.println("Clearing fault in handle"); +#endif Faults_ClearFault(FAULT_APPS); } } @@ -183,20 +188,20 @@ static void checkAndHandlePlausibilityFault() { float BSEReading_Rear = BSE_GetBSEReading()->bseRear_PSI; float BSEReading = BSEReading_Front; - if (BSEReading_Rear > BSEReading_Front){ + if (BSEReading_Rear > BSEReading_Front) { BSEReading = BSEReading_Rear; } - # if DEBUG_FLAG - Serial.print("BSE Reading: "); - Serial.println(BSEReading); - # endif +#if DEBUG_FLAG + Serial.print("BSE Reading: "); + Serial.println(BSEReading); +#endif if (APPS_GetAPPSReading() > APPS_BSE_PLAUSABILITY_TROTTLE_THRESHOLD && BSEReading > APPS_BSE_PLAUSABILITY_BRAKE_THRESHOLD) { Faults_SetFault(FAULT_APPS_BRAKE_PLAUSIBILITY); } else { - if (APPS_GetAPPSReading() < APPS_BSE_PLAUSIBILITY_RESET_THRESHOLD){ + if (APPS_GetAPPSReading() < APPS_BSE_PLAUSIBILITY_RESET_THRESHOLD) { Faults_ClearFault(FAULT_APPS_BRAKE_PLAUSIBILITY); } } From 6be950f8905b54dcaa0167e669640e7f117ee59c Mon Sep 17 00:00:00 2001 From: Anoop Koganti Date: Fri, 26 Dec 2025 17:43:19 -0800 Subject: [PATCH 29/30] Small fixes --- fsae-vehicle-fw/src/utils/utils.h | 13 +++++++------ fsae-vehicle-fw/src/vehicle/apps.cpp | 4 +++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/fsae-vehicle-fw/src/utils/utils.h b/fsae-vehicle-fw/src/utils/utils.h index e43ec7c..0096aae 100644 --- a/fsae-vehicle-fw/src/utils/utils.h +++ b/fsae-vehicle-fw/src/utils/utils.h @@ -48,17 +48,18 @@ /* ANOOP TESTING FOR 20% HERE */ -// --- APPS 0-20% -> 0-100% scaling --- +// APPS 0-20% -> 0-100% scaling -// ADC values corresponding to physical 20% pedal (your "new max") +// ADC values corresponding to physical 20% pedal) #define APPS1_20PCT_ADC 784.0F #define APPS2_20PCT_ADC 1150.0F -// Measured resting ADC (change these once you log them) -#define APPS1_REST_ADC 117.75F -#define APPS2_REST_ADC 172.5F +// Measured resting ADC (change these with actual findings this is just safe +// zone values) +#define APPS1_REST_ADC 11.75F +#define APPS2_REST_ADC 17.5F -// Clamp helper (if you don't already have it) +// Clamp helper #define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : ((x) > (hi) ? (hi) : (x))) #define CLAMP01(x) CLAMP((x), 0.0F, 1.0F) diff --git a/fsae-vehicle-fw/src/vehicle/apps.cpp b/fsae-vehicle-fw/src/vehicle/apps.cpp index fd3cd83..4c8ed54 100644 --- a/fsae-vehicle-fw/src/vehicle/apps.cpp +++ b/fsae-vehicle-fw/src/vehicle/apps.cpp @@ -53,7 +53,7 @@ void APPS_UpdateData(uint16_t rawReading1, LOWPASS_FILTER(rawReading1, appsData.apps1RawReading, appsAlpha); LOWPASS_FILTER(rawReading2, appsData.apps2RawReading, appsAlpha); - + Serial.print("\n\n\n\n\n"); Serial.print("Raw APPS1: "); Serial.println(appsData.apps1RawReading); Serial.print("Raw APPS2: "); @@ -96,6 +96,7 @@ void APPS_UpdateData(uint16_t rawReading1, } else if (appsData.appsReading2_Voltage > APPS_5V_MAX) { appsData.appsReading2_Voltage = APPS_5V_MAX; } + // Moved this upwards to before the clamping of percentage // Map voltage to percentage of throttle travel, limiting to 0-1 range // appsData.appsReading1_Percentage = @@ -149,6 +150,7 @@ static void checkAndHandleAPPSFault() { Serial.println(appsData.appsReading1_Percentage); Serial.print("Percent APPS2: "); Serial.println(appsData.appsReading2_Percentage); + // # endif if (appsData.appsReading1_Voltage < APPS_3V3_FAULT_MIN || From d66963d0307466f93b89a2ec46d9e711d99cb34a Mon Sep 17 00:00:00 2001 From: PranavKocharlakota Date: Thu, 15 Jan 2026 12:45:31 -0800 Subject: [PATCH 30/30] Add Faults to main.cpp Faults are set and cleared from main.cpp --- fsae-vehicle-fw/src/main.cpp | 91 +++++++++++-- fsae-vehicle-fw/src/vehicle/faults.cpp | 173 ++++++++++++++++++++++++- fsae-vehicle-fw/src/vehicle/faults.h | 21 ++- 3 files changed, 269 insertions(+), 16 deletions(-) diff --git a/fsae-vehicle-fw/src/main.cpp b/fsae-vehicle-fw/src/main.cpp index 128a533..94f86b4 100644 --- a/fsae-vehicle-fw/src/main.cpp +++ b/fsae-vehicle-fw/src/main.cpp @@ -253,32 +253,97 @@ void threadMain(void *pvParameters) { // print all errors if they are true in one line Serial.print(" | "); - if (MCU_GetMCU2Data()->dcMainWireOverVoltFault) + if (MCU_GetMCU2Data()->dcMainWireOverVoltFault) { + Faults_SetFault(FAULT_DC_OVER_VOLT); Serial.println("DC Over Volt Fault, "); - if (MCU_GetMCU2Data()->motorPhaseCurrFault) + } else { + Faults_ClearFault(FAULT_DC_OVER_VOLT); + } + + if (MCU_GetMCU2Data()->motorPhaseCurrFault) { + Faults_SetFault(FAULT_MOTOR_PHASE_CURR); Serial.println("Motor Phase Curr Fault, "); - if (MCU_GetMCU2Data()->mcuOverHotFault) + } else { + Faults_ClearFault(FAULT_MOTOR_PHASE_CURR); + } + + if (MCU_GetMCU2Data()->mcuOverHotFault) { + Faults_SetFault(FAULT_OVER_HOT); Serial.println("MCU Over Hot Fault, "); - if (MCU_GetMCU2Data()->resolverFault) + } else { + Faults_ClearFault(FAULT_OVER_HOT); + } + + if (MCU_GetMCU2Data()->resolverFault) { + Faults_SetFault(FAULT_RESOLVER); Serial.println("Resolver Fault, "); - if (MCU_GetMCU2Data()->phaseCurrSensorFault) + } else { + Faults_ClearFault(FAULT_RESOLVER); + } + + if (MCU_GetMCU2Data()->phaseCurrSensorFault) { + Faults_SetFault(FAULT_PHASE_CURR_SENSOR); Serial.println("Phase Curr Sensor Fault, "); - if (MCU_GetMCU2Data()->motorOverSpdFault) + } else { + Faults_ClearFault(FAULT_PHASE_CURR_SENSOR); + } + + if (MCU_GetMCU2Data()->motorOverSpdFault) { + Faults_SetFault(FAULT_MOTOR_OVER_SPEED); Serial.println("Motor Over Spd Fault, "); - if (MCU_GetMCU2Data()->drvMotorOverHotFault) + } else { + Faults_ClearFault(FAULT_MOTOR_OVER_SPEED); + } + + if (MCU_GetMCU2Data()->drvMotorOverHotFault) { + Faults_SetFault(FAULT_DRV_OVER_HOT); Serial.println("Driver Motor Over Hot Fault, "); - if (MCU_GetMCU2Data()->dcMainWireOverCurrFault) + } else { + Faults_ClearFault(FAULT_DRV_OVER_HOT); + } + + if (MCU_GetMCU2Data()->dcMainWireOverCurrFault) { + Faults_SetFault(FAULT_DC_OVER_CURR); Serial.println("DC Main Wire Over Curr Fault, "); - if (MCU_GetMCU2Data()->drvMotorOverCoolFault) + } else { + Faults_ClearFault(FAULT_DC_OVER_CURR); + } + + if (MCU_GetMCU2Data()->drvMotorOverCoolFault) { + Faults_SetFault(FAULT_DRV_OVER_COOL); Serial.println("Driver Motor Over Cool Fault, "); - if (MCU_GetMCU2Data()->dcLowVoltWarning) + } else { + Faults_ClearFault(FAULT_DRV_OVER_COOL); + } + + if (MCU_GetMCU2Data()->dcLowVoltWarning) { + Faults_SetFault(FAULT_DC_LOW_VOLT_WARN); Serial.println("DC Low Volt Warning, "); - if (MCU_GetMCU2Data()->mcu12VLowVoltWarning) + } else { + Faults_ClearFault(FAULT_DC_LOW_VOLT_WARN); + } + + if (MCU_GetMCU2Data()->mcu12VLowVoltWarning) { + Faults_SetFault(FAULT_12V_LOW_VOLT_WARN); Serial.println("MCU 12V Low Volt Warning, "); - if (MCU_GetMCU2Data()->motorStallFault) + } else { + Faults_ClearFault(FAULT_12V_LOW_VOLT_WARN); + } + + if (MCU_GetMCU2Data()->motorStallFault) { + Faults_SetFault(FAULT_MOTOR_STALL); Serial.println("Motor Stall Fault, "); - if (MCU_GetMCU2Data()->motorOpenPhaseFault) + } else { + Faults_ClearFault(FAULT_MOTOR_STALL); + } + + if (MCU_GetMCU2Data()->motorOpenPhaseFault) { + Faults_SetFault(FAULT_MOTOR_OPEN_PHASE); Serial.println("Motor Open Phase Fault, "); + } else { + Faults_ClearFault(FAULT_MOTOR_OPEN_PHASE); + } + Motor_UpdateMotor( torqueDemand, enablePrecharge, enablePower, enableRun, enableRegen, diff --git a/fsae-vehicle-fw/src/vehicle/faults.cpp b/fsae-vehicle-fw/src/vehicle/faults.cpp index 4cf212b..daab0b5 100644 --- a/fsae-vehicle-fw/src/vehicle/faults.cpp +++ b/fsae-vehicle-fw/src/vehicle/faults.cpp @@ -1,5 +1,6 @@ // Anteater Electric Racing, 2025 + #define FAULT_OVER_CURRENT_MASK (0x1) #define FAULT_UNDER_VOLTAGE_MASK (0x1 << 1) #define FAULT_OVER_TEMP_MASK (0x1 << 2) @@ -8,6 +9,23 @@ #define FAULT_BPPS_MASK (0x1 << 5) #define FAULT_APPS_BRAKE_PLAUSIBILITY_MASK (0x1 << 6) +//Inverter Faults +#define FAULT_DC_OVER_VOLT_FAULT_MASK (0x1 << 7) +#define FAULT_MOTOR_PHASE_CURR_FAULT_MASK (0x1 << 8) +#define FAULT_MCU_OVER_HOT_FAULT_MASK (0x1 << 9) +#define FAULT_RESOLVER_FAULT_MASK (0x1 << 10) +#define FAULT_PHASE_CURR_SENSOR_FAULT_MASK (0x1 << 11) +#define FAULT_MOTOR_OVER_SPD_FAULT_MASK (0x1 << 12) +#define FAULT_DRV_MOTOR_OVER_HOT_FAULT_MASK (0x1 << 13) +#define FAULT_DC_MAIN_WIRE_OVER_CURR_FAULT_MASK (0x1 << 14) +#define FAULT_DRV_MOTOR_OVER_COOL_FAULT_MASK (0x1 << 15) +#define FAULT_DC_LOW_VOLT_WARNING_MASK (0x1 << 16) +#define FAULT_MCU_12V_LOW_VOLT_WARNING_MASK (0x1 << 17) +#define FAULT_MOTOR_STALL_FAULT_MASK (0x1 << 18) +#define FAULT_MOTOR_OPEN_PHASE_FAULT_MASK (0x1 << 19) + + + #include "vehicle/faults.h" #include "utils/utils.h" #include "vehicle/motor.h" @@ -62,12 +80,66 @@ void Faults_SetFault(FaultType fault) { faultBitMap |= FAULT_APPS_BRAKE_PLAUSIBILITY_MASK; break; } + + // Inverter Faults + case FAULT_DC_OVER_VOLT: { + faultBitMap |= FAULT_DC_OVER_VOLT_FAULT_MASK; + break; + } + case FAULT_MOTOR_PHASE_CURR: { + faultBitMap |= FAULT_MOTOR_PHASE_CURR_FAULT_MASK; + break; + } + case FAULT_OVER_HOT: { + faultBitMap |= FAULT_MCU_OVER_HOT_FAULT_MASK; + break; + } + case FAULT_RESOLVER: { + faultBitMap |= FAULT_RESOLVER_FAULT_MASK; + break; + } + case FAULT_PHASE_CURR_SENSOR: { + faultBitMap |= FAULT_PHASE_CURR_SENSOR_FAULT_MASK; + break; + } + case FAULT_MOTOR_OVER_SPEED: { + faultBitMap |= FAULT_MOTOR_OVER_SPD_FAULT_MASK; + break; + } + case FAULT_DRV_OVER_HOT: { + faultBitMap |= FAULT_DRV_MOTOR_OVER_HOT_FAULT_MASK; + break; + } + case FAULT_DC_OVER_CURR: { + faultBitMap |= FAULT_DC_MAIN_WIRE_OVER_CURR_FAULT_MASK; + break; + } + case FAULT_DRV_OVER_COOL: { + faultBitMap |= FAULT_DRV_MOTOR_OVER_COOL_FAULT_MASK; + break; + } + case FAULT_DC_LOW_VOLT_WARN: { + faultBitMap |= FAULT_DC_LOW_VOLT_WARNING_MASK; + break; + } + case FAULT_12V_LOW_VOLT_WARN: { + faultBitMap |= FAULT_MCU_12V_LOW_VOLT_WARNING_MASK; + break; + } + case FAULT_MOTOR_STALL: { + faultBitMap |= FAULT_MOTOR_STALL_FAULT_MASK; + break; + } + case FAULT_MOTOR_OPEN_PHASE: { + faultBitMap |= FAULT_MOTOR_OPEN_PHASE_FAULT_MASK; + break; + } + default: { break; } } } - void Faults_ClearFault(FaultType fault) { switch (fault) { case FAULT_NONE: { @@ -107,6 +179,61 @@ void Faults_ClearFault(FaultType fault) { faultBitMap &= ~FAULT_APPS_BRAKE_PLAUSIBILITY_MASK; break; } + + // Inverter Faults + case FAULT_DC_OVER_VOLT: { + faultBitMap &= ~FAULT_DC_OVER_VOLT_FAULT_MASK; + break; + } + case FAULT_MOTOR_PHASE_CURR: { + faultBitMap &= ~FAULT_MOTOR_PHASE_CURR_FAULT_MASK; + break; + } + case FAULT_OVER_HOT: { + faultBitMap &= ~FAULT_MCU_OVER_HOT_FAULT_MASK; + break; + } + case FAULT_RESOLVER: { + faultBitMap &= ~FAULT_RESOLVER_FAULT_MASK; + break; + } + case FAULT_PHASE_CURR_SENSOR: { + faultBitMap &= ~FAULT_PHASE_CURR_SENSOR_FAULT_MASK; + break; + } + case FAULT_MOTOR_OVER_SPEED: { + faultBitMap &= ~FAULT_MOTOR_OVER_SPD_FAULT_MASK; + break; + } + case FAULT_DRV_OVER_HOT: { + faultBitMap &= ~FAULT_DRV_MOTOR_OVER_HOT_FAULT_MASK; + break; + } + case FAULT_DC_OVER_CURR: { + faultBitMap &= ~FAULT_DC_MAIN_WIRE_OVER_CURR_FAULT_MASK; + break; + } + case FAULT_DRV_OVER_COOL: { + faultBitMap &= ~FAULT_DRV_MOTOR_OVER_COOL_FAULT_MASK; + break; + } + case FAULT_DC_LOW_VOLT_WARN: { + faultBitMap &= ~FAULT_DC_LOW_VOLT_WARNING_MASK; + break; + } + case FAULT_12V_LOW_VOLT_WARN: { + faultBitMap &= ~FAULT_MCU_12V_LOW_VOLT_WARNING_MASK; + break; + } + case FAULT_MOTOR_STALL: { + faultBitMap &= ~FAULT_MOTOR_STALL_FAULT_MASK; + break; + } + case FAULT_MOTOR_OPEN_PHASE: { + faultBitMap &= ~FAULT_MOTOR_OPEN_PHASE_FAULT_MASK; + break; + } + default: { break; } @@ -125,10 +252,11 @@ void Faults_HandleFaults() { #if DEBUG_FLAG Serial.println("Clearing all faults in handle faults"); #endif - Motor_ClearFaultState(); return; } + + if (faultBitMap & FAULT_OVER_CURRENT_MASK) { Motor_SetFaultState(); } @@ -150,6 +278,47 @@ void Faults_HandleFaults() { if (faultBitMap & FAULT_APPS_BRAKE_PLAUSIBILITY_MASK) { Motor_SetFaultState(); } + + // Inverter Faults + if (faultBitMap & FAULT_DC_OVER_VOLT_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_MOTOR_PHASE_CURR_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_MCU_OVER_HOT_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_RESOLVER_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_PHASE_CURR_SENSOR_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_MOTOR_OVER_SPD_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_DRV_MOTOR_OVER_HOT_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_DC_MAIN_WIRE_OVER_CURR_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_DRV_MOTOR_OVER_COOL_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_DC_LOW_VOLT_WARNING_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_MCU_12V_LOW_VOLT_WARNING_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_MOTOR_STALL_FAULT_MASK) { + Motor_SetFaultState(); + } + if (faultBitMap & FAULT_MOTOR_OPEN_PHASE_FAULT_MASK) { + Motor_SetFaultState(); + } } // for telemetry diff --git a/fsae-vehicle-fw/src/vehicle/faults.h b/fsae-vehicle-fw/src/vehicle/faults.h index bd77ccb..d71b0e5 100644 --- a/fsae-vehicle-fw/src/vehicle/faults.h +++ b/fsae-vehicle-fw/src/vehicle/faults.h @@ -12,9 +12,28 @@ typedef enum { FAULT_APPS, FAULT_BSE, FAULT_BPPS, - FAULT_APPS_BRAKE_PLAUSIBILITY + FAULT_APPS_BRAKE_PLAUSIBILITY, + + // Inverter Faults + FAULT_DC_OVER_VOLT, + FAULT_MOTOR_PHASE_CURR, + FAULT_OVER_HOT, + FAULT_RESOLVER, + FAULT_PHASE_CURR_SENSOR, + FAULT_MOTOR_OVER_SPEED, + FAULT_DRV_OVER_HOT, + FAULT_DC_OVER_CURR, + FAULT_DRV_OVER_COOL, + FAULT_DC_LOW_VOLT_WARN, + FAULT_12V_LOW_VOLT_WARN, + FAULT_MOTOR_STALL, + FAULT_MOTOR_OPEN_PHASE, + + } FaultType; + + void Faults_Init(); void Faults_SetFault(FaultType fault);