diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 01728a6..0000000 --- a/.clang-format +++ /dev/null @@ -1,18 +0,0 @@ ---- -BasedOnStyle: WebKit -AlignAfterOpenBracket: Align -AlignConsecutiveMacros: 'true' -AlignConsecutiveAssignments: 'true' -AlignOperands: 'true' -AlignTrailingComments: 'true' -AllowShortBlocksOnASingleLine: 'false' -AllowShortFunctionsOnASingleLine: InlineOnly -AllowShortLoopsOnASingleLine: 'false' -ColumnLimit: '100' -IndentWidth: '4' -SpaceAfterLogicalNot: 'false' -SpaceBeforeAssignmentOperators: 'true' -SpaceBeforeRangeBasedForLoopColon: 'true' -TabWidth: '4' -UseTab: Always ---- diff --git a/.github/workflows/build-check.yml b/.github/workflows/build-check.yml index 7f0a4dc..5ee76bb 100644 --- a/.github/workflows/build-check.yml +++ b/.github/workflows/build-check.yml @@ -8,7 +8,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive @@ -17,4 +17,4 @@ jobs: if ! make; then echo "The application has failed to build." exit 1 # This will cause the workflow to fail - fi + fi \ No newline at end of file diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml new file mode 100644 index 0000000..80a4090 --- /dev/null +++ b/.github/workflows/format-check.yml @@ -0,0 +1,20 @@ +name: Code Style Check + +on: [push] + +jobs: + formatting-check: + name: Check format of C + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Run clang-format style check for C/C++ sources + uses: Northeastern-Electric-Racing/clang-format-action@main + with: + clang-format-version: '18' + # only check core, embedded base covered internally + check-path: "Core/" + # use the clang-format from embedded base + format-filepath: "./Drivers/Embedded-Base/clang-format" \ No newline at end of file diff --git a/Core/.clang-format-ignore b/Core/.clang-format-ignore new file mode 100644 index 0000000..06026d5 --- /dev/null +++ b/Core/.clang-format-ignore @@ -0,0 +1,6 @@ +./*/stm32* +./*/sys* +./*/FreeRTOS* +./*/freertos* +./*/main* +./Startup/* \ No newline at end of file diff --git a/Core/Inc/analyzer.h b/Core/Inc/analyzer.h index 74f5b70..324ac70 100644 --- a/Core/Inc/analyzer.h +++ b/Core/Inc/analyzer.h @@ -5,7 +5,7 @@ #include "datastructs.h" #include "segment.h" -// this is a simple empirical mapping of which therms are returning good data +// this is a simple empirical mapping of which therms are returning good data // Only in use because we can not seem to correclty map incoming therms - this allows us to forcibley select those that we visually noticed were good extern uint8_t THERM_DISABLE[NUM_CHIPS][NUM_THERMS_PER_CHIP]; @@ -17,14 +17,16 @@ extern const uint8_t MUX_OFFSET; * @note 0xFF indicates the end of the relevant therms * @note Low side */ -extern const uint8_t RELEVANT_THERM_MAP_L[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS]; +extern const uint8_t RELEVANT_THERM_MAP_L[NUM_CELLS_PER_CHIP] + [NUM_RELEVANT_THERMS]; /** * @brief Mapping the Relevant Thermistors for each cell based on cell # * @note 0xFF indicates the end of the relevant therms * @note High side */ -extern const uint8_t RELEVANT_THERM_MAP_H[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS]; +extern const uint8_t RELEVANT_THERM_MAP_H[NUM_CELLS_PER_CHIP] + [NUM_RELEVANT_THERMS]; /* * List of therms that we actually read from, NOT reordered by cell @@ -47,7 +49,7 @@ extern const uint8_t POPULATED_THERM_LIST_H[NUM_THERMS_PER_CHIP]; * * @param data */ -void analyzer_push(acc_data_t* data); +void analyzer_push(acc_data_t *data); /** * @brief Calculates the PWM required to drive the fans at the current moment in time @@ -60,8 +62,8 @@ uint8_t analyzer_calc_fan_pwm(); /** * @brief Pointer to the address of the most recent data point */ -extern acc_data_t* bmsdata; +extern acc_data_t *bmsdata; -extern acc_data_t* prevbmsdata; +extern acc_data_t *prevbmsdata; #endif \ No newline at end of file diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index b2b036f..fea2163 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -2,59 +2,62 @@ #define BMS_CONFIG_H // Hardware definition -#define NUM_SEGMENTS 6 -#define NUM_CHIPS NUM_SEGMENTS* 2 +#define NUM_SEGMENTS 6 +#define NUM_CHIPS NUM_SEGMENTS * 2 #define NUM_CELLS_PER_CHIP 10 #define NUM_THERMS_PER_CHIP 32 #define NUM_RELEVANT_THERMS 3 // Firmware limits -#define MAX_TEMP 65 //degrees C -#define MIN_TEMP -25 // deg C -#define MAX_VOLT_MEAS 65535 -#define MIN_VOLT_MEAS 0 +#define MAX_TEMP 65 //degrees C +#define MIN_TEMP -25 // deg C +#define MAX_VOLT_MEAS 65535 +#define MIN_VOLT_MEAS 0 // Boosting Parameters -#define BOOST_TIME 5 // seconds -#define BOOST_RECHARGE_TIME 30 // seconds +#define BOOST_TIME 5 // seconds +#define BOOST_RECHARGE_TIME 30 // seconds #define CONTDCL_MULTIPLIER 3 //cell limits -#define MIN_VOLT 2.5 -#define MAX_VOLT 4.2 -#define MAX_CHARGE_VOLT 4.21 -#define MAX_DELTA_V 0.015 -#define BAL_MIN_V 4.00 -#define MAX_CELL_TEMP 55 -#define MIN_CELL_TEMP 15 -#define MAX_CELL_CURR 500 // Amps per BMS cell -#define MAX_CELL_TEMP_BAL 45 -#define MAX_CHG_CELL_CURR 20 +#define MIN_VOLT 2.5 +#define MAX_VOLT 4.2 +#define MAX_CHARGE_VOLT 4.21 +#define MAX_DELTA_V 0.015 +#define BAL_MIN_V 4.00 +#define MAX_CELL_TEMP 55 +#define MIN_CELL_TEMP 15 +#define MAX_CELL_CURR 500 // Amps per BMS cell +#define MAX_CELL_TEMP_BAL 45 +#define MAX_CHG_CELL_CURR 20 // Algorithm settings #define CHARGE_SETL_TIMEOUT 60000 // 1 minute, may need adjustment #define CHARGE_SETL_TIMEUP 300000 // 5 minutes, may need adjustment #define CHARGE_VOLT_TIMEOUT 300000 // 5 minutes, may need adjustment -#define VOLT_SAG_MARGIN 0.45 // Volts above the minimum cell voltage we would like to aim for -#define OCV_CURR_THRESH 1.5 +#define VOLT_SAG_MARGIN \ + 0.45 // Volts above the minimum cell voltage we would like to aim for +#define OCV_CURR_THRESH 1.5 -#define OCV_AVG 3 +#define OCV_AVG 3 -#define MAX_STANDARD_DEV 3 // only used for standard deviation for therms calc +#define MAX_STANDARD_DEV 3 // only used for standard deviation for therms calc //Fault times -#define OVER_CURR_TIME 5000 //todo adjust these based on testing and/or counter values +#define OVER_CURR_TIME \ + 5000 //todo adjust these based on testing and/or counter values #define PRE_OVER_CURR_TIME 1000 #define OVER_CHG_CURR_TIME 1000 -#define UNDER_VOLT_TIME 45000 +#define UNDER_VOLT_TIME 45000 #define PRE_UNDER_VOLT_TIME 12000 -#define OVER_VOLT_TIME 45000 -#define LOW_CELL_TIME 45000 -#define HIGH_TEMP_TIME 60000 -#define CURR_ERR_MARG 1.1 // scaling factor, ie 1.1 = 10% error +#define OVER_VOLT_TIME 45000 +#define LOW_CELL_TIME 45000 +#define HIGH_TEMP_TIME 60000 +#define CURR_ERR_MARG 1.1 // scaling factor, ie 1.1 = 10% error -#define DCDC_CURRENT_DRAW 0 // in A, was used because our DCDC was drawing current +#define DCDC_CURRENT_DRAW \ + 0 // in A, was used because our DCDC was drawing current -#define CAN_MESSAGE_WAIT 5 +#define CAN_MESSAGE_WAIT 5 #endif \ No newline at end of file diff --git a/Core/Inc/can_handler.h b/Core/Inc/can_handler.h index 6f9da20..a78122b 100644 --- a/Core/Inc/can_handler.h +++ b/Core/Inc/can_handler.h @@ -6,15 +6,14 @@ #include #include "ringbuffer.h" - #define NUM_INBOUND_CAN1_IDS 1 #define NUM_INBOUND_CAN2_IDS 1 extern CAN_HandleTypeDef hcan1; extern CAN_HandleTypeDef hcan2; -extern ringbuffer_t* can1_rx_queue; -extern ringbuffer_t* can2_rx_queue; +extern ringbuffer_t *can1_rx_queue; +extern ringbuffer_t *can2_rx_queue; static const uint32_t can1_id_list[NUM_INBOUND_CAN1_IDS] = { //CANID_X, @@ -26,7 +25,6 @@ static const uint32_t can2_id_list[NUM_INBOUND_CAN2_IDS] = { 0x18FF50E5 }; - void can_receive_callback(CAN_HandleTypeDef *hcan); /* for 1st CAN bus */ diff --git a/Core/Inc/compute.h b/Core/Inc/compute.h index 611305e..1673096 100644 --- a/Core/Inc/compute.h +++ b/Core/Inc/compute.h @@ -7,25 +7,15 @@ #define CURRENT_SENSOR_PIN_L A1 #define CURRENT_SENSOR_PIN_H A0 -#define MEAS_5VREF_PIN A7 -#define FAULT_PIN 2 -#define CHARGE_SAFETY_RELAY 4 -#define CHARGE_DETECT 5 -#define CHARGER_BAUD 250000U -#define MC_BAUD 1000000U -#define MAX_ADC_RESOLUTION 4095 // 12 bit ADC +#define MEAS_5VREF_PIN A7 +#define FAULT_PIN 2 +#define CHARGE_SAFETY_RELAY 4 +#define CHARGE_DETECT 5 +#define CHARGER_BAUD 250000U +#define MC_BAUD 1000000U +#define MAX_ADC_RESOLUTION 4095 // 12 bit ADC - - -typedef enum { - FAN1, - FAN2, - FAN3, - FAN4, - FAN5, - FAN6, - FANMAX -} fan_select_t; +typedef enum { FAN1, FAN2, FAN3, FAN4, FAN5, FAN6, FANMAX } fan_select_t; /** * @brief inits the compute interface @@ -47,7 +37,9 @@ void compute_enable_charging(bool enable_charging); * * @return Returns a fault if we are not able to communicate with charger */ -int compute_send_charging_message(uint16_t voltage_to_set, uint16_t current_to_set, acc_data_t* bms_data); +int compute_send_charging_message(uint16_t voltage_to_set, + uint16_t current_to_set, + acc_data_t *bms_data); /** * @brief Returns if charger interlock is engaged, indicating charger LV connector is plugged in @@ -74,7 +66,8 @@ bool compute_charger_connected(); * * @return uint8_t 0 = success, 1 = fan_select is out of range, 2 = PWM channel not able to be configured */ -uint8_t compute_set_fan_speed(TIM_HandleTypeDef* pwmhandle, fan_select_t fan_select, uint8_t duty_cycle); +uint8_t compute_set_fan_speed(TIM_HandleTypeDef *pwmhandle, + fan_select_t fan_select, uint8_t duty_cycle); /** * @brief Returns the pack current sensor reading @@ -88,14 +81,14 @@ int16_t compute_get_pack_current(); * * @param bmsdata */ -void compute_send_mc_discharge_message(acc_data_t* bmsdata); +void compute_send_mc_discharge_message(acc_data_t *bmsdata); /** * @brief sends max charge/discharge current to Motor Controller * * @param bmsdata */ -void compute_send_mc_charge_message(acc_data_t* bmsdata); +void compute_send_mc_charge_message(acc_data_t *bmsdata); /** * @brief updates fault relay @@ -115,7 +108,7 @@ void compute_set_fault(int fault_state); * * @return Returns a fault if we are not able to send */ -void compute_send_acc_status_message(acc_data_t* bmsdata); +void compute_send_acc_status_message(acc_data_t *bmsdata); /** * @brief sends BMS status message @@ -127,7 +120,8 @@ void compute_send_acc_status_message(acc_data_t* bmsdata); * * @return Returns a fault if we are not able to send */ -void compute_send_bms_status_message(acc_data_t* bmsdata, int bms_state, bool balance); +void compute_send_bms_status_message(acc_data_t *bmsdata, int bms_state, + bool balance); /** * @brief sends shutdown control message @@ -147,7 +141,7 @@ void compute_send_shutdown_ctrl_message(uint8_t mpe_state); * * @return Returns a fault if we are not able to send */ -void compute_send_cell_data_message(acc_data_t* bmsdata); +void compute_send_cell_data_message(acc_data_t *bmsdata); /** * @brief sends cell voltage message @@ -161,8 +155,8 @@ void compute_send_cell_data_message(acc_data_t* bmsdata); * @return Returns a fault if we are not able to send */ void compute_send_cell_voltage_message(uint8_t cell_id, uint16_t instant_volt, - uint16_t internal_res, uint8_t shunted, - uint16_t open_voltage); + uint16_t internal_res, uint8_t shunted, + uint16_t open_voltage); /** * @brief sends out the calculated values of currents @@ -171,14 +165,14 @@ void compute_send_cell_voltage_message(uint8_t cell_id, uint16_t instant_volt, * @param charge * @param current */ -void compute_send_current_message(acc_data_t* bmsdata); +void compute_send_current_message(acc_data_t *bmsdata); /** * @brief sends cell temperature message * * @return Returns a fault if we are not able to send */ -void compute_send_cell_temp_message(acc_data_t* bmsdata); +void compute_send_cell_temp_message(acc_data_t *bmsdata); /** * @brief sends the average segment temperatures @@ -187,9 +181,9 @@ void compute_send_cell_temp_message(acc_data_t* bmsdata); * * @return Returns a fault if we are not able to send */ -void compute_send_segment_temp_message(acc_data_t* bmsdata); +void compute_send_segment_temp_message(acc_data_t *bmsdata); void compute_send_fault_message(uint8_t status, int16_t curr, int16_t in_dcl); -void compute_send_voltage_noise_message(acc_data_t* bmsdata); +void compute_send_voltage_noise_message(acc_data_t *bmsdata); #endif // COMPUTE_H diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index af344e8..2208d76 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -12,8 +12,10 @@ */ typedef struct { /* These are retrieved from the initial LTC comms */ - uint16_t voltage[NUM_CELLS_PER_CHIP]; /* store voltage readings from each chip */ - int8_t thermistor_reading[NUM_THERMS_PER_CHIP]; /* store all therm readings from each chip */ + uint16_t voltage + [NUM_CELLS_PER_CHIP]; /* store voltage readings from each chip */ + int8_t thermistor_reading + [NUM_THERMS_PER_CHIP]; /* store all therm readings from each chip */ int8_t thermistor_value[NUM_THERMS_PER_CHIP]; int error_reading; @@ -22,8 +24,10 @@ typedef struct { float cell_resistance[NUM_CELLS_PER_CHIP]; uint16_t open_cell_voltage[NUM_CELLS_PER_CHIP]; - uint8_t noise_reading[NUM_CELLS_PER_CHIP]; /* bool representing noise ignored read */ - uint8_t consecutive_noise[NUM_CELLS_PER_CHIP]; /* count representing consecutive noisy reads */ + uint8_t noise_reading + [NUM_CELLS_PER_CHIP]; /* bool representing noise ignored read */ + uint8_t consecutive_noise + [NUM_CELLS_PER_CHIP]; /* count representing consecutive noisy reads */ } chipdata_t; /** @@ -129,11 +133,11 @@ typedef struct { * @brief Represents individual BMS states */ typedef enum { - BOOT_STATE, /* State when BMS first starts up, used to initialize everything that needs + BOOT_STATE, /* State when BMS first starts up, used to initialize everything that needs configuring */ - READY_STATE, /* State when car is not on/BMS is not really doing anything */ + READY_STATE, /* State when car is not on/BMS is not really doing anything */ CHARGING_STATE, /* State when car is on and is charging (Filling battery) */ - FAULTED_STATE, /* State when BMS has detected a catastrophic fault and we need to hault + FAULTED_STATE, /* State when BMS has detected a catastrophic fault and we need to hault operations */ NUM_STATES @@ -143,13 +147,13 @@ typedef enum { * @brief Represents fault evaluation operators */ typedef enum { - GT, /* fault if {data} greater than {threshold} */ - LT, /* fault if {data} less than {threshold} */ - GE, /* fault if {data} greater than or equal to {threshold} */ - LE, /* fault if {data} less than or equal to {threshold} */ - EQ, /* fault if {data} equal to {threshold} */ + GT, /* fault if {data} greater than {threshold} */ + LT, /* fault if {data} less than {threshold} */ + GE, /* fault if {data} greater than or equal to {threshold} */ + LE, /* fault if {data} less than or equal to {threshold} */ + EQ, /* fault if {data} equal to {threshold} */ NEQ, /* fault if {data} not equal to {threshold} */ - NOP /* no operation, use for single threshold faults */ + NOP /* no operation, use for single threshold faults */ } fault_evalop_t; @@ -157,7 +161,7 @@ typedef enum { * @brief Represents data to be packaged into a fault evaluation */ typedef struct { - char* id; + char *id; nertimer_t timer; int data_1; diff --git a/Core/Inc/eepromdirectory.h b/Core/Inc/eepromdirectory.h index 23c3665..4ca4530 100644 --- a/Core/Inc/eepromdirectory.h +++ b/Core/Inc/eepromdirectory.h @@ -12,18 +12,14 @@ /* index 0 = newest, index 4 = oldest */ static uint32_t eeprom_faults[NUM_EEPROM_FAULTS]; -struct eeprom_partition -{ - char *id; /* key */ - uint16_t size; /* bytes */ - uint16_t address; /* start address */ +struct eeprom_partition { + char *id; /* key */ + uint16_t size; /* bytes */ + uint16_t address; /* start address */ }; struct eeprom_partition eeprom_data[NUM_EEPROM_ITEMS]; /* ____________KEY________________ _BYTES_ */ - - - /** * @brief partitions eeprom addresses given table of data and size @@ -47,8 +43,6 @@ uint16_t eeprom_get_index(char *key); */ char *eeprom_get_key(int index); - - /** * @brief fills passed data pointer with data from eeprom * @@ -89,5 +83,4 @@ void log_fault(uint32_t fault_code); void get_faults(); - #endif \ No newline at end of file diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index b16a269..2c93ef9 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -33,14 +33,16 @@ void segment_enable_balancing(bool balance_enable); * @param cell_num * @param balance_enable */ -void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, bool balance_enable); +void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, + bool balance_enable); /** * @brief Sets each cell to whatever state is passed in the boolean config area * * @param discharge_config */ -void segment_configure_balancing(bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]); +void segment_configure_balancing( + bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]); /** * @brief Returns if a specific cell is balancing diff --git a/Core/Inc/stateMachine.h b/Core/Inc/stateMachine.h index c442837..d68e73e 100644 --- a/Core/Inc/stateMachine.h +++ b/Core/Inc/stateMachine.h @@ -30,7 +30,6 @@ bool sm_balancing_check(acc_data_t *bmsdata); */ bool sm_charging_check(acc_data_t *bmsdata); - /** * @brief Returns any new faults or current faults that have come up * @note Should be bitwise OR'ed with the current fault status @@ -40,13 +39,13 @@ bool sm_charging_check(acc_data_t *bmsdata); */ uint32_t sm_fault_return(acc_data_t *accData); - /** +/** * @brief Used in parellel to faultReturn(), calculates each fault to append the fault status * * @param index * @return fault_code */ -uint32_t sm_fault_eval(fault_eval_t* index); +uint32_t sm_fault_eval(fault_eval_t *index); /** * @brief handles the state machine, calls the appropriate handler function and runs every loop functions @@ -72,5 +71,4 @@ void sm_broadcast_current_limit(acc_data_t *bmsdata); */ void calculate_pwm(acc_data_t *bmsdata); - #endif //BMS_STATES_H \ No newline at end of file diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index b495a5b..54f06ae 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -2,9 +2,9 @@ #include #include -acc_data_t* bmsdata; +acc_data_t *bmsdata; -acc_data_t* prevbmsdata; +acc_data_t *prevbmsdata; // clang-format off /** @@ -195,21 +195,27 @@ void calc_cell_temps() { for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - const uint8_t (*therm_map)[NUM_RELEVANT_THERMS] = (c % 2 == 0) ? RELEVANT_THERM_MAP_L : RELEVANT_THERM_MAP_H; + const uint8_t(*therm_map)[NUM_RELEVANT_THERMS] = + (c % 2 == 0) ? RELEVANT_THERM_MAP_L : + RELEVANT_THERM_MAP_H; uint8_t therm_count = 0; int temp_sum = 0; - for (uint8_t therm = 0; therm < NUM_RELEVANT_THERMS; therm++) { + for (uint8_t therm = 0; therm < NUM_RELEVANT_THERMS; + therm++) { uint8_t thermNum = therm_map[cell][therm]; if (thermNum != NO_THERM) { //printf("%d\t", bmsdata->chip_data[c].thermistor_value[therm]); - temp_sum += bmsdata->chip_data[c].thermistor_value[therm]; + temp_sum += + bmsdata->chip_data[c] + .thermistor_value[therm]; therm_count++; } } //printf("\r\n"); /* Takes the average temperature of all the relevant thermistors */ - bmsdata->chip_data[c].cell_temp[cell] = temp_sum / therm_count; + bmsdata->chip_data[c].cell_temp[cell] = + temp_sum / therm_count; therm_count = 0; } } @@ -224,9 +230,9 @@ void calc_pack_temps() bmsdata->min_temp.val = MAX_TEMP; bmsdata->min_temp.cellNum = 0; bmsdata->min_temp.chipIndex = 0; - int total_temp = 0; + int total_temp = 0; int total_seg_temp = 0; - int total_accepted = 0; + int total_accepted = 0; for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t therm = 0; therm < NUM_THERMS_PER_CHIP; therm++) { /* finds out the maximum cell temp and location */ @@ -246,29 +252,35 @@ void calc_pack_temps() // bmsdata->min_temp.chipIndex = therm; //} - total_temp += bmsdata->chip_data[c].thermistor_value[therm]; - total_seg_temp += bmsdata->chip_data[c].thermistor_value[therm]; + total_temp += + bmsdata->chip_data[c].thermistor_value[therm]; + total_seg_temp += + bmsdata->chip_data[c].thermistor_value[therm]; } /* only for NERO */ if (c % 2 == 0) { - bmsdata->segment_average_temps[c / 2] = total_seg_temp / 22; - total_seg_temp = 0; + bmsdata->segment_average_temps[c / 2] = + total_seg_temp / 22; + total_seg_temp = 0; } } - for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - if (bmsdata->chip_data[c].cell_temp[cell] > bmsdata->max_temp.val) { - bmsdata->max_temp.val = bmsdata->chip_data[c].cell_temp[cell]; + if (bmsdata->chip_data[c].cell_temp[cell] > + bmsdata->max_temp.val) { + bmsdata->max_temp.val = + bmsdata->chip_data[c].cell_temp[cell]; bmsdata->max_temp.cellNum = cell; bmsdata->max_temp.chipIndex = c; } /* finds out the minimum cell temp and location */ - if (bmsdata->chip_data[c].cell_temp[cell] < bmsdata->min_temp.val) { - bmsdata->min_temp.val = bmsdata->chip_data[c].cell_temp[cell]; + if (bmsdata->chip_data[c].cell_temp[cell] < + bmsdata->min_temp.val) { + bmsdata->min_temp.val = + bmsdata->chip_data[c].cell_temp[cell]; bmsdata->min_temp.cellNum = cell; bmsdata->min_temp.chipIndex = c; } @@ -296,50 +308,61 @@ void calc_pack_voltage_stats() bmsdata->min_ocv.val = MAX_VOLT_MEAS; bmsdata->min_ocv.cellNum = 0; bmsdata->min_ocv.chipIndex = 0; - - uint32_t total_volt = 0; - uint32_t total_ocv = 0; + + uint32_t total_volt = 0; + uint32_t total_ocv = 0; for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - /* fings out the maximum cell voltage and location */ - if (bmsdata->chip_data[c].voltage[cell] > bmsdata->max_voltage.val) { - bmsdata->max_voltage.val = bmsdata->chip_data[c].voltage[cell]; - bmsdata->max_voltage.chipIndex = c; - bmsdata->max_voltage.cellNum = cell; + if (bmsdata->chip_data[c].voltage[cell] > + bmsdata->max_voltage.val) { + bmsdata->max_voltage.val = + bmsdata->chip_data[c].voltage[cell]; + bmsdata->max_voltage.chipIndex = c; + bmsdata->max_voltage.cellNum = cell; } - if (bmsdata->chip_data[c].open_cell_voltage[cell] > bmsdata->max_ocv.val) { - bmsdata->max_ocv.val = bmsdata->chip_data[c].open_cell_voltage[cell]; - bmsdata->max_ocv.chipIndex = c; - bmsdata->max_ocv.cellNum = cell; + if (bmsdata->chip_data[c].open_cell_voltage[cell] > + bmsdata->max_ocv.val) { + bmsdata->max_ocv.val = + bmsdata->chip_data[c] + .open_cell_voltage[cell]; + bmsdata->max_ocv.chipIndex = c; + bmsdata->max_ocv.cellNum = cell; } /* finds out the minimum cell voltage and location */ - if (bmsdata->chip_data[c].voltage[cell] < bmsdata->min_voltage.val) { - bmsdata->min_voltage.val = bmsdata->chip_data[c].voltage[cell]; - bmsdata->min_voltage.chipIndex = c; - bmsdata->min_voltage.cellNum = cell; + if (bmsdata->chip_data[c].voltage[cell] < + bmsdata->min_voltage.val) { + bmsdata->min_voltage.val = + bmsdata->chip_data[c].voltage[cell]; + bmsdata->min_voltage.chipIndex = c; + bmsdata->min_voltage.cellNum = cell; } - if (bmsdata->chip_data[c].open_cell_voltage[cell] < bmsdata->min_ocv.val) { - bmsdata->min_ocv.val = bmsdata->chip_data[c].open_cell_voltage[cell]; - bmsdata->min_ocv.chipIndex = c; - bmsdata->min_ocv.cellNum = cell; + if (bmsdata->chip_data[c].open_cell_voltage[cell] < + bmsdata->min_ocv.val) { + bmsdata->min_ocv.val = + bmsdata->chip_data[c] + .open_cell_voltage[cell]; + bmsdata->min_ocv.chipIndex = c; + bmsdata->min_ocv.cellNum = cell; } total_volt += bmsdata->chip_data[c].voltage[cell]; - total_ocv += bmsdata->chip_data[c].open_cell_voltage[cell]; + total_ocv += + bmsdata->chip_data[c].open_cell_voltage[cell]; } } /* calculate some voltage stats */ - bmsdata->avg_voltage = total_volt / (NUM_CELLS_PER_CHIP * NUM_CHIPS); + bmsdata->avg_voltage = total_volt / (NUM_CELLS_PER_CHIP * NUM_CHIPS); bmsdata->pack_voltage = total_volt / 1000; /* convert to voltage * 10 */ - bmsdata->delt_voltage = bmsdata->max_voltage.val - bmsdata->min_voltage.val; + bmsdata->delt_voltage = + bmsdata->max_voltage.val - bmsdata->min_voltage.val; - bmsdata->avg_ocv = total_ocv / (NUM_CELLS_PER_CHIP * NUM_CHIPS); + bmsdata->avg_ocv = total_ocv / (NUM_CELLS_PER_CHIP * NUM_CHIPS); bmsdata->pack_ocv = total_ocv / 1000; /* convert to voltage * 10 */ bmsdata->delt_ocv = bmsdata->max_ocv.val - bmsdata->min_ocv.val; } @@ -348,20 +371,24 @@ void calc_cell_resistances() { for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - - uint8_t cell_temp = bmsdata->chip_data[c].cell_temp[cell]; + uint8_t cell_temp = + bmsdata->chip_data[c].cell_temp[cell]; /* resistance LUT increments by 5C for each index */ uint8_t resIndex = (cell_temp - MIN_TEMP) / 5; - bmsdata->chip_data[c].cell_resistance[cell] = TEMP_TO_CELL_RES[resIndex]; + bmsdata->chip_data[c].cell_resistance[cell] = + TEMP_TO_CELL_RES[resIndex]; /* Linear interpolation to more accurately represent cell resistances in between * increments of 5C */ if (cell_temp != MAX_TEMP) { - float interpolation - = (TEMP_TO_CELL_RES[resIndex + 1] - TEMP_TO_CELL_RES[resIndex]) / 5; - bmsdata->chip_data[c].cell_resistance[cell] += (interpolation * (cell_temp % 5)); + float interpolation = + (TEMP_TO_CELL_RES[resIndex + 1] - + TEMP_TO_CELL_RES[resIndex]) / + 5; + bmsdata->chip_data[c].cell_resistance[cell] += + (interpolation * (cell_temp % 5)); } } } @@ -378,16 +405,18 @@ void calc_dcl() /* Apply equation */ /* Multiplying resistance by 10 to convert from mOhm to Ohm and then to Ohm * 10000 to * account for the voltage units */ - uint16_t tmpDCL = (bmsdata->chip_data[c].open_cell_voltage[cell] - - ((MIN_VOLT + VOLT_SAG_MARGIN) * 10000)) - / (bmsdata->chip_data[c].cell_resistance[cell] * 10); + uint16_t tmpDCL = + (bmsdata->chip_data[c].open_cell_voltage[cell] - + ((MIN_VOLT + VOLT_SAG_MARGIN) * 10000)) / + (bmsdata->chip_data[c].cell_resistance[cell] * + 10); /* Taking the minimum DCL of all the cells */ if (tmpDCL < current_limit) current_limit = tmpDCL; } } - + /* ceiling for current limit */ if (current_limit > MAX_CELL_CURR) { bmsdata->discharge_limit = MAX_CELL_CURR; @@ -409,38 +438,32 @@ void calc_dcl() start_timer(&dcl_timer, 500); } - else if (is_timer_active(&dcl_timer)) - { - if (is_timer_expired(&dcl_timer)) - { + else if (is_timer_active(&dcl_timer)) { + if (is_timer_expired(&dcl_timer)) { bmsdata->discharge_limit = current_limit; } - if (current_limit > 5) - { + if (current_limit > 5) { bmsdata->discharge_limit = current_limit; cancel_timer(&dcl_timer); } - else - { + else { bmsdata->discharge_limit = prevbmsdata->discharge_limit; } - } - else - { + } else { bmsdata->discharge_limit = current_limit; } - if (bmsdata->discharge_limit > DCDC_CURRENT_DRAW) - { + if (bmsdata->discharge_limit > DCDC_CURRENT_DRAW) { bmsdata->discharge_limit -= DCDC_CURRENT_DRAW; } } void calc_cont_dcl() { - uint8_t min_res_index = (bmsdata->min_temp.val - MIN_TEMP) - / 5; /* resistance LUT increments by 5C for each index */ + uint8_t min_res_index = + (bmsdata->min_temp.val - MIN_TEMP) / + 5; /* resistance LUT increments by 5C for each index */ uint8_t max_res_index = (bmsdata->max_temp.val - MIN_TEMP) / 5; if (TEMP_TO_DCL[min_res_index] < TEMP_TO_DCL[max_res_index]) { @@ -457,10 +480,12 @@ void calcCCL() for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { /* Apply equation */ - uint16_t tmpCCL - = ((MAX_VOLT * 10000) - - (bmsdata->chip_data[c].open_cell_voltage[cell] + (VOLT_SAG_MARGIN * 10000))) - / (bmsdata->chip_data[c].cell_resistance[cell] * 10); + uint16_t tmpCCL = + ((MAX_VOLT * 10000) - + (bmsdata->chip_data[c].open_cell_voltage[cell] + + (VOLT_SAG_MARGIN * 10000))) / + (bmsdata->chip_data[c].cell_resistance[cell] * + 10); /* Multiplying resistance by 10 to convert from mOhm to Ohm and then to Ohm * 10000 to * account for the voltage units */ @@ -480,8 +505,9 @@ void calcCCL() void calc_cont_ccl() { - uint8_t min_res_index = (bmsdata->min_temp.val - MIN_TEMP) - / 5; /* resistance LUT increments by 5C for each index */ + uint8_t min_res_index = + (bmsdata->min_temp.val - MIN_TEMP) / + 5; /* resistance LUT increments by 5C for each index */ uint8_t max_res_index = (bmsdata->max_temp.val - MIN_TEMP) / 5; if (TEMP_TO_CCL[min_res_index] < TEMP_TO_CCL[max_res_index]) { @@ -490,7 +516,7 @@ void calc_cont_ccl() bmsdata->cont_CCL = TEMP_TO_CCL[max_res_index]; } - if (bmsdata->cont_CCL > MAX_CHG_CELL_CURR){ + if (bmsdata->cont_CCL > MAX_CHG_CELL_CURR) { bmsdata->cont_CCL = MAX_CHG_CELL_CURR; } } @@ -500,35 +526,59 @@ void calc_open_cell_voltage() /* if there is no previous data point, set inital open cell voltage to current reading */ if (is_first_reading_) { for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - bmsdata->chip_data[chip].open_cell_voltage[cell] - = bmsdata->chip_data[chip].voltage[cell]; + for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; + cell++) { + bmsdata->chip_data[chip] + .open_cell_voltage[cell] = + bmsdata->chip_data[chip].voltage[cell]; } } return; } /* If we are within the current threshold for open voltage measurments */ - else if (bmsdata->pack_current < (OCV_CURR_THRESH * 10) - && bmsdata->pack_current > (-OCV_CURR_THRESH * 10)) { - if (is_timer_expired(&ocvTimer) || !is_timer_active(&ocvTimer)) { + else if (bmsdata->pack_current < (OCV_CURR_THRESH * 10) && + bmsdata->pack_current > (-OCV_CURR_THRESH * 10)) { + if (is_timer_expired(&ocvTimer) || + !is_timer_active(&ocvTimer)) { for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + for (uint8_t cell = 0; + cell < NUM_CELLS_PER_CHIP; cell++) { /* Sets open cell voltage to a moving average of OCV_AVG values */ - bmsdata->chip_data[chip].open_cell_voltage[cell] - = ((uint32_t)(bmsdata->chip_data[chip].voltage[cell]) - + ((uint32_t)(prevbmsdata->chip_data[chip].open_cell_voltage[cell]) - * (OCV_AVG - 1))) - / OCV_AVG; - bmsdata->chip_data[chip].open_cell_voltage[cell] - = bmsdata->chip_data[chip].voltage[cell]; - - if (bmsdata->chip_data[chip].open_cell_voltage[cell] > MAX_VOLT * 10000) { - bmsdata->chip_data[chip].open_cell_voltage[cell] - = prevbmsdata->chip_data[chip].open_cell_voltage[cell]; - } else if (bmsdata->chip_data[chip].open_cell_voltage[cell] - < MIN_VOLT * 10000) { - bmsdata->chip_data[chip].open_cell_voltage[cell] - = prevbmsdata->chip_data[chip].open_cell_voltage[cell]; + bmsdata->chip_data[chip] + .open_cell_voltage[cell] = + ((uint32_t)(bmsdata->chip_data[chip] + .voltage[cell]) + + ((uint32_t)(prevbmsdata + ->chip_data + [chip] + .open_cell_voltage + [cell]) * + (OCV_AVG - 1))) / + OCV_AVG; + bmsdata->chip_data[chip] + .open_cell_voltage[cell] = + bmsdata->chip_data[chip] + .voltage[cell]; + + if (bmsdata->chip_data[chip] + .open_cell_voltage[cell] > + MAX_VOLT * 10000) { + bmsdata->chip_data[chip] + .open_cell_voltage[cell] = + prevbmsdata + ->chip_data[chip] + .open_cell_voltage + [cell]; + } else if (bmsdata->chip_data[chip] + .open_cell_voltage + [cell] < + MIN_VOLT * 10000) { + bmsdata->chip_data[chip] + .open_cell_voltage[cell] = + prevbmsdata + ->chip_data[chip] + .open_cell_voltage + [cell]; } } } @@ -540,8 +590,9 @@ void calc_open_cell_voltage() for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { /* Set OCV to the previous/existing OCV */ - bmsdata->chip_data[chip].open_cell_voltage[cell] - = prevbmsdata->chip_data[chip].open_cell_voltage[cell]; + bmsdata->chip_data[chip].open_cell_voltage[cell] = + prevbmsdata->chip_data[chip] + .open_cell_voltage[cell]; } } } @@ -557,18 +608,18 @@ uint8_t analyzer_calc_fan_pwm() /* Uses fan LUT and finds low and upper end. Then takes average, weighted to how far into the * interval the exact temp is */ - return ((FAN_CURVE[max_res_index] * part_of_index) - + (FAN_CURVE[min_res_index] * (5 - part_of_index))) - / (2 * 5); + return ((FAN_CURVE[max_res_index] * part_of_index) + + (FAN_CURVE[min_res_index] * (5 - part_of_index))) / + (2 * 5); } -void analyzer_push(acc_data_t* data) +void analyzer_push(acc_data_t *data) { if (prevbmsdata != NULL) free(bmsdata); prevbmsdata = bmsdata; - bmsdata = data; + bmsdata = data; disable_therms(); @@ -597,18 +648,24 @@ void analyzer_push(acc_data_t* data) void disable_therms() { - int8_t tmp_temp = 25; /* Iniitalize to room temp (necessary to stabilize when the BMS first boots up/has null values) */ - if (!is_first_reading_) tmp_temp = prevbmsdata->avg_temp; /* Set to actual average temp of the pack */ + int8_t tmp_temp = + 25; /* Iniitalize to room temp (necessary to stabilize when the BMS first boots up/has null values) */ + if (!is_first_reading_) + tmp_temp = + prevbmsdata + ->avg_temp; /* Set to actual average temp of the pack */ for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t therm = 0; therm < NUM_THERMS_PER_CHIP; therm++) { /* If 2D LUT shows therm should be disable */ if (THERM_DISABLE[c][therm]) { /* Nullify thermistor by setting to pack average */ - bmsdata->chip_data[c].thermistor_value[therm] = tmp_temp; - } - else { - bmsdata->chip_data[c].thermistor_value[therm] = bmsdata->chip_data[c].thermistor_reading[therm]; + bmsdata->chip_data[c].thermistor_value[therm] = + tmp_temp; + } else { + bmsdata->chip_data[c].thermistor_value[therm] = + bmsdata->chip_data[c] + .thermistor_reading[therm]; } } } @@ -617,20 +674,24 @@ void disable_therms() void calc_state_of_charge() { /* Spltting the delta voltage into 18 increments */ - const uint16_t increments - = ((uint16_t)(MAX_VOLT * 10000 - MIN_VOLT * 10000) / ((MAX_VOLT - MIN_VOLT) * 10)); + const uint16_t increments = + ((uint16_t)(MAX_VOLT * 10000 - MIN_VOLT * 10000) / + ((MAX_VOLT - MIN_VOLT) * 10)); /* Retrieving a index of 0-18 */ - uint8_t index = ((bmsdata->min_ocv.val) - MIN_VOLT * 10000) / increments; + uint8_t index = + ((bmsdata->min_ocv.val) - MIN_VOLT * 10000) / increments; bmsdata->soc = STATE_OF_CHARGE_CURVE[index]; if (bmsdata->soc != 100) { - float interpolation - = (float)(STATE_OF_CHARGE_CURVE[index + 1] - STATE_OF_CHARGE_CURVE[index]) / increments; - bmsdata->soc - += (uint8_t)(interpolation - * (((bmsdata->min_ocv.val) - (int32_t)(MIN_VOLT * 10000)) % increments)); + float interpolation = (float)(STATE_OF_CHARGE_CURVE[index + 1] - + STATE_OF_CHARGE_CURVE[index]) / + increments; + bmsdata->soc += (uint8_t)(interpolation * + (((bmsdata->min_ocv.val) - + (int32_t)(MIN_VOLT * 10000)) % + increments)); } if (bmsdata->soc < 0) { @@ -639,38 +700,40 @@ void calc_state_of_charge() } void calc_noise_volt_percent() -{ +{ int i = 0; for (uint8_t seg = 0; seg < NUM_SEGMENTS; seg++) { uint8_t count = 0; /* merge results from each of the two chips ona given segment */ for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { count = bmsdata->chip_data[seg + i].noise_reading[cell]; - count += bmsdata->chip_data[seg + i + 1].noise_reading[cell]; + count += bmsdata->chip_data[seg + i + 1] + .noise_reading[cell]; } i++; /* turn into percentage */ //printf("count: %d\r\n", count); - bmsdata->segment_noise_percentage[seg] = (uint8_t)(100 * (count) / (NUM_CELLS_PER_CHIP * 2.0f)); - + bmsdata->segment_noise_percentage[seg] = + (uint8_t)(100 * (count) / (NUM_CELLS_PER_CHIP * 2.0f)); } } - void high_curr_therm_check() { if (prevbmsdata == NULL) return; if (bmsdata->pack_current > 500) { - for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - bmsdata->chip_data[c].thermistor_reading[cell] - = prevbmsdata->chip_data[c].thermistor_reading[cell]; - bmsdata->chip_data[c].thermistor_value[cell] - = prevbmsdata->chip_data[c].thermistor_value[cell]; + for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; + cell++) { + bmsdata->chip_data[c].thermistor_reading[cell] = + prevbmsdata->chip_data[c] + .thermistor_reading[cell]; + bmsdata->chip_data[c].thermistor_value[cell] = + prevbmsdata->chip_data[c] + .thermistor_value[cell]; } } } @@ -683,11 +746,14 @@ void diff_curr_therm_check() if (abs(bmsdata->pack_current - prevbmsdata->pack_current) > 100) { for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - bmsdata->chip_data[c].thermistor_reading[cell] - = prevbmsdata->chip_data[c].thermistor_reading[cell]; - bmsdata->chip_data[c].thermistor_value[cell] - = prevbmsdata->chip_data[c].thermistor_value[cell]; + for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; + cell++) { + bmsdata->chip_data[c].thermistor_reading[cell] = + prevbmsdata->chip_data[c] + .thermistor_reading[cell]; + bmsdata->chip_data[c].thermistor_value[cell] = + prevbmsdata->chip_data[c] + .thermistor_value[cell]; } } } diff --git a/Core/Src/can_handler.c b/Core/Src/can_handler.c index 35e290b..e912499 100644 --- a/Core/Src/can_handler.c +++ b/Core/Src/can_handler.c @@ -2,23 +2,23 @@ #include "ringbuffer.h" #include "can_handler.h" -ringbuffer_t* can1_rx_queue = NULL; -ringbuffer_t* can2_rx_queue = NULL; +ringbuffer_t *can1_rx_queue = NULL; +ringbuffer_t *can2_rx_queue = NULL; -void can_receive_callback(CAN_HandleTypeDef* hcan) +void can_receive_callback(CAN_HandleTypeDef *hcan) { CAN_RxHeaderTypeDef rx_header; can_msg_t new_msg; /* Read in CAN message */ - if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, new_msg.data) != HAL_OK) { - + if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, + new_msg.data) != HAL_OK) { // TODO add non crtical fault capability - could create one for failed can receieve return; } new_msg.len = rx_header.DLC; // TODO: Make receiving compatible with standard IDs - new_msg.id = rx_header.ExtId; + new_msg.id = rx_header.ExtId; if (hcan == &hcan1) { ringbuffer_enqueue(can1_rx_queue, &new_msg); } else { @@ -46,20 +46,19 @@ int8_t get_can1_msg() int8_t get_can2_msg() { - /* no messages to read */ if (ringbuffer_is_empty(can2_rx_queue)) { return -1; - } + } can_msg_t msg; ringbuffer_dequeue(can2_rx_queue, &msg); // TODO list : // 1. Charger connection flag - have Charger set up with following logic, add correct CAN ID switch (msg.id) { - /* CAN ID of message charger sends every second. */ - case 0x18FF50E5: - bmsdata->is_charger_connected = true; + /* CAN ID of message charger sends every second. */ + case 0x18FF50E5: + bmsdata->is_charger_connected = true; break; default: break; diff --git a/Core/Src/compute.c b/Core/Src/compute.c index 9511632..7ba5999 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -11,7 +11,7 @@ #define MAX_CAN1_STORAGE 10 #define MAX_CAN2_STORAGE 10 -#define REF_CHANNEL 0 +#define REF_CHANNEL 0 #define VOUT_CHANNEL 1 //#define CHARGING_ENABLED @@ -32,12 +32,13 @@ extern ADC_HandleTypeDef hadc2; TIM_OC_InitTypeDef pwm_config; ADC_ChannelConfTypeDef adc_config; -const uint32_t fan_channels[6] = {TIM_CHANNEL_3, TIM_CHANNEL_1, TIM_CHANNEL_4, TIM_CHANNEL_3, TIM_CHANNEL_2, TIM_CHANNEL_1}; +const uint32_t fan_channels[6] = { TIM_CHANNEL_3, TIM_CHANNEL_1, TIM_CHANNEL_4, + TIM_CHANNEL_3, TIM_CHANNEL_2, TIM_CHANNEL_1 }; can_t can1; // main can bus, used by most peripherals can_t can2; // p2p can bus with charger -uint32_t adc_values[2] = {0}; +uint32_t adc_values[2] = { 0 }; /* private function defintions */ float read_ref_voltage(); @@ -65,8 +66,12 @@ uint8_t compute_init() pwm_config.OCPolarity = TIM_OCPOLARITY_HIGH; pwm_config.OCFastMode = TIM_OCFAST_DISABLE; - if (HAL_TIM_PWM_ConfigChannel(&htim1, &pwm_config, fan_channels[FAN1]) != HAL_OK) return -1; - if (HAL_TIM_PWM_ConfigChannel(&htim8, &pwm_config, fan_channels[FAN2]) != HAL_OK) return -1; + if (HAL_TIM_PWM_ConfigChannel(&htim1, &pwm_config, + fan_channels[FAN1]) != HAL_OK) + return -1; + if (HAL_TIM_PWM_ConfigChannel(&htim8, &pwm_config, + fan_channels[FAN2]) != HAL_OK) + return -1; // HAL_TIM_PWM_Start(&htim1, fan_channels[FAN1]); // HAL_TIM_PWM_Start(&htim1, fan_channels[FAN2]); @@ -75,11 +80,10 @@ uint8_t compute_init() // HAL_TIM_PWM_Start(&htim8, fan_channels[FAN5]); // HAL_TIM_PWM_Start(&htim8, fan_channels[FAN6]); bmsdata->is_charger_connected = false; - + HAL_ADC_Start(&hadc2); return 0; - } void compute_enable_charging(bool enable_charging) @@ -87,27 +91,29 @@ void compute_enable_charging(bool enable_charging) is_charging_enabled = enable_charging; } -int compute_send_charging_message(uint16_t voltage_to_set, uint16_t current_to_set, acc_data_t* bms_data) +int compute_send_charging_message(uint16_t voltage_to_set, + uint16_t current_to_set, acc_data_t *bms_data) { - struct __attribute__((__packed__)){ + struct __attribute__((__packed__)) { uint16_t charger_voltage; // Note the charger voltage sent over should be 10*desired voltage uint16_t charger_current; // Note the charge current sent over should be 10*desired current - uint8_t charger_control; - uint8_t reserved_1; - uint16_t reserved_23; + uint8_t charger_control; + uint8_t reserved_1; + uint16_t reserved_23; } charger_msg_data; charger_msg_data.charger_voltage = voltage_to_set * 10; charger_msg_data.charger_current = current_to_set * 10; - if (is_charging_enabled) { - charger_msg_data.charger_control = 0x00; //0:Start charging. - } else { - charger_msg_data.charger_control = 0xFF; // 1:battery protection, stop charging - } + if (is_charging_enabled) { + charger_msg_data.charger_control = 0x00; //0:Start charging. + } else { + charger_msg_data.charger_control = + 0xFF; // 1:battery protection, stop charging + } - charger_msg_data.reserved_1 = 0x00; - charger_msg_data.reserved_23 = 0x0000; + charger_msg_data.reserved_1 = 0x00; + charger_msg_data.reserved_23 = 0x0000; can_msg_t charger_msg; charger_msg.id = 0x1806E5F4; @@ -121,12 +127,12 @@ int compute_send_charging_message(uint16_t voltage_to_set, uint16_t current_to_s charger_msg.data[2] = charger_msg.data[3]; charger_msg.data[3] = temp; - #ifdef CHARGING_ENABLED +#ifdef CHARGING_ENABLED HAL_StatusTypeDef res = can_send_extended_msg(&can2, &charger_msg); - if(res != HAL_OK) { + if (res != HAL_OK) { printf("CAN ERROR CODE %X", res); } - #endif +#endif return 0; } @@ -143,18 +149,22 @@ bool compute_charger_connected() // return; // } -uint8_t compute_set_fan_speed(TIM_HandleTypeDef* pwmhandle, fan_select_t fan_select, uint8_t duty_cycle) +uint8_t compute_set_fan_speed(TIM_HandleTypeDef *pwmhandle, + fan_select_t fan_select, uint8_t duty_cycle) { - if (!pwmhandle) return -1; - if (fan_select >= FANMAX) return -1; - if (duty_cycle > 100) return -1; + if (!pwmhandle) + return -1; + if (fan_select >= FANMAX) + return -1; + if (duty_cycle > 100) + return -1; uint32_t CCR_value = 0; uint32_t channel = fan_channels[fan_select]; CCR_value = (pwmhandle->Instance->ARR * duty_cycle) / 100; - __HAL_TIM_SET_COMPARE(pwmhandle, channel, CCR_value); - + __HAL_TIM_SET_COMPARE(pwmhandle, channel, CCR_value); + return 0; } @@ -162,7 +172,7 @@ void compute_set_fault(int fault_state) { //TODO work with charger fw on this HAL_GPIO_WritePin(GPIOA, Fault_Output_Pin, !fault_state); - //if (true) digitalWrite(CHARGE_SAFETY_RELAY, 1); + //if (true) digitalWrite(CHARGE_SAFETY_RELAY, 1); } int16_t compute_get_pack_current() @@ -188,15 +198,18 @@ int16_t compute_get_pack_current() // return current; static const float CURRENT_LOWCHANNEL_MAX = 75.0; //Amps - static const float CURRENT_LOWCHANNEL_MIN = -75.0; //Amps - // static const float CURRENT_SUPPLY_VOLTAGE = 5.038; - static const float CURRENT_ADC_RESOLUTION = 5.0 / MAX_ADC_RESOLUTION; + static const float CURRENT_LOWCHANNEL_MIN = -75.0; //Amps + // static const float CURRENT_SUPPLY_VOLTAGE = 5.038; + static const float CURRENT_ADC_RESOLUTION = 5.0 / MAX_ADC_RESOLUTION; - static const float CURRENT_LOWCHANNEL_OFFSET = 2.500; // Calibrated with current = 0A - static const float CURRENT_HIGHCHANNEL_OFFSET = 2.500; // Calibrated with current = 0A + static const float CURRENT_LOWCHANNEL_OFFSET = + 2.500; // Calibrated with current = 0A + static const float CURRENT_HIGHCHANNEL_OFFSET = + 2.500; // Calibrated with current = 0A - static const float HIGHCHANNEL_GAIN = 1 / 0.0041; // Calibrated with current = 5A, 10A, 20A - static const float LOWCHANNEL_GAIN = 1 / 0.0267; + static const float HIGHCHANNEL_GAIN = + 1 / 0.0041; // Calibrated with current = 5A, 10A, 20A + static const float LOWCHANNEL_GAIN = 1 / 0.0267; // Change ADC channel to read the high current sensor change_adc1_channel(VOUT_CHANNEL); @@ -212,36 +225,46 @@ int16_t compute_get_pack_current() HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); int ref_5V = HAL_ADC_GetValue(&hadc1); - - int16_t ref_voltage_raw = (int16_t)(1000.0f * ((float)ref_5V * CURRENT_ADC_RESOLUTION)); - int16_t high_current_voltage_raw = (int16_t)(1000.0f * ((float)raw_high_current * CURRENT_ADC_RESOLUTION)); - high_current_voltage_raw = (int16_t)(5000.0f * high_current_voltage_raw / (float) ref_voltage_raw) ; + int16_t ref_voltage_raw = + (int16_t)(1000.0f * ((float)ref_5V * CURRENT_ADC_RESOLUTION)); - int16_t high_current = (high_current_voltage_raw - (1000 * CURRENT_HIGHCHANNEL_OFFSET)) * (1/4.0f); //* (HIGHCHANNEL_GAIN/100.0f))/1000; + int16_t high_current_voltage_raw = + (int16_t)(1000.0f * + ((float)raw_high_current * CURRENT_ADC_RESOLUTION)); + high_current_voltage_raw = + (int16_t)(5000.0f * high_current_voltage_raw / + (float)ref_voltage_raw); - int16_t low_current_voltage_raw = (int16_t)(1000.0f * ((float)raw_low_current * CURRENT_ADC_RESOLUTION)); - low_current_voltage_raw = (int16_t)(5000.0f * low_current_voltage_raw / (float) ref_voltage_raw) ; + int16_t high_current = (high_current_voltage_raw - + (1000 * CURRENT_HIGHCHANNEL_OFFSET)) * + (1 / 4.0f); //* (HIGHCHANNEL_GAIN/100.0f))/1000; - int16_t low_current = (float)(low_current_voltage_raw - (1000 * CURRENT_LOWCHANNEL_OFFSET)) * (1/26.7); //* (LOWCHANNEL_GAIN/100.0f))/1000; + int16_t low_current_voltage_raw = + (int16_t)(1000.0f * + ((float)raw_low_current * CURRENT_ADC_RESOLUTION)); + low_current_voltage_raw = (int16_t)(5000.0f * low_current_voltage_raw / + (float)ref_voltage_raw); - // If the current is scoped within the range of the low channel, use the low channel + int16_t low_current = (float)(low_current_voltage_raw - + (1000 * CURRENT_LOWCHANNEL_OFFSET)) * + (1 / 26.7); //* (LOWCHANNEL_GAIN/100.0f))/1000; + // If the current is scoped within the range of the low channel, use the low channel - if((low_current < CURRENT_LOWCHANNEL_MAX - 5.0 && low_current >= 0) || (low_current > CURRENT_LOWCHANNEL_MIN + 5.0 && low_current < 0)) - { + if ((low_current < CURRENT_LOWCHANNEL_MAX - 5.0 && low_current >= 0) || + (low_current > CURRENT_LOWCHANNEL_MIN + 5.0 && low_current < 0)) { //printf("\rLow Current: %d\n", -low_current); - return -low_current; - } + return -low_current; + } //printf("\rHigh Current: %d\n", -high_current); - return -high_current; + return -high_current; } -void compute_send_mc_discharge_message(acc_data_t* bmsdata) +void compute_send_mc_discharge_message(acc_data_t *bmsdata) { - - struct __attribute__((__packed__)){ + struct __attribute__((__packed__)) { uint16_t max_discharge; } discharge_data; @@ -249,21 +272,21 @@ void compute_send_mc_discharge_message(acc_data_t* bmsdata) discharge_data.max_discharge = 10 * bmsdata->discharge_limit; /* convert to big endian */ - endian_swap(&discharge_data.max_discharge, sizeof(discharge_data.max_discharge)); + endian_swap(&discharge_data.max_discharge, + sizeof(discharge_data.max_discharge)); - - can_msg_t mc_msg = {0}; - mc_msg.id = 0x156; // 0x0A is the dcl id, 0x22 is the device id set by us + can_msg_t mc_msg = { 0 }; + mc_msg.id = + 0x156; // 0x0A is the dcl id, 0x22 is the device id set by us mc_msg.len = 8; memcpy(mc_msg.data, &discharge_data, sizeof(discharge_data)); can_send_msg(&can1, &mc_msg); } -void compute_send_mc_charge_message(acc_data_t* bmsdata) +void compute_send_mc_charge_message(acc_data_t *bmsdata) { - - struct __attribute__((__packed__)){ + struct __attribute__((__packed__)) { int16_t max_charge; } charge_data; @@ -273,18 +296,18 @@ void compute_send_mc_charge_message(acc_data_t* bmsdata) /* convert to big endian */ endian_swap(&charge_data.max_charge, sizeof(charge_data.max_charge)); - can_msg_t mc_msg = {0}; - mc_msg.id = 0x176; // 0x0A is the dcl id, 0x157 is the device id set by us + can_msg_t mc_msg = { 0 }; + mc_msg.id = + 0x176; // 0x0A is the dcl id, 0x157 is the device id set by us mc_msg.len = 8; memcpy(mc_msg.data, &charge_data, sizeof(charge_data)); can_send_msg(&can1, &mc_msg); } -void compute_send_acc_status_message(acc_data_t* bmsdata) +void compute_send_acc_status_message(acc_data_t *bmsdata) { - - struct __attribute__((__packed__)){ + struct __attribute__((__packed__)) { uint16_t packVolt; uint16_t pack_current; uint16_t pack_ah; @@ -292,287 +315,322 @@ void compute_send_acc_status_message(acc_data_t* bmsdata) uint8_t pack_health; } acc_status_msg_data; - acc_status_msg_data.packVolt = bmsdata->pack_voltage; - acc_status_msg_data.pack_current = (uint16_t) (bmsdata->pack_current); // convert with 2s complement - acc_status_msg_data.pack_ah = 0; - acc_status_msg_data.pack_soc = bmsdata->soc; - acc_status_msg_data.pack_health = 0; + acc_status_msg_data.packVolt = bmsdata->pack_voltage; + acc_status_msg_data.pack_current = + (uint16_t)(bmsdata->pack_current); // convert with 2s complement + acc_status_msg_data.pack_ah = 0; + acc_status_msg_data.pack_soc = bmsdata->soc; + acc_status_msg_data.pack_health = 0; /* convert to big endian */ - endian_swap(&acc_status_msg_data.packVolt, sizeof(acc_status_msg_data.packVolt)); - endian_swap(&acc_status_msg_data.pack_current, sizeof(acc_status_msg_data.pack_current)); - endian_swap(&acc_status_msg_data.pack_ah, sizeof(acc_status_msg_data.pack_ah)); + endian_swap(&acc_status_msg_data.packVolt, + sizeof(acc_status_msg_data.packVolt)); + endian_swap(&acc_status_msg_data.pack_current, + sizeof(acc_status_msg_data.pack_current)); + endian_swap(&acc_status_msg_data.pack_ah, + sizeof(acc_status_msg_data.pack_ah)); can_msg_t acc_msg; acc_msg.id = 0x80; acc_msg.len = sizeof(acc_status_msg_data); memcpy(acc_msg.data, &acc_status_msg_data, sizeof(acc_status_msg_data)); - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif can_send_msg(line, &acc_msg); } -void compute_send_bms_status_message(acc_data_t* bmsdata, int bms_state, bool balance) +void compute_send_bms_status_message(acc_data_t *bmsdata, int bms_state, + bool balance) { - struct __attribute__((__packed__)){ - uint8_t state; - uint32_t fault; - int8_t temp_avg; - uint8_t temp_internal; - uint8_t balance; - } bms_status_msg_data; - - bms_status_msg_data.temp_avg = (int8_t)(bmsdata->avg_temp); - bms_status_msg_data.state = (uint8_t)(bms_state); - bms_status_msg_data.fault = bmsdata->fault_code; - bms_status_msg_data.temp_internal = (uint8_t)(0); - bms_status_msg_data.balance = (uint8_t)(balance); + struct __attribute__((__packed__)) { + uint8_t state; + uint32_t fault; + int8_t temp_avg; + uint8_t temp_internal; + uint8_t balance; + } bms_status_msg_data; + + bms_status_msg_data.temp_avg = (int8_t)(bmsdata->avg_temp); + bms_status_msg_data.state = (uint8_t)(bms_state); + bms_status_msg_data.fault = bmsdata->fault_code; + bms_status_msg_data.temp_internal = (uint8_t)(0); + bms_status_msg_data.balance = (uint8_t)(balance); /* convert to big endian */ - endian_swap(&bms_status_msg_data.fault, sizeof(bms_status_msg_data.fault)); - - can_msg_t acc_msg; - acc_msg.id = 0x81; - acc_msg.len = sizeof(bms_status_msg_data); - memcpy(acc_msg.data, &bms_status_msg_data, sizeof(bms_status_msg_data)); - - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif - can_send_msg(line, &acc_msg); + endian_swap(&bms_status_msg_data.fault, + sizeof(bms_status_msg_data.fault)); + + can_msg_t acc_msg; + acc_msg.id = 0x81; + acc_msg.len = sizeof(bms_status_msg_data); + memcpy(acc_msg.data, &bms_status_msg_data, sizeof(bms_status_msg_data)); + +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif + can_send_msg(line, &acc_msg); } void compute_send_shutdown_ctrl_message(uint8_t mpe_state) { - struct __attribute__((__packed__)){ - uint8_t mpeState; - } shutdown_control_msg_data; + struct __attribute__((__packed__)) { + uint8_t mpeState; + } shutdown_control_msg_data; - shutdown_control_msg_data.mpeState = mpe_state; + shutdown_control_msg_data.mpeState = mpe_state; - can_msg_t acc_msg; - acc_msg.id = 0x82; - acc_msg.len = sizeof(shutdown_control_msg_data); - memcpy(acc_msg.data, &shutdown_control_msg_data, sizeof(shutdown_control_msg_data)); + can_msg_t acc_msg; + acc_msg.id = 0x82; + acc_msg.len = sizeof(shutdown_control_msg_data); + memcpy(acc_msg.data, &shutdown_control_msg_data, + sizeof(shutdown_control_msg_data)); - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif - can_send_msg(line, &acc_msg); + can_send_msg(line, &acc_msg); } -void compute_send_cell_data_message(acc_data_t* bmsdata) +void compute_send_cell_data_message(acc_data_t *bmsdata) { - struct __attribute__((__packed__)){ - uint16_t high_cell_voltage; - uint8_t high_cell_id; - uint16_t low_cell_voltage; - uint8_t low_cell_id; - uint16_t volt_avg; - } cell_data_msg_data; - - cell_data_msg_data.high_cell_voltage = bmsdata->max_voltage.val; - cell_data_msg_data.high_cell_id = (bmsdata->max_voltage.chipIndex << 4) | bmsdata->max_voltage.cellNum; - cell_data_msg_data.low_cell_voltage = bmsdata->min_voltage.val; - cell_data_msg_data.low_cell_id = (bmsdata->min_voltage.chipIndex << 4) | bmsdata->min_voltage.cellNum; - cell_data_msg_data.volt_avg = bmsdata->avg_voltage; + struct __attribute__((__packed__)) { + uint16_t high_cell_voltage; + uint8_t high_cell_id; + uint16_t low_cell_voltage; + uint8_t low_cell_id; + uint16_t volt_avg; + } cell_data_msg_data; + + cell_data_msg_data.high_cell_voltage = bmsdata->max_voltage.val; + cell_data_msg_data.high_cell_id = + (bmsdata->max_voltage.chipIndex << 4) | + bmsdata->max_voltage.cellNum; + cell_data_msg_data.low_cell_voltage = bmsdata->min_voltage.val; + cell_data_msg_data.low_cell_id = (bmsdata->min_voltage.chipIndex << 4) | + bmsdata->min_voltage.cellNum; + cell_data_msg_data.volt_avg = bmsdata->avg_voltage; /* convert to big endian */ - endian_swap(&cell_data_msg_data.high_cell_voltage, sizeof(cell_data_msg_data.high_cell_voltage)); - endian_swap(&cell_data_msg_data.low_cell_voltage, sizeof(cell_data_msg_data.low_cell_voltage)); - endian_swap(&cell_data_msg_data.volt_avg, sizeof(cell_data_msg_data.volt_avg)); - - can_msg_t acc_msg; - acc_msg.id = 0x83; - acc_msg.len = sizeof(cell_data_msg_data); - memcpy(acc_msg.data, &cell_data_msg_data, sizeof(cell_data_msg_data)); - - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif - - can_send_msg(line, &acc_msg); + endian_swap(&cell_data_msg_data.high_cell_voltage, + sizeof(cell_data_msg_data.high_cell_voltage)); + endian_swap(&cell_data_msg_data.low_cell_voltage, + sizeof(cell_data_msg_data.low_cell_voltage)); + endian_swap(&cell_data_msg_data.volt_avg, + sizeof(cell_data_msg_data.volt_avg)); + + can_msg_t acc_msg; + acc_msg.id = 0x83; + acc_msg.len = sizeof(cell_data_msg_data); + memcpy(acc_msg.data, &cell_data_msg_data, sizeof(cell_data_msg_data)); + +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif + + can_send_msg(line, &acc_msg); } -void compute_send_cell_voltage_message(uint8_t cell_id, uint16_t instant_voltage, - uint16_t internal_Res, uint8_t shunted, - uint16_t open_voltage) +void compute_send_cell_voltage_message(uint8_t cell_id, + uint16_t instant_voltage, + uint16_t internal_Res, uint8_t shunted, + uint16_t open_voltage) { - struct __attribute__((__packed__)){ - uint8_t cellID; - uint16_t instantVoltage; - uint16_t internalResistance; - uint8_t shunted; - uint16_t openVoltage; - } cell_voltage_msg_data; - - cell_voltage_msg_data.cellID = cell_id; - cell_voltage_msg_data.instantVoltage = instant_voltage; - cell_voltage_msg_data.internalResistance = internal_Res; - cell_voltage_msg_data.shunted = shunted; - cell_voltage_msg_data.openVoltage = open_voltage; + struct __attribute__((__packed__)) { + uint8_t cellID; + uint16_t instantVoltage; + uint16_t internalResistance; + uint8_t shunted; + uint16_t openVoltage; + } cell_voltage_msg_data; + + cell_voltage_msg_data.cellID = cell_id; + cell_voltage_msg_data.instantVoltage = instant_voltage; + cell_voltage_msg_data.internalResistance = internal_Res; + cell_voltage_msg_data.shunted = shunted; + cell_voltage_msg_data.openVoltage = open_voltage; /* convert to big endian */ - endian_swap(&cell_voltage_msg_data.instantVoltage, sizeof(cell_voltage_msg_data.instantVoltage)); - endian_swap(&cell_voltage_msg_data.internalResistance, sizeof(cell_voltage_msg_data.internalResistance)); - endian_swap(&cell_voltage_msg_data.openVoltage, sizeof(cell_voltage_msg_data.openVoltage)); - - can_msg_t acc_msg; - acc_msg.id = 0x87; - acc_msg.len = sizeof(cell_voltage_msg_data); - memcpy(acc_msg.data, &cell_voltage_msg_data, sizeof(cell_voltage_msg_data)); - - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif - - can_send_msg(line, &acc_msg); + endian_swap(&cell_voltage_msg_data.instantVoltage, + sizeof(cell_voltage_msg_data.instantVoltage)); + endian_swap(&cell_voltage_msg_data.internalResistance, + sizeof(cell_voltage_msg_data.internalResistance)); + endian_swap(&cell_voltage_msg_data.openVoltage, + sizeof(cell_voltage_msg_data.openVoltage)); + + can_msg_t acc_msg; + acc_msg.id = 0x87; + acc_msg.len = sizeof(cell_voltage_msg_data); + memcpy(acc_msg.data, &cell_voltage_msg_data, + sizeof(cell_voltage_msg_data)); + +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif + + can_send_msg(line, &acc_msg); } -void compute_send_current_message(acc_data_t* bmsdata) +void compute_send_current_message(acc_data_t *bmsdata) { - struct __attribute__((__packed__)){ - uint16_t dcl; - int16_t ccl; - uint16_t pack_curr; - } current_status_msg_data; + struct __attribute__((__packed__)) { + uint16_t dcl; + int16_t ccl; + uint16_t pack_curr; + } current_status_msg_data; - current_status_msg_data.dcl = bmsdata->discharge_limit; - current_status_msg_data.ccl = -1 * bmsdata->charge_limit; - current_status_msg_data.pack_curr = bmsdata->pack_current; + current_status_msg_data.dcl = bmsdata->discharge_limit; + current_status_msg_data.ccl = -1 * bmsdata->charge_limit; + current_status_msg_data.pack_curr = bmsdata->pack_current; /* convert to big endian */ - endian_swap(¤t_status_msg_data.dcl, sizeof(current_status_msg_data.dcl)); - endian_swap(¤t_status_msg_data.ccl, sizeof(current_status_msg_data.ccl)); - endian_swap(¤t_status_msg_data.pack_curr, sizeof(current_status_msg_data.pack_curr)); - - can_msg_t acc_msg; - acc_msg.id = 0x86; - acc_msg.len = sizeof(current_status_msg_data); - memcpy(acc_msg.data, ¤t_status_msg_data, sizeof(current_status_msg_data)); - - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif - - can_send_msg(line, &acc_msg); + endian_swap(¤t_status_msg_data.dcl, + sizeof(current_status_msg_data.dcl)); + endian_swap(¤t_status_msg_data.ccl, + sizeof(current_status_msg_data.ccl)); + endian_swap(¤t_status_msg_data.pack_curr, + sizeof(current_status_msg_data.pack_curr)); + + can_msg_t acc_msg; + acc_msg.id = 0x86; + acc_msg.len = sizeof(current_status_msg_data); + memcpy(acc_msg.data, ¤t_status_msg_data, + sizeof(current_status_msg_data)); + +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif + + can_send_msg(line, &acc_msg); } -void compute_send_cell_temp_message(acc_data_t* bmsdata) +void compute_send_cell_temp_message(acc_data_t *bmsdata) { - struct __attribute__((__packed__)){ - uint16_t max_cell_temp; - uint8_t max_cell_id; - uint16_t min_cell_temp; - uint8_t min_cell_id; - uint16_t average_temp; - } cell_temp_msg_data; - - cell_temp_msg_data.max_cell_temp = bmsdata->max_temp.val; - cell_temp_msg_data.max_cell_id = (bmsdata->max_temp.chipIndex << 4) | (bmsdata->max_temp.cellNum - 17); - cell_temp_msg_data.min_cell_temp = bmsdata->min_temp.val; - cell_temp_msg_data.min_cell_id = (bmsdata->min_temp.chipIndex << 4) | (bmsdata->min_temp.cellNum - 17); - cell_temp_msg_data.average_temp = bmsdata->avg_temp; + struct __attribute__((__packed__)) { + uint16_t max_cell_temp; + uint8_t max_cell_id; + uint16_t min_cell_temp; + uint8_t min_cell_id; + uint16_t average_temp; + } cell_temp_msg_data; + + cell_temp_msg_data.max_cell_temp = bmsdata->max_temp.val; + cell_temp_msg_data.max_cell_id = (bmsdata->max_temp.chipIndex << 4) | + (bmsdata->max_temp.cellNum - 17); + cell_temp_msg_data.min_cell_temp = bmsdata->min_temp.val; + cell_temp_msg_data.min_cell_id = (bmsdata->min_temp.chipIndex << 4) | + (bmsdata->min_temp.cellNum - 17); + cell_temp_msg_data.average_temp = bmsdata->avg_temp; /* convert to big endian */ - endian_swap(&cell_temp_msg_data.max_cell_temp, sizeof(cell_temp_msg_data.max_cell_temp)); - endian_swap(&cell_temp_msg_data.min_cell_temp, sizeof(cell_temp_msg_data.min_cell_temp)); - endian_swap(&cell_temp_msg_data.average_temp, sizeof(cell_temp_msg_data.average_temp)); - - can_msg_t acc_msg; - acc_msg.id = 0x84; - acc_msg.len = sizeof(cell_temp_msg_data); - memcpy(acc_msg.data, &cell_temp_msg_data, sizeof(cell_temp_msg_data)); - - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif - - can_send_msg(line, &acc_msg); + endian_swap(&cell_temp_msg_data.max_cell_temp, + sizeof(cell_temp_msg_data.max_cell_temp)); + endian_swap(&cell_temp_msg_data.min_cell_temp, + sizeof(cell_temp_msg_data.min_cell_temp)); + endian_swap(&cell_temp_msg_data.average_temp, + sizeof(cell_temp_msg_data.average_temp)); + + can_msg_t acc_msg; + acc_msg.id = 0x84; + acc_msg.len = sizeof(cell_temp_msg_data); + memcpy(acc_msg.data, &cell_temp_msg_data, sizeof(cell_temp_msg_data)); + +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif + + can_send_msg(line, &acc_msg); } -void compute_send_segment_temp_message(acc_data_t* bmsdata) +void compute_send_segment_temp_message(acc_data_t *bmsdata) { - struct __attribute__((__packed__)){ - int8_t segment1_average_temp; - int8_t segment2_average_temp; - int8_t segment3_average_temp; - int8_t segment4_average_temp; + struct __attribute__((__packed__)) { + int8_t segment1_average_temp; + int8_t segment2_average_temp; + int8_t segment3_average_temp; + int8_t segment4_average_temp; int8_t segment5_average_temp; int8_t segment6_average_temp; - } segment_temp_msg_data; - - segment_temp_msg_data.segment1_average_temp = bmsdata->segment_average_temps[0]; - segment_temp_msg_data.segment2_average_temp = bmsdata->segment_average_temps[1]; - segment_temp_msg_data.segment3_average_temp = bmsdata->segment_average_temps[2]; - segment_temp_msg_data.segment4_average_temp = bmsdata->segment_average_temps[3]; - segment_temp_msg_data.segment5_average_temp = bmsdata->segment_average_temps[4]; - segment_temp_msg_data.segment6_average_temp = bmsdata->segment_average_temps[5]; + } segment_temp_msg_data; + + segment_temp_msg_data.segment1_average_temp = + bmsdata->segment_average_temps[0]; + segment_temp_msg_data.segment2_average_temp = + bmsdata->segment_average_temps[1]; + segment_temp_msg_data.segment3_average_temp = + bmsdata->segment_average_temps[2]; + segment_temp_msg_data.segment4_average_temp = + bmsdata->segment_average_temps[3]; + segment_temp_msg_data.segment5_average_temp = + bmsdata->segment_average_temps[4]; + segment_temp_msg_data.segment6_average_temp = + bmsdata->segment_average_temps[5]; - can_msg_t acc_msg; - acc_msg.id = 0x85; - acc_msg.len = sizeof(segment_temp_msg_data); - memcpy(acc_msg.data, &segment_temp_msg_data, sizeof(segment_temp_msg_data)); + can_msg_t acc_msg; + acc_msg.id = 0x85; + acc_msg.len = sizeof(segment_temp_msg_data); + memcpy(acc_msg.data, &segment_temp_msg_data, + sizeof(segment_temp_msg_data)); - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif - can_send_msg(line, &acc_msg); + can_send_msg(line, &acc_msg); } void compute_send_fault_message(uint8_t status, int16_t curr, int16_t in_dcl) { - struct __attribute__((__packed__)){ - uint8_t status; - int16_t pack_curr; - int16_t dcl; - } fault_msg_data; + struct __attribute__((__packed__)) { + uint8_t status; + int16_t pack_curr; + int16_t dcl; + } fault_msg_data; - fault_msg_data.status = status; + fault_msg_data.status = status; fault_msg_data.pack_curr = curr; fault_msg_data.dcl = in_dcl; - endian_swap(&fault_msg_data.pack_curr, sizeof(fault_msg_data.pack_curr)); + endian_swap(&fault_msg_data.pack_curr, + sizeof(fault_msg_data.pack_curr)); endian_swap(&fault_msg_data.dcl, sizeof(fault_msg_data.dcl)); - can_msg_t acc_msg; - acc_msg.id = 0x703; - acc_msg.len = 5; - memcpy(acc_msg.data, &fault_msg_data, sizeof(fault_msg_data)); + can_msg_t acc_msg; + acc_msg.id = 0x703; + acc_msg.len = 5; + memcpy(acc_msg.data, &fault_msg_data, sizeof(fault_msg_data)); - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif - can_send_msg(line, &acc_msg); + can_send_msg(line, &acc_msg); } -void compute_send_voltage_noise_message(acc_data_t* bmsdata) +void compute_send_voltage_noise_message(acc_data_t *bmsdata) { - struct __attribute__((__packed__)){ + struct __attribute__((__packed__)) { uint8_t seg1_noise; uint8_t seg2_noise; uint8_t seg3_noise; @@ -581,38 +639,45 @@ void compute_send_voltage_noise_message(acc_data_t* bmsdata) uint8_t seg6_noise; } voltage_noise_msg_data; - voltage_noise_msg_data.seg1_noise = bmsdata->segment_noise_percentage[0]; - voltage_noise_msg_data.seg2_noise = bmsdata->segment_noise_percentage[1]; - voltage_noise_msg_data.seg3_noise = bmsdata->segment_noise_percentage[2]; - voltage_noise_msg_data.seg4_noise = bmsdata->segment_noise_percentage[3]; - voltage_noise_msg_data.seg5_noise = bmsdata->segment_noise_percentage[4]; - voltage_noise_msg_data.seg6_noise = bmsdata->segment_noise_percentage[5]; + voltage_noise_msg_data.seg1_noise = + bmsdata->segment_noise_percentage[0]; + voltage_noise_msg_data.seg2_noise = + bmsdata->segment_noise_percentage[1]; + voltage_noise_msg_data.seg3_noise = + bmsdata->segment_noise_percentage[2]; + voltage_noise_msg_data.seg4_noise = + bmsdata->segment_noise_percentage[3]; + voltage_noise_msg_data.seg5_noise = + bmsdata->segment_noise_percentage[4]; + voltage_noise_msg_data.seg6_noise = + bmsdata->segment_noise_percentage[5]; can_msg_t acc_msg; - acc_msg.id = 0x88; + acc_msg.id = 0x88; acc_msg.len = sizeof(voltage_noise_msg_data); - memcpy(acc_msg.data, &voltage_noise_msg_data, sizeof(voltage_noise_msg_data)); + memcpy(acc_msg.data, &voltage_noise_msg_data, + sizeof(voltage_noise_msg_data)); - #ifdef CHARGING_ENABLED - can_t* line = &can2; - #else - can_t* line = &can1; - #endif +#ifdef CHARGING_ENABLED + can_t *line = &can2; +#else + can_t *line = &can1; +#endif can_send_msg(line, &acc_msg); -} +} void change_adc1_channel(uint8_t channel) { + ADC_ChannelConfTypeDef sConfig = { 0 }; - ADC_ChannelConfTypeDef sConfig = {0}; - - if (channel == REF_CHANNEL) sConfig.Channel = ADC_CHANNEL_9; - else if (channel == VOUT_CHANNEL) sConfig.Channel = ADC_CHANNEL_15; - - sConfig.Rank = 1; - sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) - { - Error_Handler(); - } + if (channel == REF_CHANNEL) + sConfig.Channel = ADC_CHANNEL_9; + else if (channel == VOUT_CHANNEL) + sConfig.Channel = ADC_CHANNEL_15; + + sConfig.Rank = 1; + sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { + Error_Handler(); + } } diff --git a/Core/Src/eepromdirectory.c b/Core/Src/eepromdirectory.c index db4ab99..df27ebb 100644 --- a/Core/Src/eepromdirectory.c +++ b/Core/Src/eepromdirectory.c @@ -2,166 +2,157 @@ #include "m24c32.h" void eepromInit() -{ - eeprom_data[0].id = (char*)("ROOT"); - eeprom_data[0].size = 1; - - eeprom_data[1].id = (char*)("FAULTS"); - eeprom_data[1].size = 21; - - // Initialize EEPROM addresses given data and length - - int i = 1; - int offset = 0; - - /* initialize root offset to zero */ - eeprom_data[0].address = EEPROM_ROOT_ADDR; - - /* continue through array, setting offsets *//* private funciton prototypes */ - while (eeprom_data[i].id != NULL) - { - offset += eeprom_data[i-1].size; - eeprom_data[i].address = offset; - i++; - } - - // TODO ADD THIS BACK AND FIGURE OUT WHAT THE FUCK ITS TRYING TO DO - //Initialize first byte of faults partition to contain the address of the end of the partition so that the - //log_fault function logs the first fault to the first 4 bytes in the partition. - // eeprom_write_data_key((char*)("FAULTS"), (eeprom_data[eeprom_get_index((char*)("FAULTS"))] - // + eeprom_data[eeprom_get_index((char*)("FAULTS"))].size - 3), 1); +{ + eeprom_data[0].id = (char *)("ROOT"); + eeprom_data[0].size = 1; + + eeprom_data[1].id = (char *)("FAULTS"); + eeprom_data[1].size = 21; + + // Initialize EEPROM addresses given data and length + + int i = 1; + int offset = 0; + + /* initialize root offset to zero */ + eeprom_data[0].address = EEPROM_ROOT_ADDR; + + /* continue through array, setting offsets */ /* private funciton prototypes */ + while (eeprom_data[i].id != NULL) { + offset += eeprom_data[i - 1].size; + eeprom_data[i].address = offset; + i++; + } + + // TODO ADD THIS BACK AND FIGURE OUT WHAT THE FUCK ITS TRYING TO DO + //Initialize first byte of faults partition to contain the address of the end of the partition so that the + //log_fault function logs the first fault to the first 4 bytes in the partition. + // eeprom_write_data_key((char*)("FAULTS"), (eeprom_data[eeprom_get_index((char*)("FAULTS"))] + // + eeprom_data[eeprom_get_index((char*)("FAULTS"))].size - 3), 1); } uint16_t eeprom_get_index(char *key) { - /* find the index of the key in the eeprom_data array */ - int i = 0; - while (eeprom_data[i].id != NULL) - { - if (eeprom_data[i].id == key) - { - return eeprom_data[i].address; - } - - i++; - } - return -1; + /* find the index of the key in the eeprom_data array */ + int i = 0; + while (eeprom_data[i].id != NULL) { + if (eeprom_data[i].id == key) { + return eeprom_data[i].address; + } + + i++; + } + return -1; } -char* eeprom_get_key(int index) +char *eeprom_get_key(int index) { - /* find the key at the index in the eeprom_data array */ - int i = 0; - while (eeprom_data[i].id != NULL) - { - if (eeprom_data[i].address == index) - { - return eeprom_data[i].id; - } - - i++; - } - return NULL; + /* find the key at the index in the eeprom_data array */ + int i = 0; + while (eeprom_data[i].id != NULL) { + if (eeprom_data[i].address == index) { + return eeprom_data[i].id; + } + + i++; + } + return NULL; } bool eeprom_read_data_key(char *key, void *data, uint16_t size) { - if(!data) { - return false; - } - /* read data from eeprom given key and size */ - int address = eeprom_get_index(key); - eeprom_read(address, data, size); - - return true; - + if (!data) { + return false; + } + /* read data from eeprom given key and size */ + int address = eeprom_get_index(key); + eeprom_read(address, data, size); + + return true; } bool eeprom_read_data_address(uint16_t address, void *data, uint16_t size) { - if(!data) { - return false; - } - /* read data from eeprom given index */ - eeprom_read(address, data, size); - return true; + if (!data) { + return false; + } + /* read data from eeprom given index */ + eeprom_read(address, data, size); + return true; } bool eeprom_write_data_key(char *key, void *data, uint16_t size) { - if(!data) { - return false; - } - /* write data to eeprom given key, offset, and size of data */ - int address = eeprom_get_index(key); - eeprom_write(address, data, size); - return true; + if (!data) { + return false; + } + /* write data to eeprom given key, offset, and size of data */ + int address = eeprom_get_index(key); + eeprom_write(address, data, size); + return true; } bool eeprom_write_data_address(uint16_t address, void *data, uint16_t size) { - if(!data) { - return false; - } - /* write data to eeprom given page, offset, and size of data */ - eeprom_write(address, data, size); - return true; + if (!data) { + return false; + } + /* write data to eeprom given page, offset, and size of data */ + eeprom_write(address, data, size); + return true; } void log_fault(uint32_t fault_code) { - uint32_t fault = fault_code; - //The next address to write a fault to is located in the first byte of the FAULTS partition. - uint8_t reg_to_write; - eeprom_read_data_address(eeprom_get_index((char*)("FAULTS")), ®_to_write, 1); - - uint8_t startIndex = eeprom_data[eeprom_get_index((char*)("FAULTS"))].address; - uint8_t size = eeprom_data[eeprom_get_index((char*)("FAULTS"))].size; - - /* if the index is at the end of the partition, wrap around (currently store 5 faults, so max = 5 + offset) */ - if (reg_to_write == size + startIndex - 3) - { - /* first byte of partition is the index of the most recent fault, faults begin at second byte */ - reg_to_write = startIndex + 1; - } - else - { - reg_to_write += 4; - } - - /* write the fault code*/ - eeprom_write_data_address(reg_to_write, &fault, 4); - /* update first byte of faults partition*/ - eeprom_write_data_address(startIndex, ®_to_write, 1); -} + uint32_t fault = fault_code; + //The next address to write a fault to is located in the first byte of the FAULTS partition. + uint8_t reg_to_write; + eeprom_read_data_address(eeprom_get_index((char *)("FAULTS")), + ®_to_write, 1); + + uint8_t startIndex = + eeprom_data[eeprom_get_index((char *)("FAULTS"))].address; + uint8_t size = eeprom_data[eeprom_get_index((char *)("FAULTS"))].size; + + /* if the index is at the end of the partition, wrap around (currently store 5 faults, so max = 5 + offset) */ + if (reg_to_write == size + startIndex - 3) { + /* first byte of partition is the index of the most recent fault, faults begin at second byte */ + reg_to_write = startIndex + 1; + } else { + reg_to_write += 4; + } + + /* write the fault code*/ + eeprom_write_data_address(reg_to_write, &fault, 4); + /* update first byte of faults partition*/ + eeprom_write_data_address(startIndex, ®_to_write, 1); +} void get_faults() { - uint8_t curr_reg; - eeprom_read_data_key("FAULTS", &curr_reg, 1); - - uint8_t startAddress = eeprom_data[eeprom_get_index((char*)("FAULTS"))].address; - uint8_t size = eeprom_data[eeprom_get_index((char*)("FAULTS"))].size; - - /* read and store the faults */ - - int currIter = 0; - while (currIter < NUM_EEPROM_FAULTS) - { - eeprom_read_data_address(curr_reg, &eeprom_faults[currIter], 4); - currIter++; - - /* if the index is at the end of the partition, wrap around (5 faults * 4 bytes per fault + offset - 3 for start of fault) */ - if (curr_reg == size + startAddress - 3) - { - /* first byte of partition is the index of the most recent fault, faults begin at second byte */ - curr_reg= startAddress + 1; - } - - else - { - /* 4 bytes per fault */ - curr_reg += 4; - } - } + uint8_t curr_reg; + eeprom_read_data_key("FAULTS", &curr_reg, 1); + + uint8_t startAddress = + eeprom_data[eeprom_get_index((char *)("FAULTS"))].address; + uint8_t size = eeprom_data[eeprom_get_index((char *)("FAULTS"))].size; + + /* read and store the faults */ + + int currIter = 0; + while (currIter < NUM_EEPROM_FAULTS) { + eeprom_read_data_address(curr_reg, &eeprom_faults[currIter], 4); + currIter++; + + /* if the index is at the end of the partition, wrap around (5 faults * 4 bytes per fault + offset - 3 for start of fault) */ + if (curr_reg == size + startAddress - 3) { + /* first byte of partition is the index of the most recent fault, faults begin at second byte */ + curr_reg = startAddress + 1; + } + + else { + /* 4 bytes per fault */ + curr_reg += 4; + } + } } \ No newline at end of file diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 8ccebbd..921edf7 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -5,17 +5,17 @@ #include "main.h" #include -#define THERM_WAIT_TIME 500 /* ms */ -#define VOLTAGE_WAIT_TIME 100 /* ms */ -#define THERM_AVG 15 /* Number of values to average */ -#define MAX_VOLT_DELTA 2500 -#define MAX_CONSEC_NOISE 10 -#define GPIO_EXPANDER_ADDR 0x40 -#define GPIO_REGISTER_ADDR 0x09 +#define THERM_WAIT_TIME 500 /* ms */ +#define VOLTAGE_WAIT_TIME 100 /* ms */ +#define THERM_AVG 15 /* Number of values to average */ +#define MAX_VOLT_DELTA 2500 +#define MAX_CONSEC_NOISE 10 +#define GPIO_EXPANDER_ADDR 0x40 +#define GPIO_REGISTER_ADDR 0x09 //TODO ensure spi 1 is correct for talking to segs extern SPI_HandleTypeDef hspi1; -ltc_config* ltc68041; +ltc_config *ltc68041; uint8_t local_config[NUM_CHIPS][6] = {}; uint8_t therm_avg_counter = 0; @@ -32,17 +32,24 @@ int voltage_error = 0; //not faulted int therm_error = 0; //not faulted /* our segments are mapped backwards and in pairs, so they are read in 1,0 then 3,2, etc*/ -const int mapping_correction[12] = {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10}; +const int mapping_correction[12] = { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10 }; uint16_t therm_settle_time_ = 0; const uint32_t VOLT_TEMP_CONV[106] = { -157300, 148800, 140300, 131800, 123300, 114800, 108772, 102744, 96716, 90688, 84660, 80328, 75996, 71664, 67332, -63000, 59860, 56720, 53580, 50440, 47300, 45004, 42708, 40412, 38116, 35820, 34124, 32428, 30732, 29036, 27340, -26076, 24812, 23548, 22284, 21020, 20074, 19128, 18182, 17236, 16290, 15576, 14862, 14148, 13434, 12720, 12176, -11632, 11088, 10544, 10000, 9584, 9168, 8753, 8337, 7921, 7600, 7279, 6957, 6636, 6315, 6065, 5816, 5566, 5317, -5067, 4872, 4676, 4481, 4285, 4090, 3936, 3782, 3627, 3473, 3319, 3197, 3075, 2953, 2831, 2709, 2612, 2514, 2417, -2319, 2222, 2144, 2066, 1988, 1910, 1832, 1769, 1706, 1644, 1581, 1518, 1467, 1416, 1366, 1315, 1264, 1223, 1181, 1140, 1098, 1057}; + 157300, 148800, 140300, 131800, 123300, 114800, 108772, 102744, 96716, + 90688, 84660, 80328, 75996, 71664, 67332, 63000, 59860, 56720, + 53580, 50440, 47300, 45004, 42708, 40412, 38116, 35820, 34124, + 32428, 30732, 29036, 27340, 26076, 24812, 23548, 22284, 21020, + 20074, 19128, 18182, 17236, 16290, 15576, 14862, 14148, 13434, + 12720, 12176, 11632, 11088, 10544, 10000, 9584, 9168, 8753, + 8337, 7921, 7600, 7279, 6957, 6636, 6315, 6065, 5816, + 5566, 5317, 5067, 4872, 4676, 4481, 4285, 4090, 3936, + 3782, 3627, 3473, 3319, 3197, 3075, 2953, 2831, 2709, + 2612, 2514, 2417, 2319, 2222, 2144, 2066, 1988, 1910, + 1832, 1769, 1706, 1644, 1581, 1518, 1467, 1416, 1366, + 1315, 1264, 1223, 1181, 1140, 1098, 1057 +}; const int32_t VOLT_TEMP_CALIB_OFFSET = 0; @@ -55,7 +62,10 @@ void pull_chip_configuration(void); int16_t calc_average(void); int8_t calc_therm_standard_dev(int16_t avg_temp); -void push_chip_configuration() { LTC6804_wrcfg(ltc68041, NUM_CHIPS, local_config); } +void push_chip_configuration() +{ + LTC6804_wrcfg(ltc68041, NUM_CHIPS, local_config); +} void segment_init() { @@ -81,22 +91,23 @@ void segment_init() uint8_t i2c_write_data[NUM_CHIPS][3]; - // Set GPIO expander to output - for(int chip = 0; chip < NUM_CHIPS; chip++) { - i2c_write_data[chip][0] = 0x40; // GPIO expander addr - i2c_write_data[chip][1] = 0x00; // GPIO direction addr - i2c_write_data[chip][2] = 0x00; // Set all to output - } - uint8_t comm_reg_data[NUM_CHIPS][6]; - - serialize_i2c_msg(i2c_write_data, comm_reg_data); - LTC6804_wrcomm(ltc68041, NUM_CHIPS, comm_reg_data); - LTC6804_stcomm(ltc68041, 24); + // Set GPIO expander to output + for (int chip = 0; chip < NUM_CHIPS; chip++) { + i2c_write_data[chip][0] = 0x40; // GPIO expander addr + i2c_write_data[chip][1] = 0x00; // GPIO direction addr + i2c_write_data[chip][2] = 0x00; // Set all to output + } + uint8_t comm_reg_data[NUM_CHIPS][6]; + + serialize_i2c_msg(i2c_write_data, comm_reg_data); + LTC6804_wrcomm(ltc68041, NUM_CHIPS, comm_reg_data); + LTC6804_stcomm(ltc68041, 24); } -void select_therm(uint8_t therm){ +void select_therm(uint8_t therm) +{ /* Exit if out of range values */ - if (therm < 1 || therm > 16){ + if (therm < 1 || therm > 16) { return; } @@ -104,12 +115,14 @@ void select_therm(uint8_t therm){ uint8_t comm_reg_data[NUM_CHIPS][6]; // select 0-16 on GPIO expander - for(int chip = 0; chip < NUM_CHIPS; chip++) { + for (int chip = 0; chip < NUM_CHIPS; chip++) { i2c_write_data[chip][0] = GPIO_EXPANDER_ADDR; i2c_write_data[chip][1] = GPIO_REGISTER_ADDR; - i2c_write_data[chip][2] = (therm - 1); // 0-15, will change multiplexer to select thermistor - } - serialize_i2c_msg(i2c_write_data, comm_reg_data); + i2c_write_data[chip][2] = + (therm - + 1); // 0-15, will change multiplexer to select thermistor + } + serialize_i2c_msg(i2c_write_data, comm_reg_data); push_chip_configuration(); LTC6804_wrcomm(ltc68041, NUM_CHIPS, comm_reg_data); LTC6804_stcomm(ltc68041, 24); @@ -124,10 +137,12 @@ int pull_voltages() */ //int test_v[12] = {800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800}; - if (!is_timer_expired(&voltage_reading_timer) && voltage_reading_timer.active) { + if (!is_timer_expired(&voltage_reading_timer) && + voltage_reading_timer.active) { for (uint8_t i = 0; i < NUM_CHIPS; i++) { - memcpy(segment_data[i].voltage, previous_data[i].voltage, - sizeof(segment_data[i].voltage)); + memcpy(segment_data[i].voltage, + previous_data[i].voltage, + sizeof(segment_data[i].voltage)); } return voltage_error; } @@ -143,8 +158,9 @@ int pull_voltages() */ if (LTC6804_rdcv(ltc68041, 0, NUM_CHIPS, raw_voltages) == -1) { for (uint8_t i = 0; i < NUM_CHIPS; i++) { - memcpy(segment_data[i].voltage, previous_data[i].voltage, - sizeof(segment_data[i].voltage)); + memcpy(segment_data[i].voltage, + previous_data[i].voltage, + sizeof(segment_data[i].voltage)); printf("Bad voltage read\n"); } @@ -153,24 +169,32 @@ int pull_voltages() /* If the read was successful, copy the voltage data */ for (uint8_t i = 0; i < NUM_CHIPS; i++) { - int corrected_index = mapping_correction[i]; /* correction to account for missing index, see more info below */ int dest_index = 0; for (uint8_t j = 0; j < NUM_CELLS_PER_CHIP + 1; j++) { - /* cell 6 on every chip is not a real reading, we need to have the array skip this, and shift the remaining readings up one index*/ - if (j == 5) continue; + if (j == 5) + continue; - segment_data[corrected_index].noise_reading[dest_index] = 0; + segment_data[corrected_index].noise_reading[dest_index] = + 0; - if (raw_voltages[i][j] > (int)(10000 * (MAX_VOLT + 0.5)) || raw_voltages[i][j] < (int)(10000 * (MIN_VOLT - 0.5))) { + if (raw_voltages[i][j] > + (int)(10000 * (MAX_VOLT + 0.5)) || + raw_voltages[i][j] < + (int)(10000 * (MIN_VOLT - 0.5))) { //if (previous_data[corrected_index].voltage[dest_index] > 45000 || previous_data[corrected_index].voltage[dest_index] < 20000) printf("poop\r\n"); - segment_data[corrected_index].voltage[dest_index] = previous_data[corrected_index].voltage[dest_index]; - segment_data[corrected_index].noise_reading[dest_index] = 1; - segment_data[corrected_index].consecutive_noise[dest_index]++; + segment_data[corrected_index] + .voltage[dest_index] = + previous_data[corrected_index] + .voltage[dest_index]; + segment_data[corrected_index] + .noise_reading[dest_index] = 1; + segment_data[corrected_index] + .consecutive_noise[dest_index]++; //printf("New data: %d\r\n", segment_data[corrected_index].voltage[dest_index]); // if (segment_data[corrected_index].consecutive_noise[dest_index] > MAX_CONSEC_NOISE) { // segment_data[corrected_index].noise_reading[dest_index] = 0; @@ -181,21 +205,25 @@ int pull_voltages() //printf("previous: %d\r\n", previous_data[corrected_index].voltage[dest_index]); //if (previous_data[corrected_index].voltage[dest_index] > 45000 || previous_data[corrected_index].voltage[dest_index] < 20000) printf("pee\r\n"); //else printf("wiping\r\n"); - segment_data[corrected_index].consecutive_noise[dest_index] = 0; - segment_data[corrected_index].voltage[dest_index] = raw_voltages[i][j]; - - if (raw_voltages[i][j] < 45000 && raw_voltages[i][j] > 24000) { - previous_data[corrected_index].voltage[dest_index] = raw_voltages[i][j]; - //printf("previous: %d\r\n", previous_data[corrected_index].voltage[dest_index]); + segment_data[corrected_index] + .consecutive_noise[dest_index] = 0; + segment_data[corrected_index] + .voltage[dest_index] = + raw_voltages[i][j]; + + if (raw_voltages[i][j] < 45000 && + raw_voltages[i][j] > 24000) { + previous_data[corrected_index] + .voltage[dest_index] = + raw_voltages[i][j]; + //printf("previous: %d\r\n", previous_data[corrected_index].voltage[dest_index]); //printf("raw: %d\r\n", segment_data[corrected_index].voltage[dest_index]); - } - + } } dest_index++; } } - /* Start the timer between readings if successful */ start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); @@ -207,10 +235,12 @@ int pull_thermistors() /* If polled too soon, just copy existing values from memory */ if (!is_timer_expired(&therm_timer)) { for (uint8_t i = 0; i < NUM_CHIPS; i++) { - memcpy(segment_data[i].thermistor_reading, previous_data[i].thermistor_reading, - sizeof(segment_data[i].thermistor_reading)); - memcpy(segment_data[i].thermistor_value, previous_data[i].thermistor_value, - sizeof(segment_data[i].thermistor_value)); + memcpy(segment_data[i].thermistor_reading, + previous_data[i].thermistor_reading, + sizeof(segment_data[i].thermistor_reading)); + memcpy(segment_data[i].thermistor_value, + previous_data[i].thermistor_value, + sizeof(segment_data[i].thermistor_value)); } return voltage_error; } @@ -227,13 +257,12 @@ int pull_thermistors() HAL_Delay(200); //push_chip_configuration(); LTC6804_clraux(ltc68041); - LTC6804_adax(ltc68041); /* Run ADC for AUX (GPIOs and refs) */ - HAL_Delay(3); + LTC6804_adax(ltc68041); /* Run ADC for AUX (GPIOs and refs) */ + HAL_Delay(3); LTC6804_rdaux(ltc68041, 0, NUM_CHIPS, raw_temp_voltages); /* Rotate through all thermistor pairs (we can poll two at once) */ for (uint8_t therm = 1; therm <= (NUM_THERMS_PER_CHIP / 2); therm++) { for (uint8_t c = 0; c < NUM_CHIPS; c++) { - int corrected_index = mapping_correction[c]; /* * Get current temperature LUT. Voltage is adjusted to account for 5V reg @@ -241,44 +270,89 @@ int pull_thermistors() */ if (therm == current_therm) { /* see "thermister decoding" in confluence in shepherd software 22A */ - uint16_t steinhart_input_low = 10000 * (float)( ((float)raw_temp_voltages[c][2])/ (raw_temp_voltages[c][0]) - 1 ); - uint16_t steinhart_input_high = 10000 * (float)( ((float)raw_temp_voltages[c][2])/ (raw_temp_voltages[c][1]) - 1 ); - - segment_data[corrected_index].thermistor_reading[therm - 1] = steinhart_est(steinhart_input_low); - segment_data[corrected_index].thermistor_reading[therm + 15] = steinhart_est(steinhart_input_high); + uint16_t steinhart_input_low = + 10000 * + (float)(((float)raw_temp_voltages[c][2]) / + (raw_temp_voltages[c] + [0]) - + 1); + uint16_t steinhart_input_high = + 10000 * + (float)(((float)raw_temp_voltages[c][2]) / + (raw_temp_voltages[c] + [1]) - + 1); + + segment_data[corrected_index] + .thermistor_reading[therm - 1] = + steinhart_est(steinhart_input_low); + segment_data[corrected_index] + .thermistor_reading[therm + 15] = + steinhart_est(steinhart_input_high); /* Directly update for a set time from start up due to therm voltages * needing to settle */ - segment_data[corrected_index].thermistor_value[therm - 1] - = segment_data[corrected_index].thermistor_reading[therm - 1]; - segment_data[corrected_index].thermistor_value[therm + 15] - = segment_data[corrected_index].thermistor_reading[therm + 15]; - - if (raw_temp_voltages[c][0] == LTC_BAD_READ - || raw_temp_voltages[c][1] == LTC_BAD_READ - || segment_data[corrected_index].thermistor_value[therm - 1] > (MAX_CELL_TEMP + 5) - || segment_data[corrected_index].thermistor_value[therm + 15] > (MAX_CELL_TEMP + 5 ) - || segment_data[corrected_index].thermistor_value[therm - 1] < (MIN_CELL_TEMP - 5) - || segment_data[corrected_index].thermistor_value[therm + 15] < (MIN_CELL_TEMP - 5 )) { - memcpy(segment_data[corrected_index].thermistor_reading, previous_data[c].thermistor_reading, - sizeof(segment_data[corrected_index].thermistor_reading)); - memcpy(segment_data[corrected_index].thermistor_value, previous_data[c].thermistor_value, - sizeof(segment_data[corrected_index].thermistor_value)); + segment_data[corrected_index] + .thermistor_value[therm - 1] = + segment_data[corrected_index] + .thermistor_reading[therm - 1]; + segment_data[corrected_index] + .thermistor_value[therm + 15] = + segment_data[corrected_index] + .thermistor_reading[therm + 15]; + + if (raw_temp_voltages[c][0] == LTC_BAD_READ || + raw_temp_voltages[c][1] == LTC_BAD_READ || + segment_data[corrected_index] + .thermistor_value[therm - 1] > + (MAX_CELL_TEMP + 5) || + segment_data[corrected_index] + .thermistor_value[therm + + 15] > + (MAX_CELL_TEMP + 5) || + segment_data[corrected_index] + .thermistor_value[therm - 1] < + (MIN_CELL_TEMP - 5) || + segment_data[corrected_index] + .thermistor_value[therm + + 15] < + (MIN_CELL_TEMP - 5)) { + memcpy(segment_data[corrected_index] + .thermistor_reading, + previous_data[c] + .thermistor_reading, + sizeof(segment_data[corrected_index] + .thermistor_reading)); + memcpy(segment_data[corrected_index] + .thermistor_value, + previous_data[c].thermistor_value, + sizeof(segment_data[corrected_index] + .thermistor_value)); } - } - else { - segment_data[corrected_index].thermistor_reading[therm - 1] = previous_data[corrected_index].thermistor_reading[therm - 1]; - segment_data[corrected_index].thermistor_reading[therm + 15] = previous_data[corrected_index].thermistor_reading[therm + 15]; - - segment_data[corrected_index].thermistor_value[therm - 1] - = segment_data[corrected_index].thermistor_reading[therm - 1]; - segment_data[corrected_index].thermistor_value[therm + 15] - = segment_data[corrected_index].thermistor_reading[therm + 15]; + } else { + segment_data[corrected_index] + .thermistor_reading[therm - 1] = + previous_data[corrected_index] + .thermistor_reading[therm - 1]; + segment_data[corrected_index] + .thermistor_reading[therm + 15] = + previous_data[corrected_index] + .thermistor_reading[therm + 15]; + + segment_data[corrected_index] + .thermistor_value[therm - 1] = + segment_data[corrected_index] + .thermistor_reading[therm - 1]; + segment_data[corrected_index] + .thermistor_value[therm + 15] = + segment_data[corrected_index] + .thermistor_reading[therm + 15]; } } } current_therm++; - start_timer(&therm_timer, 100/*THERM_WAIT_TIME*/); /* Start timer for next reading */ + start_timer(&therm_timer, + 100 /*THERM_WAIT_TIME*/); /* Start timer for next reading */ /* the following algorithms were used to eliminate noise on Car 17D - keep them off if possible */ //variance_therm_check(); @@ -317,7 +391,8 @@ void configure_discharge(uint8_t chip, uint16_t cells) * Register 5 is split in half, so we maintain the upper half and add in the * bottom half to discharge cells */ - local_config[chip][5] = (local_config[chip][5] & 0xF0) + (uint8_t)(cells >> 8); + local_config[chip][5] = + (local_config[chip][5] & 0xF0) + (uint8_t)(cells >> 8); } void segment_enable_balancing(bool balance_enable) @@ -326,7 +401,8 @@ void segment_enable_balancing(bool balance_enable) * Discharging all cells in series * Making the discharge command all 1's for all cells per chip */ - static const uint16_t DICHARGE_ALL_COMMAND = 0xFFFF >> (16 - NUM_CELLS_PER_CHIP); + static const uint16_t DICHARGE_ALL_COMMAND = 0xFFFF >> + (16 - NUM_CELLS_PER_CHIP); if (balance_enable) { for (int c = 0; c < NUM_CHIPS; c++) { @@ -344,7 +420,8 @@ void segment_enable_balancing(bool balance_enable) } // @todo Revisit after testing -void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, bool balance_enable) +void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, + bool balance_enable) { pull_chip_configuration(); @@ -358,14 +435,17 @@ void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, bool balance_enab push_chip_configuration(); } -void segment_configure_balancing(bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]) +void segment_configure_balancing( + bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]) { for (int c = 0; c < NUM_CHIPS; c++) { for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { if (discharge_config[mapping_correction[c]][cell]) - discharge_commands[mapping_correction[c]] |= 1 << cell; + discharge_commands[mapping_correction[c]] |= + 1 << cell; else - discharge_commands[mapping_correction[c]] &= ~(1 << cell); + discharge_commands[mapping_correction[c]] &= + ~(1 << cell); } configure_discharge(c, discharge_commands[c]); @@ -428,7 +508,6 @@ int8_t steinhart_est(uint16_t V) } return 80; - } void disable_gpio_pulldowns() { @@ -455,13 +534,18 @@ void disable_gpio_pulldowns() void serialize_i2c_msg(uint8_t data_to_write[][3], uint8_t comm_output[][6]) { for (int chip = 0; chip < NUM_CHIPS; chip++) { - comm_output[chip][0] = 0x60 | (data_to_write[chip][0] >> 4); /* START + high side of B0 */ - comm_output[chip][1] = (data_to_write[chip][0] << 4) | 0x00; /* low side of B0 + ACK */ - comm_output[chip][2] = 0x00 | (data_to_write[chip][1] >> 4); /* BLANK + high side of B1 */ - comm_output[chip][3] = (data_to_write[chip][1] << 4) | 0x00; /* low side of B1 + ACK */ - comm_output[chip][4] = 0x00 | (data_to_write[chip][2] >> 4); /* BLANK + high side of B2 */ - comm_output[chip][5] - = (data_to_write[chip][2] << 4) | 0x09; /* low side of B2 + STOP & NACK */ + comm_output[chip][0] = 0x60 | (data_to_write[chip][0] >> + 4); /* START + high side of B0 */ + comm_output[chip][1] = (data_to_write[chip][0] << 4) | + 0x00; /* low side of B0 + ACK */ + comm_output[chip][2] = 0x00 | (data_to_write[chip][1] >> + 4); /* BLANK + high side of B1 */ + comm_output[chip][3] = (data_to_write[chip][1] << 4) | + 0x00; /* low side of B1 + ACK */ + comm_output[chip][4] = 0x00 | (data_to_write[chip][2] >> + 4); /* BLANK + high side of B2 */ + comm_output[chip][5] = (data_to_write[chip][2] << 4) | + 0x09; /* low side of B2 + STOP & NACK */ } } @@ -472,36 +556,65 @@ void averaging_therm_check() /* Directly update for a set time from start up due to therm voltages * needing to settle */ if (therm_avg_counter < THERM_AVG * 10) { - segment_data[c].thermistor_value[therm - 1] - = segment_data[c].thermistor_reading[therm - 1]; - segment_data[c].thermistor_value[therm + 15] - = segment_data[c].thermistor_reading[therm + 15]; + segment_data[c].thermistor_value[therm - 1] = + segment_data[c] + .thermistor_reading[therm - 1]; + segment_data[c].thermistor_value[therm + 15] = + segment_data[c] + .thermistor_reading[therm + 15]; therm_avg_counter++; } else { /* We need to investigate this. Very sloppy */ /* Discard if reading is 33C */ - if (segment_data[c].thermistor_reading[therm - 1] != 33) { + if (segment_data[c] + .thermistor_reading[therm - 1] != + 33) { /* If measured value is larger than current "averaged" value, * increment value */ - if (segment_data[c].thermistor_reading[therm - 1] - > segment_data[c].thermistor_value[therm - 1]) { - segment_data[c].thermistor_value[therm - 1]++; + if (segment_data[c] + .thermistor_reading[therm - + 1] > + segment_data[c] + .thermistor_value[therm - + 1]) { + segment_data[c] + .thermistor_value[therm - + 1]++; /* If measured value is smaller than current "averaged" value, * decrement value */ - } else if (segment_data[c].thermistor_reading[therm - 1] - < segment_data[c].thermistor_value[therm - 1]) { - segment_data[c].thermistor_value[therm - 1]--; + } else if (segment_data[c] + .thermistor_reading + [therm - 1] < + segment_data[c] + .thermistor_value + [therm - 1]) { + segment_data[c] + .thermistor_value[therm - + 1]--; } } /* See comments above. Identical but for the upper 16 therms */ - if (segment_data[c].thermistor_reading[therm + 15] != 33) { - if (segment_data[c].thermistor_reading[therm + 15] - > segment_data[c].thermistor_value[therm + 15]) { - segment_data[c].thermistor_value[therm + 15]++; - } else if (segment_data[c].thermistor_reading[therm + 15] - < segment_data[c].thermistor_value[therm + 15]) { - segment_data[c].thermistor_value[therm + 15]--; + if (segment_data[c] + .thermistor_reading[therm + 15] != + 33) { + if (segment_data[c] + .thermistor_reading[therm + + 15] > + segment_data[c] + .thermistor_value[therm + + 15]) { + segment_data[c] + .thermistor_value[therm + + 15]++; + } else if (segment_data[c] + .thermistor_reading + [therm + 15] < + segment_data[c].thermistor_value + [therm + 15]) { + segment_data[c] + .thermistor_value[therm + + 15]--; } } } @@ -521,10 +634,11 @@ void standard_dev_therm_check() * If difference between thermistor and average is more than * MAX_STANDARD_DEV set the therm to pack average */ - if (abs(segment_data[c].thermistor_value[therm] - avg_temp) - > (MAX_STANDARD_DEV * standard_dev)) { + if (abs(segment_data[c].thermistor_value[therm] - + avg_temp) > (MAX_STANDARD_DEV * standard_dev)) { /* Nullify thermistor by setting to pack average */ - segment_data[c].thermistor_value[therm] = previous_data[c].thermistor_value[therm]; + segment_data[c].thermistor_value[therm] = + previous_data[c].thermistor_value[therm]; } } } @@ -535,7 +649,9 @@ int8_t calc_therm_standard_dev(int16_t avg_temp) uint16_t sum_diff_sqrd = 0; for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { for (uint8_t therm = 17; therm < 28; therm++) { - uint16_t sum_diff = abs(segment_data[chip].thermistor_value[therm] - avg_temp); + uint16_t sum_diff = + abs(segment_data[chip].thermistor_value[therm] - + avg_temp); sum_diff_sqrd += sum_diff * sum_diff; } } @@ -570,15 +686,23 @@ void variance_therm_check() if (is_timer_expired(&variance_timer)) { for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t therm = 17; therm < 28; therm++) { - if (abs(segment_data[c].thermistor_reading[therm] - - previous_data[c].thermistor_reading[therm]) - > 5 - && (segment_data[c].thermistor_reading[therm] < 10 - || segment_data[c].thermistor_reading[therm] > 30)) { - segment_data[c].thermistor_reading[therm] - = previous_data[c].thermistor_reading[therm]; - segment_data[c].thermistor_value[therm] - = previous_data[c].thermistor_value[therm]; + if (abs(segment_data[c] + .thermistor_reading[therm] - + previous_data[c] + .thermistor_reading[therm]) > + 5 && + (segment_data[c].thermistor_reading[therm] < + 10 || + segment_data[c].thermistor_reading[therm] > + 30)) { + segment_data[c] + .thermistor_reading[therm] = + previous_data[c] + .thermistor_reading + [therm]; + segment_data[c].thermistor_value[therm] = + previous_data[c] + .thermistor_value[therm]; } } } diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index 49f1e0b..45ae75f 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -5,7 +5,7 @@ #define MIN(a, b) (((a) < (b)) ? (a) : (b)) extern UART_HandleTypeDef huart4; -acc_data_t* prevAccData; +acc_data_t *prevAccData; uint32_t bms_fault = FAULTS_CLEAR; BMSState_t current_state = BOOT_STATE; @@ -40,32 +40,35 @@ void init_boot(void); void init_ready(void); void init_charging(void); void init_faulted(void); -void handle_boot(acc_data_t* bmsdata); -void handle_ready(acc_data_t* bmsdata); -void handle_charging(acc_data_t* bmsdata); -void handle_faulted(acc_data_t* bmsdata); +void handle_boot(acc_data_t *bmsdata); +void handle_ready(acc_data_t *bmsdata); +void handle_charging(acc_data_t *bmsdata); +void handle_faulted(acc_data_t *bmsdata); void request_transition(BMSState_t next_state); - -typedef void (*HandlerFunction_t)(acc_data_t* bmsdata); +typedef void (*HandlerFunction_t)(acc_data_t *bmsdata); typedef void (*InitFunction_t)(); -const InitFunction_t init_LUT[NUM_STATES] - = { &init_boot, &init_ready, &init_charging, &init_faulted }; +const InitFunction_t init_LUT[NUM_STATES] = { &init_boot, &init_ready, + &init_charging, &init_faulted }; -const HandlerFunction_t handler_LUT[NUM_STATES] - = { &handle_boot, &handle_ready, &handle_charging, &handle_faulted }; +const HandlerFunction_t handler_LUT[NUM_STATES] = { &handle_boot, &handle_ready, + &handle_charging, + &handle_faulted }; -void init_boot() { return; } +void init_boot() +{ + return; +} -void handle_boot(acc_data_t* bmsdata) +void handle_boot(acc_data_t *bmsdata) { prevAccData = NULL; segment_enable_balancing(false); compute_enable_charging(false); start_timer(&bootup_timer, 10000); printf("Bootup timer started\r\n"); - + compute_set_fault(1); // bmsdata->fault_code = FAULTS_CLEAR; @@ -80,10 +83,11 @@ void init_ready() return; } -void handle_ready(acc_data_t* bmsdata) +void handle_ready(acc_data_t *bmsdata) { /* check for charger connection */ - if (compute_charger_connected() && is_timer_expired(&bootup_timer)) { //TODO Fix once charger works + if (compute_charger_connected() && + is_timer_expired(&bootup_timer)) { //TODO Fix once charger works request_transition(READY_STATE); } else { sm_broadcast_current_limit(bmsdata); @@ -97,30 +101,36 @@ void init_charging() return; } -void handle_charging(acc_data_t* bmsdata) +void handle_charging(acc_data_t *bmsdata) { if (!compute_charger_connected()) { request_transition(READY_STATE); return; - } - else { - + } else { /* Check if we should charge */ - if (sm_charging_check(bmsdata)) compute_enable_charging(true); - else { compute_enable_charging(false); compute_send_charging_message(0, 0, bmsdata); } + if (sm_charging_check(bmsdata)) + compute_enable_charging(true); + else { + compute_enable_charging(false); + compute_send_charging_message(0, 0, bmsdata); + } /* Check if we should balance */ - if (sm_balancing_check(bmsdata)) sm_balance_cells(bmsdata); - else segment_enable_balancing(false); - + if (sm_balancing_check(bmsdata)) + sm_balance_cells(bmsdata); + else + segment_enable_balancing(false); /* Send CAN message, but not too often */ - if (is_timer_expired(&charger_message_timer) || !is_timer_active(&charger_message_timer)) { - compute_send_charging_message( - (MAX_CHARGE_VOLT * NUM_CELLS_PER_CHIP * NUM_CHIPS), 5, bmsdata); - start_timer(&charger_message_timer, CHARGE_MESSAGE_WAIT); - + if (is_timer_expired(&charger_message_timer) || + !is_timer_active(&charger_message_timer)) { + compute_send_charging_message((MAX_CHARGE_VOLT * + NUM_CELLS_PER_CHIP * + NUM_CHIPS), + 5, bmsdata); + start_timer(&charger_message_timer, + CHARGE_MESSAGE_WAIT); } } } @@ -133,7 +143,7 @@ void init_faulted() return; } -void handle_faulted(acc_data_t* bmsdata) +void handle_faulted(acc_data_t *bmsdata) { if (entered_faulted) { entered_faulted = false; @@ -155,11 +165,21 @@ void handle_faulted(acc_data_t* bmsdata) return; } -void sm_handle_state(acc_data_t* bmsdata) +void sm_handle_state(acc_data_t *bmsdata) { static uint8_t can_msg_to_send = 0; - enum {ACC_STATUS, CURRENT, BMS_STATUS, CELL_TEMP, CELL_DATA, SEGMENT_TEMP, MC_DISCHARGE, MC_CHARGE, MAX_MSGS}; - + enum { + ACC_STATUS, + CURRENT, + BMS_STATUS, + CELL_TEMP, + CELL_DATA, + SEGMENT_TEMP, + MC_DISCHARGE, + MC_CHARGE, + MAX_MSGS + }; + bmsdata->fault_code = sm_fault_return(bmsdata); //calculate_pwm(bmsdata); @@ -226,26 +246,26 @@ void request_transition(BMSState_t next_state) current_state = next_state; } -uint32_t sm_fault_return(acc_data_t* accData) +uint32_t sm_fault_return(acc_data_t *accData) { /* FAULT CHECK (Check for fuckies) */ - static nertimer_t ovr_curr_timer = {0}; - static nertimer_t ovr_chgcurr_timer = {0}; - static nertimer_t undr_volt_timer = {0}; - static nertimer_t ovr_chgvolt_timer = {0}; - static nertimer_t ovr_volt_timer = {0}; - static nertimer_t low_cell_timer = {0}; - static nertimer_t high_temp_timer = {0}; - static fault_eval_t* fault_table = NULL; - static acc_data_t* fault_data = NULL; + static nertimer_t ovr_curr_timer = { 0 }; + static nertimer_t ovr_chgcurr_timer = { 0 }; + static nertimer_t undr_volt_timer = { 0 }; + static nertimer_t ovr_chgvolt_timer = { 0 }; + static nertimer_t ovr_volt_timer = { 0 }; + static nertimer_t low_cell_timer = { 0 }; + static nertimer_t high_temp_timer = { 0 }; + static fault_eval_t *fault_table = NULL; + static acc_data_t *fault_data = NULL; fault_data = accData; - if (!fault_table) - { + if (!fault_table) { /* Note that we are only allocating this table once at runtime, so there is no need to free it */ - fault_table = (fault_eval_t*) malloc(NUM_FAULTS * sizeof(fault_eval_t)); + fault_table = (fault_eval_t *)malloc(NUM_FAULTS * + sizeof(fault_eval_t)); // clang-format off // ___________FAULT ID____________ __________TIMER___________ _____________DATA________________ __OPERATOR__ __________________________THRESHOLD____________________________ _______TIMER LENGTH_________ _____________FAULT CODE_________________ ___OPERATOR 2__ _______________DATA 2______________ __THRESHOLD 2__ fault_table[0] = (fault_eval_t) {.id = "Discharge Current Limit", .timer = ovr_curr_timer, .data_1 = fault_data->pack_current, .optype_1 = GT, .lim_1 = (fault_data->discharge_limit + DCDC_CURRENT_DRAW)*10 * CURR_ERR_MARG, .timeout = OVER_CURR_TIME, .code = DISCHARGE_LIMIT_ENFORCEMENT_FAULT, .optype_2 = NOP/* ---------------------------UNUSED------------------- */ }; @@ -267,12 +287,13 @@ uint32_t sm_fault_return(acc_data_t* accData) // clang-format on } - else - { + else { fault_table[0].data_1 = fault_data->pack_current; - fault_table[0].lim_1 = (fault_data->discharge_limit + DCDC_CURRENT_DRAW)*10 * CURR_ERR_MARG; + fault_table[0].lim_1 = + (fault_data->discharge_limit + DCDC_CURRENT_DRAW) * 10 * + CURR_ERR_MARG; fault_table[1].data_1 = fault_data->pack_current; - fault_table[1].lim_1 = (fault_data->charge_limit)*10; + fault_table[1].lim_1 = (fault_data->charge_limit) * 10; fault_table[2].data_1 = fault_data->min_voltage.val; fault_table[3].data_1 = fault_data->max_voltage.val; fault_table[4].data_1 = fault_data->max_voltage.val; @@ -292,7 +313,7 @@ uint32_t sm_fault_return(acc_data_t* accData) return fault_status; } -uint32_t sm_fault_eval(fault_eval_t* index) +uint32_t sm_fault_eval(fault_eval_t *index) { bool condition1; bool condition2; @@ -323,42 +344,39 @@ uint32_t sm_fault_eval(fault_eval_t* index) } // clang-format on - bool fault_present = ( (condition1 && condition2) || (condition1 && (index->optype_2 == NOP)) ); - if ((!(is_timer_active(&index->timer))) && !fault_present) - { + bool fault_present = ((condition1 && condition2) || + (condition1 && (index->optype_2 == NOP))); + if ((!(is_timer_active(&index->timer))) && !fault_present) { return 0; } - if (is_timer_active(&index->timer)) - { - if (!fault_present) - { + if (is_timer_active(&index->timer)) { + if (!fault_present) { printf("\t\t\t*******Fault cleared: %s\r\n", index->id); cancel_timer(&index->timer); return 0; } - if (is_timer_expired(&index->timer) && fault_present) - { + if (is_timer_expired(&index->timer) && fault_present) { printf("\t\t\t*******Faulted: %s\r\n", index->id); - compute_send_fault_message(2, index->data_1, index->lim_1); + compute_send_fault_message(2, index->data_1, + index->lim_1); return index->code; } - - else return 0; + else + return 0; } - - else if (!is_timer_active(&index->timer) && fault_present) - { - + + else if (!is_timer_active(&index->timer) && fault_present) { printf("\t\t\t*******Starting fault timer: %s\r\n", index->id); start_timer(&index->timer, index->timeout); if (index->code == DISCHARGE_LIMIT_ENFORCEMENT_FAULT) { - compute_send_fault_message(1, index->data_1, index->lim_1); + compute_send_fault_message(1, index->data_1, + index->lim_1); } - + return 0; } /* if (index->code == CELL_VOLTAGE_TOO_LOW) { @@ -369,28 +387,29 @@ uint32_t sm_fault_eval(fault_eval_t* index) return 0; } - /* charger settle countup = 1 minute pause to let readings settle and get good OCV */ /* charger settle countdown = 5 minute interval between 1 minute settle pauses */ /* charger_max_volt_timer = interval of time when voltage is too high before trying to start again */ -bool sm_charging_check(acc_data_t* bmsdata) -{ +bool sm_charging_check(acc_data_t *bmsdata) +{ if (!compute_charger_connected()) { printf("Charger not connected\r\n"); return false; } - if (!is_timer_expired(&charger_settle_countup) && is_timer_active(&charger_settle_countup)) { + if (!is_timer_expired(&charger_settle_countup) && + is_timer_active(&charger_settle_countup)) { printf("Charger settle countup active\r\n"); return false; } - - if (!is_timer_expired(&charger_max_volt_timer) && is_timer_active(&charger_max_volt_timer)) { + + if (!is_timer_expired(&charger_max_volt_timer) && + is_timer_active(&charger_max_volt_timer)) { printf("Charger max volt timer active\r\n"); return false; } - if (bmsdata->max_voltage.val > MAX_CHARGE_VOLT*10000) { + if (bmsdata->max_voltage.val > MAX_CHARGE_VOLT * 10000) { start_timer(&charger_max_volt_timer, CHARGE_VOLT_TIMEOUT); printf("Charger max volt timer started\r\n"); printf("Max voltage: %d\r\n", bmsdata->max_voltage.val); @@ -398,24 +417,23 @@ bool sm_charging_check(acc_data_t* bmsdata) } if (is_timer_active(&charger_settle_countdown)) { - if (is_timer_expired(&charger_settle_countdown)) { - start_timer(&charger_settle_countup, CHARGE_SETL_TIMEOUT); + start_timer(&charger_settle_countup, + CHARGE_SETL_TIMEOUT); return false; } - else return true; + else + return true; } - else - { + else { start_timer(&charger_settle_countdown, CHARGE_SETL_TIMEUP); return true; } - } -bool sm_balancing_check(acc_data_t* bmsdata) +bool sm_balancing_check(acc_data_t *bmsdata) { if (!compute_charger_connected()) return false; @@ -425,14 +443,15 @@ bool sm_balancing_check(acc_data_t* bmsdata) return false; if (bmsdata->delt_voltage <= (MAX_DELTA_V * 10000)) return false; - - if (is_timer_active(&charger_settle_countup) && !is_timer_expired(&charger_settle_countup)) + + if (is_timer_active(&charger_settle_countup) && + !is_timer_expired(&charger_settle_countup)) return false; return true; } -void sm_broadcast_current_limit(acc_data_t* bmsdata) +void sm_broadcast_current_limit(acc_data_t *bmsdata) { // States for Boosting State Machine static enum { BOOST_STANDBY, BOOSTING, BOOST_RECHARGE } BoostState; @@ -446,28 +465,32 @@ void sm_broadcast_current_limit(acc_data_t* bmsdata) start_timer(&boost_recharge_timer, BOOST_RECHARGE_TIME); } /* Transition out of boost recharge */ - if (is_timer_expired(&boost_recharge_timer) && BoostState == BOOST_RECHARGE) { + if (is_timer_expired(&boost_recharge_timer) && + BoostState == BOOST_RECHARGE) { BoostState = BOOST_STANDBY; } /* Transition to boosting */ - if ((bmsdata->pack_current) > ((bmsdata->cont_DCL) * 10) && BoostState == BOOST_STANDBY) { + if ((bmsdata->pack_current) > ((bmsdata->cont_DCL) * 10) && + BoostState == BOOST_STANDBY) { BoostState = BOOSTING; start_timer(&boost_timer, BOOST_TIME); } /* Currently boosting */ if (BoostState == BOOSTING || BoostState == BOOST_STANDBY) { - bmsdata->boost_setting - = MIN(bmsdata->discharge_limit, bmsdata->cont_DCL * CONTDCL_MULTIPLIER); + bmsdata->boost_setting = + MIN(bmsdata->discharge_limit, + bmsdata->cont_DCL * CONTDCL_MULTIPLIER); } /* Currently recharging boost */ else { - bmsdata->boost_setting = MIN(bmsdata->cont_DCL, bmsdata->discharge_limit); + bmsdata->boost_setting = + MIN(bmsdata->cont_DCL, bmsdata->discharge_limit); } } -void sm_balance_cells(acc_data_t* bms_data) +void sm_balance_cells(acc_data_t *bms_data) { bool balanceConfig[NUM_CHIPS][NUM_CELLS_PER_CHIP]; @@ -475,8 +498,9 @@ void sm_balance_cells(acc_data_t* bms_data) * in voltages */ for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - uint16_t delta = bms_data->chip_data[chip].voltage[cell] - - (uint16_t)bms_data->min_voltage.val; + uint16_t delta = + bms_data->chip_data[chip].voltage[cell] - + (uint16_t)bms_data->min_voltage.val; if (delta > MAX_DELTA_V * 10000) balanceConfig[chip][cell] = true; else @@ -498,15 +522,14 @@ void sm_balance_cells(acc_data_t* bms_data) segment_configure_balancing(balanceConfig); } -void calculate_pwm(acc_data_t* bmsdata) +void calculate_pwm(acc_data_t *bmsdata) { // todo actually implement algorithm - // this should include: - // 1. set PWM based on temp of "nearby" cells - // 2. automate seleciton of htim rather than hardcode + // this should include: + // 1. set PWM based on temp of "nearby" cells + // 2. automate seleciton of htim rather than hardcode - if (bmsdata->max_temp.val > 50) - { + if (bmsdata->max_temp.val > 50) { compute_set_fan_speed(&htim1, FAN1, 100); compute_set_fan_speed(&htim1, FAN2, 100); compute_set_fan_speed(&htim8, FAN3, 100); @@ -516,8 +539,7 @@ void calculate_pwm(acc_data_t* bmsdata) return; } - else if (bmsdata->max_temp.val > 40) - { + else if (bmsdata->max_temp.val > 40) { compute_set_fan_speed(&htim1, FAN1, 50); compute_set_fan_speed(&htim1, FAN2, 50); compute_set_fan_speed(&htim8, FAN3, 50); @@ -527,8 +549,7 @@ void calculate_pwm(acc_data_t* bmsdata) return; } - else if (bmsdata->max_temp.val > 30) - { + else if (bmsdata->max_temp.val > 30) { compute_set_fan_speed(&htim1, FAN1, 25); compute_set_fan_speed(&htim1, FAN2, 25); compute_set_fan_speed(&htim8, FAN3, 25); @@ -538,8 +559,7 @@ void calculate_pwm(acc_data_t* bmsdata) return; } - else - { + else { compute_set_fan_speed(&htim1, FAN1, 0); compute_set_fan_speed(&htim1, FAN2, 0); compute_set_fan_speed(&htim8, FAN3, 0); @@ -548,7 +568,4 @@ void calculate_pwm(acc_data_t* bmsdata) compute_set_fan_speed(&htim8, FAN6, 0); return; } - } - - diff --git a/Drivers/Embedded-Base b/Drivers/Embedded-Base index ff34106..fdfdca7 160000 --- a/Drivers/Embedded-Base +++ b/Drivers/Embedded-Base @@ -1 +1 @@ -Subproject commit ff34106b18e296434fc817d7a9c66efc28c07abe +Subproject commit fdfdca783209c293807b1e71efc5447d754050eb