From 60650d130adda50a0c667e4dfe4f6ed5c0cf8e25 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 17 Nov 2024 19:19:05 -0500 Subject: [PATCH 01/32] 133 adbms submodule --- .gitmodules | 3 +++ Drivers/adbms | 1 + 2 files changed, 4 insertions(+) create mode 160000 Drivers/adbms diff --git a/.gitmodules b/.gitmodules index e2548a27..da1c65f3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "Drivers/Embedded-Base"] path = Drivers/Embedded-Base url = https://github.com/Northeastern-Electric-Racing/Embedded-Base.git +[submodule "Drivers/adbms"] + path = Drivers/adbms + url = git@github.com:Northeastern-Electric-Racing/adbms.git diff --git a/Drivers/adbms b/Drivers/adbms new file mode 160000 index 00000000..1c91c8f3 --- /dev/null +++ b/Drivers/adbms @@ -0,0 +1 @@ +Subproject commit 1c91c8f3d80035a0dfb3687bc043c2a1c3220f5b From 89b9d971fc4af81ebf2dece3c290add96dc5e456 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 17 Nov 2024 19:46:20 -0500 Subject: [PATCH 02/32] 133 more copying --- Core/Src/main.c | 117 ++++++++++----- Core/Src/segment.c | 353 ++++++++++++++++++++++++++++++++++++--------- Makefile | 6 + 3 files changed, 364 insertions(+), 112 deletions(-) diff --git a/Core/Src/main.c b/Core/Src/main.c index cd9580d1..8de75f8a 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -26,6 +26,8 @@ #include "assert.h" +#include "serialPrintResult.h" + /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -38,7 +40,12 @@ //#ifdef DEBUG_EVERYTHING //#define DEBUG_CHARGING -// #define DEBUG_STATS +#define DEBUG_STATS +#define DEBUG_VOLTAGES +// #define DEBUG_RAW_VOLTAGES +#define DEBUG_RAW_VOLTAGES_FORMATTED +// #define DEBUG_OCV +// #define DEBUG_OTHER // etc etc //#endif /* USER CODE END PD */ @@ -77,7 +84,7 @@ PCD_HandleTypeDef hpcd_USB_OTG_FS; osThreadId_t defaultTaskHandle; const osThreadAttr_t defaultTask_attributes = { .name = "defaultTask", - .stack_size = 128 * 4, + .stack_size = 128 * 8, .priority = (osPriority_t) osPriorityNormal, }; /* USER CODE BEGIN PV */ @@ -126,56 +133,83 @@ int _write(int file, char* ptr, int len) { const void print_bms_stats(acc_data_t *acc_data) { static nertimer_t debug_stat_timer; - static const uint16_t PRINT_STAT_WAIT = 500; //ms + static const uint16_t PRINT_STAT_WAIT = 1000; //ms if(!is_timer_expired(&debug_stat_timer) && debug_stat_timer.active) return; + #ifdef DEBUG_OTHER //TODO get this from eeprom once implemented // question - should we read from eeprom here, or do that on loop and store locally? // printf("Prev Fault: %#x", previousFault); - printf("CAN Error:\t%ld\r\n", HAL_CAN_GetError(&hcan1)); - printf("Current * 10: %d\r\n", (acc_data->pack_current)); - printf("Min, Max, Avg Temps: %ld, %ld, %d\r\n", acc_data->min_temp.val, acc_data->max_temp.val, acc_data->avg_temp); - printf("Min, Max, Avg, Delta Voltages: %ld, %ld, %d, %d\r\n", acc_data->min_voltage.val, acc_data->max_voltage.val, acc_data->avg_voltage, acc_data->delt_voltage); - printf("DCL: %d\r\n", acc_data->discharge_limit); - printf("CCL: %d\r\n", acc_data->charge_limit); - printf("Cont CCL %d\r\n", acc_data->cont_CCL); - printf("SoC: %d\r\n", acc_data->soc); - printf("Is Balancing?: %d\r\n", segment_is_balancing()); + + printf("CAN Error:\t%ld\n", HAL_CAN_GetError(&hcan1)); + printf("Current * 10: %d\n", (acc_data->pack_current)); + printf("Min, Max, Avg Temps: %ld, %ld, %d\n", acc_data->min_temp.val, acc_data->max_temp.val, acc_data->avg_temp); + #endif + + #ifdef DEBUG_VOLTAGES + printf("Min, Max, Avg, Delta Voltages: %ld, %ld, %d, %d\n", acc_data->min_voltage.val, acc_data->max_voltage.val, acc_data->avg_voltage, acc_data->delt_voltage); + printf("Min, Max, Avg, Delta Voltages: %f, %f, %f, %f\n", acc_data->min_voltage.val / 10000.0, acc_data->max_voltage.val / 10000.0, acc_data->avg_voltage / 10000.0, acc_data->delt_voltage / 10000.0); + #endif + + #ifdef DEBUG_OTHER + printf("DCL: %d\n", acc_data->discharge_limit); + printf("CCL: %d\n", acc_data->charge_limit); + printf("Cont CCL %d\n", acc_data->cont_CCL); + printf("SoC: %d\n", acc_data->soc); + printf("Is Balancing?: %d\n", segment_is_balancing()); printf("State: "); - if (current_state == 0) printf("BOOT\r\n"); - else if (current_state == 1) printf("READY\r\n"); - else if (current_state == 2) printf("CHARGING\r\n"); - else if (current_state == 3) printf("FAULTED: %lX\r\n", acc_data->fault_code); - - printf("Voltage Noise Percent:\r\n"); - printf("Seg 1: %d\r\n", acc_data->segment_noise_percentage[0]); - printf("Seg 2: %d\r\n", acc_data->segment_noise_percentage[1]); - printf("Seg 3: %d\r\n", acc_data->segment_noise_percentage[2]); - printf("Seg 4: %d\r\n", acc_data->segment_noise_percentage[3]); - printf("Seg 5: %d\r\n", acc_data->segment_noise_percentage[4]); - printf("Seg 6: %d\r\n", acc_data->segment_noise_percentage[5]); - - printf("Raw Cell Voltage:\r\n"); + if (current_state == 0) printf("BOOT\n"); + else if (current_state == 1) printf("READY\n"); + else if (current_state == 2) printf("CHARGING\n"); + else if (current_state == 3) printf("FAULTED: %lX\n", acc_data->fault_code); + + printf("Voltage Noise Percent:\n"); + printf("Seg 1: %d\n", acc_data->segment_noise_percentage[0]); + printf("Seg 2: %d\n", acc_data->segment_noise_percentage[1]); + printf("Seg 3: %d\n", acc_data->segment_noise_percentage[2]); + printf("Seg 4: %d\n", acc_data->segment_noise_percentage[3]); + printf("Seg 5: %d\n", acc_data->segment_noise_percentage[4]); + printf("Seg 6: %d\n", acc_data->segment_noise_percentage[5]); + #endif + + #ifdef DEBUG_RAW_VOLTAGES + printf("Raw Cell Voltage:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { printf("%d\t", acc_data->chip_data[c].voltage[cell]); } - printf("\r\n"); + printf("\n"); } + #endif - printf("Open Cell Voltage:\r\n"); + #ifdef DEBUG_RAW_VOLTAGES_FORMATTED + for(uint8_t c = 0; c < NUM_CHIPS; c++) + { + for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) + { + printf("%f\t", getVoltage(acc_data->chip_data[c].voltage[cell])); + } + printf("\n"); + } + #endif + + #ifdef DEBUG_OCV + printf("Open Cell Voltage:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { printf("%d\t", acc_data->chip_data[c].open_cell_voltage[cell]); } - printf("\r\n"); + printf("\n"); } + #endif + + #ifdef DEBUG_OTHER - printf("Thermistors with Disabling:\r\n"); + printf("Thermistors with Disabling:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { printf("Chip %d: ", c); @@ -186,10 +220,10 @@ const void print_bms_stats(acc_data_t *acc_data) printf("%d ", acc_data->chip_data[c].thermistor_value[cell]); } - printf("\r\n"); + printf("\n"); } - printf("UnFiltered Thermistor Temps:\r\n"); + printf("UnFiltered Thermistor Temps:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { printf("Chip %d: ", c); @@ -199,10 +233,10 @@ const void print_bms_stats(acc_data_t *acc_data) printf("%d ", acc_data->chip_data[c].thermistor_reading[cell]); } - printf("\r\n"); + printf("\n"); } - printf("Cell Temps:\r\n"); + printf("Cell Temps:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { printf("Chip %d: ", c); @@ -212,8 +246,9 @@ const void print_bms_stats(acc_data_t *acc_data) printf("%d ", acc_data->chip_data[c].cell_temp[cell]); } - printf("\r\n"); + printf("\n"); } + #endif start_timer(&debug_stat_timer, PRINT_STAT_WAIT); } @@ -298,7 +333,7 @@ int main(void) init_both_can(&hcan1, &hcan2); segment_init(); compute_init(); - printf("Init passed\r\n"); + printf("Init passed\n"); /* USER CODE END 2 */ /* Init scheduler */ @@ -754,7 +789,7 @@ static void MX_SPI3_Init(void) hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; - hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; @@ -1183,7 +1218,9 @@ void watchdog_pet(void) void StartDefaultTask(void *argument) { /* USER CODE BEGIN 5 */ - acc_data_t *bmsdata = (acc_data_t *)argument; + #ifdef DEBUG_STATS + acc_data_t* bmsdata = (acc_data_t*) argument; + #endif bool alt = true; @@ -1195,9 +1232,9 @@ void StartDefaultTask(void *argument) #endif if (alt) { - printf(".\r\n"); + printf(".\n"); } else { - printf("..\r\n"); + printf("..\n"); } alt = !alt; diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 7faf3140..8b2ca991 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -5,8 +5,48 @@ #include #include +// TEMPORARY + +#include "common.h" +#include "adBms6830CmdList.h" +#include "adBms6830GenericType.h" +#include "serialPrintResult.h" +#include "adBms6830ParseCreate.h" +#include "mcuWrapper.h" + +#define TOTAL_IC 1 +cell_asic IC[TOTAL_IC]; + +RD REDUNDANT_MEASUREMENT = RD_OFF; +CH AUX_CH_TO_CONVERT = AUX_ALL; +CONT CONTINUOUS_MEASUREMENT = SINGLE; +OW_C_S CELL_OPEN_WIRE_DETECTION = OW_OFF_ALL_CH; +OW_AUX AUX_OPEN_WIRE_DETECTION = AUX_OW_OFF; +PUP OPEN_WIRE_CURRENT_SOURCE = PUP_DOWN; +DCP DISCHARGE_PERMITTED = DCP_OFF; +RSTF RESET_FILTER = RSTF_OFF; +ERR INJECT_ERR_SPI_READ = WITHOUT_ERR; + +/*Loop Measurement Setup These Variables are ENABLED or DISABLED Remember ALL CAPS*/ +LOOP_MEASURMENT MEASURE_CELL = + ENABLED; /* This is ENABLED or DISABLED */ +LOOP_MEASURMENT MEASURE_AVG_CELL = + ENABLED; /* This is ENABLED or DISABLED */ +LOOP_MEASURMENT MEASURE_F_CELL = + ENABLED; /* This is ENABLED or DISABLED */ +LOOP_MEASURMENT MEASURE_S_VOLTAGE = + DISABLED; /* This is ENABLED or DISABLED */ +LOOP_MEASURMENT MEASURE_AUX = + DISABLED; /* This is ENABLED or DISABLED */ +LOOP_MEASURMENT MEASURE_RAUX = + DISABLED; /* This is ENABLED or DISABLED */ +LOOP_MEASURMENT MEASURE_STAT = + ENABLED; /* This is ENABLED or DISABLED */ + +// END + #define THERM_WAIT_TIME 500 /* ms */ -#define VOLTAGE_WAIT_TIME 100 /* ms */ +#define VOLTAGE_WAIT_TIME 500 /* ms */ #define THERM_AVG 15 /* Number of values to average */ #define MAX_VOLT_DELTA 2500 #define MAX_CONSEC_NOISE 10 @@ -69,10 +109,49 @@ void push_chip_configuration() LTC6804_wrcfg(ltc68041, NUM_CHIPS, local_config); } +void adbms_wake() +{ + adBmsCsLow(); + adBmsCsHigh(); +} + +void adBms6830_init_config(uint8_t tIC, cell_asic *ic) +{ + for (uint8_t cic = 0; cic < tIC; cic++) { + /* Init config A */ + ic[cic].tx_cfga.refon = PWR_UP; + // ic[cic].cfga.cth = CVT_8_1mV; + // ic[cic].cfga.flag_d = ConfigA_Flag(FLAG_D0, FLAG_SET) | ConfigA_Flag(FLAG_D1, FLAG_SET); + ic[cic].tx_cfga.gpo = ConfigA_Gpo(GPO1, GPO_SET) | + ConfigA_Gpo(GPO2, GPO_CLR) | + ConfigA_Gpo(GPO3, GPO_CLR) | + ConfigA_Gpo(GPO4, GPO_CLR) | + ConfigA_Gpo(GPO5, GPO_CLR) | + ConfigA_Gpo(GPO6, GPO_CLR) | + ConfigA_Gpo(GPO7, GPO_CLR) | + ConfigA_Gpo(GPO8, GPO_CLR) | + ConfigA_Gpo(GPO9, GPO_CLR) | + ConfigA_Gpo(GPO10, GPO_CLR); + // ic[cic].tx_cfga.gpo = 0X3FF; /* All GPIO pull down off */ + // ic[cic].cfga.soakon = SOAKON_CLR; + // ic[cic].cfga.fc = IIR_FPA256; + + /* Init config B */ + // ic[cic].cfgb.dtmen = DTMEN_ON; + ic[cic].tx_cfgb.vov = SetOverVoltageThreshold(4.2); + ic[cic].tx_cfgb.vuv = SetUnderVoltageThreshold(3.0); + // ic[cic].cfgb.dcc = ConfigB_DccBit(DCC16, DCC_BIT_SET); + // SetConfigB_DischargeTimeOutValue(tIC, &ic[cic], RANG_0_TO_63_MIN, TIME_1MIN_OR_0_26HR); + } + adbms_wake(); + adBmsWriteData(tIC, &ic[0], WRCFGA, Config, A); + adBmsWriteData(tIC, &ic[0], WRCFGB, Config, B); +} + void segment_init() { printf("Initializing Segments..."); - + adBms6830_init_config(TOTAL_IC, &IC[0]); ltc68041 = malloc(sizeof(ltc_config)); LTC6804_initialize(ltc68041, &hspi1, GPIOA, SPI_1_CS_Pin); @@ -130,6 +209,63 @@ void select_therm(uint8_t therm) LTC6804_stcomm(ltc68041, 24); } +void read_aux_voltages() +{ + + adbms_wake(); + adBmsWriteData(NUM_CHIPS, &IC[0], WRCFGA, Config, A); + adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, + AUX_CH_TO_CONVERT); + uint32_t pladc_count = adBmsPollAdc(PLAUX1); + + printf("Aux voltage conversion completed\n"); + printPollAdcConvTime(pladc_count); + + adbms_wake(); + adBmsReadData(NUM_CHIPS, &IC[0], RDAUXA, Aux, A); + adBmsReadData(NUM_CHIPS, &IC[0], RDAUXB, Aux, B); + adBmsReadData(NUM_CHIPS, &IC[0], RDAUXC, Aux, C); + adBmsReadData(NUM_CHIPS, &IC[0], RDAUXD, Aux, D); + printVoltages(NUM_CHIPS, &IC[0], Aux); + + adbms_wake(); + adBmsWriteData(NUM_CHIPS, &IC[0], WRCFGA, Config, A); + adBms6830_Adax2(AUX_CH_TO_CONVERT); + pladc_count = adBmsPollAdc(PLAUX2); + + printf("RAux voltage conversion completed\n"); + printPollAdcConvTime(pladc_count); + + adbms_wake(); + adBmsReadData(NUM_CHIPS, &IC[0], RDRAXA, RAux, A); + adBmsReadData(NUM_CHIPS, &IC[0], RDRAXB, RAux, B); + adBmsReadData(NUM_CHIPS, &IC[0], RDRAXC, RAux, C); + adBmsReadData(NUM_CHIPS, &IC[0], RDRAXD, RAux, D); + printVoltages(NUM_CHIPS, &IC[0], RAux); +} + +void adBms6830_read_status_registers(uint8_t tIC, cell_asic *ic) +{ + adBmsWakeupIc(tIC); + adBmsWriteData(tIC, &ic[0], WRCFGA, Config, A); + adBmsWriteData(tIC, &ic[0], WRCFGB, Config, B); + adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, + AUX_CH_TO_CONVERT); + uint32_t pladc_count = adBmsPollAdc(PLADC); + adBms6830_Adcv(REDUNDANT_MEASUREMENT, CONTINUOUS_MEASUREMENT, + DISCHARGE_PERMITTED, RESET_FILTER, + CELL_OPEN_WIRE_DETECTION); + pladc_count = pladc_count + adBmsPollAdc(PLADC); + + adBmsReadData(tIC, &ic[0], RDSTATA, Status, A); + adBmsReadData(tIC, &ic[0], RDSTATB, Status, B); + adBmsReadData(tIC, &ic[0], RDSTATC, Status, C); + adBmsReadData(tIC, &ic[0], RDSTATD, Status, D); + adBmsReadData(tIC, &ic[0], RDSTATE, Status, E); + printPollAdcConvTime(pladc_count); + printStatus(tIC, &ic[0], Status, ALL_GRP); +} + int pull_voltages() { /** @@ -150,15 +286,152 @@ int pull_voltages() return voltage_error; } - uint16_t raw_voltages[NUM_CHIPS][12]; + uint16_t raw_voltages[NUM_CHIPS][NUM_CELLS_PER_CHIP]; + + IC[0].cell.c_codes[0] = 1; + IC[0].cell.c_codes[1] = 2; + IC[0].cell.c_codes[2] = 3; + + adBmsWakeupIc(TOTAL_IC); + adBmsWriteData(TOTAL_IC, &IC[0], WRCFGA, Config, A); + adBmsWriteData(TOTAL_IC, &IC[0], WRCFGB, Config, B); + adBmsWakeupIc(TOTAL_IC); + adBms6830_Adcv(REDUNDANT_MEASUREMENT, CONTINUOUS, DISCHARGE_PERMITTED, + RESET_FILTER, CELL_OPEN_WIRE_DETECTION); + HAL_Delay(1); // ADCs are updated at their conversion rate is 1ms + adBms6830_Adcv(RD_ON, CONTINUOUS, DISCHARGE_PERMITTED, RESET_FILTER, + CELL_OPEN_WIRE_DETECTION); + HAL_Delay(1); // ADCs are updated at their conversion rate is 1ms + adBms6830_Adsv(CONTINUOUS, DISCHARGE_PERMITTED, + CELL_OPEN_WIRE_DETECTION); + HAL_Delay(8); // ADCs are updated at their conversion rate is 8ms + + adBmsWakeupIc(TOTAL_IC); + adBmsReadData(TOTAL_IC, &IC[0], RDCVA, Cell, A); + adBmsReadData(TOTAL_IC, &IC[0], RDCVB, Cell, B); + adBmsReadData(TOTAL_IC, &IC[0], RDCVC, Cell, C); + adBmsReadData(TOTAL_IC, &IC[0], RDCVD, Cell, D); + adBmsReadData(TOTAL_IC, &IC[0], RDCVE, Cell, E); + adBmsReadData(TOTAL_IC, &IC[0], RDCVF, Cell, F); + // printVoltages(TOTAL_IC, &IC[0], Cell); + + float voltage; + uint8_t ic = 0; + int16_t temp; + // number of cells + uint8_t channel = 16; + uint8_t type = Cell; + for (uint8_t index = 0; index < channel; index++) { + if (type == Cell) { + temp = IC[ic].cell.c_codes[index]; + } else if (type == AvgCell) { + temp = IC[ic].acell.ac_codes[index]; + } else if (type == F_volt) { + temp = IC[ic].fcell.fc_codes[index]; + } else if (type == S_volt) { + temp = IC[ic].scell.sc_codes[index]; + } else if (type == Aux) { + temp = IC[ic].aux.a_codes[index]; + } else if (type == RAux) { + temp = IC[ic].raux.ra_codes[index]; + } + + voltage = getVoltage(temp); - push_chip_configuration(); - LTC6804_adcv(ltc68041); + raw_voltages[ic][index] = (uint16_t)temp; + + segment_data[ic].voltage[index] = raw_voltages[ic][index]; + + if (type == Cell) { + // printf("C%d=%fV= %d raw\r\n", (index + 1), voltage, + // segment_data[ic].voltage[index]); + if (index == (channel - 1)) { + // printf("CCount:%d,", IC[ic].cccrc.cmd_cntr); + // printf("PECError:%d", IC[ic].cccrc.cell_pec); + } + } + } + // printf("\n\n"); + /* + float total_volts = 0; + for (int i = 0; i < 16; i++) { + printf("Raw %d: %f\n", i, getVoltage(segment_data[ic].voltage[i])); + total_volts += getVoltage(segment_data[ic].voltage[i]); + } + printf("TOTAL VOLTAGE: %f", total_volts);*/ + + /* + if (MEASURE_AVG_CELL == ENABLED) { + adBmsReadData(TOTAL_IC, &IC[0], RDACA, AvgCell, A); + adBmsReadData(TOTAL_IC, &IC[0], RDACB, AvgCell, B); + adBmsReadData(TOTAL_IC, &IC[0], RDACC, AvgCell, C); + adBmsReadData(TOTAL_IC, &IC[0], RDACD, AvgCell, D); + adBmsReadData(TOTAL_IC, &IC[0], RDACE, AvgCell, E); + adBmsReadData(TOTAL_IC, &IC[0], RDACF, AvgCell, F); + printVoltages(TOTAL_IC, &IC[0], AvgCell); + } + + if (MEASURE_F_CELL == ENABLED) { + adBmsReadData(TOTAL_IC, &IC[0], RDFCA, F_volt, A); + adBmsReadData(TOTAL_IC, &IC[0], RDFCB, F_volt, B); + adBmsReadData(TOTAL_IC, &IC[0], RDFCC, F_volt, C); + adBmsReadData(TOTAL_IC, &IC[0], RDFCD, F_volt, D); + adBmsReadData(TOTAL_IC, &IC[0], RDFCE, F_volt, E); + adBmsReadData(TOTAL_IC, &IC[0], RDFCF, F_volt, F); + printVoltages(TOTAL_IC, &IC[0], F_volt); + } */ + + if (MEASURE_S_VOLTAGE == ENABLED) { + adBmsWakeupIc(TOTAL_IC); + adBmsReadData(TOTAL_IC, &IC[0], RDSVA, S_volt, A); + adBmsReadData(TOTAL_IC, &IC[0], RDSVB, S_volt, B); + adBmsReadData(TOTAL_IC, &IC[0], RDSVC, S_volt, C); + adBmsReadData(TOTAL_IC, &IC[0], RDSVD, S_volt, D); + adBmsReadData(TOTAL_IC, &IC[0], RDSVE, S_volt, E); + adBmsReadData(TOTAL_IC, &IC[0], RDSVF, S_volt, F); + printVoltages(TOTAL_IC, &IC[0], S_volt); + } + + if (MEASURE_AUX == ENABLED) { + adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, + OPEN_WIRE_CURRENT_SOURCE, AUX_CH_TO_CONVERT); + adBmsPollAdc(PLAUX1); + adBmsReadData(TOTAL_IC, &IC[0], RDAUXA, Aux, A); + adBmsReadData(TOTAL_IC, &IC[0], RDAUXB, Aux, B); + adBmsReadData(TOTAL_IC, &IC[0], RDAUXC, Aux, C); + adBmsReadData(TOTAL_IC, &IC[0], RDAUXD, Aux, D); + printVoltages(TOTAL_IC, &IC[0], Aux); + } + + /* + if (MEASURE_RAUX == ENABLED) { + adBmsWakeupIc(TOTAL_IC); + adBms6830_Adax2(AUX_CH_TO_CONVERT); + adBmsPollAdc(PLAUX2); + adBmsReadData(TOTAL_IC, &IC[0], RDRAXA, RAux, A); + adBmsReadData(TOTAL_IC, &IC[0], RDRAXB, RAux, B); + adBmsReadData(TOTAL_IC, &IC[0], RDRAXC, RAux, C); + adBmsReadData(TOTAL_IC, &IC[0], RDRAXD, RAux, D); + printVoltages(TOTAL_IC, &IC[0], RAux); + } */ + + if (MEASURE_STAT == ENABLED) { + adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, + OPEN_WIRE_CURRENT_SOURCE, AUX_CH_TO_CONVERT); + adBmsPollAdc(PLAUX1); + adBmsReadData(TOTAL_IC, &IC[0], RDSTATA, Status, A); + adBmsReadData(TOTAL_IC, &IC[0], RDSTATB, Status, B); + adBmsReadData(TOTAL_IC, &IC[0], RDSTATC, Status, C); + adBmsReadData(TOTAL_IC, &IC[0], RDSTATD, Status, D); + adBmsReadData(TOTAL_IC, &IC[0], RDSTATE, Status, E); + printStatus(TOTAL_IC, &IC[0], Status, ALL_GRP); + } /** * If we received an incorrect PEC indicating a bad read * copy over the data from the last good read and indicate an error */ + /* if (LTC6804_rdcv(ltc68041, 0, NUM_CHIPS, raw_voltages) == -1) { for (uint8_t i = 0; i < NUM_CHIPS; i++) { memcpy(segment_data[i].voltage, @@ -169,77 +442,13 @@ int pull_voltages() printf("Bad voltage read\n"); } return 1; - } - - /* 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; - - 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 (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]++; - // 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; - // segment_data[corrected_index].consecutive_noise[dest_index] = 0; - // segment_data[corrected_index].voltage[dest_index] = - // raw_voltages[i][j]; - // } - } else { - // 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]); 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); + read_aux_voltages(); + return 0; } diff --git a/Makefile b/Makefile index 992d235e..25fba47f 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,10 @@ Drivers/Embedded-Base/general/src/sht30.c \ Drivers/Embedded-Base/middleware/src/timer.c \ Drivers/Embedded-Base/middleware/src/ringbuffer.c \ Drivers/Embedded-Base/middleware/src/c_utils.c \ +Drivers/adbms/lib/src/adBms6830GenericType.c \ +Drivers/adbms/lib/src/adBms6830ParseCreate.c \ +Drivers/adbms/program/src/serialPrintResult.c \ +Drivers/adbms/program/src/mcuWrapper.c \ Core/Src/freertos.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c \ Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c \ @@ -156,6 +160,8 @@ C_INCLUDES = \ -IDrivers/Embedded-Base/general/include \ -IDrivers/Embedded-Base/platforms/stm32f405/include \ -IDrivers/Embedded-Base/middleware/include \ +-IDrivers/adbms/program/inc \ +-IDrivers/adbms/lib/inc \ -IMiddlewares/Third_Party/FreeRTOS/Source/include \ -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F From 004e83deb21f459b2e61660e7ea70291d872c265 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 17 Nov 2024 19:47:47 -0500 Subject: [PATCH 03/32] 133 it works --- Core/Inc/bmsConfig.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index fa9049c3..ac68e58c 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -2,9 +2,9 @@ #define BMS_CONFIG_H // Hardware definition -#define NUM_SEGMENTS 6 -#define NUM_CHIPS NUM_SEGMENTS * 2 -#define NUM_CELLS_PER_CHIP 10 +#define NUM_SEGMENTS 1 +#define NUM_CHIPS 1 //NUM_SEGMENTS * 2 +#define NUM_CELLS_PER_CHIP 16 #define NUM_THERMS_PER_CHIP 32 #define NUM_RELEVANT_THERMS 3 From fe7b35e8877591a37cbd150856cd1076e13c591e Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 17 Nov 2024 19:55:57 -0500 Subject: [PATCH 04/32] 133 debugging --- Core/Src/analyzer.c | 32 ++++++++++++++++++++++++++------ Core/Src/main.c | 20 ++++++++++++++++++-- Core/Src/segment.c | 19 +++++++++---------- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index c0509b42..3635a289 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -5,6 +5,8 @@ #include "compute.h" +#include "serialPrintResult.h" + // clang-format off /** * @brief Mapping Cell temperature to the cell resistance based on the @@ -310,10 +312,13 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) 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] > + if (getVoltage(bmsdata->chip_data[c].voltage[cell]) * + 10000 > bmsdata->max_voltage.val) { bmsdata->max_voltage.val = - bmsdata->chip_data[c].voltage[cell]; + getVoltage(bmsdata->chip_data[c] + .voltage[cell]) * + 10000; bmsdata->max_voltage.chipIndex = c; bmsdata->max_voltage.cellNum = cell; } @@ -328,10 +333,13 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) } /* finds out the minimum cell voltage and location */ - if (bmsdata->chip_data[c].voltage[cell] < + if (getVoltage(bmsdata->chip_data[c].voltage[cell]) * + 10000 < bmsdata->min_voltage.val) { bmsdata->min_voltage.val = - bmsdata->chip_data[c].voltage[cell]; + getVoltage(bmsdata->chip_data[c] + .voltage[cell]) * + 10000; bmsdata->min_voltage.chipIndex = c; bmsdata->min_voltage.cellNum = cell; } @@ -351,9 +359,21 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) } } + float real_total_volt = 0; + for (int chip = 0; chip < NUM_CHIPS; chip++) { + for (int i = 0; i < NUM_CELLS_PER_CHIP; i++) { + real_total_volt += + getVoltage(bmsdata->chip_data[chip].voltage[i]); + } + } + /* calculate some voltage stats */ - bmsdata->avg_voltage = total_volt / (NUM_CELLS_PER_CHIP * NUM_CHIPS); - bmsdata->pack_voltage = total_volt / 1000; /* convert to voltage * 10 */ + bmsdata->avg_voltage = + 10000 * (real_total_volt / (NUM_CELLS_PER_CHIP * NUM_CHIPS)); + + bmsdata->pack_voltage = + real_total_volt * 10; /* convert to voltage * 10 */ + bmsdata->delt_voltage = bmsdata->max_voltage.val - bmsdata->min_voltage.val; diff --git a/Core/Src/main.c b/Core/Src/main.c index 8de75f8a..bbb5aafd 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -122,9 +122,25 @@ void StartDefaultTask(void *argument); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ +/* the following reroutes printf to uart */ +#ifdef __GNUC__ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#else +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#endif + +PUTCHAR_PROTOTYPE +{ + HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, HAL_MAX_DELAY); + return ch; +} + int _write(int file, char* ptr, int len) { - HAL_UART_Transmit_DMA(&huart4, (uint8_t *)ptr, len); - + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) { + __io_putchar( *ptr++ ); + } return len; } diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 8b2ca991..b17e3812 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -123,15 +123,15 @@ void adBms6830_init_config(uint8_t tIC, cell_asic *ic) // ic[cic].cfga.cth = CVT_8_1mV; // ic[cic].cfga.flag_d = ConfigA_Flag(FLAG_D0, FLAG_SET) | ConfigA_Flag(FLAG_D1, FLAG_SET); ic[cic].tx_cfga.gpo = ConfigA_Gpo(GPO1, GPO_SET) | - ConfigA_Gpo(GPO2, GPO_CLR) | - ConfigA_Gpo(GPO3, GPO_CLR) | - ConfigA_Gpo(GPO4, GPO_CLR) | - ConfigA_Gpo(GPO5, GPO_CLR) | - ConfigA_Gpo(GPO6, GPO_CLR) | - ConfigA_Gpo(GPO7, GPO_CLR) | - ConfigA_Gpo(GPO8, GPO_CLR) | - ConfigA_Gpo(GPO9, GPO_CLR) | - ConfigA_Gpo(GPO10, GPO_CLR); + ConfigA_Gpo(GPO2, GPO_SET) | + ConfigA_Gpo(GPO3, GPO_SET) | + ConfigA_Gpo(GPO4, GPO_SET) | + ConfigA_Gpo(GPO5, GPO_SET) | + ConfigA_Gpo(GPO6, GPO_SET) | + ConfigA_Gpo(GPO7, GPO_SET) | + ConfigA_Gpo(GPO8, GPO_SET) | + ConfigA_Gpo(GPO9, GPO_SET) | + ConfigA_Gpo(GPO10, GPO_SET); // ic[cic].tx_cfga.gpo = 0X3FF; /* All GPIO pull down off */ // ic[cic].cfga.soakon = SOAKON_CLR; // ic[cic].cfga.fc = IIR_FPA256; @@ -211,7 +211,6 @@ void select_therm(uint8_t therm) void read_aux_voltages() { - adbms_wake(); adBmsWriteData(NUM_CHIPS, &IC[0], WRCFGA, Config, A); adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, From 331f9ddcfddab625199440fb592bcc6595d30c72 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 17 Nov 2024 20:47:52 -0500 Subject: [PATCH 05/32] 133 working prints --- Core/Src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Src/main.c b/Core/Src/main.c index bbb5aafd..8ff76e3e 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -205,7 +205,7 @@ const void print_bms_stats(acc_data_t *acc_data) { for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - printf("%f\t", getVoltage(acc_data->chip_data[c].voltage[cell])); + printf("%d\t", acc_data->chip_data[c].voltage[cell]); } printf("\n"); } @@ -373,7 +373,7 @@ int main(void) /* Create the thread(s) */ /* creation of defaultTask */ - defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes); + defaultTaskHandle = osThreadNew(StartDefaultTask, acc_data, &defaultTask_attributes); /* USER CODE BEGIN RTOS_THREADS */ From a7bff6165caf06160aa454c28d3f2748be34f347 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:49:44 -0500 Subject: [PATCH 06/32] adbms functions for config registers, get rid of some LTC code, started on pulling voltages --- Core/Src/segment.c | 277 ++++++++++++++++++++++++++++----------------- Drivers/adbms | 2 +- 2 files changed, 177 insertions(+), 102 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index b17e3812..5a03518f 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -14,6 +14,13 @@ #include "adBms6830ParseCreate.h" #include "mcuWrapper.h" +#define ALL_GPIOS_ARE_INPUTS 0x3FF + +typedef enum { + DISCHARGE_ENABLED = 0, + MUTE_ACTIVATED_DISCHARGE_DISABLED = 1 +} MUTE_ST; + #define TOTAL_IC 1 cell_asic IC[TOTAL_IC]; @@ -55,7 +62,6 @@ LOOP_MEASURMENT MEASURE_STAT = // TODO ensure spi 1 is correct for talking to segs extern SPI_HandleTypeDef hspi1; -ltc_config *ltc68041; uint8_t local_config[NUM_CHIPS][6] = {}; uint8_t therm_avg_counter = 0; @@ -103,10 +109,20 @@ void discard_neutrals(void); void pull_chip_configuration(void); int16_t calc_average(void); int8_t calc_therm_standard_dev(int16_t avg_temp); - -void push_chip_configuration() +void init_chip(cell_asic *chip); +void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge); + +/** + * @brief Set a bit in a uint16 + * + * @param number uint16 to change. + * @param n Nth bit to change. + * @param x true sets, false clears. + * @return uint16_t New uint16. + */ +inline uint16_t set_uint16_bit(uint16_t number, uint16_t n, bool x) { - LTC6804_wrcfg(ltc68041, NUM_CHIPS, local_config); + return (number & ~((uint16_t)1 << n)) | ((uint16_t)x << n); } void adbms_wake() @@ -115,74 +131,163 @@ void adbms_wake() adBmsCsHigh(); } -void adBms6830_init_config(uint8_t tIC, cell_asic *ic) -{ - for (uint8_t cic = 0; cic < tIC; cic++) { - /* Init config A */ - ic[cic].tx_cfga.refon = PWR_UP; - // ic[cic].cfga.cth = CVT_8_1mV; - // ic[cic].cfga.flag_d = ConfigA_Flag(FLAG_D0, FLAG_SET) | ConfigA_Flag(FLAG_D1, FLAG_SET); - ic[cic].tx_cfga.gpo = ConfigA_Gpo(GPO1, GPO_SET) | - ConfigA_Gpo(GPO2, GPO_SET) | - ConfigA_Gpo(GPO3, GPO_SET) | - ConfigA_Gpo(GPO4, GPO_SET) | - ConfigA_Gpo(GPO5, GPO_SET) | - ConfigA_Gpo(GPO6, GPO_SET) | - ConfigA_Gpo(GPO7, GPO_SET) | - ConfigA_Gpo(GPO8, GPO_SET) | - ConfigA_Gpo(GPO9, GPO_SET) | - ConfigA_Gpo(GPO10, GPO_SET); - // ic[cic].tx_cfga.gpo = 0X3FF; /* All GPIO pull down off */ - // ic[cic].cfga.soakon = SOAKON_CLR; - // ic[cic].cfga.fc = IIR_FPA256; - - /* Init config B */ - // ic[cic].cfgb.dtmen = DTMEN_ON; - ic[cic].tx_cfgb.vov = SetOverVoltageThreshold(4.2); - ic[cic].tx_cfgb.vuv = SetUnderVoltageThreshold(3.0); - // ic[cic].cfgb.dcc = ConfigB_DccBit(DCC16, DCC_BIT_SET); - // SetConfigB_DischargeTimeOutValue(tIC, &ic[cic], RANG_0_TO_63_MIN, TIME_1MIN_OR_0_26HR); - } - adbms_wake(); - adBmsWriteData(tIC, &ic[0], WRCFGA, Config, A); - adBmsWriteData(tIC, &ic[0], WRCFGB, Config, B); +/** + * @brief Initialize a chip with default values. + * + * @param chip Pointer to chip to initialize. + */ +void init_chip(cell_asic *chip) +{ + chip->tx_cfga.refon = PWR_UP; + chip->tx_cfga.cth = CVT_8_1mV; + chip->tx_cfga.flag_d = 0; + + // No soak on AUX ADCs + chip->tx_cfga.soakon = SOAKON_CLR; + + // short soak time by default + chip->tx_cfga.owrng = TIME_32US_TO_4_1MS; + + chip->tx_cfga.owa = OWA0; + + // All GPIOs are inputs by default + chip->tx_cfga.gpo = ALL_GPIOS_ARE_INPUTS; + + // Registers are unfrozen + chip->tx_cfga.snap = SNAP_OFF; + + // Charging is deactivated + chip->tx_cfga.mute_st = MUTE_ACTIVATED_DISCHARGE_DISABLED; + + // Not an endpoint in the daisy chain + chip->tx_cfga.comm_bk = false; + + // IIR filter disabled + chip->tx_cfga.fc = IIR_FPA_OFF; + + // Init config B + chip->tx_cfgb.vov = SetOverVoltageThreshold(4.2); + chip->tx_cfgb.vuv = SetUnderVoltageThreshold(3.0); + + // Discharge timer monitor off + chip->tx_cfgb.dtmen = DTMEN_OFF; + + // Set discharge timer range to 0 to 63 minutes with 1 minute increments + chip->tx_cfgb.dtrng = RANG_0_TO_63_MIN; + + // Disable discharge timer + chip->tx_cfgb.dcto = DCTO_TIMEOUT; + + // Disable discharge for all cells + chip->tx_cfgb.dcc = 0; } -void segment_init() +/** + * @brief Set the status of the REFON bit. + * + * @param chip Pointer to the chip to modify. + * @param state New state of the REFON bit. + */ +void set_REFON(cell_asic *chip, REFON state) { - printf("Initializing Segments..."); - adBms6830_init_config(TOTAL_IC, &IC[0]); - ltc68041 = malloc(sizeof(ltc_config)); - LTC6804_initialize(ltc68041, &hspi1, GPIOA, SPI_1_CS_Pin); + chip->tx_cfga.refon = state; +} - pull_chip_configuration(); +/** + * @brief Set the C-ADC vs. S-ADC comparison voltage threshold + * + * @param chip Pointer to the chip to modify. + * @param threshold Threshold to set. + */ +void set_volt_adc_comp_thresh(cell_asic *chip, CTH threshold) +{ + chip->tx_cfga.cth = threshold; +} - for (int c = 0; c < NUM_CHIPS; c++) { - local_config[c][0] = 0xF8; - local_config[c][1] = 0x19; /* VUV = 0x619 = 1561 -> 2.4992V */ - local_config[c][2] = 0x06; /* VOV = 0xA60 = 2656 -> 4.2496V */ - local_config[c][3] = 0xA6; - local_config[c][4] = 0x00; - local_config[c][5] = 0x00; - } - push_chip_configuration(); +/** + * @brief Set the discharge state of a cell. + * + * @param chip Pointer to chip with cell to modify. + * @param cell ID of cell to modify. + * @param discharge Cell discharge state. true to discharge, false to disable discharge. + */ +void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge) +{ + chip->tx_cfgb.dcc = set_uint16_bit(chip->tx_cfgb.dcc, cell, discharge); +} - start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); - start_timer(&therm_timer, THERM_WAIT_TIME); +/** + * @brief Write data to a chip. + * + * @param chip Chip to write to. + * @param command Command to issue to the chip. + * @param type Register type to write to. + * @param group Group of registers to write to. + */ +void write_adbms_data(cell_asic *chip, uint8_t command[2], TYPE type, GRP group) +{ + adBmsWriteData(0, chip, command, type, group); +} - uint8_t i2c_write_data[NUM_CHIPS][3]; +/** + * @brief Write data to a chip. + * + * @param chip Chip to write to. + * @param command Command to issue to the chip. + * @param type Register type to write to. + * @param group Group of registers to write to. + */ +void read_adbms_data(cell_asic *chip, uint8_t command[2], TYPE type, GRP group) +{ + adBmsReadData(0, chip, command, type, group); +} - // Set GPIO expander to output +/** + * @brief Chips go into sleep mode after the watchdog timeout period. When they sleep, they need to have their configuration registers set. + * + * @param chip Chip to wake and reset. + */ +inline void wake_and_write_configs(cell_asic *chip) +{ + adbms_wake(); + write_adbms_data(chip, WRCFGA, Config, A); + write_adbms_data(chip, WRCFGB, Config, B); +} + +/** + * @brief Initialize chips with default values. + * + */ +void segment_init() +{ + printf("Initializing Segments..."); 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 + init_chip(&IC[chip]); + adbms_wake(); + write_adbms_data(&IC[chip], WRCFGA, Config, A); + write_adbms_data(&IC[chip], WRCFGB, Config, B); } - 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); +/** + * @brief Get voltage readings from the C-ADCs. + * + * @param chip Chip to get voltage readings from. + */ +void get_c_adc_voltages(cell_asic *chip) +{ + wake_and_write_configs(chip); + adbms_wake(); + adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); + + adbms_wake(); + read_adbms_data(chip, RDCVA, Cell, A); + read_adbms_data(chip, RDCVB, Cell, B); + read_adbms_data(chip, RDCVC, Cell, C); + read_adbms_data(chip, RDCVD, Cell, D); + read_adbms_data(chip, RDCVE, Cell, E); + read_adbms_data(chip, RDCVF, Cell, F); } void select_therm(uint8_t therm) @@ -204,9 +309,9 @@ void select_therm(uint8_t 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); + // push_chip_configuration(); + // LTC6804_wrcomm(ltc68041, NUM_CHIPS, comm_reg_data); + // LTC6804_stcomm(ltc68041, 24); } void read_aux_voltages() @@ -272,9 +377,6 @@ int pull_voltages() * just copy over the contents of the last good reading and the fault status * from the most recent attempt */ - - // 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) { for (uint8_t i = 0; i < NUM_CHIPS; i++) { @@ -287,31 +389,6 @@ int pull_voltages() uint16_t raw_voltages[NUM_CHIPS][NUM_CELLS_PER_CHIP]; - IC[0].cell.c_codes[0] = 1; - IC[0].cell.c_codes[1] = 2; - IC[0].cell.c_codes[2] = 3; - - adBmsWakeupIc(TOTAL_IC); - adBmsWriteData(TOTAL_IC, &IC[0], WRCFGA, Config, A); - adBmsWriteData(TOTAL_IC, &IC[0], WRCFGB, Config, B); - adBmsWakeupIc(TOTAL_IC); - adBms6830_Adcv(REDUNDANT_MEASUREMENT, CONTINUOUS, DISCHARGE_PERMITTED, - RESET_FILTER, CELL_OPEN_WIRE_DETECTION); - HAL_Delay(1); // ADCs are updated at their conversion rate is 1ms - adBms6830_Adcv(RD_ON, CONTINUOUS, DISCHARGE_PERMITTED, RESET_FILTER, - CELL_OPEN_WIRE_DETECTION); - HAL_Delay(1); // ADCs are updated at their conversion rate is 1ms - adBms6830_Adsv(CONTINUOUS, DISCHARGE_PERMITTED, - CELL_OPEN_WIRE_DETECTION); - HAL_Delay(8); // ADCs are updated at their conversion rate is 8ms - - adBmsWakeupIc(TOTAL_IC); - adBmsReadData(TOTAL_IC, &IC[0], RDCVA, Cell, A); - adBmsReadData(TOTAL_IC, &IC[0], RDCVB, Cell, B); - adBmsReadData(TOTAL_IC, &IC[0], RDCVC, Cell, C); - adBmsReadData(TOTAL_IC, &IC[0], RDCVD, Cell, D); - adBmsReadData(TOTAL_IC, &IC[0], RDCVE, Cell, E); - adBmsReadData(TOTAL_IC, &IC[0], RDCVF, Cell, F); // printVoltages(TOTAL_IC, &IC[0], Cell); float voltage; @@ -477,10 +554,8 @@ int pull_thermistors() select_therm(current_therm); HAL_Delay(200); // push_chip_configuration(); - LTC6804_clraux(ltc68041); - LTC6804_adax(ltc68041); /* Run ADC for AUX (GPIOs and refs) */ HAL_Delay(3); - LTC6804_rdaux(ltc68041, 0, NUM_CHIPS, raw_temp_voltages); + // 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++) { @@ -631,13 +706,13 @@ void segment_enable_balancing(bool balance_enable) configure_discharge(c, DICHARGE_ALL_COMMAND); discharge_commands[c] = DICHARGE_ALL_COMMAND; } - push_chip_configuration(); + // push_chip_configuration(); } else { for (int c = 0; c < NUM_CHIPS; c++) { configure_discharge(c, 0); discharge_commands[c] = 0; } - push_chip_configuration(); + // push_chip_configuration(); } } @@ -654,7 +729,7 @@ void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, configure_discharge(chip_num, discharge_commands[chip_num]); - push_chip_configuration(); + // push_chip_configuration(); } void segment_configure_balancing( @@ -672,7 +747,7 @@ void segment_configure_balancing( configure_discharge(c, discharge_commands[c]); } - push_chip_configuration(); + // push_chip_configuration(); } bool cell_is_balancing(uint8_t chip_num, uint8_t cell_num) @@ -711,7 +786,7 @@ bool segment_is_balancing() void pull_chip_configuration() { uint8_t remote_config[NUM_CHIPS][8]; - LTC6804_rdcfg(ltc68041, NUM_CHIPS, remote_config); + // LTC6804_rdcfg(ltc68041, NUM_CHIPS, remote_config); for (int chip = 0; chip < NUM_CHIPS; chip++) { for (int index = 0; index < 6; index++) { @@ -739,7 +814,7 @@ void disable_gpio_pulldowns() for (int c = 0; c < NUM_CHIPS; c++) { local_config[c][0] |= 0x18; } - push_chip_configuration(); + // push_chip_configuration(); pull_chip_configuration(); printf("Chip CFG:\n"); diff --git a/Drivers/adbms b/Drivers/adbms index 1c91c8f3..5f73a1f7 160000 --- a/Drivers/adbms +++ b/Drivers/adbms @@ -1 +1 @@ -Subproject commit 1c91c8f3d80035a0dfb3687bc043c2a1c3220f5b +Subproject commit 5f73a1f7ccf4bd9223992213f5a26921bd66d229 From ccff5e022c0cfd98b78f3df1b1b2b766321d8b93 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Tue, 26 Nov 2024 19:34:31 -0500 Subject: [PATCH 07/32] adbms reworking code for daisy chaining --- Core/Src/segment.c | 128 +++++++++++++++++++++++++++++++++------------ 1 file changed, 95 insertions(+), 33 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 5a03518f..1aef0248 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -13,8 +13,14 @@ #include "serialPrintResult.h" #include "adBms6830ParseCreate.h" #include "mcuWrapper.h" +#include "cmsis_os.h" #define ALL_GPIOS_ARE_INPUTS 0x3FF +#define T_READY 10 /* microseconds*/ +#define T_IDLE 4.3 /* milliseconds, minimum. typ is 5.5, max is 6.7 */ +#define T_WAKE 200 /* microseconds */ +#define T_SLEEP 1.8 /* seconds minimum, typ is 2, max is 2.2 */ +#define T_REFUP 2.7 /* milliseconds minimum, typ is 3.5, max is 4.4 */ typedef enum { DISCHARGE_ENABLED = 0, @@ -127,8 +133,14 @@ inline uint16_t set_uint16_bit(uint16_t number, uint16_t n, bool x) void adbms_wake() { - adBmsCsLow(); - adBmsCsHigh(); + for (int i = 0; i < NUM_CHIPS; i++) { + /* Delay between pulses should be above T_WAKE but below T_IDLE */ + // TODO: Use osDelays (might involve preemption lolz we'll figure that out later) + adBmsCsLow(); + HAL_Delay(1); + adBmsCsHigh(); + HAL_Delay(1); + } } /** @@ -217,41 +229,44 @@ void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge) } /** - * @brief Write data to a chip. + * @brief Write data to all chips. * - * @param chip Chip to write to. + * @param chip Array of chips to write data to. * @param command Command to issue to the chip. * @param type Register type to write to. * @param group Group of registers to write to. */ -void write_adbms_data(cell_asic *chip, uint8_t command[2], TYPE type, GRP group) +void write_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, + GRP group) { - adBmsWriteData(0, chip, command, type, group); + adBmsWriteData(NUM_CHIPS, chips, command, type, group); } /** - * @brief Write data to a chip. + * @brief Read data from all chips. * - * @param chip Chip to write to. + * @param chips Array of chips to rad data to. * @param command Command to issue to the chip. * @param type Register type to write to. * @param group Group of registers to write to. */ -void read_adbms_data(cell_asic *chip, uint8_t command[2], TYPE type, GRP group) + +void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, + GRP group) { - adBmsReadData(0, chip, command, type, group); + adBmsReadData(NUM_CHIPS, chips, command, type, group); } /** - * @brief Chips go into sleep mode after the watchdog timeout period. When they sleep, they need to have their configuration registers set. + * @brief Write config registers. Wakes chips before writing. * - * @param chip Chip to wake and reset. + * @param chip Array of chips. */ -inline void wake_and_write_configs(cell_asic *chip) +inline void write_config_regs(cell_asic chips[NUM_CHIPS]) { adbms_wake(); - write_adbms_data(chip, WRCFGA, Config, A); - write_adbms_data(chip, WRCFGB, Config, B); + write_adbms_data(chips, WRCFGA, Config, A); + write_adbms_data(chips, WRCFGB, Config, B); } /** @@ -263,10 +278,8 @@ void segment_init() printf("Initializing Segments..."); for (int chip = 0; chip < NUM_CHIPS; chip++) { init_chip(&IC[chip]); - adbms_wake(); - write_adbms_data(&IC[chip], WRCFGA, Config, A); - write_adbms_data(&IC[chip], WRCFGB, Config, B); } + write_config_regs(IC); } /** @@ -276,18 +289,73 @@ void segment_init() */ void get_c_adc_voltages(cell_asic *chip) { - wake_and_write_configs(chip); + write_config_regs(chip); + adbms_wake(); + adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); + + adbms_wake(); + read_adbms_data(chip, RDCVALL, Rdcvall, ALL_GRP); + // read_adbms_data(chip, RDCVA, Cell, A); + // read_adbms_data(chip, RDCVB, Cell, B); + // read_adbms_data(chip, RDCVC, Cell, C); + // read_adbms_data(chip, RDCVD, Cell, D); + // read_adbms_data(chip, RDCVE, Cell, E); + // read_adbms_data(chip, RDCVF, Cell, F); +} + +/** + * @brief Get voltages from the S-ADCs. + * + * @param chip Chip to get voltage readings from. + */ +void get_s_adc_voltages(cell_asic *chip) +{ + write_config_regs(chip); + adbms_wake(); + adBms6830_Adsv(CONTINUOUS, DCP_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLSADC); + + adbms_wake(); + read_adbms_data(chip, RDSALL, Rdsall, ALL_GRP); + // read_adbms_data(chip, RDSVA, S_volt, A); + // read_adbms_data(chip, RDSVB, S_volt, B); + // read_adbms_data(chip, RDSVC, S_volt, C); + // read_adbms_data(chip, RDSVD, S_volt, D); + // read_adbms_data(chip, RDSVE, S_volt, E); + // read_adbms_data(chip, RDSVF, S_volt, F); +} + +/** + * @brief Get the avgeraged cell voltages. + * + * @param chip Chip that is reading voltages. + */ +void get_avgd_cell_voltages(cell_asic *chip) +{ + write_config_regs(chip); + adbms_wake(); + adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); + + adbms_wake(); + read_adbms_data(chip, RDACALL, Rdacall, ALL_GRP); +} + +/** + * @brief Get the filtered cell volrages. + * + * @param chip Chip to read cell voltages of. + */ +void get_filtered_cell_volrages(cell_asic *chip) +{ + write_config_regs(chip); adbms_wake(); adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); adbms_wake(); - read_adbms_data(chip, RDCVA, Cell, A); - read_adbms_data(chip, RDCVB, Cell, B); - read_adbms_data(chip, RDCVC, Cell, C); - read_adbms_data(chip, RDCVD, Cell, D); - read_adbms_data(chip, RDCVE, Cell, E); - read_adbms_data(chip, RDCVF, Cell, F); + read_adbms_data(chip, RDFCALL, Rdfcall, ALL_GRP); } void select_therm(uint8_t therm) @@ -348,18 +416,12 @@ void read_aux_voltages() printVoltages(NUM_CHIPS, &IC[0], RAux); } -void adBms6830_read_status_registers(uint8_t tIC, cell_asic *ic) +void adBms6830_read_status_registers(cell_asic *chip) { - adBmsWakeupIc(tIC); - adBmsWriteData(tIC, &ic[0], WRCFGA, Config, A); - adBmsWriteData(tIC, &ic[0], WRCFGB, Config, B); + write_config_regs(chip); adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, AUX_CH_TO_CONVERT); uint32_t pladc_count = adBmsPollAdc(PLADC); - adBms6830_Adcv(REDUNDANT_MEASUREMENT, CONTINUOUS_MEASUREMENT, - DISCHARGE_PERMITTED, RESET_FILTER, - CELL_OPEN_WIRE_DETECTION); - pladc_count = pladc_count + adBmsPollAdc(PLADC); adBmsReadData(tIC, &ic[0], RDSTATA, Status, A); adBmsReadData(tIC, &ic[0], RDSTATB, Status, B); From d1b4701088de996b9e63de719bad4cd97b785d38 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 8 Dec 2024 16:52:51 -0500 Subject: [PATCH 08/32] adbms wrapper written **untested** --- Core/Src/segment.c | 195 +++++++++++++++++++----------------------- Drivers/Embedded-Base | 2 +- Drivers/adbms | 2 +- 3 files changed, 90 insertions(+), 109 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 1aef0248..363e8369 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -133,14 +133,7 @@ inline uint16_t set_uint16_bit(uint16_t number, uint16_t n, bool x) void adbms_wake() { - for (int i = 0; i < NUM_CHIPS; i++) { - /* Delay between pulses should be above T_WAKE but below T_IDLE */ - // TODO: Use osDelays (might involve preemption lolz we'll figure that out later) - adBmsCsLow(); - HAL_Delay(1); - adBmsCsHigh(); - HAL_Delay(1); - } + adBmsWakeupIc(NUM_CHIPS); } /** @@ -245,12 +238,11 @@ void write_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, /** * @brief Read data from all chips. * - * @param chips Array of chips to rad data to. + * @param chips Array of chips to read data to. * @param command Command to issue to the chip. * @param type Register type to write to. * @param group Group of registers to write to. */ - void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, GRP group) { @@ -260,7 +252,7 @@ void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, /** * @brief Write config registers. Wakes chips before writing. * - * @param chip Array of chips. + * @param chips Array of chips to write config registers of. */ inline void write_config_regs(cell_asic chips[NUM_CHIPS]) { @@ -285,17 +277,17 @@ void segment_init() /** * @brief Get voltage readings from the C-ADCs. * - * @param chip Chip to get voltage readings from. + * @param chips Array of chips to get voltage readings from. */ -void get_c_adc_voltages(cell_asic *chip) +void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]) { - write_config_regs(chip); + write_config_regs(chips); adbms_wake(); adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); adbms_wake(); - read_adbms_data(chip, RDCVALL, Rdcvall, ALL_GRP); + read_adbms_data(chips, RDCVALL, Rdcvall, ALL_GRP); // read_adbms_data(chip, RDCVA, Cell, A); // read_adbms_data(chip, RDCVB, Cell, B); // read_adbms_data(chip, RDCVC, Cell, C); @@ -307,17 +299,17 @@ void get_c_adc_voltages(cell_asic *chip) /** * @brief Get voltages from the S-ADCs. * - * @param chip Chip to get voltage readings from. + * @param chip Array of chips to get voltage readings from. */ -void get_s_adc_voltages(cell_asic *chip) +void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) { - write_config_regs(chip); + write_config_regs(chips); adbms_wake(); adBms6830_Adsv(CONTINUOUS, DCP_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLSADC); adbms_wake(); - read_adbms_data(chip, RDSALL, Rdsall, ALL_GRP); + read_adbms_data(chips, RDSALL, Rdsall, ALL_GRP); // read_adbms_data(chip, RDSVA, S_volt, A); // read_adbms_data(chip, RDSVB, S_volt, B); // read_adbms_data(chip, RDSVC, S_volt, C); @@ -329,107 +321,103 @@ void get_s_adc_voltages(cell_asic *chip) /** * @brief Get the avgeraged cell voltages. * - * @param chip Chip that is reading voltages. + * @param chip Array of chips to get voltage readings of. */ -void get_avgd_cell_voltages(cell_asic *chip) +void get_avgd_cell_voltages(cell_asic chips[NUM_CHIPS]) { - write_config_regs(chip); + write_config_regs(chips); adbms_wake(); adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); adbms_wake(); - read_adbms_data(chip, RDACALL, Rdacall, ALL_GRP); + read_adbms_data(chips, RDACALL, Rdacall, ALL_GRP); } /** * @brief Get the filtered cell volrages. * - * @param chip Chip to read cell voltages of. + * @param chip Array of chips to get voltage readings of. */ -void get_filtered_cell_volrages(cell_asic *chip) +void get_filtered_cell_volrages(cell_asic chips[NUM_CHIPS]) { - write_config_regs(chip); + write_config_regs(chips); adbms_wake(); adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); adbms_wake(); - read_adbms_data(chip, RDFCALL, Rdfcall, ALL_GRP); + read_adbms_data(chips, RDFCALL, Rdfcall, ALL_GRP); } -void select_therm(uint8_t therm) +/** + * @brief Get the c and s adc voltages. Does this with RDCSALL command. + * + * @param chips Array of chips to get voltage readings of. + */ +void get_c_and_s_adc_voltages(cell_asic chips[NUM_CHIPS]) { - /* Exit if out of range values */ - if (therm < 1 || therm > 16) { - return; - } - - uint8_t i2c_write_data[NUM_CHIPS][3]; - uint8_t comm_reg_data[NUM_CHIPS][6]; + write_config_regs(chips); + adbms_wake(); + adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); - // select 0-16 on GPIO expander - 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); - // push_chip_configuration(); - // LTC6804_wrcomm(ltc68041, NUM_CHIPS, comm_reg_data); - // LTC6804_stcomm(ltc68041, 24); + adbms_wake(); + read_adbms_data(chips, RDCSALL, Rdcsall, ALL_GRP); } -void read_aux_voltages() +/** + * @brief Read every register connected to the AUX ADC. + * + * @param chips Array of chips to get voltage readings of. + */ +void read_aux_registers(cell_asic chips[NUM_CHIPS]) { - adbms_wake(); - adBmsWriteData(NUM_CHIPS, &IC[0], WRCFGA, Config, A); - adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, - AUX_CH_TO_CONVERT); - uint32_t pladc_count = adBmsPollAdc(PLAUX1); - - printf("Aux voltage conversion completed\n"); - printPollAdcConvTime(pladc_count); - - adbms_wake(); - adBmsReadData(NUM_CHIPS, &IC[0], RDAUXA, Aux, A); - adBmsReadData(NUM_CHIPS, &IC[0], RDAUXB, Aux, B); - adBmsReadData(NUM_CHIPS, &IC[0], RDAUXC, Aux, C); - adBmsReadData(NUM_CHIPS, &IC[0], RDAUXD, Aux, D); - printVoltages(NUM_CHIPS, &IC[0], Aux); + write_config_regs(chips); + adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); + adBmsPollAdc(PLAUX1); adbms_wake(); - adBmsWriteData(NUM_CHIPS, &IC[0], WRCFGA, Config, A); - adBms6830_Adax2(AUX_CH_TO_CONVERT); - pladc_count = adBmsPollAdc(PLAUX2); + read_adbms_data(chips, RDAUXA, Aux, A); + read_adbms_data(chips, RDAUXB, Aux, B); + read_adbms_data(chips, RDAUXC, Aux, C); + read_adbms_data(chips, RDAUXD, Aux, D); +} - printf("RAux voltage conversion completed\n"); - printPollAdcConvTime(pladc_count); +/** + * @brief Read voltages in every register connected to AUX2 ADC. + * + * @param chips Array of chips to get voltages of. + */ +void read_aux2_registers(cell_asic chips[NUM_CHIPS]) +{ + write_config_regs(chips); + adBms6830_Adax2(AUX_ALL); + adBmsPollAdc(PLAUX2); adbms_wake(); - adBmsReadData(NUM_CHIPS, &IC[0], RDRAXA, RAux, A); - adBmsReadData(NUM_CHIPS, &IC[0], RDRAXB, RAux, B); - adBmsReadData(NUM_CHIPS, &IC[0], RDRAXC, RAux, C); - adBmsReadData(NUM_CHIPS, &IC[0], RDRAXD, RAux, D); - printVoltages(NUM_CHIPS, &IC[0], RAux); + read_adbms_data(chips, RDRAXA, RAux, A); + read_adbms_data(chips, RDRAXB, RAux, B); + read_adbms_data(chips, RDRAXC, RAux, C); + read_adbms_data(chips, RDRAXD, RAux, D); } -void adBms6830_read_status_registers(cell_asic *chip) +/** + * @brief Read status registers. + * + * @param chips Array of chips to read voltages of. + */ +void adBms6830_read_status_registers(cell_asic chips[NUM_CHIPS]) { - write_config_regs(chip); - adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, - AUX_CH_TO_CONVERT); - uint32_t pladc_count = adBmsPollAdc(PLADC); - - adBmsReadData(tIC, &ic[0], RDSTATA, Status, A); - adBmsReadData(tIC, &ic[0], RDSTATB, Status, B); - adBmsReadData(tIC, &ic[0], RDSTATC, Status, C); - adBmsReadData(tIC, &ic[0], RDSTATD, Status, D); - adBmsReadData(tIC, &ic[0], RDSTATE, Status, E); - printPollAdcConvTime(pladc_count); - printStatus(tIC, &ic[0], Status, ALL_GRP); + write_config_regs(chips); + adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); + adBmsPollAdc(PLAUX1); + + read_adbms_data(chips, RDSTATA, Status, A); + read_adbms_data(chips, RDSTATB, Status, B); + read_adbms_data(chips, RDSTATC, Status, C); + read_adbms_data(chips, RDSTATD, Status, D); + read_adbms_data(chips, RDSTATE, Status, E); } int pull_voltages() @@ -449,6 +437,12 @@ int pull_voltages() return voltage_error; } + get_c_adc_voltages() + + /* + + OLD CODE THAT DID WORK FOR ADBMS + uint16_t raw_voltages[NUM_CHIPS][NUM_CELLS_PER_CHIP]; // printVoltages(TOTAL_IC, &IC[0], Cell); @@ -490,6 +484,9 @@ int pull_voltages() } } // printf("\n\n"); + + */ + /* float total_volts = 0; for (int i = 0; i < 16; i++) { @@ -519,6 +516,7 @@ int pull_voltages() printVoltages(TOTAL_IC, &IC[0], F_volt); } */ + /* if (MEASURE_S_VOLTAGE == ENABLED) { adBmsWakeupIc(TOTAL_IC); adBmsReadData(TOTAL_IC, &IC[0], RDSVA, S_volt, A); @@ -528,8 +526,9 @@ int pull_voltages() adBmsReadData(TOTAL_IC, &IC[0], RDSVE, S_volt, E); adBmsReadData(TOTAL_IC, &IC[0], RDSVF, S_volt, F); printVoltages(TOTAL_IC, &IC[0], S_volt); - } + } */ + /* if (MEASURE_AUX == ENABLED) { adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, AUX_CH_TO_CONVERT); @@ -539,7 +538,7 @@ int pull_voltages() adBmsReadData(TOTAL_IC, &IC[0], RDAUXC, Aux, C); adBmsReadData(TOTAL_IC, &IC[0], RDAUXD, Aux, D); printVoltages(TOTAL_IC, &IC[0], Aux); - } + } */ /* if (MEASURE_RAUX == ENABLED) { @@ -553,6 +552,7 @@ int pull_voltages() printVoltages(TOTAL_IC, &IC[0], RAux); } */ + /* if (MEASURE_STAT == ENABLED) { adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, OPEN_WIRE_CURRENT_SOURCE, AUX_CH_TO_CONVERT); @@ -563,30 +563,11 @@ int pull_voltages() adBmsReadData(TOTAL_IC, &IC[0], RDSTATD, Status, D); adBmsReadData(TOTAL_IC, &IC[0], RDSTATE, Status, E); printStatus(TOTAL_IC, &IC[0], Status, ALL_GRP); - } - - /** - * If we received an incorrect PEC indicating a bad read - * copy over the data from the last good read and indicate an error - */ - /* - 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)); - - crc_error_check++; - printf("Bad voltage read\n"); - } - return 1; }*/ /* Start the timer between readings if successful */ start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); - read_aux_voltages(); - return 0; } diff --git a/Drivers/Embedded-Base b/Drivers/Embedded-Base index 83258635..f6ffa63e 160000 --- a/Drivers/Embedded-Base +++ b/Drivers/Embedded-Base @@ -1 +1 @@ -Subproject commit 83258635fc749ac72adb4b52e61f4f1a42e1842f +Subproject commit f6ffa63e1dc78f1cdff5c0196e2a43e901b8d0f6 diff --git a/Drivers/adbms b/Drivers/adbms index 5f73a1f7..eef63db1 160000 --- a/Drivers/adbms +++ b/Drivers/adbms @@ -1 +1 @@ -Subproject commit 5f73a1f7ccf4bd9223992213f5a26921bd66d229 +Subproject commit eef63db194526432e4c004820283badae4034e04 From c671679ae0d85722f94065c0c5af99b86c3cb7d5 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:09:53 -0500 Subject: [PATCH 09/32] adbms cleaning up old functions --- Core/Src/segment.c | 287 ++------------------------------------------- 1 file changed, 10 insertions(+), 277 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 363e8369..bf649408 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -69,7 +69,6 @@ LOOP_MEASURMENT MEASURE_STAT = // TODO ensure spi 1 is correct for talking to segs extern SPI_HandleTypeDef hspi1; -uint8_t local_config[NUM_CHIPS][6] = {}; uint8_t therm_avg_counter = 0; chipdata_t *segment_data = NULL; @@ -437,7 +436,7 @@ int pull_voltages() return voltage_error; } - get_c_adc_voltages() + get_c_adc_voltages(IC); /* @@ -571,136 +570,11 @@ int pull_voltages() return 0; } -int pull_thermistors() +void 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)); - } - return voltage_error; - } - - uint16_t raw_temp_voltages[NUM_CHIPS][6]; + read_aux_registers(IC); - static uint8_t current_therm = 1; - if (current_therm > 16) { - current_therm = 1; - } - - /* Sets multiplexors to select thermistors */ - select_therm(current_therm); - HAL_Delay(200); - // push_chip_configuration(); - 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 - * fluctuations (index 2 is a reading of the ADC 5V ref) - */ - 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); - - /* 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)); - } - } 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 */ - - /* the following algorithms were used to eliminate noise on Car 17D - keep - * them off if possible */ - // variance_therm_check(); - // standard_dev_therm_check(); - // averaging_therm_check(); - // discard_neutrals(); - - return 0; /* Read successfully */ + // TODO: Convert voltages to temperatures, store in a data structure } void segment_retrieve_data(chipdata_t databuf[NUM_CHIPS]) @@ -710,7 +584,7 @@ void segment_retrieve_data(chipdata_t databuf[NUM_CHIPS]) /* Pull voltages and thermistors and indiacate if there was a problem during * retrieval */ voltage_error = pull_voltages(); - therm_error = pull_thermistors(); + pull_thermistors(); /* Save the contents of the reading so that we can use it to fill in missing * data */ @@ -719,123 +593,21 @@ void segment_retrieve_data(chipdata_t databuf[NUM_CHIPS]) segment_data = NULL; } -void configure_discharge(uint8_t chip, uint16_t cells) +bool segment_is_balancing() { - /* - * chipConfigurations[chip][4] == chipConfigurations[Literally what chip you - * want][register] 4 and 5 are registers to discharge chips - */ - local_config[chip][4] = (uint8_t)(cells & 0x00FF); - - /* - * 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); + // TODO: Change for new topology + return false; } 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); - - if (balance_enable) { - for (int c = 0; c < NUM_CHIPS; c++) { - configure_discharge(c, DICHARGE_ALL_COMMAND); - discharge_commands[c] = DICHARGE_ALL_COMMAND; - } - // push_chip_configuration(); - } else { - for (int c = 0; c < NUM_CHIPS; c++) { - configure_discharge(c, 0); - discharge_commands[c] = 0; - } - // push_chip_configuration(); - } -} - -// @todo Revisit after testing -void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, - bool balance_enable) -{ - pull_chip_configuration(); - - if (balance_enable) - discharge_commands[chip_num] |= (1 << cell_num); - else - discharge_commands[chip_num] &= ~(1 << cell_num); - - configure_discharge(chip_num, discharge_commands[chip_num]); - - // push_chip_configuration(); + // TODO: Change for new topology } 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; - else - discharge_commands[mapping_correction[c]] &= - ~(1 << cell); - } - - configure_discharge(c, discharge_commands[c]); - } - // push_chip_configuration(); -} - -bool cell_is_balancing(uint8_t chip_num, uint8_t cell_num) -{ - /* If the cell is one of the first 8, check the 4th register */ - if (cell_num < 8) { - return local_config[chip_num][4] & (1 << cell_num); - } - /* If the cell number is greater than 8, check the 5th register */ - else { - return local_config[chip_num][5] & (1 << (cell_num - 8)); - } - - return false; /* default case */ -} - -bool segment_is_balancing() -{ - for (int c = 0; c < NUM_CHIPS; c++) { - /* Reading from the 4th config register */ - for (int cell = 0; cell < 8; cell++) { - if (local_config[c][4] & (1 << cell)) - return true; - } - - /* Reading from the 5th config register */ - for (int cell = 0; cell < 4; cell++) { - if (local_config[c][5] & (1 << (cell))) - return true; - } - } - - return false; -} - -void pull_chip_configuration() -{ - uint8_t remote_config[NUM_CHIPS][8]; - // LTC6804_rdcfg(ltc68041, NUM_CHIPS, remote_config); - - for (int chip = 0; chip < NUM_CHIPS; chip++) { - for (int index = 0; index < 6; index++) { - local_config[chip][index] = remote_config[chip][index]; - } - } + // TODO: Change for new topology } int8_t steinhart_est(uint16_t V) @@ -849,45 +621,6 @@ int8_t steinhart_est(uint16_t V) return 80; } -void disable_gpio_pulldowns() -{ - HAL_Delay(1000); - /* Turn OFF GPIO 1 & 2 pull downs */ - pull_chip_configuration(); - for (int c = 0; c < NUM_CHIPS; c++) { - local_config[c][0] |= 0x18; - } - // push_chip_configuration(); - - pull_chip_configuration(); - printf("Chip CFG:\n"); - for (int c = 0; c < NUM_CHIPS; c++) { - for (int byte = 0; byte < 6; byte++) { - printf("%x", local_config[c][byte]); - printf("\t"); - } - printf("\n"); - } - printf("Done\n"); -} - -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 */ - } -} void averaging_therm_check() { From f0a2a60c048ac23e6d4e933ef6e491573f79f4d5 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sat, 14 Dec 2024 10:04:49 -0500 Subject: [PATCH 10/32] adbms balancing config changes --- Core/Src/segment.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index bf649408..e180c7d9 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -601,13 +601,34 @@ bool segment_is_balancing() void segment_enable_balancing(bool balance_enable) { - // TODO: Change for new topology + if (!balance_enable) { + // Initializes all array elements to zero + bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP] = { 0 }; + segment_configure_balancing(discharge_config); + } else { + /* this func is never called with an arg of true (and shouldn't be given its function) + TODO: change this func to just be "segment disable balancing". Kept for now for compatibility with old system + */ + } } +/** + * @brief Configure which cells should discharge, and send configuration to ICs. + * + * @param discharge_config Array containing the discharge configuration. true = discharge, false = do not discharge. + */ void segment_configure_balancing( bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]) { - // TODO: Change for new topology + // DEBUG: Untested + // TODO: Test + for (int chip = 0; chip < NUM_CHIPS; chip++) { + for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + set_cell_discharge(&IC[chip], cell, + discharge_config[chip][cell]); + } + } + write_config_regs(IC); } int8_t steinhart_est(uint16_t V) From e6111073955f80c20d7be193e92cd6162e613aa3 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Wed, 25 Dec 2024 18:42:58 -0500 Subject: [PATCH 11/32] adbms add chips to acc_data_t and make functions compatible with new datastructure --- Core/Inc/datastructs.h | 4 + Core/Inc/segment.h | 15 +-- Core/Src/analyzer.c | 64 +++++------- Core/Src/main.c | 2 +- Core/Src/segment.c | 226 +++++++++++++++++++++------------------- Core/Src/shep_tasks.c | 4 +- Core/Src/stateMachine.c | 44 ++++---- 7 files changed, 179 insertions(+), 180 deletions(-) diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index d95eeb64..e39e4e81 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -6,6 +6,7 @@ #include "bmsConfig.h" #include "timer.h" #include "cmsis_os2.h" +#include "adBms6830Data.h" /** * @brief Individual chip data @@ -84,6 +85,9 @@ typedef struct { /* Array of data from all chips in the system */ chipdata_t chip_data[NUM_CHIPS]; + /* Array of structs containing raw data from and configurations for the ADBMS6830 chips */ + cell_asic chips[NUM_CHIPS]; + int fault_status; int16_t pack_current; /* this value is multiplied by 10 to account for decimal precision */ diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index 607259d5..9e49ae9c 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -15,14 +15,15 @@ void segment_init(); * * @todo make sure that retrieving cell data doesn't block code too much */ -void segment_retrieve_data(chipdata_t databuf[NUM_CHIPS]); +void segment_retrieve_data(acc_data_t *bmsdata); /** * @brief Enables/disables balancing for all cells * - * @param balance_enable + * @param chips Array of ADBMS6830 data structs. + * @param balance_enable False to disable balancing, true to enable. */ -void segment_enable_balancing(bool balance_enable); +void segment_enable_balancing(cell_asic chips[NUM_CHIPS], bool balance_enable); /** * @brief Enables/disables balancing for a specific cell @@ -35,11 +36,13 @@ 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 + * @brief Set the cell balancing configuration and send it to the segments. + * + * @param chips Array of ADBMS6830 data structs. + * @param discharge_config Configuration for which cells to discharge. */ void segment_configure_balancing( + cell_asic chips[NUM_CHIPS], bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]); /** diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 3635a289..da1e46e6 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -122,22 +122,6 @@ const uint8_t RELEVANT_THERM_MAP_L[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS] = {6 + MUX_OFFSET, 8 + MUX_OFFSET, NO_THERM}, }; -uint8_t THERM_DISABLE[NUM_CHIPS][NUM_THERMS_PER_CHIP] = -{ - {1,0,1,0,0,1,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,0,0,1,0 }, - {1,0,1,0,0,1,0,0,1,0,1,1,0,1,1,0,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1 }, - {1,0,1,0,0,1,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 }, - {1,0,1,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,0,0,1,1,1,0,1,0,0,1,0,0,0,0 }, - {1,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1 }, - {1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0 }, - {1,0,1,0,0,1,0,0,1,0,1,1,0,0,1,1,0,0,1,0,1,1,1,0,0,0,0,0,0,0,1,0 }, - {1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1 }, - {1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0 }, - {1,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0 }, - {1,1,1,0,0,1,0,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0 }, - {1,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0 } -}; - /* * List of therms that we actually read from, NOT reordered by cell */ @@ -225,9 +209,11 @@ void calc_pack_temps(acc_data_t *bmsdata) bmsdata->min_temp.val = MAX_TEMP; bmsdata->min_temp.cellNum = 0; bmsdata->min_temp.chipIndex = 0; + int total_temp = 0; int total_seg_temp = 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 */ @@ -638,29 +624,29 @@ uint8_t analyzer_calc_fan_pwm(acc_data_t *bmsdata) (2 * 5); } -void disable_therms(acc_data_t *bmsdata) -{ - 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 = - bmsdata->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]; - } - } - } -} +// void disable_therms(acc_data_t *bmsdata) +// { +// 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 = +// bmsdata->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]; +// } +// } +// } +// } void calc_state_of_charge(acc_data_t *bmsdata) { diff --git a/Core/Src/main.c b/Core/Src/main.c index 8ff76e3e..f3aca116 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -347,7 +347,7 @@ int main(void) HAL_Delay(500); init_both_can(&hcan1, &hcan2); - segment_init(); + segment_init(acc_data->chip_data); compute_init(); printf("Init passed\n"); /* USER CODE END 2 */ diff --git a/Core/Src/segment.c b/Core/Src/segment.c index e180c7d9..ba6c6253 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -27,9 +27,6 @@ typedef enum { MUTE_ACTIVATED_DISCHARGE_DISABLED = 1 } MUTE_ST; -#define TOTAL_IC 1 -cell_asic IC[TOTAL_IC]; - RD REDUNDANT_MEASUREMENT = RD_OFF; CH AUX_CH_TO_CONVERT = AUX_ALL; CONT CONTINUOUS_MEASUREMENT = SINGLE; @@ -71,7 +68,6 @@ extern SPI_HandleTypeDef hspi1; uint8_t therm_avg_counter = 0; -chipdata_t *segment_data = NULL; chipdata_t previous_data[NUM_CHIPS] = {}; uint16_t discharge_commands[NUM_CHIPS] = {}; @@ -110,9 +106,9 @@ const int32_t VOLT_TEMP_CALIB_OFFSET = 0; void serialize_i2c_msg(uint8_t data_to_write[][3], uint8_t comm_output[][6]); int8_t steinhart_est(uint16_t V); void variance_therm_check(void); -void discard_neutrals(void); +void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]); void pull_chip_configuration(void); -int16_t calc_average(void); +int16_t calc_average(chipdata_t segment_data[NUM_CHIPS]); int8_t calc_therm_standard_dev(int16_t avg_temp); void init_chip(cell_asic *chip); void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge); @@ -130,6 +126,10 @@ inline uint16_t set_uint16_bit(uint16_t number, uint16_t n, bool x) return (number & ~((uint16_t)1 << n)) | ((uint16_t)x << n); } +/** + * @brief Wake every ADBMS6830 IC in the daisy chain. Takes NUM_CHIPS * 8 ms to finish. + * + */ void adbms_wake() { adBmsWakeupIc(NUM_CHIPS); @@ -264,13 +264,13 @@ inline void write_config_regs(cell_asic chips[NUM_CHIPS]) * @brief Initialize chips with default values. * */ -void segment_init() +void segment_init(cell_asic chips[NUM_CHIPS]) { printf("Initializing Segments..."); for (int chip = 0; chip < NUM_CHIPS; chip++) { - init_chip(&IC[chip]); + init_chip(&chips[chip]); } - write_config_regs(IC); + write_config_regs(chips); } /** @@ -419,24 +419,39 @@ void adBms6830_read_status_registers(cell_asic chips[NUM_CHIPS]) read_adbms_data(chips, RDSTATE, Status, E); } -int pull_voltages() +int pull_voltages(acc_data_t *bmsdata) { /** * If we haven't waited long enough between pulling voltage data * just copy over the contents of the last good reading and the fault status * from the most recent attempt */ + + // TODO: should probably get rid of this 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(&bmsdata->chips[i], &previous_data[i], + sizeof(bmsdata->chips[i])); } return voltage_error; } - get_c_adc_voltages(IC); + get_c_adc_voltages(bmsdata->chips); + + // TODO: Change number of cells per chip for alpha and beta + // or not cuz we can just copy all the values here and handle this in analyzer + + // NOTE: Its kind of silly to just copy voltages like this. We should consolidate + // chip data and chips later, or design analyzer to read voltages from chips rather + // than chipdata + + for (int chip = 0; chip < NUM_CHIPS; chip++) { + for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + bmsdata->chip_data->voltage[cell] = + bmsdata->chips->cell.c_codes[cell]; + } + } /* @@ -570,27 +585,17 @@ int pull_voltages() return 0; } -void pull_thermistors() -{ - read_aux_registers(IC); - - // TODO: Convert voltages to temperatures, store in a data structure -} - -void segment_retrieve_data(chipdata_t databuf[NUM_CHIPS]) +void segment_retrieve_data(acc_data_t *bmsdata) { - segment_data = databuf; - /* Pull voltages and thermistors and indiacate if there was a problem during * retrieval */ - voltage_error = pull_voltages(); - pull_thermistors(); + voltage_error = pull_voltages(bmsdata); + read_aux_registers(bmsdata->chips); /* Save the contents of the reading so that we can use it to fill in missing * data */ - memcpy(previous_data, segment_data, sizeof(chipdata_t) * NUM_CHIPS); - - segment_data = NULL; + memcpy(previous_data, bmsdata->chip_data, + sizeof(chipdata_t) * NUM_CHIPS); } bool segment_is_balancing() @@ -599,12 +604,12 @@ bool segment_is_balancing() return false; } -void segment_enable_balancing(bool balance_enable) +void segment_enable_balancing(cell_asic chips[NUM_CHIPS], bool balance_enable) { if (!balance_enable) { // Initializes all array elements to zero bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP] = { 0 }; - segment_configure_balancing(discharge_config); + segment_configure_balancing(chips, discharge_config); } else { /* this func is never called with an arg of true (and shouldn't be given its function) TODO: change this func to just be "segment disable balancing". Kept for now for compatibility with old system @@ -618,17 +623,18 @@ void segment_enable_balancing(bool balance_enable) * @param discharge_config Array containing the discharge configuration. true = discharge, false = do not discharge. */ void segment_configure_balancing( + cell_asic chips[NUM_CHIPS], bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]) { // DEBUG: Untested // TODO: Test for (int chip = 0; chip < NUM_CHIPS; chip++) { for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - set_cell_discharge(&IC[chip], cell, + set_cell_discharge(&chips[chip], cell, discharge_config[chip][cell]); } } - write_config_regs(IC); + write_config_regs(chips); } int8_t steinhart_est(uint16_t V) @@ -643,7 +649,7 @@ int8_t steinhart_est(uint16_t V) return 80; } -void averaging_therm_check() +void averaging_therm_check(chipdata_t segment_data[NUM_CHIPS]) { for (int therm = 1; therm <= 16; therm++) { for (int c = 0; c < NUM_CHIPS; c++) { @@ -716,48 +722,48 @@ void averaging_therm_check() } } -void standard_dev_therm_check() -{ - if (previous_data == NULL) - return; - int16_t avg_temp = calc_average(); - uint8_t standard_dev = calc_therm_standard_dev(avg_temp); - for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t therm = 17; therm < 28; therm++) { - /* - * 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)) { - /* Nullify thermistor by setting to pack average */ - segment_data[c].thermistor_value[therm] = - previous_data[c].thermistor_value[therm]; - } - } - } -} - -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); - sum_diff_sqrd += sum_diff * sum_diff; - } - } - - uint8_t standard_dev = sqrt(sum_diff_sqrd / 88); - if (standard_dev < 8) { - standard_dev = 8; - } - return standard_dev; -} - -int16_t calc_average() +// void standard_dev_therm_check(chipdata_t segment_data[NUM_CHIPS]) +// { +// if (previous_data == NULL) +// return; +// int16_t avg_temp = calc_average(segment_data); +// uint8_t standard_dev = calc_therm_standard_dev(avg_temp); +// for (uint8_t c = 0; c < NUM_CHIPS; c++) { +// for (uint8_t therm = 17; therm < 28; therm++) { +// /* +// * 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)) { +// /* Nullify thermistor by setting to pack average */ +// segment_data[c].thermistor_value[therm] = +// previous_data[c].thermistor_value[therm]; +// } +// } +// } +// } + +// int8_t calc_therm_standard_dev(chipdata_t segment_data[NUM_CHIPS], 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); +// sum_diff_sqrd += sum_diff * sum_diff; +// } +// } + +// uint8_t standard_dev = sqrt(sum_diff_sqrd / 88); +// if (standard_dev < 8) { +// standard_dev = 8; +// } +// return standard_dev; +// } + +int16_t calc_average(chipdata_t segment_data[NUM_CHIPS]) { int16_t avg = 0; for (int chip = 0; chip < NUM_CHIPS; chip++) { @@ -770,40 +776,40 @@ int16_t calc_average() return avg; } -void variance_therm_check() -{ - if (previous_data == NULL) { - start_timer(&variance_timer, 1000); - return; - } - - 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]; - } - } - } - } -} - -void discard_neutrals() +// void variance_therm_check() +// { +// if (previous_data == NULL) { +// start_timer(&variance_timer, 1000); +// return; +// } + +// 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]; +// } +// } +// } +// } +// } + +void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]) { for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t therm = 17; therm < 28; therm++) { diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index 2e04369c..60db88f6 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -29,7 +29,7 @@ void vGetSegmentData(void *pv_params) { acc_data_t *bmsdata = (acc_data_t *)pv_params; for (;;) { - segment_retrieve_data(bmsdata->chip_data); + segment_retrieve_data(bmsdata); osThreadFlagsSet(analyzer_thread, ANALYZER_FLAG); osDelay(1000 / SAMPLE_RATE); } @@ -47,7 +47,7 @@ void vAnalyzer(void *pv_params) osThreadFlagsWait(ANALYZER_FLAG, osFlagsWaitAny, osWaitForever); osMutexAcquire(bmsdata->mutex, osWaitForever); - disable_therms(bmsdata); + // disable_therms(bmsdata); calc_cell_temps(bmsdata); calc_pack_temps(bmsdata); diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index e59f0a20..802c84b1 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -36,18 +36,18 @@ const bool valid_transition_from_to[NUM_STATES][NUM_STATES] = { }; /* private function prototypes */ -void init_boot(void); -void init_ready(void); -void init_charging(void); -void init_faulted(void); +void init_boot(acc_data_t *bmsdata); +void init_ready(acc_data_t *bmsdata); +void init_charging(acc_data_t *bmsdata); +void init_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); +void request_transition(acc_data_t *bmsdata, BMSState_t next_state); typedef void (*HandlerFunction_t)(acc_data_t *bmsdata); -typedef void (*InitFunction_t)(); +typedef void (*InitFunction_t)(acc_data_t *bmsdata); const InitFunction_t init_LUT[NUM_STATES] = { &init_boot, &init_ready, &init_charging, &init_faulted }; @@ -56,7 +56,7 @@ const HandlerFunction_t handler_LUT[NUM_STATES] = { &handle_boot, &handle_ready, &handle_charging, &handle_faulted }; -void init_boot() +void init_boot(acc_data_t *bmsdata) { return; } @@ -64,7 +64,7 @@ void init_boot() void handle_boot(acc_data_t *bmsdata) { prevAccData = NULL; - segment_enable_balancing(false); + segment_enable_balancing(bmsdata->chips, false); compute_enable_charging(false); start_timer(&bootup_timer, 10000); printf("Bootup timer started\r\n"); @@ -72,13 +72,13 @@ void handle_boot(acc_data_t *bmsdata) compute_set_fault(1); // bmsdata->fault_code = FAULTS_CLEAR; - request_transition(READY_STATE); + request_transition(bmsdata, READY_STATE); return; } -void init_ready() +void init_ready(acc_data_t *bmsdata) { - segment_enable_balancing(false); + segment_enable_balancing(bmsdata->chips, false); compute_enable_charging(false); return; } @@ -88,14 +88,14 @@ 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 - request_transition(READY_STATE); + request_transition(bmsdata, READY_STATE); } else { sm_broadcast_current_limit(bmsdata); return; } } -void init_charging() +void init_charging(acc_data_t *bmsdata) { cancel_timer(&charger_settle_countup); return; @@ -104,7 +104,7 @@ void init_charging() void handle_charging(acc_data_t *bmsdata) { if (!compute_charger_connected()) { - request_transition(READY_STATE); + request_transition(bmsdata, READY_STATE); return; } else { @@ -120,7 +120,7 @@ void handle_charging(acc_data_t *bmsdata) if (sm_balancing_check(bmsdata)) sm_balance_cells(bmsdata); else - segment_enable_balancing(false); + segment_enable_balancing(bmsdata->chips, false); /* Send CAN message, but not too often */ if (is_timer_expired(&charger_message_timer) || @@ -135,9 +135,9 @@ void handle_charging(acc_data_t *bmsdata) } } -void init_faulted() +void init_faulted(acc_data_t *bmsdata) { - segment_enable_balancing(false); + segment_enable_balancing(bmsdata->chips, false); compute_enable_charging(false); entered_faulted = true; return; @@ -152,7 +152,7 @@ void handle_faulted(acc_data_t *bmsdata) if (bmsdata->fault_code == FAULTS_CLEAR) { compute_set_fault(1); - request_transition(BOOT_STATE); + request_transition(bmsdata, BOOT_STATE); return; } @@ -173,7 +173,7 @@ void sm_handle_state(acc_data_t *bmsdata) if (bmsdata->fault_code != FAULTS_CLEAR) { bmsdata->discharge_limit = 0; - request_transition(FAULTED_STATE); + request_transition(bmsdata, FAULTED_STATE); } handler_LUT[current_state](bmsdata); @@ -183,14 +183,14 @@ void sm_handle_state(acc_data_t *bmsdata) sm_broadcast_current_limit(bmsdata); } -void request_transition(BMSState_t next_state) +void request_transition(acc_data_t *bmsdata, BMSState_t next_state) { if (current_state == next_state) return; if (!valid_transition_from_to[current_state][next_state]) return; - init_LUT[next_state](); + init_LUT[next_state](bmsdata); current_state = next_state; } @@ -472,7 +472,7 @@ void sm_balance_cells(acc_data_t *bms_data) } #endif - segment_configure_balancing(balanceConfig); + segment_configure_balancing(bms_data->chips, balanceConfig); } void calculate_pwm(acc_data_t *bmsdata) From 6791c57046b5397caf9c57824ff1de20a22a066d Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Wed, 25 Dec 2024 19:06:30 -0500 Subject: [PATCH 12/32] adbms changing GPIO modes and integrating balancing functions with adbms --- Core/Inc/segment.h | 17 ++++++++-------- Core/Src/compute.c | 2 +- Core/Src/main.c | 4 ++-- Core/Src/segment.c | 44 +++++++++++++++++++++++++---------------- Core/Src/stateMachine.c | 8 ++++---- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index 9e49ae9c..c1559154 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -18,12 +18,11 @@ void segment_init(); void segment_retrieve_data(acc_data_t *bmsdata); /** - * @brief Enables/disables balancing for all cells + * @brief Disables balancing for all cells. * * @param chips Array of ADBMS6830 data structs. - * @param balance_enable False to disable balancing, true to enable. */ -void segment_enable_balancing(cell_asic chips[NUM_CHIPS], bool balance_enable); +void segment_disable_balancing(cell_asic chips[NUM_CHIPS]); /** * @brief Enables/disables balancing for a specific cell @@ -55,12 +54,12 @@ void segment_configure_balancing( bool cell_is_balancing(uint8_t chip_num, uint8_t cell_num); /** - * @brief Returns if any cells are balancing - * @todo This should just be a state variable -Scott - * - * @return true - * @return false + * @brief Returns if any cells are balancing. + * + * @param chips Array of ADBMS6830 chips. + * @return true + * @return false */ -bool segment_is_balancing(); +bool segment_is_balancing(cell_asic chips[NUM_CHIPS]); #endif \ No newline at end of file diff --git a/Core/Src/compute.c b/Core/Src/compute.c index 022c1ac0..16fdf53c 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -332,7 +332,7 @@ void compute_send_bms_status_message(acc_data_t *bmsdata, int 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); // segment_is_balancing() + (uint8_t)(balance); /* convert to big endian */ endian_swap(&bms_status_msg_data.fault, diff --git a/Core/Src/main.c b/Core/Src/main.c index f3aca116..e29c4363 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -172,7 +172,7 @@ const void print_bms_stats(acc_data_t *acc_data) printf("CCL: %d\n", acc_data->charge_limit); printf("Cont CCL %d\n", acc_data->cont_CCL); printf("SoC: %d\n", acc_data->soc); - printf("Is Balancing?: %d\n", segment_is_balancing()); + printf("Is Balancing?: %d\n", segment_is_balancing(acc_data->chips)); printf("State: "); if (current_state == 0) printf("BOOT\n"); else if (current_state == 1) printf("READY\n"); @@ -1256,7 +1256,7 @@ void StartDefaultTask(void *argument) alt = !alt; compute_send_bms_status_message(bmsdata, current_state, - segment_is_balancing()); + segment_is_balancing(bmsdata->chips)); HAL_IWDG_Refresh(&hiwdg); diff --git a/Core/Src/segment.c b/Core/Src/segment.c index ba6c6253..5aa692d4 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -220,6 +220,22 @@ void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge) chip->tx_cfgb.dcc = set_uint16_bit(chip->tx_cfgb.dcc, cell, discharge); } +/** + * @brief Set the mode of a GPIO pin on an ADBMS8630. + * + * @param chip ADBMS6830 chip + * @param gpio Number of the GPIO pin to change (1-10) + * @param mode Whether the pin should be an input or an output. True is input, False is output. + */ +void set_gpio_mode(cell_asic *chip, uint8_t gpio, bool mode) +{ + if (gpio > 10 || gpio < 1) { + printf("ERROR: Invalid GPIO pin %d\n", gpio); + return; + } + chip->tx_cfga.gpo = set_uint16_bit(chip->tx_cfga.gpo, gpio - 1, mode); +} + /** * @brief Write data to all chips. * @@ -439,10 +455,7 @@ int pull_voltages(acc_data_t *bmsdata) get_c_adc_voltages(bmsdata->chips); - // TODO: Change number of cells per chip for alpha and beta - // or not cuz we can just copy all the values here and handle this in analyzer - - // NOTE: Its kind of silly to just copy voltages like this. We should consolidate + // TODO: Its kind of silly to just copy voltages like this. We should consolidate // chip data and chips later, or design analyzer to read voltages from chips rather // than chipdata @@ -598,23 +611,21 @@ void segment_retrieve_data(acc_data_t *bmsdata) sizeof(chipdata_t) * NUM_CHIPS); } -bool segment_is_balancing() +bool segment_is_balancing(cell_asic chips[NUM_CHIPS]) { - // TODO: Change for new topology + for (int chip = 0; chip < NUM_CHIPS; chip++) { + if (chips[chip].tx_cfga.mute_st != MUTE_ACTIVATED_DISCHARGE_DISABLED) { + return true; + } + } return false; } -void segment_enable_balancing(cell_asic chips[NUM_CHIPS], bool balance_enable) +void segment_disable_balancing(cell_asic chips[NUM_CHIPS]) { - if (!balance_enable) { - // Initializes all array elements to zero - bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP] = { 0 }; - segment_configure_balancing(chips, discharge_config); - } else { - /* this func is never called with an arg of true (and shouldn't be given its function) - TODO: change this func to just be "segment disable balancing". Kept for now for compatibility with old system - */ - } + // Initializes all array elements to zero + bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP] = { 0 }; + segment_configure_balancing(chips, discharge_config); } /** @@ -626,7 +637,6 @@ void segment_configure_balancing( cell_asic chips[NUM_CHIPS], bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]) { - // DEBUG: Untested // TODO: Test for (int chip = 0; chip < NUM_CHIPS; chip++) { for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index 802c84b1..8eb91af0 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -64,7 +64,7 @@ void init_boot(acc_data_t *bmsdata) void handle_boot(acc_data_t *bmsdata) { prevAccData = NULL; - segment_enable_balancing(bmsdata->chips, false); + segment_disable_balancing(bmsdata->chips); compute_enable_charging(false); start_timer(&bootup_timer, 10000); printf("Bootup timer started\r\n"); @@ -78,7 +78,7 @@ void handle_boot(acc_data_t *bmsdata) void init_ready(acc_data_t *bmsdata) { - segment_enable_balancing(bmsdata->chips, false); + segment_disable_balancing(bmsdata->chips); compute_enable_charging(false); return; } @@ -120,7 +120,7 @@ void handle_charging(acc_data_t *bmsdata) if (sm_balancing_check(bmsdata)) sm_balance_cells(bmsdata); else - segment_enable_balancing(bmsdata->chips, false); + segment_disable_balancing(bmsdata->chips); /* Send CAN message, but not too often */ if (is_timer_expired(&charger_message_timer) || @@ -137,7 +137,7 @@ void handle_charging(acc_data_t *bmsdata) void init_faulted(acc_data_t *bmsdata) { - segment_enable_balancing(bmsdata->chips, false); + segment_disable_balancing(bmsdata->chips); compute_enable_charging(false); entered_faulted = true; return; From 93379f0db4886675cff6fb8ca0c60fc4509e7c56 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Thu, 26 Dec 2024 11:53:47 -0500 Subject: [PATCH 13/32] adbms cleaning up balancing and removing LTC driver from make file --- Core/Inc/segment.h | 11 ----------- Core/Src/segment.c | 13 ++++++++++++- Makefile | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index c1559154..7d292369 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -1,7 +1,6 @@ #ifndef SEGMENT_H #define SEGMENT_H -#include "ltc68041.h" #include "bmsConfig.h" #include "datastructs.h" @@ -24,16 +23,6 @@ void segment_retrieve_data(acc_data_t *bmsdata); */ void segment_disable_balancing(cell_asic chips[NUM_CHIPS]); -/** - * @brief Enables/disables balancing for a specific cell - * - * @param chip_num - * @param cell_num - * @param balance_enable - */ -void cell_enable_balancing(uint8_t chip_num, uint8_t cell_num, - bool balance_enable); - /** * @brief Set the cell balancing configuration and send it to the segments. * diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 5aa692d4..c899c179 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -614,7 +614,8 @@ void segment_retrieve_data(acc_data_t *bmsdata) bool segment_is_balancing(cell_asic chips[NUM_CHIPS]) { for (int chip = 0; chip < NUM_CHIPS; chip++) { - if (chips[chip].tx_cfga.mute_st != MUTE_ACTIVATED_DISCHARGE_DISABLED) { + if (chips[chip].tx_cfga.mute_st != + MUTE_ACTIVATED_DISCHARGE_DISABLED) { return true; } } @@ -625,6 +626,9 @@ void segment_disable_balancing(cell_asic chips[NUM_CHIPS]) { // Initializes all array elements to zero bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP] = { 0 }; + for (int chip = 0; chip < NUM_CHIPS; chip++) { + chips[chip].tx_cfga.mute_st = MUTE_ACTIVATED_DISCHARGE_DISABLED; + } segment_configure_balancing(chips, discharge_config); } @@ -642,6 +646,13 @@ void segment_configure_balancing( for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { set_cell_discharge(&chips[chip], cell, discharge_config[chip][cell]); + + // Enable balancing for a chip if a cell is to be discharged + if (chips[chip].tx_cfga.mute_st == + MUTE_ACTIVATED_DISCHARGE_DISABLED && + discharge_config[chip][cell]) { + chips[chip].tx_cfga.mute_st = DISCHARGE_ENABLED; + } } } write_config_regs(chips); diff --git a/Makefile b/Makefile index 25fba47f..1cad36b6 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,6 @@ Core/Src/stm32f4xx_it.c \ Core/Src/stm32f4xx_hal_msp.c \ Drivers/Embedded-Base/platforms/stm32f405/src/can.c \ Drivers/Embedded-Base/general/src/m24c32.c \ -Drivers/Embedded-Base/general/src/ltc68041.c \ Drivers/Embedded-Base/general/src/sht30.c \ Drivers/Embedded-Base/middleware/src/timer.c \ Drivers/Embedded-Base/middleware/src/ringbuffer.c \ From 5a42a6bdf0032834e05300ba63cc303175ff69f5 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Wed, 1 Jan 2025 17:08:24 -0500 Subject: [PATCH 14/32] adbms more cleanup of 22A code and starting on analyzer for alpha and beta therms --- Core/Inc/bmsConfig.h | 4 +- Core/Inc/datastructs.h | 5 ++ Core/Inc/segment.h | 2 +- Core/Src/analyzer.c | 147 +++++++++++++++++++++++------------------ Core/Src/main.c | 2 +- Core/Src/segment.c | 64 ++++++------------ 6 files changed, 112 insertions(+), 112 deletions(-) diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index ac68e58c..74825f79 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -5,8 +5,10 @@ #define NUM_SEGMENTS 1 #define NUM_CHIPS 1 //NUM_SEGMENTS * 2 #define NUM_CELLS_PER_CHIP 16 +#define NUM_CELLS_ALPHA 16 +#define NUM_CELLS_BETA 12 #define NUM_THERMS_PER_CHIP 32 -#define NUM_RELEVANT_THERMS 3 +#define NUM_RELEVANT_THERMS 1 // Firmware limits #define MAX_TEMP 65 //degrees C diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index e39e4e81..1c6e3b64 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -30,6 +30,9 @@ typedef struct { [NUM_CELLS_PER_CHIP]; /* bool representing noise ignored read */ uint8_t consecutive_noise [NUM_CELLS_PER_CHIP]; /* count representing consecutive noisy reads */ + + /* True if chip is alpha, False if Chip is Beta */ + bool alpha; } chipdata_t; /** @@ -82,6 +85,8 @@ typedef struct { #define ACCUMULATOR_FRAME_SIZE sizeof(acc_data_t); typedef struct { + /* chip_data and chips are parallel arrays. */ + /* Array of data from all chips in the system */ chipdata_t chip_data[NUM_CHIPS]; diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index 7d292369..d335be7d 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -7,7 +7,7 @@ /** * @brief Initializes the segments */ -void segment_init(); +void segment_init(acc_data_t *bmsdata); /** * @brief Pulls all cell data from the segments and returns all cell data diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index da1e46e6..87610a54 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -7,6 +7,17 @@ #include "serialPrintResult.h" +#define GPIO1 0 +#define GPIO2 1 +#define GPIO3 2 +#define GPIO4 3 +#define GPIO5 4 +#define GPIO6 5 +#define GPIO7 6 +#define GPIO8 7 +#define GPIO9 8 +#define GPIO10 9 + // clang-format off /** * @brief Mapping Cell temperature to the cell resistance based on the @@ -84,6 +95,8 @@ const uint8_t FAN_CURVE[16] = const uint8_t NO_THERM = 0xFF; const uint8_t MUX_OFFSET = 16; +//TODO: MAKE THESE THERM MAPPINGS CORRECT + /** * @brief Mapping the Relevant Thermistors for each cell based on cell # * @note 0xFF indicates the end of the relevant therms @@ -91,16 +104,22 @@ const uint8_t MUX_OFFSET = 16; */ const uint8_t RELEVANT_THERM_MAP_H[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS] = { - {5, 3, NO_THERM}, - {12 + MUX_OFFSET, 14 + MUX_OFFSET, NO_THERM}, - {2, 0, 1}, - {9 + MUX_OFFSET, 11 + MUX_OFFSET, NO_THERM}, - {8, 6, NO_THERM}, - {0 + MUX_OFFSET, 2 + MUX_OFFSET, NO_THERM}, - {12, 14, 13}, - {3 + MUX_OFFSET, 5 + MUX_OFFSET, NO_THERM}, - {11, 9, NO_THERM}, - {6 + MUX_OFFSET, 8 + MUX_OFFSET, NO_THERM}, + {GPIO1}, + {GPIO1}, + {GPIO2}, + {GPIO2}, + {GPIO3}, + {GPIO3}, + {GPIO4}, + {GPIO4}, + {GPIO5}, + {GPIO6}, + {GPIO7}, + {GPIO7}, + {GPIO7}, + {GPIO7}, + {GPIO7}, + {GPIO7}, }; /** @@ -110,56 +129,24 @@ const uint8_t RELEVANT_THERM_MAP_H[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS] = */ const uint8_t RELEVANT_THERM_MAP_L[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS] = { - {5, 3, 4}, - {12 + MUX_OFFSET, 14 + MUX_OFFSET, NO_THERM}, - {2, 0, NO_THERM}, - {11 + MUX_OFFSET, 9 + MUX_OFFSET, NO_THERM}, - {6, 7, 8}, - {0 + MUX_OFFSET, 2 + MUX_OFFSET, NO_THERM}, - {14, 12, NO_THERM}, - {5 + MUX_OFFSET, 3 + MUX_OFFSET, NO_THERM}, - {9, 10, 11}, - {6 + MUX_OFFSET, 8 + MUX_OFFSET, NO_THERM}, -}; - -/* - * List of therms that we actually read from, NOT reordered by cell - */ -const uint8_t POPULATED_THERM_LIST_H[NUM_THERMS_PER_CHIP] = -{ - true, false, true, - true, true, true, - true, true, true, - true, true, true, - true, false, true, false, - true, false, true, - true, false, true, - true, false, true, - true, false, true, - true, false, true, false -}; - -const uint8_t POPULATED_THERM_LIST_L[NUM_THERMS_PER_CHIP] = -{ - true, true, true, - true, false, true, - true, false, true, - true, false, true, - true, true, true, false, - true, false, true, - true, false, true, - true, false, true, - true, false, true, - true, false, true, false + {GPIO1}, + {GPIO1}, + {GPIO2}, + {GPIO2}, + {GPIO3}, + {GPIO3}, + {GPIO4}, + {GPIO4}, + {GPIO5}, + {GPIO6}, + {GPIO7}, + {GPIO7}, + {GPIO7}, + {GPIO7}, + {GPIO7}, + {GPIO7}, }; -/** - * @brief Selecting thermistors to ignore - * - * @note True / 1 will disable the thermistor - * @note disabling both unpopulaed (see above) and populated but bad cells ( not great permanent solution) - */ - // clang-format on nertimer_t analysisTimer; @@ -167,11 +154,43 @@ nertimer_t ocvTimer; bool is_first_reading_ = true; +void calc_alpha_temps(acc_data_t *bmsdata) +{ + for (int cell = 0; cell < NUM_CELLS_ALPHA; cell++) { + bmsdata->chip_data + } +} + +void calc_beta_temps(acc_data_t *bmsdata) +{ +} + /* we are not corrctly mapping each therm reading to the correct cell. So, we are taking the average of all good readings (not disabled) for a given chip, and assigning that to be the cell val for every cell in the chip*/ void calc_cell_temps(acc_data_t *bmsdata) { + for (int chip = 0; chip < NUM_CHIPS; chip++) { + if (bmsdata->chip_data[chip]->alpha) { + for (int cell = 0; cell < NUM_CELLS_ALPHA; cell++) { + int sum = 0; + for (int therm = 0; therm < NUM_RELEVANT_THERMS; + therm++) { + sum += bmsdata->chips[chip].aux.a_codes + [RELEVANT_THERM_MAP_H + [cell][therm]] + } + bmsdata->chip_data[chip].cell_temp[cell]. + } + } else { + calc_beta_temps(bmsdata); + } + } + + /* + + 22A CODE FOR REFERENC + 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] = @@ -193,11 +212,11 @@ void calc_cell_temps(acc_data_t *bmsdata) } //printf("\r\n"); /* Takes the average temperature of all the relevant thermistors */ - bmsdata->chip_data[c].cell_temp[cell] = - temp_sum / therm_count; - therm_count = 0; - } - } + bmsdata->chip_data[c].cell_temp[cell] = temp_sum / therm_count; + therm_count = 0; +} +} +* / } void calc_pack_temps(acc_data_t *bmsdata) @@ -213,7 +232,7 @@ void calc_pack_temps(acc_data_t *bmsdata) int total_temp = 0; int total_seg_temp = 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 */ diff --git a/Core/Src/main.c b/Core/Src/main.c index e29c4363..45e23d06 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -347,7 +347,7 @@ int main(void) HAL_Delay(500); init_both_can(&hcan1, &hcan2); - segment_init(acc_data->chip_data); + segment_init(acc_data); compute_init(); printf("Init passed\n"); /* USER CODE END 2 */ diff --git a/Core/Src/segment.c b/Core/Src/segment.c index c899c179..b9cfa20c 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -5,8 +5,6 @@ #include #include -// TEMPORARY - #include "common.h" #include "adBms6830CmdList.h" #include "adBms6830GenericType.h" @@ -27,34 +25,6 @@ typedef enum { MUTE_ACTIVATED_DISCHARGE_DISABLED = 1 } MUTE_ST; -RD REDUNDANT_MEASUREMENT = RD_OFF; -CH AUX_CH_TO_CONVERT = AUX_ALL; -CONT CONTINUOUS_MEASUREMENT = SINGLE; -OW_C_S CELL_OPEN_WIRE_DETECTION = OW_OFF_ALL_CH; -OW_AUX AUX_OPEN_WIRE_DETECTION = AUX_OW_OFF; -PUP OPEN_WIRE_CURRENT_SOURCE = PUP_DOWN; -DCP DISCHARGE_PERMITTED = DCP_OFF; -RSTF RESET_FILTER = RSTF_OFF; -ERR INJECT_ERR_SPI_READ = WITHOUT_ERR; - -/*Loop Measurement Setup These Variables are ENABLED or DISABLED Remember ALL CAPS*/ -LOOP_MEASURMENT MEASURE_CELL = - ENABLED; /* This is ENABLED or DISABLED */ -LOOP_MEASURMENT MEASURE_AVG_CELL = - ENABLED; /* This is ENABLED or DISABLED */ -LOOP_MEASURMENT MEASURE_F_CELL = - ENABLED; /* This is ENABLED or DISABLED */ -LOOP_MEASURMENT MEASURE_S_VOLTAGE = - DISABLED; /* This is ENABLED or DISABLED */ -LOOP_MEASURMENT MEASURE_AUX = - DISABLED; /* This is ENABLED or DISABLED */ -LOOP_MEASURMENT MEASURE_RAUX = - DISABLED; /* This is ENABLED or DISABLED */ -LOOP_MEASURMENT MEASURE_STAT = - ENABLED; /* This is ENABLED or DISABLED */ - -// END - #define THERM_WAIT_TIME 500 /* ms */ #define VOLTAGE_WAIT_TIME 500 /* ms */ #define THERM_AVG 15 /* Number of values to average */ @@ -75,7 +45,6 @@ nertimer_t therm_timer; nertimer_t voltage_reading_timer; nertimer_t variance_timer; -int voltage_error = 0; // not faulted int therm_error = 0; // not faulted uint16_t crc_error_check = 0; @@ -85,6 +54,7 @@ const int mapping_correction[12] = { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10 }; uint16_t therm_settle_time_ = 0; +// TODO: replace for new thermistors 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, @@ -103,7 +73,6 @@ const uint32_t VOLT_TEMP_CONV[106] = { const int32_t VOLT_TEMP_CALIB_OFFSET = 0; /* private function prototypes */ -void serialize_i2c_msg(uint8_t data_to_write[][3], uint8_t comm_output[][6]); int8_t steinhart_est(uint16_t V); void variance_therm_check(void); void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]); @@ -170,6 +139,8 @@ void init_chip(cell_asic *chip) chip->tx_cfga.fc = IIR_FPA_OFF; // Init config B + + // If the corresponding fault bits are sent high, it does not affect the IC chip->tx_cfgb.vov = SetOverVoltageThreshold(4.2); chip->tx_cfgb.vuv = SetUnderVoltageThreshold(3.0); @@ -280,11 +251,13 @@ inline void write_config_regs(cell_asic chips[NUM_CHIPS]) * @brief Initialize chips with default values. * */ -void segment_init(cell_asic chips[NUM_CHIPS]) +void segment_init(acc_data_t *bmsdata) { printf("Initializing Segments..."); for (int chip = 0; chip < NUM_CHIPS; chip++) { - init_chip(&chips[chip]); + init_chip(&bmsdata->chips[chip]); + // TODO: Make sure this is accurate + bmsdata->chip_data->alpha = chip % 2 == 0; } write_config_regs(chips); } @@ -435,7 +408,7 @@ void adBms6830_read_status_registers(cell_asic chips[NUM_CHIPS]) read_adbms_data(chips, RDSTATE, Status, E); } -int pull_voltages(acc_data_t *bmsdata) +void pull_voltages(acc_data_t *bmsdata) { /** * If we haven't waited long enough between pulling voltage data @@ -450,7 +423,6 @@ int pull_voltages(acc_data_t *bmsdata) memcpy(&bmsdata->chips[i], &previous_data[i], sizeof(bmsdata->chips[i])); } - return voltage_error; } get_c_adc_voltages(bmsdata->chips); @@ -468,7 +440,7 @@ int pull_voltages(acc_data_t *bmsdata) /* - OLD CODE THAT DID WORK FOR ADBMS + OLD CODE THAT DID WORK FOR ADBMS. KEEPING IN FOR DEBUGGING. uint16_t raw_voltages[NUM_CHIPS][NUM_CELLS_PER_CHIP]; @@ -557,8 +529,8 @@ int pull_voltages(acc_data_t *bmsdata) /* if (MEASURE_AUX == ENABLED) { - adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, - OPEN_WIRE_CURRENT_SOURCE, AUX_CH_TO_CONVERT); + adBms6830_Adax(AUX_OW_OFF, + PUP_DOWN, AUX_ALL); adBmsPollAdc(PLAUX1); adBmsReadData(TOTAL_IC, &IC[0], RDAUXA, Aux, A); adBmsReadData(TOTAL_IC, &IC[0], RDAUXB, Aux, B); @@ -570,7 +542,7 @@ int pull_voltages(acc_data_t *bmsdata) /* if (MEASURE_RAUX == ENABLED) { adBmsWakeupIc(TOTAL_IC); - adBms6830_Adax2(AUX_CH_TO_CONVERT); + adBms6830_Adax2(AUX_ALL); adBmsPollAdc(PLAUX2); adBmsReadData(TOTAL_IC, &IC[0], RDRAXA, RAux, A); adBmsReadData(TOTAL_IC, &IC[0], RDRAXB, RAux, B); @@ -581,8 +553,8 @@ int pull_voltages(acc_data_t *bmsdata) /* if (MEASURE_STAT == ENABLED) { - adBms6830_Adax(AUX_OPEN_WIRE_DETECTION, - OPEN_WIRE_CURRENT_SOURCE, AUX_CH_TO_CONVERT); + adBms6830_Adax(AUX_OW_OFF, + PUP_DOWN, AUX_ALL); adBmsPollAdc(PLAUX1); adBmsReadData(TOTAL_IC, &IC[0], RDSTATA, Status, A); adBmsReadData(TOTAL_IC, &IC[0], RDSTATB, Status, B); @@ -594,16 +566,18 @@ int pull_voltages(acc_data_t *bmsdata) /* Start the timer between readings if successful */ start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); - - return 0; } void segment_retrieve_data(acc_data_t *bmsdata) { /* Pull voltages and thermistors and indiacate if there was a problem during * retrieval */ - voltage_error = pull_voltages(bmsdata); + pull_voltages(bmsdata); + + // The GPIOs in the AUX registers contain voltage readings from the therms. read_aux_registers(bmsdata->chips); + // If you want redundant Thermistor readings, uncomment the following. + read_aux2_registers(bmsdata->chips); /* Save the contents of the reading so that we can use it to fill in missing * data */ From 61e424ea6d052e576a010f477879e1fd75111cec Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:07:53 -0500 Subject: [PATCH 15/32] adbms therms cleanup and changes for alpha and beta stacks --- Core/Inc/bmsConfig.h | 13 +-- Core/Inc/datastructs.h | 2 - Core/Src/analyzer.c | 98 +++++++++++----------- Core/Src/segment.c | 179 +++++++++++++++++++---------------------- 4 files changed, 139 insertions(+), 153 deletions(-) diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index 74825f79..73aa7bdb 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -2,11 +2,14 @@ #define BMS_CONFIG_H // Hardware definition -#define NUM_SEGMENTS 1 -#define NUM_CHIPS 1 //NUM_SEGMENTS * 2 -#define NUM_CELLS_PER_CHIP 16 -#define NUM_CELLS_ALPHA 16 -#define NUM_CELLS_BETA 12 +#define NUM_SEGMENTS 1 +#define NUM_CHIPS 1 //NUM_SEGMENTS * 2 +#define NUM_CELLS_PER_CHIP 16 +#define NUM_CELLS_ALPHA 16 +#define NUM_CELLS_BETA 12 +#define NUM_CELLS \ + ((NUM_CELLS_ALPHA * (NUM_CHIPS / 2.0)) + \ + (NUM_CELLS_BETA * (NUM_CHIPS / 2.0))) #define NUM_THERMS_PER_CHIP 32 #define NUM_RELEVANT_THERMS 1 diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index 1c6e3b64..5b6b9d39 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -16,8 +16,6 @@ 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 */ int8_t thermistor_value[NUM_THERMS_PER_CHIP]; int error_reading; diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 87610a54..9b7f9bb7 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -154,42 +154,45 @@ nertimer_t ocvTimer; bool is_first_reading_ = true; -void calc_alpha_temps(acc_data_t *bmsdata) +/** + * @brief Calcualte the cell temperatures for a chip. + * + * @param chip_data Pointer to processed chip data. + * @param chip Pointer to raw chip data. + * @param num_cells The number of cells connected to the chip. + */ +void calc_chip_temps(chipdata_t *chip_data, cell_asic *chip, int num_cells) { - for (int cell = 0; cell < NUM_CELLS_ALPHA; cell++) { - bmsdata->chip_data + for (int cell = 0; cell < num_cells; cell++) { + int sum = 0; + for (int therm = 0; therm < NUM_RELEVANT_THERMS; therm++) { + // TODO: use the correct relevant therm map + sum += chip->aux.a_codes[RELEVANT_THERM_MAP_H[cell] + [therm]]; + } + chip_data->cell_temp[cell] = sum / NUM_RELEVANT_THERMS; } } -void calc_beta_temps(acc_data_t *bmsdata) -{ -} - -/* we are not corrctly mapping each therm reading to the correct cell. So, we are taking the average of all good readings (not disabled) for a given chip, - and assigning that to be the cell val for every cell in the chip*/ - void calc_cell_temps(acc_data_t *bmsdata) { for (int chip = 0; chip < NUM_CHIPS; chip++) { - if (bmsdata->chip_data[chip]->alpha) { - for (int cell = 0; cell < NUM_CELLS_ALPHA; cell++) { - int sum = 0; - for (int therm = 0; therm < NUM_RELEVANT_THERMS; - therm++) { - sum += bmsdata->chips[chip].aux.a_codes - [RELEVANT_THERM_MAP_H - [cell][therm]] - } - bmsdata->chip_data[chip].cell_temp[cell]. - } + if (bmsdata->chip_data[chip].alpha) { + calc_chip_temps(&bmsdata->chip_data[chip], + &bmsdata->chips[chip], NUM_CELLS_ALPHA); } else { - calc_beta_temps(bmsdata); + calc_chip_temps(&bmsdata->chip_data[chip], + &bmsdata->chips[chip], NUM_CELLS_BETA); } } /* + - 22A CODE FOR REFERENC + 22A CODE FOR REFERENCE + + //we are not corrctly mapping each therm reading to the correct cell. So, we are taking the average of all good readings (not disabled) for a given chip, + //and assigning that to be the cell val for every cell in the chip for (uint8_t c = 0; c < NUM_CHIPS; c++) { for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { @@ -211,12 +214,12 @@ void calc_cell_temps(acc_data_t *bmsdata) } } //printf("\r\n"); - /* Takes the average temperature of all the relevant thermistors */ - bmsdata->chip_data[c].cell_temp[cell] = temp_sum / therm_count; - therm_count = 0; -} -} -* / + + // Takes the average temperature of all the relevant thermistors + bmsdata->chip_data[c].cell_temp[cell] = temp_sum / therm_count; + therm_count = 0; + } + */ } void calc_pack_temps(acc_data_t *bmsdata) @@ -311,18 +314,19 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) bmsdata->min_ocv.cellNum = 0; bmsdata->min_ocv.chipIndex = 0; - uint32_t total_volt = 0; - uint32_t total_ocv = 0; + float total_volt = 0; + float 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 (getVoltage(bmsdata->chip_data[c].voltage[cell]) * + if (getVoltage(bmsdata->chips[c].cell.c_codes[cell]) * 10000 > bmsdata->max_voltage.val) { bmsdata->max_voltage.val = - getVoltage(bmsdata->chip_data[c] - .voltage[cell]) * + getVoltage( + bmsdata->chips[c] + .cell.c_codes[cell]) * 10000; bmsdata->max_voltage.chipIndex = c; bmsdata->max_voltage.cellNum = cell; @@ -338,12 +342,13 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) } /* finds out the minimum cell voltage and location */ - if (getVoltage(bmsdata->chip_data[c].voltage[cell]) * + if (getVoltage(bmsdata->chips[c].cell.c_codes[cell]) * 10000 < bmsdata->min_voltage.val) { bmsdata->min_voltage.val = - getVoltage(bmsdata->chip_data[c] - .voltage[cell]) * + getVoltage( + bmsdata->chips[c] + .cell.c_codes[cell]) * 10000; bmsdata->min_voltage.chipIndex = c; bmsdata->min_voltage.cellNum = cell; @@ -358,31 +363,22 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) bmsdata->min_ocv.cellNum = cell; } - total_volt += bmsdata->chip_data[c].voltage[cell]; + total_volt += getVoltage( + bmsdata->chips[c].cell.c_codes[cell]); total_ocv += bmsdata->chip_data[c].open_cell_voltage[cell]; } } - float real_total_volt = 0; - for (int chip = 0; chip < NUM_CHIPS; chip++) { - for (int i = 0; i < NUM_CELLS_PER_CHIP; i++) { - real_total_volt += - getVoltage(bmsdata->chip_data[chip].voltage[i]); - } - } - /* calculate some voltage stats */ - bmsdata->avg_voltage = - 10000 * (real_total_volt / (NUM_CELLS_PER_CHIP * NUM_CHIPS)); + bmsdata->avg_voltage = total_volt / NUM_CELLS; - bmsdata->pack_voltage = - real_total_volt * 10; /* convert to voltage * 10 */ + bmsdata->pack_voltage = total_volt * 10; /* convert to voltage * 10 */ 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; bmsdata->pack_ocv = total_ocv / 1000; /* convert to voltage * 10 */ bmsdata->delt_ocv = bmsdata->max_ocv.val - bmsdata->min_ocv.val; diff --git a/Core/Src/segment.c b/Core/Src/segment.c index b9cfa20c..cef095ef 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -259,7 +259,7 @@ void segment_init(acc_data_t *bmsdata) // TODO: Make sure this is accurate bmsdata->chip_data->alpha = chip % 2 == 0; } - write_config_regs(chips); + write_config_regs(bmsdata->chips); } /** @@ -427,17 +427,6 @@ void pull_voltages(acc_data_t *bmsdata) get_c_adc_voltages(bmsdata->chips); - // TODO: Its kind of silly to just copy voltages like this. We should consolidate - // chip data and chips later, or design analyzer to read voltages from chips rather - // than chipdata - - for (int chip = 0; chip < NUM_CHIPS; chip++) { - for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - bmsdata->chip_data->voltage[cell] = - bmsdata->chips->cell.c_codes[cell]; - } - } - /* OLD CODE THAT DID WORK FOR ADBMS. KEEPING IN FOR DEBUGGING. @@ -644,78 +633,78 @@ int8_t steinhart_est(uint16_t V) return 80; } -void averaging_therm_check(chipdata_t segment_data[NUM_CHIPS]) -{ - for (int therm = 1; therm <= 16; therm++) { - for (int c = 0; c < NUM_CHIPS; c++) { - /* 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]; - 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 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 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]--; - } - } - - /* 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]--; - } - } - } - } - } -} +// void averaging_therm_check(chipdata_t segment_data[NUM_CHIPS]) +// { +// for (int therm = 1; therm <= 16; therm++) { +// for (int c = 0; c < NUM_CHIPS; c++) { +// /* 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]; +// 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 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 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]--; +// } +// } + +// /* 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]--; +// } +// } +// } +// } +// } +// } // void standard_dev_therm_check(chipdata_t segment_data[NUM_CHIPS]) // { @@ -804,14 +793,14 @@ int16_t calc_average(chipdata_t segment_data[NUM_CHIPS]) // } // } -void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]) -{ - for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t therm = 17; therm < 28; therm++) { - if (segment_data[c].thermistor_reading[therm] == 33) { - segment_data[c].thermistor_reading[therm] = 25; - segment_data[c].thermistor_value[therm] = 25; - } - } - } -} +// void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]) +// { +// for (uint8_t c = 0; c < NUM_CHIPS; c++) { +// for (uint8_t therm = 17; therm < 28; therm++) { +// if (segment_data[c].thermistor_reading[therm] == 33) { +// segment_data[c].thermistor_reading[therm] = 25; +// segment_data[c].thermistor_value[therm] = 25; +// } +// } +// } +// } From 540f19bedbcacd474418121fecfacd6a9adb70cb Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:50:40 -0500 Subject: [PATCH 16/32] adbms functions for configuring chips --- Core/Src/segment.c | 116 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 6 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index cef095ef..e24bb749 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -183,7 +183,7 @@ void set_volt_adc_comp_thresh(cell_asic *chip, CTH threshold) * @brief Set the discharge state of a cell. * * @param chip Pointer to chip with cell to modify. - * @param cell ID of cell to modify. + * @param cell ID of cell to modify. Cell indexes start are from 1-16 (NOT ZERO INDEXED). * @param discharge Cell discharge state. true to discharge, false to disable discharge. */ void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge) @@ -191,6 +191,39 @@ void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge) chip->tx_cfgb.dcc = set_uint16_bit(chip->tx_cfgb.dcc, cell, discharge); } +/** + * @brief Set the state of the SOAKON bit to either enable or disable soak times. + * + * @param chip Pointer to chip to configure + * @param state Enable or disable SOAKON + */ +void set_soak_on(cell_asic *chip, SOAKON state) +{ + chip->tx_cfga.soakon = state; +} + +/** + * @brief Set the open wire detection soak time range. + * + * @param chip Pointer to chip to configure + * @param range The range of time over which to soak for open wire detection + */ +void set_open_wire_soak_range(cell_asic *chip, OWRNG range) +{ + chip->tx_cfga.owrng = range; +} + +/** + * @brief Set the open wire soak time. See data sheet for formula. + * + * @param chip Pointer to chip configuration + * @param time The amount of time to soak for. Higher OWA is a higher soak time. + */ +void set_open_wire_soak_time(cell_asic *chip, OWA time) +{ + chip->tx_cfga.owa = time; +} + /** * @brief Set the mode of a GPIO pin on an ADBMS8630. * @@ -207,6 +240,77 @@ void set_gpio_mode(cell_asic *chip, uint8_t gpio, bool mode) chip->tx_cfga.gpo = set_uint16_bit(chip->tx_cfga.gpo, gpio - 1, mode); } +/** + * @brief Set the corner frequency of the IIR filter. + * + * @param chip Pointer to chip config + * @param freq Corner frequency (see IIR_FPA enum for frequencies) + */ +void set_iir_corner_freq(cell_asic *chip, IIR_FPA freq) +{ + chip->tx_cfga.fc = freq; +} + +/** + * @brief Configure a chip as a break in the isoSPI daisy chain. + * + * @param chip Pointer to chip config + * @param is_break True if chip is break, false if chip is not break + */ +void set_comm_break(cell_asic *chip, bool is_break) +{ + chip->tx_cfga.comm_bk = is_break; +} + +/** + * @brief Set whether or not this chip is taking a snapshot. The chip will not begin reading new values unless the snapshot bit is cleared. + * + * @param chip Pointer to chip config + * @param take_snapshot True to take a snapshot, false to end the snapshot + */ +void set_snapshot(cell_asic *chip, bool take_snapshot) +{ + chip->tx_cfga.snap = take_snapshot; +} + +/** + * @brief Enable/disable the discharge timer monitor. + * + * @param chip Pointer to chip config + * @param enabled True if discharge timer monitor is enabled, false if otherwise + */ +void set_discharge_timer_monitor(cell_asic *chip, bool enabled) +{ + chip->tx_cfgb.dtmen = enabled; +} + +/** + * @brief Configure the discharge timer range, which affects the resolution. + * + * @param chip Pointer to chip config + * @param large True for large range, False for small range + */ +void set_discharge_timer_range(cell_asic *chip, bool large) +{ + chip->tx_cfgb.dtrng = large; +} + +/** + * @brief Set the discharge monitor timeout, which is dependent on the discharge timer range. + * + * @param chip Pointer to chip config + * @param timeout Base for timeout multiplicaiton. Must be below six bits. + */ +void set_discharge_timeout(cell_asic *chip, uint8_t timeout) +{ + if (timeout >> 6 > 0) { + printf("Invalid discharge time\n"); + return; + //TODO: Non-critical fault + } + chip->tx_cfgb.dcto = timeout; +} + /** * @brief Write data to all chips. * @@ -327,7 +431,7 @@ void get_avgd_cell_voltages(cell_asic chips[NUM_CHIPS]) * * @param chip Array of chips to get voltage readings of. */ -void get_filtered_cell_volrages(cell_asic chips[NUM_CHIPS]) +void get_filtered_cell_voltages(cell_asic chips[NUM_CHIPS]) { write_config_regs(chips); adbms_wake(); @@ -559,9 +663,9 @@ void pull_voltages(acc_data_t *bmsdata) void segment_retrieve_data(acc_data_t *bmsdata) { - /* Pull voltages and thermistors and indiacate if there was a problem during - * retrieval */ - pull_voltages(bmsdata); + get_c_adc_voltages(bmsdata->chips); + + // get_s_adc_voltages(bmsdata->chips); // The GPIOs in the AUX registers contain voltage readings from the therms. read_aux_registers(bmsdata->chips); @@ -607,7 +711,7 @@ void segment_configure_balancing( // TODO: Test for (int chip = 0; chip < NUM_CHIPS; chip++) { for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - set_cell_discharge(&chips[chip], cell, + set_cell_discharge(&chips[chip], cell + 1, discharge_config[chip][cell]); // Enable balancing for a chip if a cell is to be discharged From 591fe500a31b4ee377d79213fb087504f40c6b03 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:56:48 -0500 Subject: [PATCH 17/32] forgot to build --- Core/Src/segment.c | 167 ++++++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 77 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index e24bb749..581f8993 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -13,17 +13,11 @@ #include "mcuWrapper.h" #include "cmsis_os.h" -#define ALL_GPIOS_ARE_INPUTS 0x3FF -#define T_READY 10 /* microseconds*/ -#define T_IDLE 4.3 /* milliseconds, minimum. typ is 5.5, max is 6.7 */ -#define T_WAKE 200 /* microseconds */ -#define T_SLEEP 1.8 /* seconds minimum, typ is 2, max is 2.2 */ -#define T_REFUP 2.7 /* milliseconds minimum, typ is 3.5, max is 4.4 */ - -typedef enum { - DISCHARGE_ENABLED = 0, - MUTE_ACTIVATED_DISCHARGE_DISABLED = 1 -} MUTE_ST; +#define T_READY 10 /* microseconds*/ +#define T_IDLE 4.3 /* milliseconds, minimum. typ is 5.5, max is 6.7 */ +#define T_WAKE 200 /* microseconds */ +#define T_SLEEP 1.8 /* seconds minimum, typ is 2, max is 2.2 */ +#define T_REFUP 2.7 /* milliseconds minimum, typ is 3.5, max is 4.4 */ #define THERM_WAIT_TIME 500 /* ms */ #define VOLTAGE_WAIT_TIME 500 /* ms */ @@ -104,59 +98,6 @@ void adbms_wake() adBmsWakeupIc(NUM_CHIPS); } -/** - * @brief Initialize a chip with default values. - * - * @param chip Pointer to chip to initialize. - */ -void init_chip(cell_asic *chip) -{ - chip->tx_cfga.refon = PWR_UP; - chip->tx_cfga.cth = CVT_8_1mV; - chip->tx_cfga.flag_d = 0; - - // No soak on AUX ADCs - chip->tx_cfga.soakon = SOAKON_CLR; - - // short soak time by default - chip->tx_cfga.owrng = TIME_32US_TO_4_1MS; - - chip->tx_cfga.owa = OWA0; - - // All GPIOs are inputs by default - chip->tx_cfga.gpo = ALL_GPIOS_ARE_INPUTS; - - // Registers are unfrozen - chip->tx_cfga.snap = SNAP_OFF; - - // Charging is deactivated - chip->tx_cfga.mute_st = MUTE_ACTIVATED_DISCHARGE_DISABLED; - - // Not an endpoint in the daisy chain - chip->tx_cfga.comm_bk = false; - - // IIR filter disabled - chip->tx_cfga.fc = IIR_FPA_OFF; - - // Init config B - - // If the corresponding fault bits are sent high, it does not affect the IC - chip->tx_cfgb.vov = SetOverVoltageThreshold(4.2); - chip->tx_cfgb.vuv = SetUnderVoltageThreshold(3.0); - - // Discharge timer monitor off - chip->tx_cfgb.dtmen = DTMEN_OFF; - - // Set discharge timer range to 0 to 63 minutes with 1 minute increments - chip->tx_cfgb.dtrng = RANG_0_TO_63_MIN; - - // Disable discharge timer - chip->tx_cfgb.dcto = DCTO_TIMEOUT; - - // Disable discharge for all cells - chip->tx_cfgb.dcc = 0; -} - /** * @brief Set the status of the REFON bit. * @@ -179,6 +120,12 @@ void set_volt_adc_comp_thresh(cell_asic *chip, CTH threshold) chip->tx_cfga.cth = threshold; } +void set_diagnostic_flags(cell_asic *chip, FLAG_D config) +{ + chip->tx_cfga.flag_d = + (uint8_t)set_uint16_bit(chip->tx_cfga.flag_d, config, true); +} + /** * @brief Set the discharge state of a cell. * @@ -229,15 +176,15 @@ void set_open_wire_soak_time(cell_asic *chip, OWA time) * * @param chip ADBMS6830 chip * @param gpio Number of the GPIO pin to change (1-10) - * @param mode Whether the pin should be an input or an output. True is input, False is output. + * @param input True is input, False is output. */ -void set_gpio_mode(cell_asic *chip, uint8_t gpio, bool mode) +void set_gpio_mode(cell_asic *chip, uint8_t gpio, bool input) { if (gpio > 10 || gpio < 1) { printf("ERROR: Invalid GPIO pin %d\n", gpio); return; } - chip->tx_cfga.gpo = set_uint16_bit(chip->tx_cfga.gpo, gpio - 1, mode); + chip->tx_cfga.gpo = set_uint16_bit(chip->tx_cfga.gpo, gpio - 1, input); } /** @@ -262,6 +209,17 @@ void set_comm_break(cell_asic *chip, bool is_break) chip->tx_cfga.comm_bk = is_break; } +/** + * @brief Enable/disable discharging through the mute discharge bit. + * + * @param chip Pointer to chip config + * @param disable_discharge True to disable discharge, false to enable discharge. + */ +void set_mute_state(cell_asic *chip, bool disable_discharge) +{ + chip->tx_cfga.mute_st = disable_discharge; +} + /** * @brief Set whether or not this chip is taking a snapshot. The chip will not begin reading new values unless the snapshot bit is cleared. * @@ -311,6 +269,67 @@ void set_discharge_timeout(cell_asic *chip, uint8_t timeout) chip->tx_cfgb.dcto = timeout; } +/** + * @brief Initialize a chip with default values. + * + * @param chip Pointer to chip to initialize. + */ +void init_chip(cell_asic *chip) +{ + set_REFON(chip, PWR_UP); + set_volt_adc_comp_thresh(chip, CVT_8_1mV); + chip->tx_cfga.flag_d = 0; + + // No soak on AUX ADCs + set_soak_on(chip, SOAKON_CLR); + + // short soak time by default + set_open_wire_soak_range(chip, TIME_32US_TO_4_1MS); + + // No open wire detect soak + set_open_wire_soak_time(chip, OWA0); + + // All GPIOs are inputs by default + set_gpio_mode(chip, 0, true); + set_gpio_mode(chip, 1, true); + set_gpio_mode(chip, 2, true); + set_gpio_mode(chip, 3, true); + set_gpio_mode(chip, 4, true); + set_gpio_mode(chip, 5, true); + set_gpio_mode(chip, 6, true); + set_gpio_mode(chip, 7, true); + set_gpio_mode(chip, 8, true); + set_gpio_mode(chip, 9, true); + set_gpio_mode(chip, 10, true); + + // Registers are unfrozen + set_snapshot(chip, SNAP_OFF); + + // Charging is deactivated + set_mute_state(chip, true); + + // Not an endpoint in the daisy chain + set_comm_break(chip, false); + + // IIR filter disabled + set_iir_corner_freq(chip, IIR_FPA_OFF); + + // Init config B + + // If the corresponding fault bits are sent high, it does not affect the IC + chip->tx_cfgb.vov = SetOverVoltageThreshold(4.2); + chip->tx_cfgb.vuv = SetUnderVoltageThreshold(3.0); + + // Discharge timer monitor off + set_discharge_timer_monitor(chip, false); + + // Set discharge timer range to 0 to 63 minutes with 1 minute increments + set_discharge_timer_range(chip, RANG_0_TO_63_MIN); + + // Disable discharge for all cells + chip->tx_cfgb.dcc = 0; +} + /** * @brief Write data to all chips. * @@ -681,8 +700,7 @@ void segment_retrieve_data(acc_data_t *bmsdata) bool segment_is_balancing(cell_asic chips[NUM_CHIPS]) { for (int chip = 0; chip < NUM_CHIPS; chip++) { - if (chips[chip].tx_cfga.mute_st != - MUTE_ACTIVATED_DISCHARGE_DISABLED) { + if (chips[chip].tx_cfgb.dcc > 0) { return true; } } @@ -694,7 +712,7 @@ void segment_disable_balancing(cell_asic chips[NUM_CHIPS]) // Initializes all array elements to zero bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP] = { 0 }; for (int chip = 0; chip < NUM_CHIPS; chip++) { - chips[chip].tx_cfga.mute_st = MUTE_ACTIVATED_DISCHARGE_DISABLED; + set_mute_state(&chips[chip], true); } segment_configure_balancing(chips, discharge_config); } @@ -702,6 +720,7 @@ void segment_disable_balancing(cell_asic chips[NUM_CHIPS]) /** * @brief Configure which cells should discharge, and send configuration to ICs. * + * @param chips Array of ADBMS6830 datastructs * @param discharge_config Array containing the discharge configuration. true = discharge, false = do not discharge. */ void segment_configure_balancing( @@ -713,13 +732,7 @@ void segment_configure_balancing( for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { set_cell_discharge(&chips[chip], cell + 1, discharge_config[chip][cell]); - - // Enable balancing for a chip if a cell is to be discharged - if (chips[chip].tx_cfga.mute_st == - MUTE_ACTIVATED_DISCHARGE_DISABLED && - discharge_config[chip][cell]) { - chips[chip].tx_cfga.mute_st = DISCHARGE_ENABLED; - } + set_mute_state(&chips[chip], false); } } write_config_regs(chips); From a0e9240f14581cbaef075b4993f35f00e9487ece Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sat, 11 Jan 2025 10:36:46 -0500 Subject: [PATCH 18/32] adbms debugging volts and therms --- Core/Src/analyzer.c | 3 ++- Core/Src/main.c | 10 +++++++--- Core/Src/segment.c | 37 +++++++++++++++++++++++-------------- Core/Src/shep_tasks.c | 1 + 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 9b7f9bb7..04378451 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -371,7 +371,8 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) } /* calculate some voltage stats */ - bmsdata->avg_voltage = total_volt / NUM_CELLS; + // TODO: Make this based on total cells when actual segment is here + bmsdata->avg_voltage = (total_volt * 10000) / 16; bmsdata->pack_voltage = total_volt * 10; /* convert to voltage * 10 */ diff --git a/Core/Src/main.c b/Core/Src/main.c index 45e23d06..40a3ecbb 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -45,6 +45,7 @@ // #define DEBUG_RAW_VOLTAGES #define DEBUG_RAW_VOLTAGES_FORMATTED // #define DEBUG_OCV +// #define DEUBG_THERMS // #define DEBUG_OTHER // etc etc //#endif @@ -194,7 +195,7 @@ const void print_bms_stats(acc_data_t *acc_data) { for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - printf("%d\t", acc_data->chip_data[c].voltage[cell]); + printf("%d\t", acc_data->chips[c].cell.c_codes[cell]); } printf("\n"); } @@ -205,7 +206,7 @@ const void print_bms_stats(acc_data_t *acc_data) { for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - printf("%d\t", acc_data->chip_data[c].voltage[cell]); + printf("%.3f\t", getVoltage(acc_data->chips[c].cell.c_codes[cell])); } printf("\n"); } @@ -238,7 +239,7 @@ const void print_bms_stats(acc_data_t *acc_data) printf("\n"); } - + printf("UnFiltered Thermistor Temps:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { @@ -252,6 +253,9 @@ const void print_bms_stats(acc_data_t *acc_data) printf("\n"); } + #endif + + #ifdef DEUBG_THERMS printf("Cell Temps:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 581f8993..7f497b26 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -95,7 +95,22 @@ inline uint16_t set_uint16_bit(uint16_t number, uint16_t n, bool x) */ void adbms_wake() { - adBmsWakeupIc(NUM_CHIPS); + adBmsCsLow(); + adBmsCsHigh(); + + /* + DEBUG: Theoretically, below should work for one IC, but it is not. + It shold be necessarry for multiple IC operation. + */ + + // for (uint8_t ic = 0; ic < total_ic; ic++) { + // adBmsCsLow(); + // Delay_ms(4); + // adBmsCsHigh(); + // Delay_ms(4); + // } + + // adBmsWakeupIc(NUM_CHIPS); } /** @@ -290,7 +305,6 @@ void init_chip(cell_asic *chip) set_open_wire_soak_time(chip, OWA0); // All GPIOs are inputs by default - set_gpio_mode(chip, 0, true); set_gpio_mode(chip, 1, true); set_gpio_mode(chip, 2, true); set_gpio_mode(chip, 3, true); @@ -363,7 +377,7 @@ void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, * * @param chips Array of chips to write config registers of. */ -inline void write_config_regs(cell_asic chips[NUM_CHIPS]) +void write_config_regs(cell_asic chips[NUM_CHIPS]) { adbms_wake(); write_adbms_data(chips, WRCFGA, Config, A); @@ -386,25 +400,18 @@ void segment_init(acc_data_t *bmsdata) } /** - * @brief Get voltage readings from the C-ADCs. + * @brief Get voltage readings from the C-ADCs. Takes a single shot measurement. * * @param chips Array of chips to get voltage readings from. */ void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]) { write_config_regs(chips); - adbms_wake(); - adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); - adBmsPollAdc(PLCADC); - adbms_wake(); + // Take single shot measurement + adBms6830_Adcv(RD_ON, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); read_adbms_data(chips, RDCVALL, Rdcvall, ALL_GRP); - // read_adbms_data(chip, RDCVA, Cell, A); - // read_adbms_data(chip, RDCVB, Cell, B); - // read_adbms_data(chip, RDCVC, Cell, C); - // read_adbms_data(chip, RDCVD, Cell, D); - // read_adbms_data(chip, RDCVE, Cell, E); - // read_adbms_data(chip, RDCVF, Cell, F); } /** @@ -682,11 +689,13 @@ void pull_voltages(acc_data_t *bmsdata) void segment_retrieve_data(acc_data_t *bmsdata) { + // printf("Get C adc voltages\n"); get_c_adc_voltages(bmsdata->chips); // get_s_adc_voltages(bmsdata->chips); // The GPIOs in the AUX registers contain voltage readings from the therms. + // printf("Get therms\n"); read_aux_registers(bmsdata->chips); // If you want redundant Thermistor readings, uncomment the following. read_aux2_registers(bmsdata->chips); diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index 60db88f6..c0e04d62 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -29,6 +29,7 @@ void vGetSegmentData(void *pv_params) { acc_data_t *bmsdata = (acc_data_t *)pv_params; for (;;) { + // printf("Get segment data\n"); segment_retrieve_data(bmsdata); osThreadFlagsSet(analyzer_thread, ANALYZER_FLAG); osDelay(1000 / SAMPLE_RATE); From 8a7b0856f96daca92528badf92c8f4ab64f1a401 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Tue, 14 Jan 2025 08:35:44 -0500 Subject: [PATCH 19/32] adbms therms mapping and temperature calculation, cleanup legacy code --- Core/Inc/analyzer.h | 25 ++-- Core/Inc/bmsConfig.h | 15 ++- Core/Inc/datastructs.h | 16 ++- Core/Inc/segment.h | 11 +- Core/Src/analyzer.c | 251 ++++++++++++++++++---------------------- Core/Src/main.c | 38 +++--- Core/Src/segment.c | 49 ++++---- Core/Src/shep_tasks.c | 2 +- Core/Src/stateMachine.c | 34 +++--- 9 files changed, 199 insertions(+), 242 deletions(-) diff --git a/Core/Inc/analyzer.h b/Core/Inc/analyzer.h index 0e9b0759..d89a1bbe 100644 --- a/Core/Inc/analyzer.h +++ b/Core/Inc/analyzer.h @@ -11,23 +11,6 @@ extern uint8_t THERM_DISABLE[NUM_CHIPS][NUM_THERMS_PER_CHIP]; extern const uint8_t NO_THERM; extern const uint8_t MUX_OFFSET; - -/** - * @brief Mapping the Relevant Thermistors for each cell based on cell # - * @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]; - -/** - * @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]; - /* * List of therms that we actually read from, NOT reordered by cell */ @@ -44,6 +27,14 @@ extern const uint8_t POPULATED_THERM_LIST_H[NUM_THERMS_PER_CHIP]; //#define MAX_SIZE_OF_HIST_QUEUE 300000U //bytes +/** + * @brief Get the number of cells on a chip. + * + * @param chip_data Pointer to struct containing chip data. + * @return uint8_t The number of cells in the chip. + */ +uint8_t get_num_cells(chipdata_t *chip_data); + /** * @brief Calculate thermistor values and cell temps using thermistors. * diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index 73aa7bdb..f1f04b4f 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -2,16 +2,15 @@ #define BMS_CONFIG_H // Hardware definition -#define NUM_SEGMENTS 1 -#define NUM_CHIPS 1 //NUM_SEGMENTS * 2 -#define NUM_CELLS_PER_CHIP 16 -#define NUM_CELLS_ALPHA 16 -#define NUM_CELLS_BETA 12 -#define NUM_CELLS \ +#define NUM_SEGMENTS 1 +#define NUM_CHIPS 1 //NUM_SEGMENTS * 2 +#define NUM_CELLS_ALPHA 14 +#define NUM_CELLS_BETA 11 +#define NUM_CELLS_SEG NUM_CELLS_ALPHA + NUM_CELLS_BETA +#define NUM_CELLS \ ((NUM_CELLS_ALPHA * (NUM_CHIPS / 2.0)) + \ (NUM_CELLS_BETA * (NUM_CHIPS / 2.0))) -#define NUM_THERMS_PER_CHIP 32 -#define NUM_RELEVANT_THERMS 1 +#define NUM_THERMS_PER_CHIP 14 // Firmware limits #define MAX_TEMP 65 //degrees C diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index 5b6b9d39..f3e19b4e 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -13,21 +13,19 @@ * @note stores thermistor values, voltage readings, and the discharge status */ 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_value[NUM_THERMS_PER_CHIP]; int error_reading; /* These are calculated during the analysis of data */ - int8_t cell_temp[NUM_CELLS_PER_CHIP]; - float cell_resistance[NUM_CELLS_PER_CHIP]; - uint16_t open_cell_voltage[NUM_CELLS_PER_CHIP]; + + /* Cell temperature in celsius */ + int8_t cell_temp[NUM_CELLS_ALPHA]; + float cell_resistance[NUM_CELLS_ALPHA]; + uint16_t open_cell_voltage[NUM_CELLS_ALPHA]; uint8_t noise_reading - [NUM_CELLS_PER_CHIP]; /* bool representing noise ignored read */ + [NUM_CELLS_ALPHA]; /* bool representing noise ignored read */ uint8_t consecutive_noise - [NUM_CELLS_PER_CHIP]; /* count representing consecutive noisy reads */ + [NUM_CELLS_ALPHA]; /* count representing consecutive noisy reads */ /* True if chip is alpha, False if Chip is Beta */ bool alpha; diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index d335be7d..7c5f7ef8 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -21,17 +21,16 @@ void segment_retrieve_data(acc_data_t *bmsdata); * * @param chips Array of ADBMS6830 data structs. */ -void segment_disable_balancing(cell_asic chips[NUM_CHIPS]); +void segment_disable_balancing(acc_data_t *bmsdata); /** - * @brief Set the cell balancing configuration and send it to the segments. + * @brief Configure which cells should discharge, and send configuration to ICs. * - * @param chips Array of ADBMS6830 data structs. - * @param discharge_config Configuration for which cells to discharge. + * @param bmsdata Pointer to acc data struct. + * @param discharge_config Array containing the discharge configuration. true = discharge, false = do not discharge. */ void segment_configure_balancing( - cell_asic chips[NUM_CHIPS], - bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]); + acc_data_t *bmsdata, bool discharge_config[NUM_CHIPS][NUM_CELLS_ALPHA]); /** * @brief Returns if a specific cell is balancing diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 04378451..1a025e3f 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -2,6 +2,7 @@ #include #include +#include #include "compute.h" @@ -18,7 +19,20 @@ #define GPIO9 8 #define GPIO10 9 +typedef enum { + THERM1 = 0, + THERM2, + THERM3, + THERM4, + THERM5, + THERM6, + THERM7 +} THERM; + // clang-format off + +//TODO: CHANGE ALL FOR NEW CELLS + /** * @brief Mapping Cell temperature to the cell resistance based on the * nominal cell resistance curve profile of the Samsung 186500 INR in the @@ -79,6 +93,8 @@ const uint8_t STATE_OF_CHARGE_CURVE[18] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 15, 24, 56, 74, 85, 95, 98, 100 }; +// END TODO + /** * @brief Mapping desired fan speed PWM to the cell temperature * @@ -95,56 +111,26 @@ const uint8_t FAN_CURVE[16] = const uint8_t NO_THERM = 0xFF; const uint8_t MUX_OFFSET = 16; -//TODO: MAKE THESE THERM MAPPINGS CORRECT - -/** - * @brief Mapping the Relevant Thermistors for each cell based on cell # - * @note 0xFF indicates the end of the relevant therms - * @note High side - */ -const uint8_t RELEVANT_THERM_MAP_H[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS] = -{ - {GPIO1}, - {GPIO1}, - {GPIO2}, - {GPIO2}, - {GPIO3}, - {GPIO3}, - {GPIO4}, - {GPIO4}, - {GPIO5}, - {GPIO6}, - {GPIO7}, - {GPIO7}, - {GPIO7}, - {GPIO7}, - {GPIO7}, - {GPIO7}, -}; - /** - * @brief Mapping the Relevant Thermistors for each cell based on cell # - * @note 0xFF indicates the end of the relevant therms - * @note Low side + * @brief Map cells to therms. + * */ -const uint8_t RELEVANT_THERM_MAP_L[NUM_CELLS_PER_CHIP][NUM_RELEVANT_THERMS] = +const THERM THERM_MAP[NUM_CELLS_ALPHA] = { - {GPIO1}, - {GPIO1}, - {GPIO2}, - {GPIO2}, - {GPIO3}, - {GPIO3}, - {GPIO4}, - {GPIO4}, - {GPIO5}, - {GPIO6}, - {GPIO7}, - {GPIO7}, - {GPIO7}, - {GPIO7}, - {GPIO7}, - {GPIO7}, + THERM1, + THERM1, + THERM2, + THERM2, + THERM3, + THERM3, + THERM4, + THERM4, + THERM5, + THERM5, + THERM6, + THERM6, + THERM7, + THERM7 }; // clang-format on @@ -154,37 +140,33 @@ nertimer_t ocvTimer; bool is_first_reading_ = true; -/** - * @brief Calcualte the cell temperatures for a chip. - * - * @param chip_data Pointer to processed chip data. - * @param chip Pointer to raw chip data. - * @param num_cells The number of cells connected to the chip. - */ -void calc_chip_temps(chipdata_t *chip_data, cell_asic *chip, int num_cells) +uint8_t get_num_cells(chipdata_t *chip_data) { - for (int cell = 0; cell < num_cells; cell++) { - int sum = 0; - for (int therm = 0; therm < NUM_RELEVANT_THERMS; therm++) { - // TODO: use the correct relevant therm map - sum += chip->aux.a_codes[RELEVANT_THERM_MAP_H[cell] - [therm]]; - } - chip_data->cell_temp[cell] = sum / NUM_RELEVANT_THERMS; + if (chip_data->alpha) { + return NUM_CELLS_ALPHA; + } else { + return NUM_CELLS_BETA; } } void calc_cell_temps(acc_data_t *bmsdata) { + // TODO: DELETE THIS JUST USING FOR PROFILING HOW LONG THIS SHIT TAKES + uint32_t start = HAL_GetTick(); for (int chip = 0; chip < NUM_CHIPS; chip++) { - if (bmsdata->chip_data[chip].alpha) { - calc_chip_temps(&bmsdata->chip_data[chip], - &bmsdata->chips[chip], NUM_CELLS_ALPHA); - } else { - calc_chip_temps(&bmsdata->chip_data[chip], - &bmsdata->chips[chip], NUM_CELLS_BETA); + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[chip]); + + for (int cell = 0; cell < num_cells; cell++) { + int16_t x = bmsdata->chips[chip] + .aux.a_codes[THERM_MAP[cell]]; + + /* Polynomial fit of temperatures -7 -> 65 celsius vs. thermistor voltage. */ + int8_t temp = 0.6984 * pow(x, 4) + 4.4933 * pow(x, 3) - + 10.278 * pow(x, 2) + 34.184 * x + 2.7608; + bmsdata->chip_data[chip].cell_temp[cell] = temp; } } + printf("%ld\n", HAL_GetTick() - start); /* @@ -234,43 +216,11 @@ void calc_pack_temps(acc_data_t *bmsdata) int total_temp = 0; int total_seg_temp = 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 */ + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[c]); - //if (THERM_DISABLE[c][therm]) continue; - total_accepted++; - //if (bmsdata->chip_data[c].thermistor_value[therm] > bmsdata->max_temp.val) { - // bmsdata->max_temp.val = bmsdata->chip_data[c].thermistor_value[therm]; - // bmsdata->max_temp.cellNum = c; - // bmsdata->max_temp.chipIndex = therm; - //} - - /* finds out the minimum cell temp and location */ - //if (bmsdata->chip_data[c].thermistor_value[therm] < bmsdata->min_temp.val) { - // bmsdata->min_temp.val = bmsdata->chip_data[c].thermistor_value[therm]; - // bmsdata->min_temp.cellNum = c; - // bmsdata->min_temp.chipIndex = 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; - } - } - - for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + for (uint8_t cell = 0; cell < num_cells; cell++) { if (bmsdata->chip_data[c].cell_temp[cell] > bmsdata->max_temp.val) { bmsdata->max_temp.val = @@ -287,11 +237,21 @@ void calc_pack_temps(acc_data_t *bmsdata) bmsdata->min_temp.cellNum = cell; bmsdata->min_temp.chipIndex = c; } + + total_temp += bmsdata->chip_data[c].cell_temp[cell]; + total_seg_temp += bmsdata->chip_data[c].cell_temp[cell]; + } + /* only for NERO */ + if (c % 2 == 0) { + bmsdata->segment_average_temps[c / 2] = + total_seg_temp / + (NUM_CELLS_ALPHA + NUM_CELLS_BETA); + total_seg_temp = 0; } } - /* takes the average of all the cell temperatures */ - bmsdata->avg_temp = total_temp / (total_accepted); + /* Takes the average of all the cell temperatures. */ + bmsdata->avg_temp = total_temp / NUM_CELLS; compute_send_cell_temp_message(bmsdata); } @@ -318,7 +278,8 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) float total_ocv = 0; for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[c]); + for (uint8_t cell = 0; cell < num_cells; cell++) { /* fings out the maximum cell voltage and location */ if (getVoltage(bmsdata->chips[c].cell.c_codes[cell]) * 10000 > @@ -390,7 +351,9 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) void calc_cell_resistances(acc_data_t *bmsdata) { for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[c]); + + for (uint8_t cell = 0; cell < num_cells; cell++) { uint8_t cell_temp = bmsdata->chip_data[c].cell_temp[cell]; @@ -423,7 +386,8 @@ void calc_dcl(acc_data_t *bmsdata) int16_t current_limit = 0x7FFF; for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[c]); + for (uint8_t cell = 0; cell < num_cells; cell++) { /* Apply equation */ /* Multiplying resistance by 10 to convert from mOhm to Ohm and then to Ohm * 10000 to * account for the voltage units */ @@ -485,6 +449,7 @@ void calc_dcl(acc_data_t *bmsdata) compute_send_current_message(bmsdata); } +//TODO: Fix for new cells and BMS void calc_cont_dcl(acc_data_t *bmsdata) { uint8_t min_res_index = @@ -504,7 +469,8 @@ void calcCCL(acc_data_t *bmsdata) int16_t currentLimit = 0x7FFF; for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[c]); + for (uint8_t cell = 0; cell < num_cells; cell++) { /* Apply equation */ uint16_t tmpCCL = ((MAX_VOLT * 10000) - @@ -550,6 +516,8 @@ void calc_cont_ccl(acc_data_t *bmsdata) } } +//TODO: Make it actually calc OCVs. Revise algorithm and stuff. +//TODO: Change for new cells (probs not needed). void calc_open_cell_voltage(acc_data_t *bmsdata) { static chipdata_t prev_chipdata[12]; @@ -557,13 +525,14 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) /* 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++) { + uint8_t num_cells = + get_num_cells(&bmsdata->chip_data[chip]); + for (uint8_t cell = 0; cell < num_cells; cell++) { bmsdata->chip_data[chip] .open_cell_voltage[cell] = - bmsdata->chip_data[chip].voltage[cell]; + bmsdata->chips[chip].cell.c_codes[cell]; prev_chipdata[chip].open_cell_voltage[cell] = - bmsdata->chip_data[chip].voltage[cell]; + bmsdata->chips[chip].cell.c_codes[cell]; } } return; @@ -574,21 +543,24 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) 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++) { + uint8_t num_cells = get_num_cells( + &bmsdata->chip_data[chip]); + for (uint8_t cell = 0; cell < num_cells; + 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)(bmsdata->chips[chip] + .cell + .c_codes[cell]) + ((uint32_t)(prev_chipdata[chip].open_cell_voltage [cell]) * (OCV_AVG - 1))) / OCV_AVG; bmsdata->chip_data[chip] .open_cell_voltage[cell] = - bmsdata->chip_data[chip] - .voltage[cell]; + bmsdata->chips[chip] + .cell.c_codes[cell]; if (bmsdata->chip_data[chip] .open_cell_voltage[cell] > @@ -616,7 +588,8 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) start_timer(&ocvTimer, 1000); } for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[chip]); + for (uint8_t cell = 0; cell < num_cells; cell++) { /* Set OCV to the previous/existing OCV */ bmsdata->chip_data[chip].open_cell_voltage[cell] = prev_chipdata[chip].open_cell_voltage[cell]; @@ -694,25 +667,27 @@ void calc_state_of_charge(acc_data_t *bmsdata) compute_send_acc_status_message(bmsdata); } -void calc_noise_volt_percent(acc_data_t *bmsdata) -{ - int i = 0; - for (uint8_t seg = 0; seg < NUM_SEGMENTS; seg++) { - uint8_t count = 0; - /* merge results from each of the two chips on a 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]; - } - i++; +// NOTE: This function is broken or something. +// void calc_noise_volt_percent(acc_data_t *bmsdata) +// { +// int i = 0; +// for (uint8_t seg = 0; seg < NUM_SEGMENTS; seg++) { +// uint8_t count = 0; + +// /* merge results from each of the two chips on a given segment */ +// for (uint8_t cell = 0; cell < NUM_CELLS_SEG; cell++) { +// count = bmsdata->chip_data[seg + i].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)); - } -} +// /* turn into percentage */ +// //printf("count: %d\r\n", count); +// bmsdata->segment_noise_percentage[seg] = +// (uint8_t)(100 * (count) / (NUM_CELLS_SEG * 2.0f)); +// } +// } // void high_curr_therm_check() // { diff --git a/Core/Src/main.c b/Core/Src/main.c index 40a3ecbb..a6ee22b2 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -193,7 +193,8 @@ const void print_bms_stats(acc_data_t *acc_data) printf("Raw Cell Voltage:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { - for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) + uint8_t num_cells = get_num_cells(&acc_data->chip_data[c]); + for(uint8_t cell = 0; cell < num_cells; cell++) { printf("%d\t", acc_data->chips[c].cell.c_codes[cell]); } @@ -204,7 +205,8 @@ const void print_bms_stats(acc_data_t *acc_data) #ifdef DEBUG_RAW_VOLTAGES_FORMATTED for(uint8_t c = 0; c < NUM_CHIPS; c++) { - for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) + uint8_t num_cells = get_num_cells(&acc_data->chip_data[c]); + for(uint8_t cell = 0; cell < num_cells; cell++) { printf("%.3f\t", getVoltage(acc_data->chips[c].cell.c_codes[cell])); } @@ -216,7 +218,8 @@ const void print_bms_stats(acc_data_t *acc_data) printf("Open Cell Voltage:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { - for(uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) + uint8_t num_cells = get_num_cells(&acc_data->chip_data[c]); + for(uint8_t cell = 0; cell < num_cells; cell++) { printf("%d\t", acc_data->chip_data[c].open_cell_voltage[cell]); } @@ -225,29 +228,22 @@ const void print_bms_stats(acc_data_t *acc_data) #endif #ifdef DEBUG_OTHER - - printf("Thermistors with Disabling:\n"); - for(uint8_t c = 0; c < NUM_CHIPS; c++) - { - printf("Chip %d: ", c); - - for (uint8_t cell = 0; cell < NUM_THERMS_PER_CHIP; cell++) { - - //if (THERM_DISABLE[c][cell]) continue; - printf("%d ", acc_data->chip_data[c].thermistor_value[cell]); - } - - printf("\n"); - } printf("UnFiltered Thermistor Temps:\n"); for(uint8_t c = 0; c < NUM_CHIPS; c++) { printf("Chip %d: ", c); - for (uint8_t cell = 0; cell < NUM_THERMS_PER_CHIP; cell++) { + uint8_t num_therms; + if (acc_data->chip_data->alpha) { + num_therms = 7; + } else { + num_therms = 6; + } + + for (uint8_t therm = 0; therm < num_therms; therm++) { - printf("%d ", acc_data->chip_data[c].thermistor_reading[cell]); + printf("%d ", acc_data->chips[c].aux.a_codes[therm]); } printf("\n"); @@ -260,8 +256,8 @@ const void print_bms_stats(acc_data_t *acc_data) for(uint8_t c = 0; c < NUM_CHIPS; c++) { printf("Chip %d: ", c); - - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(&acc_data->chip_data[c]); + for (uint8_t cell = 0; cell < num_cells; cell++) { printf("%d ", acc_data->chip_data[c].cell_temp[cell]); } diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 7f497b26..92db5ca0 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -4,6 +4,7 @@ #include #include #include +#include "analyzer.h" #include "common.h" #include "adBms6830CmdList.h" @@ -716,35 +717,29 @@ bool segment_is_balancing(cell_asic chips[NUM_CHIPS]) return false; } -void segment_disable_balancing(cell_asic chips[NUM_CHIPS]) +void segment_disable_balancing(acc_data_t *bmsdata) { // Initializes all array elements to zero - bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP] = { 0 }; + bool discharge_config[NUM_CHIPS][NUM_CELLS_ALPHA] = { 0 }; for (int chip = 0; chip < NUM_CHIPS; chip++) { - set_mute_state(&chips[chip], true); + set_mute_state(&bmsdata->chips[chip], true); } - segment_configure_balancing(chips, discharge_config); + segment_configure_balancing(bmsdata, discharge_config); } -/** - * @brief Configure which cells should discharge, and send configuration to ICs. - * - * @param chips Array of ADBMS6830 datastructs - * @param discharge_config Array containing the discharge configuration. true = discharge, false = do not discharge. - */ void segment_configure_balancing( - cell_asic chips[NUM_CHIPS], - bool discharge_config[NUM_CHIPS][NUM_CELLS_PER_CHIP]) + acc_data_t *bmsdata, bool discharge_config[NUM_CHIPS][NUM_CELLS_ALPHA]) { // TODO: Test for (int chip = 0; chip < NUM_CHIPS; chip++) { - for (int cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { - set_cell_discharge(&chips[chip], cell + 1, + uint8_t num_cells = get_num_cells(bmsdata->chip_data); + for (int cell = 0; cell < num_cells; cell++) { + set_cell_discharge(&bmsdata->chips[chip], cell + 1, discharge_config[chip][cell]); - set_mute_state(&chips[chip], false); + set_mute_state(&bmsdata->chips[chip], false); } } - write_config_regs(chips); + write_config_regs(bmsdata->chips); } int8_t steinhart_est(uint16_t V) @@ -873,18 +868,18 @@ int8_t steinhart_est(uint16_t V) // return standard_dev; // } -int16_t calc_average(chipdata_t segment_data[NUM_CHIPS]) -{ - int16_t avg = 0; - for (int chip = 0; chip < NUM_CHIPS; chip++) { - for (int therm = 17; therm < 28; therm++) { - avg += segment_data[chip].thermistor_value[therm]; - } - } +// int16_t calc_average(chipdata_t segment_data[NUM_CHIPS]) +// { +// int16_t avg = 0; +// for (int chip = 0; chip < NUM_CHIPS; chip++) { +// for (int therm = 17; therm < 28; therm++) { +// avg += segment_data[chip].thermistor_value[therm]; +// } +// } - avg = avg / (NUM_CHIPS * 11); - return avg; -} +// avg = avg / (NUM_CHIPS * 11); +// return avg; +// } // void variance_therm_check() // { diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index c0e04d62..c9909af2 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -66,7 +66,7 @@ void vAnalyzer(void *pv_params) // temporary end calc_state_of_charge(bmsdata); - calc_noise_volt_percent(bmsdata); + // calc_noise_volt_percent(bmsdata); osMutexRelease(bmsdata->mutex); } diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index 8eb91af0..22b52048 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -64,7 +64,7 @@ void init_boot(acc_data_t *bmsdata) void handle_boot(acc_data_t *bmsdata) { prevAccData = NULL; - segment_disable_balancing(bmsdata->chips); + segment_disable_balancing(bmsdata); compute_enable_charging(false); start_timer(&bootup_timer, 10000); printf("Bootup timer started\r\n"); @@ -78,7 +78,7 @@ void handle_boot(acc_data_t *bmsdata) void init_ready(acc_data_t *bmsdata) { - segment_disable_balancing(bmsdata->chips); + segment_disable_balancing(bmsdata); compute_enable_charging(false); return; } @@ -120,15 +120,16 @@ void handle_charging(acc_data_t *bmsdata) if (sm_balancing_check(bmsdata)) sm_balance_cells(bmsdata); else - segment_disable_balancing(bmsdata->chips); + segment_disable_balancing(bmsdata); /* 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); + compute_send_charging_message( + (MAX_CHARGE_VOLT * + (NUM_CELLS_ALPHA + NUM_CELLS_BETA) * + NUM_CHIPS), + 5, bmsdata); start_timer(&charger_message_timer, CHARGE_MESSAGE_WAIT); } @@ -137,7 +138,7 @@ void handle_charging(acc_data_t *bmsdata) void init_faulted(acc_data_t *bmsdata) { - segment_disable_balancing(bmsdata->chips); + segment_disable_balancing(bmsdata); compute_enable_charging(false); entered_faulted = true; return; @@ -443,17 +444,19 @@ void sm_broadcast_current_limit(acc_data_t *bmsdata) } } -void sm_balance_cells(acc_data_t *bms_data) +void sm_balance_cells(acc_data_t *bmsdata) { - bool balanceConfig[NUM_CHIPS][NUM_CELLS_PER_CHIP]; + bool balanceConfig[NUM_CHIPS][NUM_CELLS_ALPHA]; /* For all cells of all the chips, figure out if we need to balance by * comparing the difference in voltages */ for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(&bmsdata->chip_data[chip]); + + for (uint8_t cell = 0; cell < num_cells; cell++) { uint16_t delta = - bms_data->chip_data[chip].voltage[cell] - - (uint16_t)bms_data->min_voltage.val; + bmsdata->chips[chip].cell.c_codes[cell] - + (uint16_t)bmsdata->min_voltage.val; if (delta > MAX_DELTA_V * 10000) balanceConfig[chip][cell] = true; else @@ -464,7 +467,8 @@ void sm_balance_cells(acc_data_t *bms_data) #ifdef DEBUG_CHARGING printf("Cell Balancing:"); for (uint8_t c = 0; c < NUM_CHIPS; c++) { - for (uint8_t cell = 0; cell < NUM_CELLS_PER_CHIP; cell++) { + uint8_t num_cells = get_num_cells(bmsdata->chip_data[c]); + for (uint8_t cell = 0; cell < num_cells; cell++) { printf(balanceConfig[c][cell]); printf("\t"); } @@ -472,7 +476,7 @@ void sm_balance_cells(acc_data_t *bms_data) } #endif - segment_configure_balancing(bms_data->chips, balanceConfig); + segment_configure_balancing(bmsdata, balanceConfig); } void calculate_pwm(acc_data_t *bmsdata) From a3d12bcc2104b6eca5cc4587e008e3fa512686f5 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:20:02 -0500 Subject: [PATCH 20/32] adbms cleanup, add TODOs for future work --- Core/Src/analyzer.c | 7 ++ Core/Src/compute.c | 1 - Core/Src/segment.c | 179 ---------------------------------------- Core/Src/stateMachine.c | 8 +- 4 files changed, 11 insertions(+), 184 deletions(-) diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 1a025e3f..01046e08 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -377,6 +377,7 @@ void calc_cell_resistances(acc_data_t *bmsdata) } } +// TODO: Change to match P45Bs. void calc_dcl(acc_data_t *bmsdata) { static nertimer_t dcl_timer; @@ -464,6 +465,7 @@ void calc_cont_dcl(acc_data_t *bmsdata) } } +//TODO: Change for P45B electrical characteristics. void calcCCL(acc_data_t *bmsdata) { int16_t currentLimit = 0x7FFF; @@ -498,6 +500,7 @@ void calcCCL(acc_data_t *bmsdata) compute_send_current_message(bmsdata); } +//TODO: Change for P45B electrical characteristics. void calc_cont_ccl(acc_data_t *bmsdata) { uint8_t min_res_index = @@ -597,6 +600,7 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) } } +//TODO: Change for new fans and cell temps uint8_t analyzer_calc_fan_pwm(acc_data_t *bmsdata) { /* Resistance LUT increments by 5C for each index, plus we account for negative minimum */ @@ -637,6 +641,9 @@ uint8_t analyzer_calc_fan_pwm(acc_data_t *bmsdata) // } // } +//TODO: Change for P45B electrical characteristics. +//TODO: Add coulomb couting. +// FUTURE: State of power calcs. void calc_state_of_charge(acc_data_t *bmsdata) { /* Spltting the delta voltage into 18 increments */ diff --git a/Core/Src/compute.c b/Core/Src/compute.c index 16fdf53c..b971f2bd 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -155,7 +155,6 @@ uint8_t compute_set_fan_speed(TIM_HandleTypeDef *pwmhandle, 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); } diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 92db5ca0..d63c9c32 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -37,7 +37,6 @@ chipdata_t previous_data[NUM_CHIPS] = {}; uint16_t discharge_commands[NUM_CHIPS] = {}; nertimer_t therm_timer; -nertimer_t voltage_reading_timer; nertimer_t variance_timer; int therm_error = 0; // not faulted @@ -49,26 +48,9 @@ const int mapping_correction[12] = { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10 }; uint16_t therm_settle_time_ = 0; -// TODO: replace for new thermistors -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 -}; - const int32_t VOLT_TEMP_CALIB_OFFSET = 0; /* private function prototypes */ -int8_t steinhart_est(uint16_t V); void variance_therm_check(void); void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]); void pull_chip_configuration(void); @@ -539,155 +521,6 @@ void adBms6830_read_status_registers(cell_asic chips[NUM_CHIPS]) read_adbms_data(chips, RDSTATE, Status, E); } -void pull_voltages(acc_data_t *bmsdata) -{ - /** - * If we haven't waited long enough between pulling voltage data - * just copy over the contents of the last good reading and the fault status - * from the most recent attempt - */ - - // TODO: should probably get rid of this - if (!is_timer_expired(&voltage_reading_timer) && - voltage_reading_timer.active) { - for (uint8_t i = 0; i < NUM_CHIPS; i++) { - memcpy(&bmsdata->chips[i], &previous_data[i], - sizeof(bmsdata->chips[i])); - } - } - - get_c_adc_voltages(bmsdata->chips); - - /* - - OLD CODE THAT DID WORK FOR ADBMS. KEEPING IN FOR DEBUGGING. - - uint16_t raw_voltages[NUM_CHIPS][NUM_CELLS_PER_CHIP]; - - // printVoltages(TOTAL_IC, &IC[0], Cell); - - float voltage; - uint8_t ic = 0; - int16_t temp; - // number of cells - uint8_t channel = 16; - uint8_t type = Cell; - for (uint8_t index = 0; index < channel; index++) { - if (type == Cell) { - temp = IC[ic].cell.c_codes[index]; - } else if (type == AvgCell) { - temp = IC[ic].acell.ac_codes[index]; - } else if (type == F_volt) { - temp = IC[ic].fcell.fc_codes[index]; - } else if (type == S_volt) { - temp = IC[ic].scell.sc_codes[index]; - } else if (type == Aux) { - temp = IC[ic].aux.a_codes[index]; - } else if (type == RAux) { - temp = IC[ic].raux.ra_codes[index]; - } - - voltage = getVoltage(temp); - - raw_voltages[ic][index] = (uint16_t)temp; - - segment_data[ic].voltage[index] = raw_voltages[ic][index]; - - if (type == Cell) { - // printf("C%d=%fV= %d raw\r\n", (index + 1), voltage, - // segment_data[ic].voltage[index]); - if (index == (channel - 1)) { - // printf("CCount:%d,", IC[ic].cccrc.cmd_cntr); - // printf("PECError:%d", IC[ic].cccrc.cell_pec); - } - } - } - // printf("\n\n"); - - */ - - /* - float total_volts = 0; - for (int i = 0; i < 16; i++) { - printf("Raw %d: %f\n", i, getVoltage(segment_data[ic].voltage[i])); - total_volts += getVoltage(segment_data[ic].voltage[i]); - } - printf("TOTAL VOLTAGE: %f", total_volts);*/ - - /* - if (MEASURE_AVG_CELL == ENABLED) { - adBmsReadData(TOTAL_IC, &IC[0], RDACA, AvgCell, A); - adBmsReadData(TOTAL_IC, &IC[0], RDACB, AvgCell, B); - adBmsReadData(TOTAL_IC, &IC[0], RDACC, AvgCell, C); - adBmsReadData(TOTAL_IC, &IC[0], RDACD, AvgCell, D); - adBmsReadData(TOTAL_IC, &IC[0], RDACE, AvgCell, E); - adBmsReadData(TOTAL_IC, &IC[0], RDACF, AvgCell, F); - printVoltages(TOTAL_IC, &IC[0], AvgCell); - } - - if (MEASURE_F_CELL == ENABLED) { - adBmsReadData(TOTAL_IC, &IC[0], RDFCA, F_volt, A); - adBmsReadData(TOTAL_IC, &IC[0], RDFCB, F_volt, B); - adBmsReadData(TOTAL_IC, &IC[0], RDFCC, F_volt, C); - adBmsReadData(TOTAL_IC, &IC[0], RDFCD, F_volt, D); - adBmsReadData(TOTAL_IC, &IC[0], RDFCE, F_volt, E); - adBmsReadData(TOTAL_IC, &IC[0], RDFCF, F_volt, F); - printVoltages(TOTAL_IC, &IC[0], F_volt); - } */ - - /* - if (MEASURE_S_VOLTAGE == ENABLED) { - adBmsWakeupIc(TOTAL_IC); - adBmsReadData(TOTAL_IC, &IC[0], RDSVA, S_volt, A); - adBmsReadData(TOTAL_IC, &IC[0], RDSVB, S_volt, B); - adBmsReadData(TOTAL_IC, &IC[0], RDSVC, S_volt, C); - adBmsReadData(TOTAL_IC, &IC[0], RDSVD, S_volt, D); - adBmsReadData(TOTAL_IC, &IC[0], RDSVE, S_volt, E); - adBmsReadData(TOTAL_IC, &IC[0], RDSVF, S_volt, F); - printVoltages(TOTAL_IC, &IC[0], S_volt); - } */ - - /* - if (MEASURE_AUX == ENABLED) { - adBms6830_Adax(AUX_OW_OFF, - PUP_DOWN, AUX_ALL); - adBmsPollAdc(PLAUX1); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXA, Aux, A); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXB, Aux, B); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXC, Aux, C); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXD, Aux, D); - printVoltages(TOTAL_IC, &IC[0], Aux); - } */ - - /* - if (MEASURE_RAUX == ENABLED) { - adBmsWakeupIc(TOTAL_IC); - adBms6830_Adax2(AUX_ALL); - adBmsPollAdc(PLAUX2); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXA, RAux, A); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXB, RAux, B); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXC, RAux, C); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXD, RAux, D); - printVoltages(TOTAL_IC, &IC[0], RAux); - } */ - - /* - if (MEASURE_STAT == ENABLED) { - adBms6830_Adax(AUX_OW_OFF, - PUP_DOWN, AUX_ALL); - adBmsPollAdc(PLAUX1); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATA, Status, A); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATB, Status, B); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATC, Status, C); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATD, Status, D); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATE, Status, E); - printStatus(TOTAL_IC, &IC[0], Status, ALL_GRP); - }*/ - - /* Start the timer between readings if successful */ - start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); -} - void segment_retrieve_data(acc_data_t *bmsdata) { // printf("Get C adc voltages\n"); @@ -742,18 +575,6 @@ void segment_configure_balancing( write_config_regs(bmsdata->chips); } -int8_t steinhart_est(uint16_t V) -{ - /* min temp - max temp with buffer on both */ - for (int i = -25; i < 80; i++) { - if (V > VOLT_TEMP_CONV[i + 25]) { - return i; - } - } - - return 80; -} - // void averaging_therm_check(chipdata_t segment_data[NUM_CHIPS]) // { // for (int therm = 1; therm <= 16; therm++) { diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index 22b52048..ff4b34b8 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -101,6 +101,7 @@ void init_charging(acc_data_t *bmsdata) return; } +// TODO: Improve algorithm. Change for new cells. Make more configurable. void handle_charging(acc_data_t *bmsdata) { if (!compute_charger_connected()) { @@ -159,9 +160,6 @@ void handle_faulted(acc_data_t *bmsdata) else { compute_set_fault(0); - - // TODO update to HAL - // digitalWrite(CHARGE_SAFETY_RELAY, 0); } return; } @@ -387,6 +385,7 @@ bool sm_charging_check(acc_data_t *bmsdata) } } +// TODO: Improve algorithm. bool sm_balancing_check(acc_data_t *bmsdata) { if (!compute_charger_connected()) @@ -444,6 +443,7 @@ void sm_broadcast_current_limit(acc_data_t *bmsdata) } } +//TODO: Improve algorithm void sm_balance_cells(acc_data_t *bmsdata) { bool balanceConfig[NUM_CHIPS][NUM_CELLS_ALPHA]; @@ -481,7 +481,7 @@ void sm_balance_cells(acc_data_t *bmsdata) void calculate_pwm(acc_data_t *bmsdata) { - // todo actually implement algorithm + // TODO: actually implement algorithm // this should include: // 1. set PWM based on temp of "nearby" cells // 2. automate seleciton of htim rather than hardcode From 5becce5b6793498b0f5d88e4eddcfbd192b1a335 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:20:02 -0500 Subject: [PATCH 21/32] adbms cleanup, add TODOs for future work --- Core/Src/analyzer.c | 7 ++ Core/Src/compute.c | 4 +- Core/Src/segment.c | 179 ---------------------------------------- Core/Src/stateMachine.c | 8 +- 4 files changed, 12 insertions(+), 186 deletions(-) diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 1a025e3f..01046e08 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -377,6 +377,7 @@ void calc_cell_resistances(acc_data_t *bmsdata) } } +// TODO: Change to match P45Bs. void calc_dcl(acc_data_t *bmsdata) { static nertimer_t dcl_timer; @@ -464,6 +465,7 @@ void calc_cont_dcl(acc_data_t *bmsdata) } } +//TODO: Change for P45B electrical characteristics. void calcCCL(acc_data_t *bmsdata) { int16_t currentLimit = 0x7FFF; @@ -498,6 +500,7 @@ void calcCCL(acc_data_t *bmsdata) compute_send_current_message(bmsdata); } +//TODO: Change for P45B electrical characteristics. void calc_cont_ccl(acc_data_t *bmsdata) { uint8_t min_res_index = @@ -597,6 +600,7 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) } } +//TODO: Change for new fans and cell temps uint8_t analyzer_calc_fan_pwm(acc_data_t *bmsdata) { /* Resistance LUT increments by 5C for each index, plus we account for negative minimum */ @@ -637,6 +641,9 @@ uint8_t analyzer_calc_fan_pwm(acc_data_t *bmsdata) // } // } +//TODO: Change for P45B electrical characteristics. +//TODO: Add coulomb couting. +// FUTURE: State of power calcs. void calc_state_of_charge(acc_data_t *bmsdata) { /* Spltting the delta voltage into 18 increments */ diff --git a/Core/Src/compute.c b/Core/Src/compute.c index 16fdf53c..1c27fb67 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -155,7 +155,6 @@ uint8_t compute_set_fan_speed(TIM_HandleTypeDef *pwmhandle, 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); } @@ -331,8 +330,7 @@ void compute_send_bms_status_message(acc_data_t *bmsdata, int bms_state, 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); + bms_status_msg_data.balance = (uint8_t)(balance); /* convert to big endian */ endian_swap(&bms_status_msg_data.fault, diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 92db5ca0..d63c9c32 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -37,7 +37,6 @@ chipdata_t previous_data[NUM_CHIPS] = {}; uint16_t discharge_commands[NUM_CHIPS] = {}; nertimer_t therm_timer; -nertimer_t voltage_reading_timer; nertimer_t variance_timer; int therm_error = 0; // not faulted @@ -49,26 +48,9 @@ const int mapping_correction[12] = { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10 }; uint16_t therm_settle_time_ = 0; -// TODO: replace for new thermistors -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 -}; - const int32_t VOLT_TEMP_CALIB_OFFSET = 0; /* private function prototypes */ -int8_t steinhart_est(uint16_t V); void variance_therm_check(void); void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]); void pull_chip_configuration(void); @@ -539,155 +521,6 @@ void adBms6830_read_status_registers(cell_asic chips[NUM_CHIPS]) read_adbms_data(chips, RDSTATE, Status, E); } -void pull_voltages(acc_data_t *bmsdata) -{ - /** - * If we haven't waited long enough between pulling voltage data - * just copy over the contents of the last good reading and the fault status - * from the most recent attempt - */ - - // TODO: should probably get rid of this - if (!is_timer_expired(&voltage_reading_timer) && - voltage_reading_timer.active) { - for (uint8_t i = 0; i < NUM_CHIPS; i++) { - memcpy(&bmsdata->chips[i], &previous_data[i], - sizeof(bmsdata->chips[i])); - } - } - - get_c_adc_voltages(bmsdata->chips); - - /* - - OLD CODE THAT DID WORK FOR ADBMS. KEEPING IN FOR DEBUGGING. - - uint16_t raw_voltages[NUM_CHIPS][NUM_CELLS_PER_CHIP]; - - // printVoltages(TOTAL_IC, &IC[0], Cell); - - float voltage; - uint8_t ic = 0; - int16_t temp; - // number of cells - uint8_t channel = 16; - uint8_t type = Cell; - for (uint8_t index = 0; index < channel; index++) { - if (type == Cell) { - temp = IC[ic].cell.c_codes[index]; - } else if (type == AvgCell) { - temp = IC[ic].acell.ac_codes[index]; - } else if (type == F_volt) { - temp = IC[ic].fcell.fc_codes[index]; - } else if (type == S_volt) { - temp = IC[ic].scell.sc_codes[index]; - } else if (type == Aux) { - temp = IC[ic].aux.a_codes[index]; - } else if (type == RAux) { - temp = IC[ic].raux.ra_codes[index]; - } - - voltage = getVoltage(temp); - - raw_voltages[ic][index] = (uint16_t)temp; - - segment_data[ic].voltage[index] = raw_voltages[ic][index]; - - if (type == Cell) { - // printf("C%d=%fV= %d raw\r\n", (index + 1), voltage, - // segment_data[ic].voltage[index]); - if (index == (channel - 1)) { - // printf("CCount:%d,", IC[ic].cccrc.cmd_cntr); - // printf("PECError:%d", IC[ic].cccrc.cell_pec); - } - } - } - // printf("\n\n"); - - */ - - /* - float total_volts = 0; - for (int i = 0; i < 16; i++) { - printf("Raw %d: %f\n", i, getVoltage(segment_data[ic].voltage[i])); - total_volts += getVoltage(segment_data[ic].voltage[i]); - } - printf("TOTAL VOLTAGE: %f", total_volts);*/ - - /* - if (MEASURE_AVG_CELL == ENABLED) { - adBmsReadData(TOTAL_IC, &IC[0], RDACA, AvgCell, A); - adBmsReadData(TOTAL_IC, &IC[0], RDACB, AvgCell, B); - adBmsReadData(TOTAL_IC, &IC[0], RDACC, AvgCell, C); - adBmsReadData(TOTAL_IC, &IC[0], RDACD, AvgCell, D); - adBmsReadData(TOTAL_IC, &IC[0], RDACE, AvgCell, E); - adBmsReadData(TOTAL_IC, &IC[0], RDACF, AvgCell, F); - printVoltages(TOTAL_IC, &IC[0], AvgCell); - } - - if (MEASURE_F_CELL == ENABLED) { - adBmsReadData(TOTAL_IC, &IC[0], RDFCA, F_volt, A); - adBmsReadData(TOTAL_IC, &IC[0], RDFCB, F_volt, B); - adBmsReadData(TOTAL_IC, &IC[0], RDFCC, F_volt, C); - adBmsReadData(TOTAL_IC, &IC[0], RDFCD, F_volt, D); - adBmsReadData(TOTAL_IC, &IC[0], RDFCE, F_volt, E); - adBmsReadData(TOTAL_IC, &IC[0], RDFCF, F_volt, F); - printVoltages(TOTAL_IC, &IC[0], F_volt); - } */ - - /* - if (MEASURE_S_VOLTAGE == ENABLED) { - adBmsWakeupIc(TOTAL_IC); - adBmsReadData(TOTAL_IC, &IC[0], RDSVA, S_volt, A); - adBmsReadData(TOTAL_IC, &IC[0], RDSVB, S_volt, B); - adBmsReadData(TOTAL_IC, &IC[0], RDSVC, S_volt, C); - adBmsReadData(TOTAL_IC, &IC[0], RDSVD, S_volt, D); - adBmsReadData(TOTAL_IC, &IC[0], RDSVE, S_volt, E); - adBmsReadData(TOTAL_IC, &IC[0], RDSVF, S_volt, F); - printVoltages(TOTAL_IC, &IC[0], S_volt); - } */ - - /* - if (MEASURE_AUX == ENABLED) { - adBms6830_Adax(AUX_OW_OFF, - PUP_DOWN, AUX_ALL); - adBmsPollAdc(PLAUX1); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXA, Aux, A); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXB, Aux, B); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXC, Aux, C); - adBmsReadData(TOTAL_IC, &IC[0], RDAUXD, Aux, D); - printVoltages(TOTAL_IC, &IC[0], Aux); - } */ - - /* - if (MEASURE_RAUX == ENABLED) { - adBmsWakeupIc(TOTAL_IC); - adBms6830_Adax2(AUX_ALL); - adBmsPollAdc(PLAUX2); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXA, RAux, A); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXB, RAux, B); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXC, RAux, C); - adBmsReadData(TOTAL_IC, &IC[0], RDRAXD, RAux, D); - printVoltages(TOTAL_IC, &IC[0], RAux); - } */ - - /* - if (MEASURE_STAT == ENABLED) { - adBms6830_Adax(AUX_OW_OFF, - PUP_DOWN, AUX_ALL); - adBmsPollAdc(PLAUX1); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATA, Status, A); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATB, Status, B); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATC, Status, C); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATD, Status, D); - adBmsReadData(TOTAL_IC, &IC[0], RDSTATE, Status, E); - printStatus(TOTAL_IC, &IC[0], Status, ALL_GRP); - }*/ - - /* Start the timer between readings if successful */ - start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); -} - void segment_retrieve_data(acc_data_t *bmsdata) { // printf("Get C adc voltages\n"); @@ -742,18 +575,6 @@ void segment_configure_balancing( write_config_regs(bmsdata->chips); } -int8_t steinhart_est(uint16_t V) -{ - /* min temp - max temp with buffer on both */ - for (int i = -25; i < 80; i++) { - if (V > VOLT_TEMP_CONV[i + 25]) { - return i; - } - } - - return 80; -} - // void averaging_therm_check(chipdata_t segment_data[NUM_CHIPS]) // { // for (int therm = 1; therm <= 16; therm++) { diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index 22b52048..ff4b34b8 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -101,6 +101,7 @@ void init_charging(acc_data_t *bmsdata) return; } +// TODO: Improve algorithm. Change for new cells. Make more configurable. void handle_charging(acc_data_t *bmsdata) { if (!compute_charger_connected()) { @@ -159,9 +160,6 @@ void handle_faulted(acc_data_t *bmsdata) else { compute_set_fault(0); - - // TODO update to HAL - // digitalWrite(CHARGE_SAFETY_RELAY, 0); } return; } @@ -387,6 +385,7 @@ bool sm_charging_check(acc_data_t *bmsdata) } } +// TODO: Improve algorithm. bool sm_balancing_check(acc_data_t *bmsdata) { if (!compute_charger_connected()) @@ -444,6 +443,7 @@ void sm_broadcast_current_limit(acc_data_t *bmsdata) } } +//TODO: Improve algorithm void sm_balance_cells(acc_data_t *bmsdata) { bool balanceConfig[NUM_CHIPS][NUM_CELLS_ALPHA]; @@ -481,7 +481,7 @@ void sm_balance_cells(acc_data_t *bmsdata) void calculate_pwm(acc_data_t *bmsdata) { - // todo actually implement algorithm + // TODO: actually implement algorithm // this should include: // 1. set PWM based on temp of "nearby" cells // 2. automate seleciton of htim rather than hardcode From 74ae15d76f77255d7358e9787b6f3ff7a655db7c Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:16:27 -0500 Subject: [PATCH 22/32] Set up task and send function for debug mode per cell data --- Core/Inc/bmsConfig.h | 2 ++ Core/Inc/compute.h | 21 ++++++++++----------- Core/Inc/shep_tasks.h | 9 +++++++++ Core/Src/analyzer.c | 2 +- Core/Src/compute.c | 22 +++++++++------------- Core/Src/main.c | 5 +++++ Core/Src/shep_tasks.c | 31 +++++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 25 deletions(-) diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index f1f04b4f..fd6e6d8d 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -1,6 +1,8 @@ #ifndef BMS_CONFIG_H #define BMS_CONFIG_H +#define DEBUG_MODE_ENABLED true + // Hardware definition #define NUM_SEGMENTS 1 #define NUM_CHIPS 1 //NUM_SEGMENTS * 2 diff --git a/Core/Inc/compute.h b/Core/Inc/compute.h index 176da204..ba83d1ae 100644 --- a/Core/Inc/compute.h +++ b/Core/Inc/compute.h @@ -141,22 +141,21 @@ 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_voltage_message(acc_data_t *bmsdata); /** - * @brief sends cell voltage message + * @brief Send a message over CAN containing the data of an individual cell. * - * @param cell_id - * @param instant_volt - * @param internal_res - * @param shunted - * @param open_voltage + * @param cell_id The ID of the cell. + * @param instant_volt Raw cell voltage reading. + * @param internal_res Internal resistance of the cell. + * @param temperature Cell temperature. + * @param discharging Whether or not the cell is discharging while balancing. * - * @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); +void compute_send_cell_data_message(uint8_t cell_id, uint16_t instant_volt, + uint16_t internal_res, uint8_t shunted, + bool discharging); /** * @brief sends out the calculated values of currents diff --git a/Core/Inc/shep_tasks.h b/Core/Inc/shep_tasks.h index 6b9510be..da18dccd 100644 --- a/Core/Inc/shep_tasks.h +++ b/Core/Inc/shep_tasks.h @@ -49,4 +49,13 @@ void vStateMachine(void *pv_params); extern osThreadId_t state_machine_thread; extern const osThreadAttr_t state_machine_attrs; +/** + * @brief Task that handles all BMS debug mode functionalities. + * + * @param pv_params Pointer to accumulator data struct. + */ +void vDebugMode(void *pv_params); +extern osThreadId_t debug_mode_thread; +extern const osThreadAttr_t debug_mode_attrs; + #endif diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 01046e08..4a7fd020 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -345,7 +345,7 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) bmsdata->delt_ocv = bmsdata->max_ocv.val - bmsdata->min_ocv.val; compute_send_acc_status_message(bmsdata); - compute_send_cell_data_message(bmsdata); + compute_send_cell_voltage_message(bmsdata); } void calc_cell_resistances(acc_data_t *bmsdata) diff --git a/Core/Src/compute.c b/Core/Src/compute.c index b971f2bd..28cd71cb 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -330,8 +330,7 @@ void compute_send_bms_status_message(acc_data_t *bmsdata, int bms_state, 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); + bms_status_msg_data.balance = (uint8_t)(balance); /* convert to big endian */ endian_swap(&bms_status_msg_data.fault, @@ -357,7 +356,7 @@ void compute_send_shutdown_ctrl_message(uint8_t mpe_state) queue_can_msg(bms_can_msgs[SHUTDOWN_CTRL]); } -void compute_send_cell_data_message(acc_data_t *bmsdata) +void compute_send_cell_voltage_message(acc_data_t *bmsdata) { struct __attribute__((__packed__)) { uint16_t high_cell_voltage; @@ -390,32 +389,29 @@ void compute_send_cell_data_message(acc_data_t *bmsdata) queue_can_msg(bms_can_msgs[CELL_DATA]); } -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_data_message(uint8_t cell_id, uint16_t instant_voltage, + uint16_t internal_Res, uint8_t temperature, + bool discharging) { struct __attribute__((__packed__)) { uint8_t cellID; uint16_t instantVoltage; uint16_t internalResistance; - uint8_t shunted; - uint16_t openVoltage; + int8_t temperature; + bool discharging; } 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; + cell_voltage_msg_data.temperature = temperature; + cell_voltage_msg_data.discharging = discharging; /* 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)); memcpy(bms_can_msgs[CELL_VOLTAGE].data, &cell_voltage_msg_data, sizeof(cell_voltage_msg_data)); diff --git a/Core/Src/main.c b/Core/Src/main.c index a6ee22b2..116447df 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -395,6 +395,11 @@ int main(void) state_machine_thread = osThreadNew(vStateMachine, acc_data, &state_machine_attrs); assert(state_machine_thread); + if (DEBUG_MODE_ENABLED) { + debug_mode_thread = osThreadNew(vDebugMode, acc_data, &debug_mode_attrs); + assert(debug_mode_thread); + } + /* USER CODE END RTOS_THREADS */ /* USER CODE BEGIN RTOS_EVENTS */ diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index c9909af2..030774d5 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -100,3 +100,34 @@ void vStateMachine(void *pv_params) osDelay(10); } } + +osThreadId_t debug_mode_thread; +const osThreadAttr_t debug_mode_attrs = { .name = "Debug Mode Thread", + .stack_size = 2048, + .priority = osPriorityNormal }; +void vDebugMode(void *pv_params) +{ + acc_data_t *bmsdata = (acc_data_t *)pv_params; + + while (69 < 420) { + int cell_ID = 0; + + for (int c = 0; c < NUM_CHIPS; c++) { + uint8_t num_cells = + get_num_cells(&bmsdata->chip_data[c]); + for (int cell = 0; cell < num_cells; cell++) { + compute_send_cell_data_message( + cell_ID, + bmsdata->chips[c].cell.c_codes[cell], + bmsdata->chip_data[c] + .cell_resistance[cell], + bmsdata->chip_data[c].cell_temp[cell], + (bmsdata->chips[cell].tx_cfgb.dcc >> + cell) & 1u); + cell_ID += 1; + + osDelay(6); + } + } + } +} \ No newline at end of file From a44b4767fad276014b154f85e2b99aa091ac9795 Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Fri, 17 Jan 2025 08:17:25 -0500 Subject: [PATCH 23/32] debug mode create task and CAN message functions --- Core/Inc/can_handler.h | 11 +++ Core/Inc/compute.h | 90 ++++++++++++++++++---- Core/Src/compute.c | 164 +++++++++++++++++++++++++++++++++-------- Core/Src/shep_tasks.c | 37 +++++++--- Drivers/Embedded-Base | 2 +- 5 files changed, 248 insertions(+), 56 deletions(-) diff --git a/Core/Inc/can_handler.h b/Core/Inc/can_handler.h index 02c0b802..b5987b2b 100644 --- a/Core/Inc/can_handler.h +++ b/Core/Inc/can_handler.h @@ -25,6 +25,17 @@ #define FAULT_CANID 0x703 #define NOISE_CANID 0x88 #define DEBUG_CANID 0x702 +#define ALPHA_CELL_CANID 0x6FA +#define BETA_CELL_CANID 0x6FB +#define CELL_MSG_SIZE 7 +#define BETA_STAT_A_CANID 0x6FD +#define BETA_STAT_A_SIZE 8 +#define BETA_STAT_B_CANID 0x6FE +#define BETA_STAT_B_SIZE 8 +#define ALPHA_STAT_A_CANID 0x6FC +#define ALPHA_STAT_A_SIZE 7 +#define ALPHA_STAT_B_CANID 0x6FF +#define ALPHA_STAT_B_SIZE 7 typedef struct { uint32_t prev_tick; diff --git a/Core/Inc/compute.h b/Core/Inc/compute.h index ba83d1ae..7bcfb0c8 100644 --- a/Core/Inc/compute.h +++ b/Core/Inc/compute.h @@ -143,20 +143,6 @@ void compute_send_shutdown_ctrl_message(uint8_t mpe_state); */ void compute_send_cell_voltage_message(acc_data_t *bmsdata); -/** - * @brief Send a message over CAN containing the data of an individual cell. - * - * @param cell_id The ID of the cell. - * @param instant_volt Raw cell voltage reading. - * @param internal_res Internal resistance of the cell. - * @param temperature Cell temperature. - * @param discharging Whether or not the cell is discharging while balancing. - * - */ -void compute_send_cell_data_message(uint8_t cell_id, uint16_t instant_volt, - uint16_t internal_res, uint8_t shunted, - bool discharging); - /** * @brief sends out the calculated values of currents * @@ -203,4 +189,80 @@ void compute_send_debug_message(uint8_t debug0, uint8_t debug1, uint16_t debug2, */ void compute_send_voltage_noise_message(acc_data_t *bmsdata); +/** + * @brief Send a message containing cell data. + * + * @param alpha If this message contains alpha cell data. False sends a beta cell message. + * @param temperature Temperature in Celsius. Has a maximum value of 80 degrees celsius. + * @param voltage_a The voltage of cell A. + * @param voltage_b The voltage of cell B. + * @param chip_ID The chip ID. + * @param cell_a The number of cell A. + * @param cell_b The number of cell B. + * @param discharging_a The state of cell A while balancing. + * @param discharging_b The state of cell B while balancing. + */ +void compute_send_cell_data_message(bool alpha, uint16_t temperature, + uint16_t voltage_a, uint16_t voltage_b, + uint8_t chip_ID, uint8_t cell_a, + uint8_t cell_b, bool discharging_a, + bool discharging_b); + +/** + * @brief Send cell message containing Beta cell 10, the Beta onboard therm, the temperature of the ADBMS6830 die, and the voltage from V+ to V-. + * + * @param cell_temperature Temperature of Beta cell 10. + * @param voltage Voltage of Beta cell 10. + * @param discharging Whether or not the cell is discharging. + * @param chip The ID of the chip. + * @param segment_temperature The output of the onboard therm. + * @param die_temperature The temperature of the ADBMS6830 die. + * @param vpv The voltage from V+ to V-. + */ +void compute_send_beta_status_a_message(uint16_t cell_temperature, + uint16_t voltage, bool discharging, + uint8_t chip, + uint16_t segment_temperature, + uint16_t die_temperature, uint16_t vpv); + +/** + * @brief Send message containing ADBMS6830 diagnostic data. + * + * @param vref2 Second reference voltage for ADBMS6830. + * @param v_analog Analog power supply voltage. + * @param v_digital Digital power supply voltage. + * @param chip ID of the chip. + * @param v_res VREF2 across a resistor for open wire detection. + * @param vmv Voltage between S1N and V-. + */ +void compute_send_beta_status_b_message(uint16_t vref2, uint16_t v_analog, + uint16_t v_digital, uint8_t chip, + uint16_t v_res, uint16_t vmv); + +/** + * @brief Send message containing ADBMS6830 diagnostic data and onboard therm data. + * + * @param segment_temp Temperature reading from on-board therm. + * @param chip ID of the chip. + * @param die_temperature Temperature of the ADBOS6830 die. + * @param vpv The voltage from V+ to V-. + * @param vmv Voltage between S1N and V-. + */ +void compute_send_alpha_status_a_message(uint16_t segment_temp, uint8_t chip, + uint16_t die_temperature, uint16_t vpv, + uint16_t vmv); + +/** + * @brief Send message containing ADBMS6830 diagnostic data. + * + * @param v_res VREF2 across a resistor for open wire detection. + * @param chip ID of the chip. + * @param vref2 Second reference voltage for ADBMS6830. + * @param v_analog Analog power supply voltage. + * @param v_digital Digital power supply voltage. + */ +void compute_send_alpha_status_b_message(uint16_t v_res, uint8_t chip, + uint16_t vref2, uint16_t v_analog, + uint16_t v_digital); + #endif // COMPUTE_H diff --git a/Core/Src/compute.c b/Core/Src/compute.c index 28cd71cb..018e4271 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -389,36 +389,6 @@ void compute_send_cell_voltage_message(acc_data_t *bmsdata) queue_can_msg(bms_can_msgs[CELL_DATA]); } -void compute_send_cell_data_message(uint8_t cell_id, uint16_t instant_voltage, - uint16_t internal_Res, uint8_t temperature, - bool discharging) -{ - struct __attribute__((__packed__)) { - uint8_t cellID; - uint16_t instantVoltage; - uint16_t internalResistance; - int8_t temperature; - bool discharging; - } 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.temperature = temperature; - cell_voltage_msg_data.discharging = discharging; - - /* 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)); - - memcpy(bms_can_msgs[CELL_VOLTAGE].data, &cell_voltage_msg_data, - sizeof(cell_voltage_msg_data)); - - queue_can_msg(bms_can_msgs[CELL_VOLTAGE]); -} - void compute_send_current_message(acc_data_t *bmsdata) { struct __attribute__((__packed__)) { @@ -583,6 +553,138 @@ void compute_send_debug_message(uint8_t debug0, uint8_t debug1, uint16_t debug2, queue_can_msg(bms_can_msgs[DEBUG]); } +void compute_send_cell_data_message(bool alpha, uint16_t temperature, + uint16_t voltage_a, uint16_t voltage_b, + uint8_t chip_ID, uint8_t cell_a, + uint8_t cell_b, bool discharging_a, + bool discharging_b) +{ + endian_swap(&temperature, sizeof(temperature)); + endian_swap(&voltage_a, sizeof(voltage_a)); + endian_swap(&voltage_b, sizeof(voltage_b)); + + can_msg_t msg; + if (alpha) { + msg.id = ALPHA_CELL_CANID; + } else { + msg.id = BETA_CELL_CANID; + } + msg.len = CELL_MSG_SIZE; + + msg.data[0] = (temperature >> 2); + msg.data[1] = (temperature << 8) | (voltage_a >> 7); + msg.data[2] = (voltage_a << 6) | (voltage_b >> 12); + msg.data[3] = (voltage_b << 1); + msg.data[4] = (voltage_b << 9) | chip_ID; + msg.data[5] = (cell_a << 4) | cell_b; + msg.data[6] = (discharging_a << 7) | (discharging_b << 6); + + queue_can_msg(msg); +} + +void compute_send_beta_status_a_message(uint16_t cell_temperature, + uint16_t voltage, bool discharging, + uint8_t chip, + uint16_t segment_temperature, + uint16_t die_temperature, uint16_t vpv) +{ + endian_swap(&cell_temperature, sizeof(cell_temperature)); + endian_swap(&voltage, sizeof(voltage)); + endian_swap(&segment_temperature, sizeof(segment_temperature)); + endian_swap(&die_temperature, sizeof(die_temperature)); + endian_swap(&vpv, sizeof(vpv)); + + can_msg_t msg; + msg.id = BETA_STAT_A_CANID; + msg.len = BETA_STAT_A_SIZE; + + msg.data[0] = cell_temperature >> 2; + msg.data[1] = (cell_temperature << 8) | (voltage >> 7); + msg.data[2] = (voltage << 6) | discharging; + msg.data[3] = (chip << 4) | segment_temperature >> 6; + msg.data[4] = (segment_temperature << 4) | (die_temperature >> 11); + msg.data[5] = die_temperature >> 3; + msg.data[6] = (die_temperature << 10) | (vpv >> 8); + msg.data[7] = vpv >> 5; + + queue_can_msg(msg); +} + +void compute_send_beta_status_b_message(uint16_t vref2, uint16_t v_analog, + uint16_t v_digital, uint8_t chip, + uint16_t v_res, uint16_t vmv) +{ + endian_swap(&vref2, sizeof(vref2)); + endian_swap(&v_analog, sizeof(v_analog)); + endian_swap(&v_digital, sizeof(v_digital)); + endian_swap(&v_res, sizeof(v_res)); + endian_swap(&vmv, sizeof(vmv)); + + can_msg_t msg; + msg.id = BETA_STAT_B_CANID; + msg.len = BETA_STAT_B_SIZE; + + msg.data[0] = vref2 >> 5; + msg.data[1] = (vref2 << 8) | (v_analog >> 7); + msg.data[2] = (v_analog << 3) | (v_digital >> 9); + msg.data[3] = v_digital << 1; + msg.data[4] = (v_digital << 9) | (chip << 3) | (v_res >> 10); + msg.data[5] = v_res << 3; + msg.data[6] = (v_res << 11) | (vmv >> 8); + msg.data[7] = vmv << 5; + + queue_can_msg(msg); +} + +void compute_send_alpha_status_a_message(uint16_t segment_temp, uint8_t chip, + uint16_t die_temperature, uint16_t vpv, + uint16_t vmv) +{ + endian_swap(&segment_temp, sizeof(segment_temp)); + endian_swap(&die_temperature, sizeof(die_temperature)); + endian_swap(&vpv, sizeof(vpv)); + endian_swap(&vmv, sizeof(vmv)); + + can_msg_t msg; + msg.id = ALPHA_STAT_A_CANID; + msg.len = ALPHA_STAT_A_SIZE; + + msg.data[0] = segment_temp >> 2; + msg.data[1] = (segment_temp << 8) | (chip << 2) | + (die_temperature >> 11); + msg.data[2] = die_temperature << 2; + msg.data[3] = (die_temperature << 10) | (vpv >> 8); + msg.data[4] = vpv << 5; + msg.data[5] = vmv >> 5; + msg.data[6] = vmv << 8; + + queue_can_msg(msg); +} + +void compute_send_alpha_status_b_message(uint16_t v_res, uint8_t chip, + uint16_t vref2, uint16_t v_analog, + uint16_t v_digital) +{ + endian_swap(&v_res, sizeof(v_res)); + endian_swap(&vref2, sizeof(vref2)); + endian_swap(&v_analog, sizeof(v_analog)); + endian_swap(&v_digital, sizeof(v_digital)); + + can_msg_t msg; + msg.id = ALPHA_STAT_B_CANID; + msg.len = ALPHA_STAT_B_SIZE; + + msg.data[0] = v_res >> 5; + msg.data[1] = (v_res << 8) | (chip >> 1); + msg.data[2] = (chip << 7) | (vref2 >> 6); + msg.data[3] = (vref2 << 7) | (v_analog >> 11); + msg.data[4] = v_analog >> 3; + msg.data[6] = (v_analog << 10) | (v_digital >> 8); + msg.data[7] = v_analog << 5; + + queue_can_msg(msg); +} + void change_adc1_channel(uint8_t channel) { ADC_ChannelConfTypeDef sConfig = { 0 }; @@ -597,4 +699,4 @@ void change_adc1_channel(uint8_t channel) if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } -} +} \ No newline at end of file diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index 030774d5..ded20e69 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -15,6 +15,7 @@ #include "analyzer.h" #include "compute.h" #include +#include "serialPrintResult.h" #define STATE_MACHINE_FLAG 1 @@ -110,22 +111,38 @@ void vDebugMode(void *pv_params) acc_data_t *bmsdata = (acc_data_t *)pv_params; while (69 < 420) { - int cell_ID = 0; - for (int c = 0; c < NUM_CHIPS; c++) { uint8_t num_cells = get_num_cells(&bmsdata->chip_data[c]); - for (int cell = 0; cell < num_cells; cell++) { + for (int cell = 0; cell < num_cells; cell += 2) { compute_send_cell_data_message( - cell_ID, - bmsdata->chips[c].cell.c_codes[cell], - bmsdata->chip_data[c] - .cell_resistance[cell], + bmsdata->chip_data[c].alpha, + bmsdata->chip_data[c].cell_temp[cell], - (bmsdata->chips[cell].tx_cfgb.dcc >> - cell) & 1u); - cell_ID += 1; + 10000 * getVoltage( + bmsdata->chips[c] + .cell + .c_codes[cell]), + + 10000 * getVoltage( + bmsdata->chips[c] + .cell + .c_codes[cell + + 1]), + + c, + + cell, + + cell + 1, + + (bmsdata->chips[c].tx_cfgb.dcc >> + cell) & 1, + + (bmsdata->chips[c].tx_cfgb.dcc >> + (cell + 1)) & + 1); osDelay(6); } } diff --git a/Drivers/Embedded-Base b/Drivers/Embedded-Base index f6ffa63e..4f5c2501 160000 --- a/Drivers/Embedded-Base +++ b/Drivers/Embedded-Base @@ -1 +1 @@ -Subproject commit f6ffa63e1dc78f1cdff5c0196e2a43e901b8d0f6 +Subproject commit 4f5c25018ede00b10343a099f715e19bd1f95837 From 6e34ff5c1085984a6cf6df5082dd252256b9d48c Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:38:04 -0500 Subject: [PATCH 24/32] adbms S vs C ADC comparison and PEC error count --- Core/Src/segment.c | 75 ++++++++++++++++++++++++++++++++++--------- Drivers/Embedded-Base | 2 +- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/Core/Src/segment.c b/Core/Src/segment.c index d63c9c32..f3880512 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -5,6 +5,7 @@ #include #include #include "analyzer.h" +#include "c_utils.h" #include "common.h" #include "adBms6830CmdList.h" @@ -34,21 +35,10 @@ extern SPI_HandleTypeDef hspi1; uint8_t therm_avg_counter = 0; chipdata_t previous_data[NUM_CHIPS] = {}; -uint16_t discharge_commands[NUM_CHIPS] = {}; -nertimer_t therm_timer; nertimer_t variance_timer; -int therm_error = 0; // not faulted -uint16_t crc_error_check = 0; - -/* 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 }; - -uint16_t therm_settle_time_ = 0; - -const int32_t VOLT_TEMP_CALIB_OFFSET = 0; +uint32_t pec_error_count = 0; /* private function prototypes */ void variance_therm_check(void); @@ -353,6 +343,23 @@ void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, GRP group) { adBmsReadData(NUM_CHIPS, chips, command, type, group); + + // Count PEC errors + for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { + // Yes, they did separate every PEC as if that mattered. + pec_error_count += + chips[chip].cccrc.cfgr_pec + chips[chip].cccrc.sid_pec + + chips[chip].cccrc.cell_pec + + chips[chip].cccrc.acell_pec + + chips[chip].cccrc.scell_pec + + chips[chip].cccrc.fcell_pec + + chips[chip].cccrc.aux_pec + chips[chip].cccrc.raux_pec + + chips[chip].cccrc.stat_pec + + chips[chip].cccrc.comm_pec + chips[chip].cccrc.pwm_pec; + if (pec_error_count > 0) { + printf("PEC COUNT: %ld\n", pec_error_count); + } + } } /** @@ -392,13 +399,13 @@ void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]) write_config_regs(chips); // Take single shot measurement - adBms6830_Adcv(RD_ON, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBms6830_Adcv(RD_OFF, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); read_adbms_data(chips, RDCVALL, Rdcvall, ALL_GRP); } /** - * @brief Get voltages from the S-ADCs. + * @brief Get voltages from the S-ADCs. Makes a single shot measurement. * * @param chip Array of chips to get voltage readings from. */ @@ -406,7 +413,7 @@ void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) { write_config_regs(chips); adbms_wake(); - adBms6830_Adsv(CONTINUOUS, DCP_OFF, OW_OFF_ALL_CH); + adBms6830_Adsv(SINGLE, DCP_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLSADC); adbms_wake(); @@ -419,6 +426,44 @@ void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) // read_adbms_data(chip, RDSVF, S_volt, F); } +/** + * @brief Do a single shot, redundant C-ADC measurement and read + * the contents of Status Register Group C, which contains the + * CSxFLT bits indicating whether the difference between the + * C and S ADC measurements was above the CTH[2:0] set in config + * register A. + * + * @param chips Pointer to accumulator data struct. + */ +void get_adc_comparison(acc_data_t *bmsdata) +{ + write_config_regs(chips); + + // Take single shot measurement + adBms6830_Adcv(RD_ON, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); + read_adbms_data(chips, RDCVALL, Rdcvall, ALL_GRP); + + // Result of C-ADC and S-ADC comparison is stored in status register group C + read_adbms_data(chips, RDSTATC, Status, C); + + for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { + uint8_t cells = get_num_cells(bmsdata->chip_data[chip]); + for (uint8_t cell = 0; cell < cells; cell++) { + if (NER_GET_BIT(bmsdata->chips[chip].statc.cs_flt, + cell)) { + printf("ADC VOLTAGE DISCREPANCY ERROR\nChip %d, Cell %d\nC-ADC: %f, S-ADC%f\n", + chip + 1, cell + 1, + getVoltage(bmsdata->chips[chip] + .cell.c_codes[cell]), + getVoltage( + bmsdata->chips[chip] + .scell.sc_codes[cell])); + } + } + } +} + /** * @brief Get the avgeraged cell voltages. * diff --git a/Drivers/Embedded-Base b/Drivers/Embedded-Base index f6ffa63e..4f5c2501 160000 --- a/Drivers/Embedded-Base +++ b/Drivers/Embedded-Base @@ -1 +1 @@ -Subproject commit f6ffa63e1dc78f1cdff5c0196e2a43e901b8d0f6 +Subproject commit 4f5c25018ede00b10343a099f715e19bd1f95837 From 0c881b148cca0d0ad417e38dc88a3d728dbde4ec Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sat, 18 Jan 2025 17:04:22 -0500 Subject: [PATCH 25/32] adbms debug mode stuff --- Core/Inc/datastructs.h | 3 ++ Core/Inc/segment.h | 25 ++++++++++++ Core/Src/analyzer.c | 37 +++++++++++++---- Core/Src/main.c | 5 +-- Core/Src/segment.c | 74 ++++++++++++++++++++++------------ Core/Src/shep_tasks.c | 90 +++++++++++++++++++++++++++++++++++++----- 6 files changed, 189 insertions(+), 45 deletions(-) diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index f3e19b4e..d923ed4c 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -29,6 +29,9 @@ typedef struct { /* True if chip is alpha, False if Chip is Beta */ bool alpha; + + /* For temperatures of on-board therms. Length 1 if Alpha, length 2 if Beta. */ + int8_t on_board_temp; } chipdata_t; /** diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index 7c5f7ef8..98033d7e 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -50,4 +50,29 @@ bool cell_is_balancing(uint8_t chip_num, uint8_t cell_num); */ bool segment_is_balancing(cell_asic chips[NUM_CHIPS]); +/** + * @brief Do a single shot, redundant C-ADC measurement and read + * the contents of Status Register Group C, which contains the + * CSxFLT bits indicating whether the difference between the + * C and S ADC measurements was above the CTH[2:0] set in config + * register A. + * + * @param chips Pointer to accumulator data struct. + */ +void get_adc_comparison(acc_data_t *bmsdata); + +/** + * @brief Read the serial ID of the chip. + * + * @param chips Array of chips to read. + */ +void read_serial_id(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Read voltages in every register connected to AUX2 ADC. + * + * @param chips Array of chips to get voltages of. + */ +void read_aux2_registers(cell_asic chips[NUM_CHIPS]); + #endif \ No newline at end of file diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 4a7fd020..e318b6c5 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -149,10 +149,21 @@ uint8_t get_num_cells(chipdata_t *chip_data) } } +/** + * @brief Calculate a cell temperature based on the thermistor reading. + * + * @param x The thremistor reading. + * @return int8_t Temperature in celsius. + */ +int8_t calc_cell_temp(uint16_t x) +{ + /* Polynomial fit of temperatures -7 -> 65 celsius vs. thermistor voltage. */ + return 0.6984 * pow(x, 4) + 4.4933 * pow(x, 3) - 10.278 * pow(x, 2) + + 34.184 * x + 2.7608; +} + void calc_cell_temps(acc_data_t *bmsdata) { - // TODO: DELETE THIS JUST USING FOR PROFILING HOW LONG THIS SHIT TAKES - uint32_t start = HAL_GetTick(); for (int chip = 0; chip < NUM_CHIPS; chip++) { uint8_t num_cells = get_num_cells(&bmsdata->chip_data[chip]); @@ -160,13 +171,25 @@ void calc_cell_temps(acc_data_t *bmsdata) int16_t x = bmsdata->chips[chip] .aux.a_codes[THERM_MAP[cell]]; - /* Polynomial fit of temperatures -7 -> 65 celsius vs. thermistor voltage. */ - int8_t temp = 0.6984 * pow(x, 4) + 4.4933 * pow(x, 3) - - 10.278 * pow(x, 2) + 34.184 * x + 2.7608; - bmsdata->chip_data[chip].cell_temp[cell] = temp; + bmsdata->chip_data[chip].cell_temp[cell] = + calc_cell_temp(x); + } + + // Calculate onboard therm temps + + if (!bmsdata->chip_data[chip].alpha) { + // Take average of both onboard therms + bmsdata->chip_data[chip].on_board_temp = + (calc_cell_temp(( + bmsdata->chips[chip].aux.a_codes[6])) + + calc_cell_temp( + bmsdata->chips[chip].aux.a_codes[7])) / + 2; + } else { + bmsdata->chip_data[chip].on_board_temp = calc_cell_temp( + bmsdata->chips[chip].aux.a_codes[7]); } } - printf("%ld\n", HAL_GetTick() - start); /* diff --git a/Core/Src/main.c b/Core/Src/main.c index 116447df..d0cc9a0d 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -40,7 +40,7 @@ //#ifdef DEBUG_EVERYTHING //#define DEBUG_CHARGING -#define DEBUG_STATS +// #define DEBUG_STATS #define DEBUG_VOLTAGES // #define DEBUG_RAW_VOLTAGES #define DEBUG_RAW_VOLTAGES_FORMATTED @@ -380,6 +380,7 @@ int main(void) /* Messaging */ can_dispatch_handle = osThreadNew(vCanDispatch, &hcan1, &can_dispatch_attributes); assert(can_dispatch_handle); + can_receive_thread = osThreadNew(vCanReceive, NULL, &can_receive_attributes); assert(can_receive_thread); @@ -1239,9 +1240,7 @@ void watchdog_pet(void) void StartDefaultTask(void *argument) { /* USER CODE BEGIN 5 */ - #ifdef DEBUG_STATS acc_data_t* bmsdata = (acc_data_t*) argument; - #endif bool alt = true; diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 20d57ff4..6ef3c77a 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -34,8 +34,6 @@ extern SPI_HandleTypeDef hspi1; uint8_t therm_avg_counter = 0; -chipdata_t previous_data[NUM_CHIPS] = {}; - nertimer_t variance_timer; uint32_t pec_error_count = 0; @@ -357,9 +355,23 @@ void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, chips[chip].cccrc.stat_pec + chips[chip].cccrc.comm_pec + chips[chip].cccrc.pwm_pec; if (pec_error_count > 0) { - printf("PEC COUNT: %ld\n", pec_error_count); + printf("PEC COUNT: %ld | Chip: %d | CMD: %d\n", + pec_error_count, chip, type); } + + chips[chip].cccrc.cfgr_pec = 0; + chips[chip].cccrc.sid_pec = 0; + chips[chip].cccrc.cell_pec = 0; + chips[chip].cccrc.acell_pec = 0; + chips[chip].cccrc.scell_pec = 0; + chips[chip].cccrc.fcell_pec = 0; + chips[chip].cccrc.aux_pec = 0; + chips[chip].cccrc.raux_pec = 0; + chips[chip].cccrc.stat_pec = 0; + chips[chip].cccrc.comm_pec = 0; + chips[chip].cccrc.pwm_pec = 0; } + pec_error_count = 0; } /** @@ -384,7 +396,7 @@ void segment_init(acc_data_t *bmsdata) for (int chip = 0; chip < NUM_CHIPS; chip++) { init_chip(&bmsdata->chips[chip]); // TODO: Make sure this is accurate - bmsdata->chip_data->alpha = chip % 2 == 0; + bmsdata->chip_data[chip].alpha = chip % 2 == 0; } write_config_regs(bmsdata->chips); } @@ -426,17 +438,10 @@ void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) // read_adbms_data(chip, RDSVF, S_volt, F); } -/** - * @brief Do a single shot, redundant C-ADC measurement and read - * the contents of Status Register Group C, which contains the - * CSxFLT bits indicating whether the difference between the - * C and S ADC measurements was above the CTH[2:0] set in config - * register A. - * - * @param chips Pointer to accumulator data struct. - */ void get_adc_comparison(acc_data_t *bmsdata) { + // TODO: S-ADC measurements are all over the place. + write_config_regs(bmsdata->chips); // Take single shot measurement @@ -452,7 +457,7 @@ void get_adc_comparison(acc_data_t *bmsdata) for (uint8_t cell = 0; cell < cells; cell++) { if (NER_GET_BIT(bmsdata->chips[chip].statc.cs_flt, cell)) { - printf("ADC VOLTAGE DISCREPANCY ERROR\nChip %d, Cell %d\nC-ADC: %f, S-ADC%f\n", + printf("ADC VOLTAGE DISCREPANCY ERROR\nChip %d, Cell %d\nC-ADC: %f, S-ADC: %f\n", chip + 1, cell + 1, getVoltage(bmsdata->chips[chip] .cell.c_codes[cell]), @@ -551,9 +556,9 @@ void read_aux2_registers(cell_asic chips[NUM_CHIPS]) /** * @brief Read status registers. * - * @param chips Array of chips to read voltages of. + * @param chips Array of chips to read. */ -void adBms6830_read_status_registers(cell_asic chips[NUM_CHIPS]) +void read_status_registers(cell_asic chips[NUM_CHIPS]) { write_config_regs(chips); adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); @@ -566,23 +571,40 @@ void adBms6830_read_status_registers(cell_asic chips[NUM_CHIPS]) read_adbms_data(chips, RDSTATE, Status, E); } +/** + * @brief Read status and aux registers in one command. + * + * @param chips Array of chips to read. + */ +void read_status_aux_registers(cell_asic chips[NUM_CHIPS]) +{ + write_config_regs(chips); + adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); + adBmsPollAdc(PLAUX1); + + read_adbms_data(chips, RDASALL, Rdasall, ALL_GRP); +} + +/** + * @brief Read the serial ID of the chip. + * + * @param chips Array of chips to read. + */ +void read_serial_id(cell_asic chips[NUM_CHIPS]) +{ + read_adbms_data(chips, RDSID, Sid, NONE); +} + void segment_retrieve_data(acc_data_t *bmsdata) { // printf("Get C adc voltages\n"); get_c_adc_voltages(bmsdata->chips); - // get_s_adc_voltages(bmsdata->chips); - // The GPIOs in the AUX registers contain voltage readings from the therms. - // printf("Get therms\n"); - read_aux_registers(bmsdata->chips); - // If you want redundant Thermistor readings, uncomment the following. - read_aux2_registers(bmsdata->chips); + read_status_aux_registers(bmsdata->chips); - /* Save the contents of the reading so that we can use it to fill in missing - * data */ - memcpy(previous_data, bmsdata->chip_data, - sizeof(chipdata_t) * NUM_CHIPS); + // If you want redundant Thermistor readings, uncomment the following. + // read_aux2_registers(bmsdata->chips); } bool segment_is_balancing(cell_asic chips[NUM_CHIPS]) diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index ded20e69..0438a325 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -111,40 +111,112 @@ void vDebugMode(void *pv_params) acc_data_t *bmsdata = (acc_data_t *)pv_params; while (69 < 420) { - for (int c = 0; c < NUM_CHIPS; c++) { + // get_adc_comparison(bmsdata); + + // read_serial_id(bmsdata->chips); + + read_aux2_registers(bmsdata->chips); + + for (int chip = 0; chip < NUM_CHIPS; chip++) { uint8_t num_cells = - get_num_cells(&bmsdata->chip_data[c]); + get_num_cells(&bmsdata->chip_data[chip]); for (int cell = 0; cell < num_cells; cell += 2) { compute_send_cell_data_message( - bmsdata->chip_data[c].alpha, + bmsdata->chip_data[chip].alpha, - bmsdata->chip_data[c].cell_temp[cell], + bmsdata->chip_data[chip].cell_temp[cell], 10000 * getVoltage( - bmsdata->chips[c] + bmsdata->chips[chip] .cell .c_codes[cell]), 10000 * getVoltage( - bmsdata->chips[c] + bmsdata->chips[chip] .cell .c_codes[cell + 1]), - c, + chip, cell, cell + 1, - (bmsdata->chips[c].tx_cfgb.dcc >> + (bmsdata->chips[chip].tx_cfgb.dcc >> cell) & 1, - (bmsdata->chips[c].tx_cfgb.dcc >> + (bmsdata->chips[chip].tx_cfgb.dcc >> (cell + 1)) & 1); osDelay(6); } + + // Send chip status messages + if (!bmsdata->chip_data[chip].alpha) { + compute_send_beta_status_a_message( + 10000 * getVoltage( + bmsdata->chip_data[chip] + .cell_temp[10]), + 10000 * getVoltage( + bmsdata->chips[chip] + .cell + .c_codes[10]), + NER_GET_BIT( + bmsdata->chips[chip].tx_cfgb.dcc, + 10), + chip, + bmsdata->chip_data[chip].on_board_temp, + (getVoltage(bmsdata->chips[chip] + .stata.itmp) / + 0.0075) - + 273, + 10000 * getVoltage( + bmsdata->chips[chip] + .raux + .ra_codes[9])); + compute_send_beta_status_b_message( + 10000 * getVoltage( + bmsdata->chips[chip] + .stata.vref2), + 10000 * getVoltage(bmsdata->chips[chip] + .statb.va), + 10000 * getVoltage(bmsdata->chips[chip] + .statb.vd), + chip, + 10000 * getVoltage(bmsdata->chips[chip] + .statb.vr4k), + 10000 * getVoltage( + bmsdata->chips[chip] + .raux + .ra_codes[8])); + } else { + compute_send_alpha_status_a_message( + bmsdata->chip_data->on_board_temp, chip, + (getVoltage(bmsdata->chips[chip] + .stata.itmp) / + 0.0075) - + 273, + 10000 * getVoltage( + bmsdata->chips[chip] + .raux + .ra_codes[9]), + 10000 * getVoltage( + bmsdata->chips[chip] + .raux + .ra_codes[8])); + compute_send_alpha_status_b_message( + 10000 * getVoltage(bmsdata->chips[chip] + .statb.vr4k), + chip, + 10000 * getVoltage( + bmsdata->chips[chip] + .stata.vref2), + 10000 * getVoltage(bmsdata->chips[chip] + .statb.va), + 10000 * getVoltage(bmsdata->chips[chip] + .statb.vd)); + } } } } \ No newline at end of file From 6f56377a2f3498bd0e6fbd221d943dc4b30e9f0e Mon Sep 17 00:00:00 2001 From: Scott A <89099102+Sabramz@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:19:07 -0500 Subject: [PATCH 26/32] adbms change debug mode CAN messages to use bit fields --- Core/Src/compute.c | 125 +++++++++++++++++++++++++++++++-------------- Core/Src/segment.c | 1 + 2 files changed, 88 insertions(+), 38 deletions(-) diff --git a/Core/Src/compute.c b/Core/Src/compute.c index 018e4271..067ebd46 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -563,6 +563,26 @@ void compute_send_cell_data_message(bool alpha, uint16_t temperature, endian_swap(&voltage_a, sizeof(voltage_a)); endian_swap(&voltage_b, sizeof(voltage_b)); + struct __attribute__((__packed__)) { + uint16_t temperature : 10; + uint16_t voltage_a : 13; + uint16_t voltage_b : 13; + uint8_t chip_ID : 4; + uint8_t cell_a : 4; + uint8_t cell_b : 4; + uint8_t discharging_a : 1; + uint8_t discharging_b : 1; + } cell_data_msg_data; + + cell_data_msg_data.temperature = temperature; + cell_data_msg_data.voltage_a = voltage_a; + cell_data_msg_data.voltage_b = voltage_b; + cell_data_msg_data.chip_ID = chip_ID; + cell_data_msg_data.cell_a = cell_a; + cell_data_msg_data.cell_b = cell_b; + cell_data_msg_data.discharging_a = discharging_a; + cell_data_msg_data.discharging_b = discharging_b; + can_msg_t msg; if (alpha) { msg.id = ALPHA_CELL_CANID; @@ -571,13 +591,7 @@ void compute_send_cell_data_message(bool alpha, uint16_t temperature, } msg.len = CELL_MSG_SIZE; - msg.data[0] = (temperature >> 2); - msg.data[1] = (temperature << 8) | (voltage_a >> 7); - msg.data[2] = (voltage_a << 6) | (voltage_b >> 12); - msg.data[3] = (voltage_b << 1); - msg.data[4] = (voltage_b << 9) | chip_ID; - msg.data[5] = (cell_a << 4) | cell_b; - msg.data[6] = (discharging_a << 7) | (discharging_b << 6); + memcpy(msg.data, &cell_data_msg_data, CELL_MSG_SIZE); queue_can_msg(msg); } @@ -594,18 +608,29 @@ void compute_send_beta_status_a_message(uint16_t cell_temperature, endian_swap(&die_temperature, sizeof(die_temperature)); endian_swap(&vpv, sizeof(vpv)); + struct __attribute__((__packed__)) { + uint16_t cell_temperature : 10; + uint16_t voltage : 13; + uint8_t discharging : 1; + uint8_t chip : 4; + uint16_t segment_temperature : 10; + uint16_t die_temperature : 13; + uint16_t vpv : 13; + } beta_status_a_data; + + beta_status_a_data.cell_temperature = cell_temperature; + beta_status_a_data.voltage = voltage; + beta_status_a_data.discharging = discharging; + beta_status_a_data.chip = chip; + beta_status_a_data.segment_temperature = segment_temperature; + beta_status_a_data.die_temperature = die_temperature; + beta_status_a_data.vpv = vpv; + can_msg_t msg; msg.id = BETA_STAT_A_CANID; msg.len = BETA_STAT_A_SIZE; - msg.data[0] = cell_temperature >> 2; - msg.data[1] = (cell_temperature << 8) | (voltage >> 7); - msg.data[2] = (voltage << 6) | discharging; - msg.data[3] = (chip << 4) | segment_temperature >> 6; - msg.data[4] = (segment_temperature << 4) | (die_temperature >> 11); - msg.data[5] = die_temperature >> 3; - msg.data[6] = (die_temperature << 10) | (vpv >> 8); - msg.data[7] = vpv >> 5; + memcpy(msg.data, &beta_status_a_data, BETA_STAT_A_SIZE); queue_can_msg(msg); } @@ -620,18 +645,27 @@ void compute_send_beta_status_b_message(uint16_t vref2, uint16_t v_analog, endian_swap(&v_res, sizeof(v_res)); endian_swap(&vmv, sizeof(vmv)); + struct __attribute__((__packed__)) { + uint16_t vref2 : 13; + uint16_t v_analog : 10; + uint16_t v_digital : 10; + uint8_t chip : 4; + uint16_t v_res : 13; + uint16_t vmv : 13; + } beta_status_b_data; + + beta_status_b_data.vref2 = vref2; + beta_status_b_data.v_analog = v_analog; + beta_status_b_data.v_digital = v_digital; + beta_status_b_data.chip = chip; + beta_status_b_data.v_res = v_res; + beta_status_b_data.vmv = vmv; + can_msg_t msg; msg.id = BETA_STAT_B_CANID; msg.len = BETA_STAT_B_SIZE; - msg.data[0] = vref2 >> 5; - msg.data[1] = (vref2 << 8) | (v_analog >> 7); - msg.data[2] = (v_analog << 3) | (v_digital >> 9); - msg.data[3] = v_digital << 1; - msg.data[4] = (v_digital << 9) | (chip << 3) | (v_res >> 10); - msg.data[5] = v_res << 3; - msg.data[6] = (v_res << 11) | (vmv >> 8); - msg.data[7] = vmv << 5; + memcpy(msg.data, &beta_status_b_data, BETA_STAT_B_SIZE); queue_can_msg(msg); } @@ -645,18 +679,25 @@ void compute_send_alpha_status_a_message(uint16_t segment_temp, uint8_t chip, endian_swap(&vpv, sizeof(vpv)); endian_swap(&vmv, sizeof(vmv)); + struct __attribute__((__packed__)) { + uint16_t segment_temp : 10; + uint8_t chip : 4; + uint16_t die_temperature : 13; + uint16_t vpv : 13; + uint16_t vmv : 13; + } alpha_status_a_data; + + alpha_status_a_data.segment_temp = segment_temp; + alpha_status_a_data.chip = chip; + alpha_status_a_data.die_temperature = die_temperature; + alpha_status_a_data.vpv = vpv; + alpha_status_a_data.vmv = vmv; + can_msg_t msg; msg.id = ALPHA_STAT_A_CANID; msg.len = ALPHA_STAT_A_SIZE; - msg.data[0] = segment_temp >> 2; - msg.data[1] = (segment_temp << 8) | (chip << 2) | - (die_temperature >> 11); - msg.data[2] = die_temperature << 2; - msg.data[3] = (die_temperature << 10) | (vpv >> 8); - msg.data[4] = vpv << 5; - msg.data[5] = vmv >> 5; - msg.data[6] = vmv << 8; + memcpy(msg.data, &alpha_status_a_data, ALPHA_STAT_A_SIZE); queue_can_msg(msg); } @@ -670,17 +711,25 @@ void compute_send_alpha_status_b_message(uint16_t v_res, uint8_t chip, endian_swap(&v_analog, sizeof(v_analog)); endian_swap(&v_digital, sizeof(v_digital)); + struct __attribute__((__packed__)) { + uint16_t v_res : 13; + uint8_t chip : 4; + uint16_t vref2 : 13; + uint16_t v_analog : 13; + uint16_t v_digital : 13; + } alpha_status_b_data; + + alpha_status_b_data.v_res = v_res; + alpha_status_b_data.chip = chip; + alpha_status_b_data.vref2 = vref2; + alpha_status_b_data.v_analog = v_analog; + alpha_status_b_data.v_digital = v_digital; + can_msg_t msg; msg.id = ALPHA_STAT_B_CANID; msg.len = ALPHA_STAT_B_SIZE; - msg.data[0] = v_res >> 5; - msg.data[1] = (v_res << 8) | (chip >> 1); - msg.data[2] = (chip << 7) | (vref2 >> 6); - msg.data[3] = (vref2 << 7) | (v_analog >> 11); - msg.data[4] = v_analog >> 3; - msg.data[6] = (v_analog << 10) | (v_digital >> 8); - msg.data[7] = v_analog << 5; + memcpy(msg.data, &alpha_status_b_data, ALPHA_STAT_B_SIZE); queue_can_msg(msg); } diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 6ef3c77a..aaec32a8 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -354,6 +354,7 @@ void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, chips[chip].cccrc.aux_pec + chips[chip].cccrc.raux_pec + chips[chip].cccrc.stat_pec + chips[chip].cccrc.comm_pec + chips[chip].cccrc.pwm_pec; + if (pec_error_count > 0) { printf("PEC COUNT: %ld | Chip: %d | CMD: %d\n", pec_error_count, chip, type); From 3dafe3b2b8180a3d9f14068e2600d88edd1e831f Mon Sep 17 00:00:00 2001 From: Jack Rubacha Date: Fri, 24 Jan 2025 20:13:44 -0500 Subject: [PATCH 27/32] General changes/improvements (#151) --- .github/workflows/build-check.yml | 2 +- .github/workflows/format-check.yml | 1 + .mxproject | 9 +- Core/Inc/FreeRTOSConfig.h | 3 +- Core/Inc/adi_interaction.h | 231 ++++++++++ Core/Inc/bmsConfig.h | 1 + Core/Inc/segment.h | 18 +- Core/Inc/stm32f4xx_hal_conf.h | 2 +- Core/Inc/stm32f4xx_it.h | 5 +- Core/Src/adi_interaction.c | 363 ++++++++++++++++ Core/Src/analyzer.c | 34 +- Core/Src/main.c | 96 ++++- Core/Src/segment.c | 583 ++++---------------------- Core/Src/shep_tasks.c | 14 +- Core/Src/stateMachine.c | 2 +- Core/Src/stm32f4xx_hal_msp.c | 30 +- Core/Src/stm32f4xx_hal_timebase_tim.c | 138 ++++++ Core/Src/stm32f4xx_it.c | 82 ++-- Core/Src/syscalls.c | 176 ++++++++ Core/Src/sysmem.c | 79 ++++ Drivers/adbms | 2 +- Makefile | 10 +- shepherd2.ioc | 43 +- stm32f405rgtx_flash.ld | 208 +++++++++ 24 files changed, 1533 insertions(+), 599 deletions(-) create mode 100644 Core/Inc/adi_interaction.h create mode 100644 Core/Src/adi_interaction.c create mode 100644 Core/Src/stm32f4xx_hal_timebase_tim.c create mode 100644 Core/Src/syscalls.c create mode 100644 Core/Src/sysmem.c create mode 100644 stm32f405rgtx_flash.ld diff --git a/.github/workflows/build-check.yml b/.github/workflows/build-check.yml index 5ee76bbc..222e8985 100644 --- a/.github/workflows/build-check.yml +++ b/.github/workflows/build-check.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive - + token: ${{ secrets.PAT_TOKEN }} - name: Execute Make run: | if ! make; then diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml index 80a40900..e1a21c4f 100644 --- a/.github/workflows/format-check.yml +++ b/.github/workflows/format-check.yml @@ -10,6 +10,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive + token: ${{ secrets.PAT_TOKEN }} - name: Run clang-format style check for C/C++ sources uses: Northeastern-Electric-Racing/clang-format-action@main with: diff --git a/.mxproject b/.mxproject index d1b3aea1..b96dd2c9 100644 --- a/.mxproject +++ b/.mxproject @@ -1,8 +1,8 @@ [PreviousLibFiles] -LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_system.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_utils.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dmamux.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_system.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_utils.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dmamux.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_starmc1.h;Drivers/CMSIS/Include/core_cm55.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/pac_armv81.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_armv81mml.h;Drivers/CMSIS/Include/pmu_armv8.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/cachel1_armv7.h;Drivers/CMSIS/Include/cmsis_armclang_ltm.h;Drivers/CMSIS/Include/core_cm35p.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm85.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_iccarm.h; +LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_system.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_utils.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dmamux.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_system.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_utils.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_dmamux.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_i2c.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h;Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h;Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h;Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h;Middlewares/Third_Party/FreeRTOS/Source/include/list.h;Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h;Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h;Middlewares/Third_Party/FreeRTOS/Source/include/portable.h;Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h;Middlewares/Third_Party/FreeRTOS/Source/include/queue.h;Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h;Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h;Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h;Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h;Middlewares/Third_Party/FreeRTOS/Source/include/task.h;Middlewares/Third_Party/FreeRTOS/Source/include/timers.h;Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/core_cm35p.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/pmu_armv8.h;Drivers/CMSIS/Include/cachel1_armv7.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm55.h;Drivers/CMSIS/Include/cmsis_armclang_ltm.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_starmc1.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_cm85.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_armv81mml.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/pac_armv81.h; [PreviousUsedMakefileFiles] -SourceFiles=Core/Src/main.c;Core/Src/freertos.c;Core/Src/stm32f4xx_it.c;Core/Src/stm32f4xx_hal_msp.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Core/Src/system_stm32f4xx.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Core/Src/system_stm32f4xx.c;;;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c; +SourceFiles=Core/Src/main.c;Core/Src/freertos.c;Core/Src/stm32f4xx_it.c;Core/Src/stm32f4xx_hal_msp.c;Core/Src/stm32f4xx_hal_timebase_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Core/Src/system_stm32f4xx.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Core/Src/system_stm32f4xx.c;;;Middlewares/Third_Party/FreeRTOS/Source/croutine.c;Middlewares/Third_Party/FreeRTOS/Source/event_groups.c;Middlewares/Third_Party/FreeRTOS/Source/list.c;Middlewares/Third_Party/FreeRTOS/Source/queue.c;Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c;Middlewares/Third_Party/FreeRTOS/Source/tasks.c;Middlewares/Third_Party/FreeRTOS/Source/timers.c;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c;Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c; HeaderPath=Drivers/STM32F4xx_HAL_Driver/Inc;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;Middlewares/Third_Party/FreeRTOS/Source/include;Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F;Drivers/CMSIS/Device/ST/STM32F4xx/Include;Drivers/CMSIS/Include;Core/Inc; CDefines=USE_HAL_DRIVER;STM32F405xx;USE_HAL_DRIVER;USE_HAL_DRIVER; @@ -19,11 +19,12 @@ HeaderFiles#3=../Core/Inc/main.h HeaderFolderListSize=1 HeaderPath#0=../Core/Inc HeaderFiles=; -SourceFileListSize=4 +SourceFileListSize=5 SourceFiles#0=../Core/Src/freertos.c SourceFiles#1=../Core/Src/stm32f4xx_it.c SourceFiles#2=../Core/Src/stm32f4xx_hal_msp.c -SourceFiles#3=../Core/Src/main.c +SourceFiles#3=../Core/Src/stm32f4xx_hal_timebase_tim.c +SourceFiles#4=../Core/Src/main.c SourceFolderListSize=1 SourcePath#0=../Core/Src SourceFiles=; diff --git a/Core/Inc/FreeRTOSConfig.h b/Core/Inc/FreeRTOSConfig.h index c1e8e9b6..41e0046f 100644 --- a/Core/Inc/FreeRTOSConfig.h +++ b/Core/Inc/FreeRTOSConfig.h @@ -51,7 +51,6 @@ #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) #include extern uint32_t SystemCoreClock; - void xPortSysTickHandler(void); #endif #ifndef CMSIS_device_header #define CMSIS_device_header "stm32f4xx.h" @@ -164,7 +163,7 @@ standard names. */ /* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ -#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1 +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0 /* USER CODE BEGIN Defines */ /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ diff --git a/Core/Inc/adi_interaction.h b/Core/Inc/adi_interaction.h new file mode 100644 index 00000000..d44e6889 --- /dev/null +++ b/Core/Inc/adi_interaction.h @@ -0,0 +1,231 @@ +#include "adBms6830Data.h" +#include "bmsConfig.h" + +// --- BEGIN SET HELPERS --- + +/** + * @brief Set the status of the REFON bit. + * + * @param chip Pointer to the chip to modify. + * @param state New state of the REFON bit. + */ +void set_REFON(cell_asic *chip, REFON state); + +/** + * @brief Set the C-ADC vs. S-ADC comparison voltage threshold + * + * @param chip Pointer to the chip to modify. + * @param threshold Threshold to set. + */ +void set_volt_adc_comp_thresh(cell_asic *chip, CTH threshold); + +void set_diagnostic_flags(cell_asic *chip, FLAG_D config); + +/** + * @brief Set the discharge state of a cell. + * + * @param chip Pointer to chip with cell to modify. + * @param cell ID of cell to modify. Cell indexes start are from 1-16 (NOT ZERO INDEXED). + * @param discharge Cell discharge state. true to discharge, false to disable discharge. + */ +void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge); + +/** + * @brief Set the state of the SOAKON bit to either enable or disable soak times. + * + * @param chip Pointer to chip to configure + * @param state Enable or disable SOAKON + */ +void set_soak_on(cell_asic *chip, SOAKON state); + +/** + * @brief Set the soak time range. + * + * @param chip Pointer to chip to configure + * @param range The range of time over which to soak for aux and aux2 + */ +void set_aux_soak_range(cell_asic *chip, OWRNG range); + +/** + * @brief Set the open wire soak time. See data sheet for formula. + * + * @param chip Pointer to chip configuration + * @param time The amount of time to soak for. Higher OWA is a higher soak time. + */ +void set_open_wire_soak_time(cell_asic *chip, OWA time); + +/** + * @brief Set the pull of a GPIO pin on an ADBMS8630. + * + * @param chip ADBMS6830 chip + * @param gpio Number of the GPIO pin to change (1-10) + * @param input True is no pull down, False is pull down. + */ +void set_gpio_pull(cell_asic *chip, uint8_t gpio, bool input); + +/** + * @brief Set the corner frequency of the IIR filter. + * + * @param chip Pointer to chip config + * @param freq Corner frequency (see IIR_FPA enum for frequencies) + */ +void set_iir_corner_freq(cell_asic *chip, IIR_FPA freq); + +/** + * @brief Configure a chip as a break in the isoSPI daisy chain. + * + * @param chip Pointer to chip config + * @param is_break True if chip is break, false if chip is not break + */ +void set_comm_break(cell_asic *chip, bool is_break); + +/** + * @brief Enable/disable discharging through the mute discharge bit. + * + * @param chip Pointer to chip config + * @param disable_discharge True to disable discharge, false to enable discharge. + */ +void set_mute_state(cell_asic *chip, bool disable_discharge); + +/** + * @brief Set whether or not this chip is taking a snapshot. The chip will not begin reading new values unless the snapshot bit is cleared. + * + * @param chip Pointer to chip config + * @param take_snapshot True to take a snapshot, false to end the snapshot + */ +void set_snapshot(cell_asic *chip, bool take_snapshot); + +/** + * @brief Enable/disable the discharge timer monitor. + * + * @param chip Pointer to chip config + * @param enabled True if discharge timer monitor is enabled, false if otherwise + */ +void set_discharge_timer_monitor(cell_asic *chip, bool enabled); + +/** + * @brief Configure the discharge timer range, which affects the resolution. + * + * @param chip Pointer to chip config + * @param large True for large range, False for small range + */ +void set_discharge_timer_range(cell_asic *chip, bool large); + +/** + * @brief Set the discharge monitor timeout, which is dependent on the discharge timer range. + * + * @param chip Pointer to chip config + * @param timeout Base for timeout multiplicaiton. Must be below six bits. + */ +void set_discharge_timeout(cell_asic *chip, uint8_t timeout); + +// --- END SET HELPERS --- + +// --- BEGIN WRITE COMMANDS --- + +/** + * @brief Write config registers. Wakes chips before writing. + * + * @param chips Array of chips to write config registers of. + */ +void write_config_regs(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Clears all status regster C flags except the CS FLT + * + * @param chips + */ +void write_clear_flags(cell_asic chips[NUM_CHIPS]); + +// --- END WRITE COMMANDS --- + +// --- BEGIN READ COMMANDS --- + +/** + * @brief Read all filtered voltage results. IIR must be on and ADC must be continous + * + * @param chips The chips to read voltages from + */ +void read_filtered_voltage_registers(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Read every register connected to the AUX ADC. + * + * @param chips Array of chips to get voltage readings of. + */ +void adc_and_read_aux_registers(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Read voltages in every register connected to AUX2 ADC. + * + * @param chips Array of chips to get voltages of. + */ +void adc_and_read_aux2_registers(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Read status registers. + * + * @param chips Array of chips to read. + */ +void read_status_registers(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Read status and aux registers in one command. + * + * @param chips Array of chips to read. + */ +void read_status_aux_registers(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Read the serial ID of the chip. + * + * @param chips Array of chips to read. + */ +void read_serial_id(cell_asic chips[NUM_CHIPS]); + +// --- END READ COMMANDS --- + +// --- BEGIN ADC POLL --- + +/** + * @brief Get voltage readings from the C-ADCs. Takes a single shot measurement. + * + * @param chips Array of chips to get voltage readings from. + */ +void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Get voltages from the S-ADCs. Makes a single shot measurement. + * + * @param chip Array of chips to get voltage readings from. + */ +void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Get the avgeraged cell voltages. + * + * @param chip Array of chips to get voltage readings of. + */ +void get_avgd_cell_voltages(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Get the filtered cell volrages. + * + * @param chip Array of chips to get voltage readings of. + */ +void get_filtered_cell_voltages(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Get the c and s adc voltages. Does this with RDCSALL command. + * + * @param chips Array of chips to get voltage readings of. + */ +void get_c_and_s_adc_voltages(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Starts a continous c ADC conversion with S redundancy + * + */ +void start_c_adc_conv(); + +// --- END ADC POLL --- diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index fd6e6d8d..96e8e425 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -2,6 +2,7 @@ #define BMS_CONFIG_H #define DEBUG_MODE_ENABLED true +#define DEBUG_STATS // Hardware definition #define NUM_SEGMENTS 1 diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index 98033d7e..dfc2e0b6 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -12,10 +12,15 @@ void segment_init(acc_data_t *bmsdata); /** * @brief Pulls all cell data from the segments and returns all cell data * - * @todo make sure that retrieving cell data doesn't block code too much */ void segment_retrieve_data(acc_data_t *bmsdata); +/** + * @brief Fetch extra data for segment + * + */ +void segment_retrieve_debug_data(acc_data_t *bmsdata); + /** * @brief Disables balancing for all cells. * @@ -32,15 +37,6 @@ void segment_disable_balancing(acc_data_t *bmsdata); void segment_configure_balancing( acc_data_t *bmsdata, bool discharge_config[NUM_CHIPS][NUM_CELLS_ALPHA]); -/** - * @brief Returns if a specific cell is balancing - * - * @param chip_num - * @return true - * @return false - */ -bool cell_is_balancing(uint8_t chip_num, uint8_t cell_num); - /** * @brief Returns if any cells are balancing. * @@ -73,6 +69,6 @@ void read_serial_id(cell_asic chips[NUM_CHIPS]); * * @param chips Array of chips to get voltages of. */ -void read_aux2_registers(cell_asic chips[NUM_CHIPS]); +void adc_and_read_aux2_registers(cell_asic chips[NUM_CHIPS]); #endif \ No newline at end of file diff --git a/Core/Inc/stm32f4xx_hal_conf.h b/Core/Inc/stm32f4xx_hal_conf.h index e28f8b19..caa25296 100644 --- a/Core/Inc/stm32f4xx_hal_conf.h +++ b/Core/Inc/stm32f4xx_hal_conf.h @@ -214,7 +214,7 @@ #define MAC_ADDR5 0U /* Definition of the Ethernet driver buffers size and count */ -#define ETH_RX_BUF_SIZE /* buffer size for receive */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ #define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ #define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ diff --git a/Core/Inc/stm32f4xx_it.h b/Core/Inc/stm32f4xx_it.h index 2b9b7aa9..78f33294 100644 --- a/Core/Inc/stm32f4xx_it.h +++ b/Core/Inc/stm32f4xx_it.h @@ -52,12 +52,13 @@ void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void DebugMon_Handler(void); -void SysTick_Handler(void); -void CAN1_RX0_IRQHandler(void); void DMA1_Stream4_IRQHandler(void); +void CAN1_RX0_IRQHandler(void); +void TIM3_IRQHandler(void); void UART4_IRQHandler(void); void DMA2_Stream0_IRQHandler(void); void CAN2_RX0_IRQHandler(void); +void CAN2_RX1_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/Core/Src/adi_interaction.c b/Core/Src/adi_interaction.c new file mode 100644 index 00000000..5a16948e --- /dev/null +++ b/Core/Src/adi_interaction.c @@ -0,0 +1,363 @@ +#include "adi_interaction.h" +#include "adBms6830CmdList.h" +#include "adBms6830GenericType.h" +#include "mcuWrapper.h" + +/** + * @brief Set a bit in a uint16 + * + * @param number uint16 to change. + * @param n Nth bit to change. + * @param x true sets, false clears. + * @return uint16_t New uint16. + */ +inline uint16_t set_uint16_bit(uint16_t number, uint16_t n, bool x) +{ + return (number & ~((uint16_t)1 << n)) | ((uint16_t)x << n); +} + +// --- BEGIN SET HELPERS --- + +void set_REFON(cell_asic *chip, REFON state) +{ + chip->tx_cfga.refon = state; +} + +void set_volt_adc_comp_thresh(cell_asic *chip, CTH threshold) +{ + chip->tx_cfga.cth = threshold; +} + +void set_diagnostic_flags(cell_asic *chip, FLAG_D config) +{ + chip->tx_cfga.flag_d = + (uint8_t)set_uint16_bit(chip->tx_cfga.flag_d, config, true); +} + +void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge) +{ + chip->tx_cfgb.dcc = set_uint16_bit(chip->tx_cfgb.dcc, cell, discharge); +} + +void set_soak_on(cell_asic *chip, SOAKON state) +{ + chip->tx_cfga.soakon = state; +} + +void set_aux_soak_range(cell_asic *chip, OWRNG range) +{ + chip->tx_cfga.owrng = range; +} + +void set_open_wire_soak_time(cell_asic *chip, OWA time) +{ + chip->tx_cfga.owa = time; +} + +void set_gpio_pull(cell_asic *chip, uint8_t gpio, bool input) +{ + if (gpio > 10 || gpio < 1) { + printf("ERROR: Invalid GPIO pin %d\n", gpio); + return; + } + chip->tx_cfga.gpo = set_uint16_bit(chip->tx_cfga.gpo, gpio - 1, input); +} + +void set_iir_corner_freq(cell_asic *chip, IIR_FPA freq) +{ + chip->tx_cfga.fc = freq; +} + +void set_comm_break(cell_asic *chip, bool is_break) +{ + chip->tx_cfga.comm_bk = is_break; +} + +void set_mute_state(cell_asic *chip, bool disable_discharge) +{ + chip->tx_cfga.mute_st = disable_discharge; +} + +void set_snapshot(cell_asic *chip, bool take_snapshot) +{ + chip->tx_cfga.snap = take_snapshot; +} + +void set_discharge_timer_monitor(cell_asic *chip, bool enabled) +{ + chip->tx_cfgb.dtmen = enabled; +} + +void set_discharge_timer_range(cell_asic *chip, bool large) +{ + chip->tx_cfgb.dtrng = large; +} + +void set_discharge_timeout(cell_asic *chip, uint8_t timeout) +{ + if (timeout >> 6 > 0) { + printf("Invalid discharge time\n"); + return; + // TODO: Non-critical fault + } + chip->tx_cfgb.dcto = timeout; +} + +// --- END SET HELPERS --- + +// void start_cell_voltages_adc(cell_asic chips[NUM_CHIPS]) +// { +// adbms_wake(); +// adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); +// adBmsPollAdc(PLCADC); +// } + +// --- BEGIN RW --- + +extern TIM_HandleTypeDef htim2; + +/** + * @brief Delays a certain number of microseconds + * + * Approximately +50% error as seen in logic analyzer + * + * @param us the number of us to delay + */ +inline void delay_us(uint16_t us) +{ + uint16_t tickstart = __HAL_TIM_GET_COUNTER(&htim2); + uint16_t wait = us; + + while ((__HAL_TIM_GET_COUNTER(&htim2) - tickstart) < wait) { + } +} + +/** + * @brief Wake every ADBMS6830 IC in the daisy chain. Blocking wait for around 30us * NUM_CHIPS. + * + */ +void adbms_wake() +{ + for (uint8_t ic = 0; ic < NUM_CHIPS; ic++) { + adBmsCsLow(); + adBmsCsHigh(); + delay_us(20); + } +} + +/** + * @brief Write data to all chips. + * + * @param chip Array of chips to write data to. + * @param command Command to issue to the chip. + * @param type Register type to write to. + * @param group Group of registers to write to. + */ +void write_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, + GRP group) +{ + adbms_wake(); + + for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { + adBmsWriteData(NUM_CHIPS, &chips[chip], command, type, group); + } +} + +/** + * @brief Read data from all chips. + * + * @param chips Array of chips to read data to. + * @param command Command to issue to the chip. + * @param type Register type to write to. + * @param group Group of registers to write to. + */ +void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, + GRP group) +{ + adbms_wake(); + + for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { + adBmsReadData(NUM_CHIPS, &chips[chip], command, type, group); + } + + // Count PEC errors + uint32_t pec_error_count = 0; + for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { + // Yes, they did separate every PEC as if that mattered. + pec_error_count += + chips[chip].cccrc.cfgr_pec + chips[chip].cccrc.sid_pec + + chips[chip].cccrc.cell_pec + + chips[chip].cccrc.acell_pec + + chips[chip].cccrc.scell_pec + + chips[chip].cccrc.fcell_pec + + chips[chip].cccrc.aux_pec + chips[chip].cccrc.raux_pec + + chips[chip].cccrc.stat_pec + + chips[chip].cccrc.comm_pec + chips[chip].cccrc.pwm_pec; + + if (pec_error_count > 0) { + printf("PEC COUNT: %ld | Chip: %d | CMD: %d\n", + pec_error_count, chip, type); + } + + chips[chip].cccrc.cfgr_pec = 0; + chips[chip].cccrc.sid_pec = 0; + chips[chip].cccrc.cell_pec = 0; + chips[chip].cccrc.acell_pec = 0; + chips[chip].cccrc.scell_pec = 0; + chips[chip].cccrc.fcell_pec = 0; + chips[chip].cccrc.aux_pec = 0; + chips[chip].cccrc.raux_pec = 0; + chips[chip].cccrc.stat_pec = 0; + chips[chip].cccrc.comm_pec = 0; + chips[chip].cccrc.pwm_pec = 0; + } + pec_error_count = 0; +} + +// --- BEGIN WRITE COMMANDS --- + +void write_config_regs(cell_asic chips[NUM_CHIPS]) +{ + write_adbms_data(chips, WRCFGA, Config, A); + write_adbms_data(chips, WRCFGB, Config, B); +} + +void write_clear_flags(cell_asic chips[NUM_CHIPS]) +{ + for (int chip = 0; chip < NUM_CHIPS; chip++) { + chips[chip].clflag.cl_sleep = 1; + chips[chip].clflag.cl_smed = 1; + chips[chip].clflag.cl_sed = 1; + chips[chip].clflag.cl_cmed = 1; + chips[chip].clflag.cl_ced = 1; + chips[chip].clflag.cl_vduv = 1; + chips[chip].clflag.cl_vdov = 1; + chips[chip].clflag.cl_vauv = 1; + chips[chip].clflag.cl_vaov = 1; + chips[chip].clflag.cl_oscchk = 1; + chips[chip].clflag.cl_tmode = 1; + chips[chip].clflag.cl_thsd = 1; + chips[chip].clflag.cl_sleep = 1; + chips[chip].clflag.cl_spiflt = 1; + chips[chip].clflag.cl_vdel = 1; + chips[chip].clflag.cl_vde = 1; + } + write_adbms_data(chips, CLRFLAG, Clrflag, NONE); +} + +// --- END WRITE COMMANDS + +// --- BEGIN READ COMMANDS --- + +void read_filtered_voltage_registers(cell_asic chips[NUM_CHIPS]) +{ + read_adbms_data(chips, RDFCALL, Rdfcall, ALL_GRP); +} + +void adc_and_read_aux_registers(cell_asic chips[NUM_CHIPS]) +{ + // TODO only poll correct GPIOs + adbms_wake(); + adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); + adBmsPollAdc(PLAUX2); + + read_adbms_data(chips, RDAUXA, Aux, A); + read_adbms_data(chips, RDAUXB, Aux, B); + read_adbms_data(chips, RDAUXC, Aux, C); + read_adbms_data(chips, RDAUXD, Aux, D); +} + +void adc_and_read_aux2_registers(cell_asic chips[NUM_CHIPS]) +{ + adbms_wake(); + adBms6830_Adax2(AUX_ALL); + adBmsPollAdc(PLAUX2); + + read_adbms_data(chips, RDRAXA, RAux, A); + read_adbms_data(chips, RDRAXB, RAux, B); + read_adbms_data(chips, RDRAXC, RAux, C); + read_adbms_data(chips, RDRAXD, RAux, D); +} + +void read_status_registers(cell_asic chips[NUM_CHIPS]) +{ + read_adbms_data(chips, RDSTATA, Status, A); + read_adbms_data(chips, RDSTATB, Status, B); + read_adbms_data(chips, RDSTATC, Status, C); + read_adbms_data(chips, RDSTATD, Status, D); + read_adbms_data(chips, RDSTATE, Status, E); +} + +void read_status_aux_registers(cell_asic chips[NUM_CHIPS]) +{ + read_adbms_data(chips, RDASALL, Rdasall, ALL_GRP); +} + +void read_serial_id(cell_asic chips[NUM_CHIPS]) +{ + read_adbms_data(chips, RDSID, Sid, NONE); +} + +// --- END READ COMMANDS --- + +// --- BEGIN ADC POLL --- + +void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]) +{ + adbms_wake(); + // Take single shot measurement + adBms6830_Adcv(RD_OFF, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); + read_adbms_data(chips, RDCVALL, Rdcvall, ALL_GRP); +} + +void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) +{ + write_config_regs(chips); + adbms_wake(); + adBms6830_Adsv(SINGLE, DCP_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLSADC); + + adbms_wake(); + read_adbms_data(chips, RDSALL, Rdsall, ALL_GRP); + // read_adbms_data(chip, RDSVA, S_volt, A); + // read_adbms_data(chip, RDSVB, S_volt, B); + // read_adbms_data(chip, RDSVC, S_volt, C); + // read_adbms_data(chip, RDSVD, S_volt, D); + // read_adbms_data(chip, RDSVE, S_volt, E); + // read_adbms_data(chip, RDSVF, S_volt, F); +} + +void get_avgd_cell_voltages(cell_asic chips[NUM_CHIPS]) +{ + adbms_wake(); + adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); + + adbms_wake(); + read_adbms_data(chips, RDACALL, Rdacall, ALL_GRP); +} + +void get_filtered_cell_voltages(cell_asic chips[NUM_CHIPS]) +{ + adbms_wake(); + read_adbms_data(chips, RDFCALL, Rdfcall, ALL_GRP); +} + +void get_c_and_s_adc_voltages(cell_asic chips[NUM_CHIPS]) +{ + adbms_wake(); + adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + adBmsPollAdc(PLCADC); + + adbms_wake(); + read_adbms_data(chips, RDCSALL, Rdcsall, ALL_GRP); +} + +void start_c_adc_conv() +{ + adbms_wake(); + adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_ON, OW_OFF_ALL_CH); +} + +// --- END ADC POLL --- diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index e318b6c5..4ef2bc46 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -169,7 +169,7 @@ void calc_cell_temps(acc_data_t *bmsdata) for (int cell = 0; cell < num_cells; cell++) { int16_t x = bmsdata->chips[chip] - .aux.a_codes[THERM_MAP[cell]]; + .raux.ra_codes[THERM_MAP[cell]]; bmsdata->chip_data[chip].cell_temp[cell] = calc_cell_temp(x); @@ -180,14 +180,14 @@ void calc_cell_temps(acc_data_t *bmsdata) if (!bmsdata->chip_data[chip].alpha) { // Take average of both onboard therms bmsdata->chip_data[chip].on_board_temp = - (calc_cell_temp(( - bmsdata->chips[chip].aux.a_codes[6])) + - calc_cell_temp( - bmsdata->chips[chip].aux.a_codes[7])) / + (calc_cell_temp((bmsdata->chips[chip] + .raux.ra_codes[6])) + + calc_cell_temp(bmsdata->chips[chip] + .raux.ra_codes[7])) / 2; } else { bmsdata->chip_data[chip].on_board_temp = calc_cell_temp( - bmsdata->chips[chip].aux.a_codes[7]); + bmsdata->chips[chip].raux.ra_codes[7]); } } @@ -304,13 +304,13 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) uint8_t num_cells = get_num_cells(&bmsdata->chip_data[c]); for (uint8_t cell = 0; cell < num_cells; cell++) { /* fings out the maximum cell voltage and location */ - if (getVoltage(bmsdata->chips[c].cell.c_codes[cell]) * + if (getVoltage(bmsdata->chips[c].fcell.fc_codes[cell]) * 10000 > bmsdata->max_voltage.val) { bmsdata->max_voltage.val = getVoltage( bmsdata->chips[c] - .cell.c_codes[cell]) * + .fcell.fc_codes[cell]) * 10000; bmsdata->max_voltage.chipIndex = c; bmsdata->max_voltage.cellNum = cell; @@ -326,13 +326,13 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) } /* finds out the minimum cell voltage and location */ - if (getVoltage(bmsdata->chips[c].cell.c_codes[cell]) * + if (getVoltage(bmsdata->chips[c].fcell.fc_codes[cell]) * 10000 < bmsdata->min_voltage.val) { bmsdata->min_voltage.val = getVoltage( bmsdata->chips[c] - .cell.c_codes[cell]) * + .fcell.fc_codes[cell]) * 10000; bmsdata->min_voltage.chipIndex = c; bmsdata->min_voltage.cellNum = cell; @@ -348,7 +348,7 @@ void calc_pack_voltage_stats(acc_data_t *bmsdata) } total_volt += getVoltage( - bmsdata->chips[c].cell.c_codes[cell]); + bmsdata->chips[c].fcell.fc_codes[cell]); total_ocv += bmsdata->chip_data[c].open_cell_voltage[cell]; } @@ -556,9 +556,11 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) for (uint8_t cell = 0; cell < num_cells; cell++) { bmsdata->chip_data[chip] .open_cell_voltage[cell] = - bmsdata->chips[chip].cell.c_codes[cell]; + bmsdata->chips[chip] + .fcell.fc_codes[cell]; prev_chipdata[chip].open_cell_voltage[cell] = - bmsdata->chips[chip].cell.c_codes[cell]; + bmsdata->chips[chip] + .fcell.fc_codes[cell]; } } return; @@ -577,8 +579,8 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) bmsdata->chip_data[chip] .open_cell_voltage[cell] = ((uint32_t)(bmsdata->chips[chip] - .cell - .c_codes[cell]) + + .fcell + .fc_codes[cell]) + ((uint32_t)(prev_chipdata[chip].open_cell_voltage [cell]) * (OCV_AVG - 1))) / @@ -586,7 +588,7 @@ void calc_open_cell_voltage(acc_data_t *bmsdata) bmsdata->chip_data[chip] .open_cell_voltage[cell] = bmsdata->chips[chip] - .cell.c_codes[cell]; + .fcell.fc_codes[cell]; if (bmsdata->chip_data[chip] .open_cell_voltage[cell] > diff --git a/Core/Src/main.c b/Core/Src/main.c index d0cc9a0d..f3230a68 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -74,6 +74,7 @@ SPI_HandleTypeDef hspi3; TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim2; +TIM_HandleTypeDef htim5; TIM_HandleTypeDef htim8; UART_HandleTypeDef huart4; @@ -85,7 +86,7 @@ PCD_HandleTypeDef hpcd_USB_OTG_FS; osThreadId_t defaultTaskHandle; const osThreadAttr_t defaultTask_attributes = { .name = "defaultTask", - .stack_size = 128 * 8, + .stack_size = 256 * 4, .priority = (osPriority_t) osPriorityNormal, }; /* USER CODE BEGIN PV */ @@ -110,6 +111,7 @@ static void MX_TIM8_Init(void); static void MX_ADC1_Init(void); static void MX_ADC2_Init(void); static void MX_IWDG_Init(void); +static void MX_TIM5_Init(void); void StartDefaultTask(void *argument); /* USER CODE BEGIN PFP */ @@ -208,7 +210,7 @@ const void print_bms_stats(acc_data_t *acc_data) uint8_t num_cells = get_num_cells(&acc_data->chip_data[c]); for(uint8_t cell = 0; cell < num_cells; cell++) { - printf("%.3f\t", getVoltage(acc_data->chips[c].cell.c_codes[cell])); + printf("%.3f\t", getVoltage(acc_data->chips[c].fcell.fc_codes[cell])); } printf("\n"); } @@ -227,6 +229,19 @@ const void print_bms_stats(acc_data_t *acc_data) } #endif +#define DEBUG_THERM_VOLTS + #ifdef DEBUG_THERM_VOLTS + printf("THERM VOLTS: \n"); + for(uint8_t c = 0; c < NUM_CHIPS; c++) + { + for(uint8_t gpio = 0; gpio < 10; gpio++) + { + printf("%f\t", getVoltage(acc_data->chips[c].raux.ra_codes[gpio])); + } + printf("\n"); + } + #endif + #ifdef DEBUG_OTHER printf("UnFiltered Thermistor Temps:\n"); @@ -290,6 +305,7 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *phuart) */ int main(void) { + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ @@ -332,6 +348,7 @@ int main(void) MX_ADC1_Init(); MX_ADC2_Init(); MX_IWDG_Init(); + MX_TIM5_Init(); /* USER CODE BEGIN 2 */ //for (int i = 0; i < 58; i++) //{ @@ -373,7 +390,7 @@ int main(void) /* Create the thread(s) */ /* creation of defaultTask */ - defaultTaskHandle = osThreadNew(StartDefaultTask, acc_data, &defaultTask_attributes); + defaultTaskHandle = osThreadNew(StartDefaultTask, (void*) acc_data, &defaultTask_attributes); /* USER CODE BEGIN RTOS_THREADS */ @@ -411,6 +428,7 @@ int main(void) osKernelStart(); /* We should never get here as control is now taken by the scheduler */ + /* Infinite loop */ /* USER CODE BEGIN WHILE */ for(;;) { @@ -811,7 +829,7 @@ static void MX_SPI3_Init(void) hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; - hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; + hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; @@ -924,7 +942,7 @@ static void MX_TIM2_Init(void) /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; - htim2.Init.Prescaler = 0; + htim2.Init.Prescaler = 16; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 4294967295; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; @@ -945,11 +963,56 @@ static void MX_TIM2_Init(void) Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ - + HAL_TIM_Base_Start(&htim2); /* USER CODE END TIM2_Init 2 */ } +/** + * @brief TIM5 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM5_Init(void) +{ + + /* USER CODE BEGIN TIM5_Init 0 */ + + /* USER CODE END TIM5_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM5_Init 1 */ + + /* USER CODE END TIM5_Init 1 */ + htim5.Instance = TIM5; + htim5.Init.Prescaler = 0; + htim5.Init.CounterMode = TIM_COUNTERMODE_UP; + htim5.Init.Period = 4294967295; + htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim5) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM5_Init 2 */ + + /* USER CODE END TIM5_Init 2 */ + +} + /** * @brief TIM8 Initialization Function * @param None @@ -1269,6 +1332,27 @@ void StartDefaultTask(void *argument) /* USER CODE END 5 */ } +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM3 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM3) { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + /** * @brief This function is executed in case of error occurrence. * @retval None diff --git a/Core/Src/segment.c b/Core/Src/segment.c index aaec32a8..065d3569 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -1,19 +1,11 @@ #include "segment.h" -#include "main.h" #include -#include -#include -#include #include "analyzer.h" #include "c_utils.h" -#include "common.h" -#include "adBms6830CmdList.h" -#include "adBms6830GenericType.h" #include "serialPrintResult.h" #include "adBms6830ParseCreate.h" -#include "mcuWrapper.h" -#include "cmsis_os.h" +#include "adi_interaction.h" #define T_READY 10 /* microseconds*/ #define T_IDLE 4.3 /* milliseconds, minimum. typ is 5.5, max is 6.7 */ @@ -29,263 +21,54 @@ #define GPIO_EXPANDER_ADDR 0x40 #define GPIO_REGISTER_ADDR 0x09 -// TODO ensure spi 1 is correct for talking to segs -extern SPI_HandleTypeDef hspi1; +extern TIM_HandleTypeDef htim2; uint8_t therm_avg_counter = 0; nertimer_t variance_timer; -uint32_t pec_error_count = 0; - /* private function prototypes */ -void variance_therm_check(void); -void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]); -void pull_chip_configuration(void); -int16_t calc_average(chipdata_t segment_data[NUM_CHIPS]); -int8_t calc_therm_standard_dev(int16_t avg_temp); +// void variance_therm_check(void); +// void discard_neutrals(chipdata_t segment_data[NUM_CHIPS]); +// void pull_chip_configuration(void); +// int16_t calc_average(chipdata_t segment_data[NUM_CHIPS]); +// int8_t calc_therm_standard_dev(int16_t avg_temp); void init_chip(cell_asic *chip); +void write_config_regs(cell_asic chip[NUM_CHIPS]); void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge); /** - * @brief Set a bit in a uint16 - * - * @param number uint16 to change. - * @param n Nth bit to change. - * @param x true sets, false clears. - * @return uint16_t New uint16. - */ -inline uint16_t set_uint16_bit(uint16_t number, uint16_t n, bool x) -{ - return (number & ~((uint16_t)1 << n)) | ((uint16_t)x << n); -} - -/** - * @brief Wake every ADBMS6830 IC in the daisy chain. Takes NUM_CHIPS * 8 ms to finish. - * - */ -void adbms_wake() -{ - adBmsCsLow(); - adBmsCsHigh(); - - /* - DEBUG: Theoretically, below should work for one IC, but it is not. - It shold be necessarry for multiple IC operation. - */ - - // for (uint8_t ic = 0; ic < total_ic; ic++) { - // adBmsCsLow(); - // Delay_ms(4); - // adBmsCsHigh(); - // Delay_ms(4); - // } - - // adBmsWakeupIc(NUM_CHIPS); -} - -/** - * @brief Set the status of the REFON bit. - * - * @param chip Pointer to the chip to modify. - * @param state New state of the REFON bit. - */ -void set_REFON(cell_asic *chip, REFON state) -{ - chip->tx_cfga.refon = state; -} - -/** - * @brief Set the C-ADC vs. S-ADC comparison voltage threshold - * - * @param chip Pointer to the chip to modify. - * @param threshold Threshold to set. - */ -void set_volt_adc_comp_thresh(cell_asic *chip, CTH threshold) -{ - chip->tx_cfga.cth = threshold; -} - -void set_diagnostic_flags(cell_asic *chip, FLAG_D config) -{ - chip->tx_cfga.flag_d = - (uint8_t)set_uint16_bit(chip->tx_cfga.flag_d, config, true); -} - -/** - * @brief Set the discharge state of a cell. - * - * @param chip Pointer to chip with cell to modify. - * @param cell ID of cell to modify. Cell indexes start are from 1-16 (NOT ZERO INDEXED). - * @param discharge Cell discharge state. true to discharge, false to disable discharge. - */ -void set_cell_discharge(cell_asic *chip, uint8_t cell, bool discharge) -{ - chip->tx_cfgb.dcc = set_uint16_bit(chip->tx_cfgb.dcc, cell, discharge); -} - -/** - * @brief Set the state of the SOAKON bit to either enable or disable soak times. - * - * @param chip Pointer to chip to configure - * @param state Enable or disable SOAKON - */ -void set_soak_on(cell_asic *chip, SOAKON state) -{ - chip->tx_cfga.soakon = state; -} - -/** - * @brief Set the open wire detection soak time range. - * - * @param chip Pointer to chip to configure - * @param range The range of time over which to soak for open wire detection - */ -void set_open_wire_soak_range(cell_asic *chip, OWRNG range) -{ - chip->tx_cfga.owrng = range; -} - -/** - * @brief Set the open wire soak time. See data sheet for formula. - * - * @param chip Pointer to chip configuration - * @param time The amount of time to soak for. Higher OWA is a higher soak time. - */ -void set_open_wire_soak_time(cell_asic *chip, OWA time) -{ - chip->tx_cfga.owa = time; -} - -/** - * @brief Set the mode of a GPIO pin on an ADBMS8630. - * - * @param chip ADBMS6830 chip - * @param gpio Number of the GPIO pin to change (1-10) - * @param input True is input, False is output. - */ -void set_gpio_mode(cell_asic *chip, uint8_t gpio, bool input) -{ - if (gpio > 10 || gpio < 1) { - printf("ERROR: Invalid GPIO pin %d\n", gpio); - return; - } - chip->tx_cfga.gpo = set_uint16_bit(chip->tx_cfga.gpo, gpio - 1, input); -} - -/** - * @brief Set the corner frequency of the IIR filter. - * - * @param chip Pointer to chip config - * @param freq Corner frequency (see IIR_FPA enum for frequencies) - */ -void set_iir_corner_freq(cell_asic *chip, IIR_FPA freq) -{ - chip->tx_cfga.fc = freq; -} - -/** - * @brief Configure a chip as a break in the isoSPI daisy chain. - * - * @param chip Pointer to chip config - * @param is_break True if chip is break, false if chip is not break - */ -void set_comm_break(cell_asic *chip, bool is_break) -{ - chip->tx_cfga.comm_bk = is_break; -} - -/** - * @brief Enable/disable discharging through the mute discharge bit. - * - * @param chip Pointer to chip config - * @param disable_discharge True to disable discharge, false to enable discharge. - */ -void set_mute_state(cell_asic *chip, bool disable_discharge) -{ - chip->tx_cfga.mute_st = disable_discharge; -} - -/** - * @brief Set whether or not this chip is taking a snapshot. The chip will not begin reading new values unless the snapshot bit is cleared. - * - * @param chip Pointer to chip config - * @param take_snapshot True to take a snapshot, false to end the snapshot - */ -void set_snapshot(cell_asic *chip, bool take_snapshot) -{ - chip->tx_cfga.snap = take_snapshot; -} - -/** - * @brief Enable/disable the discharge timer monitor. - * - * @param chip Pointer to chip config - * @param enabled True if discharge timer monitor is enabled, false if otherwise - */ -void set_discharge_timer_monitor(cell_asic *chip, bool enabled) -{ - chip->tx_cfgb.dtmen = enabled; -} - -/** - * @brief Configure the discharge timer range, which affects the resolution. - * - * @param chip Pointer to chip config - * @param large True for large range, False for small range - */ -void set_discharge_timer_range(cell_asic *chip, bool large) -{ - chip->tx_cfgb.dtrng = large; -} - -/** - * @brief Set the discharge monitor timeout, which is dependent on the discharge timer range. - * - * @param chip Pointer to chip config - * @param timeout Base for timeout multiplicaiton. Must be below six bits. - */ -void set_discharge_timeout(cell_asic *chip, uint8_t timeout) -{ - if (timeout >> 6 > 0) { - printf("Invalid discharge time\n"); - return; - //TODO: Non-critical fault - } - chip->tx_cfgb.dcto = timeout; -} - -/** - * @brief Initialize a chip with default values. + * @brief Initialize a chip with our default values. * * @param chip Pointer to chip to initialize. */ void init_chip(cell_asic *chip) { set_REFON(chip, PWR_UP); - set_volt_adc_comp_thresh(chip, CVT_8_1mV); + // WARNING, THE ENUM IS WRONG, CHECK TABLE 102 + set_volt_adc_comp_thresh(chip, CVT_45mV); chip->tx_cfga.flag_d = 0; - // No soak on AUX ADCs - set_soak_on(chip, SOAKON_CLR); - - // short soak time by default - set_open_wire_soak_range(chip, TIME_32US_TO_4_1MS); + // Short soak on ADAX + set_soak_on(chip, SOAKON_SET); + set_aux_soak_range(chip, SHORT); // No open wire detect soak set_open_wire_soak_time(chip, OWA0); - // All GPIOs are inputs by default - set_gpio_mode(chip, 1, true); - set_gpio_mode(chip, 2, true); - set_gpio_mode(chip, 3, true); - set_gpio_mode(chip, 4, true); - set_gpio_mode(chip, 5, true); - set_gpio_mode(chip, 6, true); - set_gpio_mode(chip, 7, true); - set_gpio_mode(chip, 8, true); - set_gpio_mode(chip, 9, true); - set_gpio_mode(chip, 10, true); + // Set therm GPIOs + set_gpio_pull(chip, 1, true); + set_gpio_pull(chip, 2, true); + set_gpio_pull(chip, 3, true); + set_gpio_pull(chip, 4, true); + set_gpio_pull(chip, 5, true); + set_gpio_pull(chip, 6, true); + set_gpio_pull(chip, 7, true); // this is a on board therm for beta only + set_gpio_pull(chip, 8, true); // this is a on board therm + + // set outputs, 9=iso led 10=bal LED + set_gpio_pull(chip, 9, false); + set_gpio_pull(chip, 10, false); // Registers are unfrozen set_snapshot(chip, SNAP_OFF); @@ -297,7 +80,7 @@ void init_chip(cell_asic *chip) set_comm_break(chip, false); // IIR filter disabled - set_iir_corner_freq(chip, IIR_FPA_OFF); + set_iir_corner_freq(chip, IIR_FPA16); // Init config B @@ -315,78 +98,6 @@ void init_chip(cell_asic *chip) chip->tx_cfgb.dcc = 0; } -/** - * @brief Write data to all chips. - * - * @param chip Array of chips to write data to. - * @param command Command to issue to the chip. - * @param type Register type to write to. - * @param group Group of registers to write to. - */ -void write_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, - GRP group) -{ - adBmsWriteData(NUM_CHIPS, chips, command, type, group); -} - -/** - * @brief Read data from all chips. - * - * @param chips Array of chips to read data to. - * @param command Command to issue to the chip. - * @param type Register type to write to. - * @param group Group of registers to write to. - */ -void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, - GRP group) -{ - adBmsReadData(NUM_CHIPS, chips, command, type, group); - - // Count PEC errors - for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { - // Yes, they did separate every PEC as if that mattered. - pec_error_count += - chips[chip].cccrc.cfgr_pec + chips[chip].cccrc.sid_pec + - chips[chip].cccrc.cell_pec + - chips[chip].cccrc.acell_pec + - chips[chip].cccrc.scell_pec + - chips[chip].cccrc.fcell_pec + - chips[chip].cccrc.aux_pec + chips[chip].cccrc.raux_pec + - chips[chip].cccrc.stat_pec + - chips[chip].cccrc.comm_pec + chips[chip].cccrc.pwm_pec; - - if (pec_error_count > 0) { - printf("PEC COUNT: %ld | Chip: %d | CMD: %d\n", - pec_error_count, chip, type); - } - - chips[chip].cccrc.cfgr_pec = 0; - chips[chip].cccrc.sid_pec = 0; - chips[chip].cccrc.cell_pec = 0; - chips[chip].cccrc.acell_pec = 0; - chips[chip].cccrc.scell_pec = 0; - chips[chip].cccrc.fcell_pec = 0; - chips[chip].cccrc.aux_pec = 0; - chips[chip].cccrc.raux_pec = 0; - chips[chip].cccrc.stat_pec = 0; - chips[chip].cccrc.comm_pec = 0; - chips[chip].cccrc.pwm_pec = 0; - } - pec_error_count = 0; -} - -/** - * @brief Write config registers. Wakes chips before writing. - * - * @param chips Array of chips to write config registers of. - */ -void write_config_regs(cell_asic chips[NUM_CHIPS]) -{ - adbms_wake(); - write_adbms_data(chips, WRCFGA, Config, A); - write_adbms_data(chips, WRCFGB, Config, B); -} - /** * @brief Initialize chips with default values. * @@ -400,58 +111,21 @@ void segment_init(acc_data_t *bmsdata) bmsdata->chip_data[chip].alpha = chip % 2 == 0; } write_config_regs(bmsdata->chips); -} - -/** - * @brief Get voltage readings from the C-ADCs. Takes a single shot measurement. - * - * @param chips Array of chips to get voltage readings from. - */ -void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]) -{ - write_config_regs(chips); - // Take single shot measurement - adBms6830_Adcv(RD_OFF, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); - adBmsPollAdc(PLCADC); - read_adbms_data(chips, RDCVALL, Rdcvall, ALL_GRP); + start_c_adc_conv(); } -/** - * @brief Get voltages from the S-ADCs. Makes a single shot measurement. - * - * @param chip Array of chips to get voltage readings from. - */ -void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) -{ - write_config_regs(chips); - adbms_wake(); - adBms6830_Adsv(SINGLE, DCP_OFF, OW_OFF_ALL_CH); - adBmsPollAdc(PLSADC); - - adbms_wake(); - read_adbms_data(chips, RDSALL, Rdsall, ALL_GRP); - // read_adbms_data(chip, RDSVA, S_volt, A); - // read_adbms_data(chip, RDSVB, S_volt, B); - // read_adbms_data(chip, RDSVC, S_volt, C); - // read_adbms_data(chip, RDSVD, S_volt, D); - // read_adbms_data(chip, RDSVE, S_volt, E); - // read_adbms_data(chip, RDSVF, S_volt, F); -} - -void get_adc_comparison(acc_data_t *bmsdata) +void segment_adc_comparison(acc_data_t *bmsdata) { // TODO: S-ADC measurements are all over the place. - write_config_regs(bmsdata->chips); - // Take single shot measurement - adBms6830_Adcv(RD_ON, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); - adBmsPollAdc(PLCADC); - read_adbms_data(bmsdata->chips, RDCVALL, Rdcvall, ALL_GRP); + // adBms6830_Adcv(RD_ON, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); + // adBmsPollAdc(PLCADC); + // read_adbms_data(bmsdata->chips, RDCVALL, Rdcvall, ALL_GRP); // Result of C-ADC and S-ADC comparison is stored in status register group C - read_adbms_data(bmsdata->chips, RDSTATC, Status, C); + read_status_registers(bmsdata->chips); for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { uint8_t cells = get_num_cells(&bmsdata->chip_data[chip]); @@ -460,8 +134,9 @@ void get_adc_comparison(acc_data_t *bmsdata) cell)) { printf("ADC VOLTAGE DISCREPANCY ERROR\nChip %d, Cell %d\nC-ADC: %f, S-ADC: %f\n", chip + 1, cell + 1, - getVoltage(bmsdata->chips[chip] - .cell.c_codes[cell]), + getVoltage( + bmsdata->chips[chip] + .fcell.fc_codes[cell]), getVoltage( bmsdata->chips[chip] .scell.sc_codes[cell])); @@ -470,142 +145,70 @@ void get_adc_comparison(acc_data_t *bmsdata) } } -/** - * @brief Get the avgeraged cell voltages. - * - * @param chip Array of chips to get voltage readings of. - */ -void get_avgd_cell_voltages(cell_asic chips[NUM_CHIPS]) +void segment_monitor_flts(cell_asic chips[NUM_CHIPS]) { - write_config_regs(chips); - adbms_wake(); - adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); - adBmsPollAdc(PLCADC); - - adbms_wake(); - read_adbms_data(chips, RDACALL, Rdacall, ALL_GRP); -} - -/** - * @brief Get the filtered cell volrages. - * - * @param chip Array of chips to get voltage readings of. - */ -void get_filtered_cell_voltages(cell_asic chips[NUM_CHIPS]) -{ - write_config_regs(chips); - adbms_wake(); - adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); - adBmsPollAdc(PLCADC); - - adbms_wake(); - read_adbms_data(chips, RDFCALL, Rdfcall, ALL_GRP); -} - -/** - * @brief Get the c and s adc voltages. Does this with RDCSALL command. - * - * @param chips Array of chips to get voltage readings of. - */ -void get_c_and_s_adc_voltages(cell_asic chips[NUM_CHIPS]) -{ - write_config_regs(chips); - adbms_wake(); - adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); - adBmsPollAdc(PLCADC); - - adbms_wake(); - read_adbms_data(chips, RDCSALL, Rdcsall, ALL_GRP); -} - -/** - * @brief Read every register connected to the AUX ADC. - * - * @param chips Array of chips to get voltage readings of. - */ -void read_aux_registers(cell_asic chips[NUM_CHIPS]) -{ - write_config_regs(chips); - adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); - adBmsPollAdc(PLAUX1); - - adbms_wake(); - read_adbms_data(chips, RDAUXA, Aux, A); - read_adbms_data(chips, RDAUXB, Aux, B); - read_adbms_data(chips, RDAUXC, Aux, C); - read_adbms_data(chips, RDAUXD, Aux, D); -} - -/** - * @brief Read voltages in every register connected to AUX2 ADC. - * - * @param chips Array of chips to get voltages of. - */ -void read_aux2_registers(cell_asic chips[NUM_CHIPS]) -{ - write_config_regs(chips); - adBms6830_Adax2(AUX_ALL); - adBmsPollAdc(PLAUX2); - - adbms_wake(); - read_adbms_data(chips, RDRAXA, RAux, A); - read_adbms_data(chips, RDRAXB, RAux, B); - read_adbms_data(chips, RDRAXC, RAux, C); - read_adbms_data(chips, RDRAXD, RAux, D); -} - -/** - * @brief Read status registers. - * - * @param chips Array of chips to read. - */ -void read_status_registers(cell_asic chips[NUM_CHIPS]) -{ - write_config_regs(chips); - adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); - adBmsPollAdc(PLAUX1); - - read_adbms_data(chips, RDSTATA, Status, A); - read_adbms_data(chips, RDSTATB, Status, B); - read_adbms_data(chips, RDSTATC, Status, C); - read_adbms_data(chips, RDSTATD, Status, D); - read_adbms_data(chips, RDSTATE, Status, E); + read_status_registers(chips); + for (int chip = 0; chip < NUM_CHIPS; chip++) { + if (chips[chip].statc.va_ov) { + printf("A OV FLT\n"); + } + if (chips[chip].statc.va_uv) { + printf("A UV FLT\n"); + } + if (chips[chip].statc.vd_ov) { + printf("D OV FLT\n"); + } + if (chips[chip].statc.vd_uv) { + printf("D OV FLT\n"); + } + if (chips[chip].statc.vde) { + printf("VDE FLT\n"); + } + if (chips[chip].statc.vdel) { + printf("VDEL FLT\n"); + } + if (chips[chip].statc.spiflt) { + printf("SPI SLV FLT\n"); + } + if (chips[chip].statc.sleep) { + printf("SLEEP OCCURED\n"); + } + if (chips[chip].statc.thsd) { + printf("THERMAL FLT\n"); + } + if (chips[chip].statc.oscchk) { + printf("OSC FLT\n"); + } + if (chips[chip].statc.otp1_med) { + printf("CMED? FLT\n"); + } + if (chips[chip].statc.otp2_med) { + printf("SMED? FLT\n"); + } + } + // clear them + write_clear_flags(chips); } -/** - * @brief Read status and aux registers in one command. - * - * @param chips Array of chips to read. - */ -void read_status_aux_registers(cell_asic chips[NUM_CHIPS]) +// ensure stuff used is in the correctfunction +void segment_retrieve_data(acc_data_t *bmsdata) { - write_config_regs(chips); - adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); - adBmsPollAdc(PLAUX1); + // read from ADC convs + read_filtered_voltage_registers(bmsdata->chips); - read_adbms_data(chips, RDASALL, Rdasall, ALL_GRP); -} + // check our fault flags + segment_monitor_flts(bmsdata->chips); -/** - * @brief Read the serial ID of the chip. - * - * @param chips Array of chips to read. - */ -void read_serial_id(cell_asic chips[NUM_CHIPS]) -{ - read_adbms_data(chips, RDSID, Sid, NONE); + // read all therms using AUX 2 + adc_and_read_aux2_registers(bmsdata->chips); } - -void segment_retrieve_data(acc_data_t *bmsdata) +void segment_retrieve_debug_data(acc_data_t *bmsdata) { - // printf("Get C adc voltages\n"); - get_c_adc_voltages(bmsdata->chips); - - // The GPIOs in the AUX registers contain voltage readings from the therms. - read_status_aux_registers(bmsdata->chips); + // poll stuff like vref, etc. + adc_and_read_aux_registers(bmsdata->chips); - // If you want redundant Thermistor readings, uncomment the following. - // read_aux2_registers(bmsdata->chips); + // read the above into status registers + read_status_registers(bmsdata->chips); } bool segment_is_balancing(cell_asic chips[NUM_CHIPS]) @@ -640,7 +243,7 @@ void segment_configure_balancing( set_mute_state(&bmsdata->chips[chip], false); } } - write_config_regs(bmsdata->chips); + // write_config_regs(bmsdata->chips); } // void averaging_therm_check(chipdata_t segment_data[NUM_CHIPS]) diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index 0438a325..a51bd754 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -115,7 +115,7 @@ void vDebugMode(void *pv_params) // read_serial_id(bmsdata->chips); - read_aux2_registers(bmsdata->chips); + segment_retrieve_debug_data(bmsdata); for (int chip = 0; chip < NUM_CHIPS; chip++) { uint8_t num_cells = @@ -149,7 +149,7 @@ void vDebugMode(void *pv_params) (bmsdata->chips[chip].tx_cfgb.dcc >> (cell + 1)) & 1); - osDelay(6); + osDelay(1000 / NUM_CHIPS); } // Send chip status messages @@ -171,10 +171,11 @@ void vDebugMode(void *pv_params) .stata.itmp) / 0.0075) - 273, - 10000 * getVoltage( + 10000 * 20 * + getVoltage( // VPV is ra_code 11 w/ different scale bmsdata->chips[chip] .raux - .ra_codes[9])); + .ra_codes[11])); compute_send_beta_status_b_message( 10000 * getVoltage( bmsdata->chips[chip] @@ -186,10 +187,11 @@ void vDebugMode(void *pv_params) chip, 10000 * getVoltage(bmsdata->chips[chip] .statb.vr4k), - 10000 * getVoltage( + 10000 * 20 * + getVoltage( // VMV is ra_code 10 bmsdata->chips[chip] .raux - .ra_codes[8])); + .ra_codes[10])); } else { compute_send_alpha_status_a_message( bmsdata->chip_data->on_board_temp, chip, diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index ff4b34b8..a77906b1 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -455,7 +455,7 @@ void sm_balance_cells(acc_data_t *bmsdata) for (uint8_t cell = 0; cell < num_cells; cell++) { uint16_t delta = - bmsdata->chips[chip].cell.c_codes[cell] - + bmsdata->chips[chip].fcell.fc_codes[cell] - (uint16_t)bmsdata->min_voltage.val; if (delta > MAX_DELTA_V * 10000) balanceConfig[chip][cell] = true; diff --git a/Core/Src/stm32f4xx_hal_msp.c b/Core/Src/stm32f4xx_hal_msp.c index 4b82fd5f..116021cd 100644 --- a/Core/Src/stm32f4xx_hal_msp.c +++ b/Core/Src/stm32f4xx_hal_msp.c @@ -20,7 +20,6 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" - /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ @@ -68,6 +67,7 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); */ void HAL_MspInit(void) { + /* USER CODE BEGIN MspInit 0 */ /* USER CODE END MspInit 0 */ @@ -282,6 +282,8 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) /* CAN2 interrupt Init */ HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn); /* USER CODE BEGIN CAN2_MspInit 1 */ /* USER CODE END CAN2_MspInit 1 */ @@ -340,6 +342,7 @@ void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan) /* CAN2 interrupt DeInit */ HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn); /* USER CODE BEGIN CAN2_MspDeInit 1 */ /* USER CODE END CAN2_MspDeInit 1 */ @@ -379,6 +382,7 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) /* USER CODE BEGIN I2C1_MspInit 1 */ /* USER CODE END I2C1_MspInit 1 */ + } } @@ -609,6 +613,17 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) /* USER CODE END TIM2_MspInit 1 */ } + else if(htim_base->Instance==TIM5) + { + /* USER CODE BEGIN TIM5_MspInit 0 */ + + /* USER CODE END TIM5_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM5_CLK_ENABLE(); + /* USER CODE BEGIN TIM5_MspInit 1 */ + + /* USER CODE END TIM5_MspInit 1 */ + } else if(htim_base->Instance==TIM8) { /* USER CODE BEGIN TIM8_MspInit 0 */ @@ -703,6 +718,17 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) /* USER CODE END TIM2_MspDeInit 1 */ } + else if(htim_base->Instance==TIM5) + { + /* USER CODE BEGIN TIM5_MspDeInit 0 */ + + /* USER CODE END TIM5_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM5_CLK_DISABLE(); + /* USER CODE BEGIN TIM5_MspDeInit 1 */ + + /* USER CODE END TIM5_MspDeInit 1 */ + } else if(htim_base->Instance==TIM8) { /* USER CODE BEGIN TIM8_MspDeInit 0 */ @@ -771,6 +797,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart) /* USER CODE BEGIN UART4_MspInit 1 */ /* USER CODE END UART4_MspInit 1 */ + } } @@ -847,6 +874,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ /* USER CODE END USB_OTG_FS_MspInit 1 */ + } } diff --git a/Core/Src/stm32f4xx_hal_timebase_tim.c b/Core/Src/stm32f4xx_hal_timebase_tim.c new file mode 100644 index 00000000..2e90dc2d --- /dev/null +++ b/Core/Src/stm32f4xx_hal_timebase_tim.c @@ -0,0 +1,138 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f4xx_hal_timebase_tim.c + * @brief HAL time base based on the hardware TIM. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" +#include "stm32f4xx_hal_tim.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +TIM_HandleTypeDef htim3; +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief This function configures the TIM3 as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority: Tick interrupt priority. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock, uwAPB1Prescaler = 0U; + + uint32_t uwPrescalerValue = 0U; + uint32_t pFLatency; + + HAL_StatusTypeDef status; + + /* Enable TIM3 clock */ + __HAL_RCC_TIM3_CLK_ENABLE(); + +/* Get clock configuration */ + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + + /* Get APB1 prescaler */ + uwAPB1Prescaler = clkconfig.APB1CLKDivider; + /* Compute TIM3 clock */ + if (uwAPB1Prescaler == RCC_HCLK_DIV1) + { + uwTimclock = HAL_RCC_GetPCLK1Freq(); + } + else + { + uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq(); + } + + /* Compute the prescaler value to have TIM3 counter clock equal to 1MHz */ + uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U); + + /* Initialize TIM3 */ + htim3.Instance = TIM3; + + /* Initialize TIMx peripheral as follow: + + + Period = [(TIM3CLK/1000) - 1]. to have a (1/1000) s time base. + + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. + + ClockDivision = 0 + + Counter direction = Up + */ + htim3.Init.Period = (1000000U / 1000U) - 1U; + htim3.Init.Prescaler = uwPrescalerValue; + htim3.Init.ClockDivision = 0; + htim3.Init.CounterMode = TIM_COUNTERMODE_UP; + htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + + status = HAL_TIM_Base_Init(&htim3); + if (status == HAL_OK) + { + /* Start the TIM time Base generation in interrupt mode */ + status = HAL_TIM_Base_Start_IT(&htim3); + if (status == HAL_OK) + { + /* Enable the TIM3 global Interrupt */ + HAL_NVIC_EnableIRQ(TIM3_IRQn); + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + /* Configure the TIM IRQ priority */ + HAL_NVIC_SetPriority(TIM3_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + status = HAL_ERROR; + } + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Suspend Tick increment. + * @note Disable the tick increment by disabling TIM3 update interrupt. + * @param None + * @retval None + */ +void HAL_SuspendTick(void) +{ + /* Disable TIM3 update Interrupt */ + __HAL_TIM_DISABLE_IT(&htim3, TIM_IT_UPDATE); +} + +/** + * @brief Resume Tick increment. + * @note Enable the tick increment by Enabling TIM3 update interrupt. + * @param None + * @retval None + */ +void HAL_ResumeTick(void) +{ + /* Enable TIM3 Update interrupt */ + __HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE); +} + diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c index 5ed2a906..eea515e8 100644 --- a/Core/Src/stm32f4xx_it.c +++ b/Core/Src/stm32f4xx_it.c @@ -20,8 +20,6 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f4xx_it.h" -#include "FreeRTOS.h" -#include "task.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "can_handler.h" @@ -63,6 +61,8 @@ extern CAN_HandleTypeDef hcan1; extern CAN_HandleTypeDef hcan2; extern DMA_HandleTypeDef hdma_uart4_tx; extern UART_HandleTypeDef huart4; +extern TIM_HandleTypeDef htim3; + /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -158,28 +158,6 @@ void DebugMon_Handler(void) /* USER CODE END DebugMonitor_IRQn 1 */ } -/** - * @brief This function handles System tick timer. - */ -void SysTick_Handler(void) -{ - /* USER CODE BEGIN SysTick_IRQn 0 */ - - /* USER CODE END SysTick_IRQn 0 */ - HAL_IncTick(); -#if (INCLUDE_xTaskGetSchedulerState == 1 ) - if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) - { -#endif /* INCLUDE_xTaskGetSchedulerState */ - xPortSysTickHandler(); -#if (INCLUDE_xTaskGetSchedulerState == 1 ) - } -#endif /* INCLUDE_xTaskGetSchedulerState */ - /* USER CODE BEGIN SysTick_IRQn 1 */ - - /* USER CODE END SysTick_IRQn 1 */ -} - /******************************************************************************/ /* STM32F4xx Peripheral Interrupt Handlers */ /* Add here the Interrupt Handlers for the used peripherals. */ @@ -201,20 +179,6 @@ void DMA1_Stream4_IRQHandler(void) /* USER CODE END DMA1_Stream4_IRQn 1 */ } -/** - * @brief This function handles UART4 global interrupt. - */ -void UART4_IRQHandler(void) -{ - /* USER CODE BEGIN UART4_IRQn 0 */ - - /* USER CODE END UART4_IRQn 0 */ - HAL_UART_IRQHandler(&huart4); - /* USER CODE BEGIN UART4_IRQn 1 */ - - /* USER CODE END UART4_IRQn 1 */ -} - /** * @brief This function handles CAN1 RX0 interrupts. */ @@ -229,6 +193,34 @@ void CAN1_RX0_IRQHandler(void) /* USER CODE END CAN1_RX0_IRQn 1 */ } +/** + * @brief This function handles TIM3 global interrupt. + */ +void TIM3_IRQHandler(void) +{ + /* USER CODE BEGIN TIM3_IRQn 0 */ + + /* USER CODE END TIM3_IRQn 0 */ + HAL_TIM_IRQHandler(&htim3); + /* USER CODE BEGIN TIM3_IRQn 1 */ + + /* USER CODE END TIM3_IRQn 1 */ +} + +/** + * @brief This function handles UART4 global interrupt. + */ +void UART4_IRQHandler(void) +{ + /* USER CODE BEGIN UART4_IRQn 0 */ + + /* USER CODE END UART4_IRQn 0 */ + HAL_UART_IRQHandler(&huart4); + /* USER CODE BEGIN UART4_IRQn 1 */ + + /* USER CODE END UART4_IRQn 1 */ +} + /** * @brief This function handles DMA2 stream0 global interrupt. */ @@ -257,6 +249,20 @@ void CAN2_RX0_IRQHandler(void) /* USER CODE END CAN2_RX0_IRQn 1 */ } +/** + * @brief This function handles CAN2 RX1 interrupt. + */ +void CAN2_RX1_IRQHandler(void) +{ + /* USER CODE BEGIN CAN2_RX1_IRQn 0 */ + + /* USER CODE END CAN2_RX1_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan2); + /* USER CODE BEGIN CAN2_RX1_IRQn 1 */ + + /* USER CODE END CAN2_RX1_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/Core/Src/syscalls.c b/Core/Src/syscalls.c new file mode 100644 index 00000000..e33a8492 --- /dev/null +++ b/Core/Src/syscalls.c @@ -0,0 +1,176 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeMX + * @brief Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Variables */ +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + + +char *__env[1] = { 0 }; +char **environ = __env; + + +/* Functions */ +void initialise_monitor_handles() +{ +} + +int _getpid(void) +{ + return 1; +} + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + errno = EINVAL; + return -1; +} + +void _exit (int status) +{ + _kill(status, -1); + while (1) {} /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + *ptr++ = __io_getchar(); + } + + return len; +} + +__attribute__((weak)) int _write(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + (void)file; + return -1; +} + + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _open(char *path, int flags, ...) +{ + (void)path; + (void)flags; + /* Pretend like we always fail */ + return -1; +} + +int _wait(int *status) +{ + (void)status; + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + (void)name; + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + (void)buf; + return -1; +} + +int _stat(char *file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + (void)old; + (void)new; + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + (void)name; + (void)argv; + (void)env; + errno = ENOMEM; + return -1; +} diff --git a/Core/Src/sysmem.c b/Core/Src/sysmem.c new file mode 100644 index 00000000..246470ee --- /dev/null +++ b/Core/Src/sysmem.c @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Generated by STM32CubeMX + * @brief System Memory calls file + * + * For more information about which C functions + * need which of these lowlevel functions + * please consult the newlib libc manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc + * and others from the C library + * + * @verbatim + * ############################################################################ + * # .data # .bss # newlib heap # MSP stack # + * # # # # Reserved by _Min_Stack_Size # + * ############################################################################ + * ^-- RAM start ^-- _end _estack, RAM end --^ + * @endverbatim + * + * This implementation starts allocating at the '_end' linker symbol + * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack + * The implementation considers '_estack' linker symbol to be RAM end + * NOTE: If the MSP stack, at any point during execution, grows larger than the + * reserved size, please increase the '_Min_Stack_Size'. + * + * @param incr Memory size + * @return Pointer to allocated memory + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + const uint8_t *max_heap = (uint8_t *)stack_limit; + uint8_t *prev_heap_end; + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) + { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing into the reserved MSP stack */ + if (__sbrk_heap_end + incr > max_heap) + { + errno = ENOMEM; + return (void *)-1; + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + return (void *)prev_heap_end; +} diff --git a/Drivers/adbms b/Drivers/adbms index eef63db1..c0e54fe0 160000 --- a/Drivers/adbms +++ b/Drivers/adbms @@ -1 +1 @@ -Subproject commit eef63db194526432e4c004820283badae4034e04 +Subproject commit c0e54fe0f2280b90ea6176444d1e3cdbfbc2164e diff --git a/Makefile b/Makefile index 1cad36b6..91cb92ff 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [4.2.0-B44] date: [Fri Nov 08 16:32:06 EST 2024] +# File automatically-generated by tool: [projectgenerator] version: [4.5.0-RC5] date: [Thu Jan 23 18:47:54 EST 2025] ########################################################################################################################## # ------------------------------------------------ @@ -41,6 +41,7 @@ Core/Src/analyzer.c \ Core/Src/compute.c \ Core/Src/eepromdirectory.c \ Core/Src/segment.c \ +Core/Src/adi_interaction.c \ Core/Src/stateMachine.c \ Core/Src/can_handler.c \ Core/Src/shep_tasks.c \ @@ -94,7 +95,10 @@ Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ Middlewares/Third_Party/FreeRTOS/Source/timers.c \ Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \ Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ -Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c +Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ +Core/Src/sysmem.c \ +Core/Src/syscalls.c \ +Core/Src/stm32f4xx_hal_timebase_tim.c # ASM sources ASM_SOURCES = \ @@ -184,7 +188,7 @@ CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" # LDFLAGS ####################################### # link script -LDSCRIPT = STM32F405RGTx_FLASH.ld +LDSCRIPT = stm32f405rgtx_flash.ld # libraries LIBS = -lc -lm -lnosys diff --git a/shepherd2.ioc b/shepherd2.ioc index 35cfe3e0..028e1f8f 100644 --- a/shepherd2.ioc +++ b/shepherd2.ioc @@ -67,8 +67,9 @@ Dma.UART4_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.UART4_TX.1.PeriphInc=DMA_PINC_DISABLE Dma.UART4_TX.1.Priority=DMA_PRIORITY_LOW Dma.UART4_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode -FREERTOS.IPParameters=Tasks01,configUSE_PREEMPTION,configUSE_MALLOC_FAILED_HOOK,configCHECK_FOR_STACK_OVERFLOW,configTOTAL_HEAP_SIZE -FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL +FREERTOS.FootprintOK=true +FREERTOS.IPParameters=Tasks01,configUSE_PREEMPTION,configUSE_MALLOC_FAILED_HOOK,configCHECK_FOR_STACK_OVERFLOW,configTOTAL_HEAP_SIZE,FootprintOK +FREERTOS.Tasks01=defaultTask,24,256,StartDefaultTask,Default,acc_data,Dynamic,NULL,NULL FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2 FREERTOS.configTOTAL_HEAP_SIZE=30000 FREERTOS.configUSE_MALLOC_FAILED_HOOK=1 @@ -88,9 +89,10 @@ Mcu.IP12=SPI3 Mcu.IP13=SYS Mcu.IP14=TIM1 Mcu.IP15=TIM2 -Mcu.IP16=TIM8 -Mcu.IP17=UART4 -Mcu.IP18=USB_OTG_FS +Mcu.IP16=TIM5 +Mcu.IP17=TIM8 +Mcu.IP18=UART4 +Mcu.IP19=USB_OTG_FS Mcu.IP2=CAN1 Mcu.IP3=CAN2 Mcu.IP4=DMA @@ -99,7 +101,7 @@ Mcu.IP6=I2C1 Mcu.IP7=IWDG Mcu.IP8=NVIC Mcu.IP9=RCC -Mcu.IPNb=19 +Mcu.IPNb=20 Mcu.Name=STM32F405RGTx Mcu.Package=LQFP64 Mcu.Pin0=PC13-ANTI_TAMP @@ -150,20 +152,21 @@ Mcu.Pin49=PB9 Mcu.Pin5=PC0 Mcu.Pin50=VP_FREERTOS_VS_CMSIS_V2 Mcu.Pin51=VP_IWDG_VS_IWDG -Mcu.Pin52=VP_SYS_VS_Systick +Mcu.Pin52=VP_SYS_VS_tim3 Mcu.Pin53=VP_TIM1_VS_ClockSourceINT Mcu.Pin54=VP_TIM2_VS_ClockSourceINT -Mcu.Pin55=VP_TIM8_VS_ClockSourceINT +Mcu.Pin55=VP_TIM5_VS_ClockSourceINT +Mcu.Pin56=VP_TIM8_VS_ClockSourceINT Mcu.Pin6=PC1 Mcu.Pin7=PC2 Mcu.Pin8=PC3 Mcu.Pin9=PA0-WKUP -Mcu.PinsNb=56 +Mcu.PinsNb=57 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F405RGTx -MxCube.Version=6.10.0 -MxDb.Version=DB.6.0.100 +MxCube.Version=6.13.0 +MxDb.Version=DB.6.0.130 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.CAN1_RX0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true NVIC.CAN2_RX0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true @@ -181,7 +184,10 @@ NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false NVIC.SavedPendsvIrqHandlerGenerated=true NVIC.SavedSvcallIrqHandlerGenerated=true NVIC.SavedSystickIrqHandlerGenerated=true -NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:true\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false +NVIC.TIM3_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true +NVIC.TimeBase=TIM3_IRQn +NVIC.TimeBaseIP=TIM3 NVIC.UART4_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false PA0-WKUP.Mode=Asynchronous @@ -436,11 +442,11 @@ SPI2.Mode=SPI_MODE_MASTER SPI2.NSS=SPI_NSS_SOFT SPI2.TIMode=SPI_TIMODE_DISABLE SPI2.VirtualType=VM_MASTER -SPI3.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2 +SPI3.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8 SPI3.CLKPhase=SPI_PHASE_1EDGE SPI3.CLKPolarity=SPI_POLARITY_LOW SPI3.CRCCalculation=SPI_CRCCALCULATION_DISABLE -SPI3.CalculateBaudRate=8.0 MBits/s +SPI3.CalculateBaudRate=2.0 MBits/s SPI3.DataSize=SPI_DATASIZE_8BIT SPI3.Direction=SPI_DIRECTION_2LINES SPI3.FirstBit=SPI_FIRSTBIT_MSB @@ -452,6 +458,9 @@ SPI3.VirtualType=VM_MASTER TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 TIM1.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation3 CH3 +TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_DISABLE +TIM2.IPParameters=Prescaler,AutoReloadPreload +TIM2.Prescaler=16 TIM8.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 TIM8.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 TIM8.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 @@ -475,12 +484,14 @@ VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2 VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG -VP_SYS_VS_Systick.Mode=SysTick -VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_SYS_VS_tim3.Mode=TIM3 +VP_SYS_VS_tim3.Signal=SYS_VS_tim3 VP_TIM1_VS_ClockSourceINT.Mode=Internal VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT VP_TIM2_VS_ClockSourceINT.Mode=Internal VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT +VP_TIM5_VS_ClockSourceINT.Mode=Internal +VP_TIM5_VS_ClockSourceINT.Signal=TIM5_VS_ClockSourceINT VP_TIM8_VS_ClockSourceINT.Mode=Internal VP_TIM8_VS_ClockSourceINT.Signal=TIM8_VS_ClockSourceINT board=custom diff --git a/stm32f405rgtx_flash.ld b/stm32f405rgtx_flash.ld new file mode 100644 index 00000000..4dcf56f0 --- /dev/null +++ b/stm32f405rgtx_flash.ld @@ -0,0 +1,208 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : STM32CubeMX +** +** Abstract : Linker script for STM32F405RGTx series +** 1024Kbytes FLASH and 192Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed “as is,” without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2019 STMicroelectronics

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of STMicroelectronics nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + +} + + From b9218f206eb1abda00c531dedfce789a429b6b69 Mon Sep 17 00:00:00 2001 From: Jack Rubacha Date: Fri, 24 Jan 2025 20:29:52 -0500 Subject: [PATCH 28/32] fixups --- Core/Inc/datastructs.h | 1 - Core/Src/compute.c | 36 ------- Core/Src/segment.c | 12 +-- STM32F405RGTx_FLASH.ld | 209 ----------------------------------------- 4 files changed, 5 insertions(+), 253 deletions(-) delete mode 100644 STM32F405RGTx_FLASH.ld diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index fe7545ac..781ab1de 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -93,7 +93,6 @@ typedef struct { /* Array of structs containing raw data from and configurations for the ADBMS6830 chips */ cell_asic chips[NUM_CHIPS]; - int fault_status; int fault_status; // FIXME: this field is unused int16_t pack_current; /* this value is multiplied by 10 to account for decimal precision */ diff --git a/Core/Src/compute.c b/Core/Src/compute.c index 633a5b64..e7de1add 100644 --- a/Core/Src/compute.c +++ b/Core/Src/compute.c @@ -435,42 +435,6 @@ void compute_send_cell_voltage_message(acc_data_t *bmsdata) queue_can_msg(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) -{ - 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 msg; - msg.id = CELL_VOLTAGE_CANID; - msg.len = CELL_VOLTAGE_SIZE; - - memcpy(msg.data, &cell_voltage_msg_data, sizeof(cell_voltage_msg_data)); - - queue_can_msg(msg); -} - void compute_send_current_message(acc_data_t *bmsdata) { struct __attribute__((__packed__)) { diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 065d3569..ac9a9de6 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -13,13 +13,11 @@ #define T_SLEEP 1.8 /* seconds minimum, typ is 2, max is 2.2 */ #define T_REFUP 2.7 /* milliseconds minimum, typ is 3.5, max is 4.4 */ -#define THERM_WAIT_TIME 500 /* ms */ -#define VOLTAGE_WAIT_TIME 500 /* 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 500 /* ms */ +#define THERM_AVG 15 /* Number of values to average */ +#define MAX_VOLT_DELTA 2500 +#define MAX_CONSEC_NOISE 10 extern TIM_HandleTypeDef htim2; diff --git a/STM32F405RGTx_FLASH.ld b/STM32F405RGTx_FLASH.ld deleted file mode 100644 index 6f1d7fe7..00000000 --- a/STM32F405RGTx_FLASH.ld +++ /dev/null @@ -1,209 +0,0 @@ -/* -****************************************************************************** -** - -** File : LinkerScript.ld -** -** Author : STM32CubeMX -** -** Abstract : Linker script for STM32F405RGTx series -** 1024Kbytes FLASH and 192Kbytes RAM -** -** Set heap size, stack size and stack location according -** to application requirements. -** -** Set memory bank area and size if external memory is used. -** -** Target : STMicroelectronics STM32 -** -** Distribution: The file is distributed “as is,” without any warranty -** of any kind. -** -***************************************************************************** -** @attention -** -**

© COPYRIGHT(c) 2019 STMicroelectronics

-** -** Redistribution and use in source and binary forms, with or without modification, -** are permitted provided that the following conditions are met: -** 1. Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** 3. Neither the name of STMicroelectronics nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -***************************************************************************** -*/ - -/* Entry Point */ -ENTRY(Reset_Handler) - -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ -RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K -CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K -FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K -} - -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into FLASH */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM AT> FLASH - - _siccmram = LOADADDR(.ccmram); - - /* CCM-RAM section - * - * IMPORTANT NOTE! - * If initialized variables will be placed in this section, - * the startup code needs to be modified to copy the init-values. - */ - .ccmram : - { - . = ALIGN(4); - _sccmram = .; /* create a global symbol at ccmram start */ - *(.ccmram) - *(.ccmram*) - - . = ALIGN(4); - _eccmram = .; /* create a global symbol at ccmram end */ - } >CCMRAM AT> FLASH - - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM - - - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } -} - - From 3426aaabc3afae276115556ed28ce95ef5892e7d Mon Sep 17 00:00:00 2001 From: Jack Rubacha Date: Fri, 24 Jan 2025 20:30:26 -0500 Subject: [PATCH 29/32] fmt --- Core/Inc/can_handler.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Core/Inc/can_handler.h b/Core/Inc/can_handler.h index d6214258..d197992c 100644 --- a/Core/Inc/can_handler.h +++ b/Core/Inc/can_handler.h @@ -40,17 +40,17 @@ #define NOISE_SIZE 6 #define DEBUG_CANID 0x702 -#define ALPHA_CELL_CANID 0x6FA -#define BETA_CELL_CANID 0x6FB -#define CELL_MSG_SIZE 7 -#define BETA_STAT_A_CANID 0x6FD -#define BETA_STAT_A_SIZE 8 -#define BETA_STAT_B_CANID 0x6FE -#define BETA_STAT_B_SIZE 8 -#define ALPHA_STAT_A_CANID 0x6FC -#define ALPHA_STAT_A_SIZE 7 -#define ALPHA_STAT_B_CANID 0x6FF -#define ALPHA_STAT_B_SIZE 7 +#define ALPHA_CELL_CANID 0x6FA +#define BETA_CELL_CANID 0x6FB +#define CELL_MSG_SIZE 7 +#define BETA_STAT_A_CANID 0x6FD +#define BETA_STAT_A_SIZE 8 +#define BETA_STAT_B_CANID 0x6FE +#define BETA_STAT_B_SIZE 8 +#define ALPHA_STAT_A_CANID 0x6FC +#define ALPHA_STAT_A_SIZE 7 +#define ALPHA_STAT_B_CANID 0x6FF +#define ALPHA_STAT_B_SIZE 7 typedef struct { uint32_t prev_tick; @@ -74,9 +74,9 @@ typedef enum { RL_MSG_COUNT } rate_lim_t; -#define DEBUG_SIZE 8 -#define FAULT_TIMER_CANID 0x6FF -#define FAULT_TIMER_SIZE 4 +#define DEBUG_SIZE 8 +#define FAULT_TIMER_CANID 0x6FF +#define FAULT_TIMER_SIZE 4 void can_receive_callback(CAN_HandleTypeDef *hcan); From 89db8b6ba14db6bbb5002e9b1ee56450fad95fe0 Mon Sep 17 00:00:00 2001 From: Jack Rubacha Date: Fri, 24 Jan 2025 21:13:19 -0500 Subject: [PATCH 30/32] segment reboot every 45 seconds --- Core/Inc/adi_interaction.h | 7 ++++++ Core/Inc/segment.h | 9 +++++++ Core/Src/adi_interaction.c | 49 +++++++++++++++++++++++++------------- Core/Src/segment.c | 9 ++++++- Core/Src/shep_tasks.c | 18 +++++++++----- 5 files changed, 69 insertions(+), 23 deletions(-) diff --git a/Core/Inc/adi_interaction.h b/Core/Inc/adi_interaction.h index d44e6889..da04d7dd 100644 --- a/Core/Inc/adi_interaction.h +++ b/Core/Inc/adi_interaction.h @@ -123,6 +123,13 @@ void set_discharge_timeout(cell_asic *chip, uint8_t timeout); // --- BEGIN WRITE COMMANDS --- +/** + * @brief Soft reset all chips, then re-wake them + * + * @param chips + */ +void soft_reset_chips(cell_asic chips[NUM_CHIPS]); + /** * @brief Write config registers. Wakes chips before writing. * diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index dfc2e0b6..37309e67 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -46,6 +46,15 @@ void segment_configure_balancing( */ bool segment_is_balancing(cell_asic chips[NUM_CHIPS]); + +/** + * @brief Reset, then wake, then re-configure all chips + * + * @param bmsdata + */ +void segment_restart(acc_data_t *bmsdata); + + /** * @brief Do a single shot, redundant C-ADC measurement and read * the contents of Status Register Group C, which contains the diff --git a/Core/Src/adi_interaction.c b/Core/Src/adi_interaction.c index 5a16948e..461cd219 100644 --- a/Core/Src/adi_interaction.c +++ b/Core/Src/adi_interaction.c @@ -107,7 +107,7 @@ void set_discharge_timeout(cell_asic *chip, uint8_t timeout) // void start_cell_voltages_adc(cell_asic chips[NUM_CHIPS]) // { -// adbms_wake(); +// adbms_wake_isospi(); // adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); // adBmsPollAdc(PLCADC); // } @@ -133,10 +133,10 @@ inline void delay_us(uint16_t us) } /** - * @brief Wake every ADBMS6830 IC in the daisy chain. Blocking wait for around 30us * NUM_CHIPS. + * @brief Wake the isoSPI of every ADBMS6830 IC in the daisy chain. Blocking wait for around 30us * NUM_CHIPS. * */ -void adbms_wake() +void adbms_wake_isospi() { for (uint8_t ic = 0; ic < NUM_CHIPS; ic++) { adBmsCsLow(); @@ -145,6 +145,18 @@ void adbms_wake() } } +/** + * @brief Wake the chip of every ADBMS6830 IC. Blocking wait about 1ms * NUM_CHIPS + * + */ +void adbms_wake_core() { + for (uint8_t ic = 0; ic < NUM_CHIPS; ic++) { + adBmsCsLow(); + adBmsCsHigh(); + delay_us(1000); + } +} + /** * @brief Write data to all chips. * @@ -156,7 +168,7 @@ void adbms_wake() void write_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, GRP group) { - adbms_wake(); + adbms_wake_isospi(); for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { adBmsWriteData(NUM_CHIPS, &chips[chip], command, type, group); @@ -174,7 +186,7 @@ void write_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, GRP group) { - adbms_wake(); + adbms_wake_isospi(); for (uint8_t chip = 0; chip < NUM_CHIPS; chip++) { adBmsReadData(NUM_CHIPS, &chips[chip], command, type, group); @@ -216,6 +228,11 @@ void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, // --- BEGIN WRITE COMMANDS --- +void soft_reset_chips(cell_asic chips[NUM_CHIPS]) { + write_adbms_data(chips, SRST, Comm, NONE); + adbms_wake_core(); +} + void write_config_regs(cell_asic chips[NUM_CHIPS]) { write_adbms_data(chips, WRCFGA, Config, A); @@ -257,7 +274,7 @@ void read_filtered_voltage_registers(cell_asic chips[NUM_CHIPS]) void adc_and_read_aux_registers(cell_asic chips[NUM_CHIPS]) { // TODO only poll correct GPIOs - adbms_wake(); + adbms_wake_isospi(); adBms6830_Adax(AUX_OW_OFF, PUP_DOWN, AUX_ALL); adBmsPollAdc(PLAUX2); @@ -269,7 +286,7 @@ void adc_and_read_aux_registers(cell_asic chips[NUM_CHIPS]) void adc_and_read_aux2_registers(cell_asic chips[NUM_CHIPS]) { - adbms_wake(); + adbms_wake_isospi(); adBms6830_Adax2(AUX_ALL); adBmsPollAdc(PLAUX2); @@ -304,7 +321,7 @@ void read_serial_id(cell_asic chips[NUM_CHIPS]) void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]) { - adbms_wake(); + adbms_wake_isospi(); // Take single shot measurement adBms6830_Adcv(RD_OFF, SINGLE, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); @@ -314,11 +331,11 @@ void get_c_adc_voltages(cell_asic chips[NUM_CHIPS]) void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) { write_config_regs(chips); - adbms_wake(); + adbms_wake_isospi(); adBms6830_Adsv(SINGLE, DCP_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLSADC); - adbms_wake(); + adbms_wake_isospi(); read_adbms_data(chips, RDSALL, Rdsall, ALL_GRP); // read_adbms_data(chip, RDSVA, S_volt, A); // read_adbms_data(chip, RDSVB, S_volt, B); @@ -330,33 +347,33 @@ void get_s_adc_voltages(cell_asic chips[NUM_CHIPS]) void get_avgd_cell_voltages(cell_asic chips[NUM_CHIPS]) { - adbms_wake(); + adbms_wake_isospi(); adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); - adbms_wake(); + adbms_wake_isospi(); read_adbms_data(chips, RDACALL, Rdacall, ALL_GRP); } void get_filtered_cell_voltages(cell_asic chips[NUM_CHIPS]) { - adbms_wake(); + adbms_wake_isospi(); read_adbms_data(chips, RDFCALL, Rdfcall, ALL_GRP); } void get_c_and_s_adc_voltages(cell_asic chips[NUM_CHIPS]) { - adbms_wake(); + adbms_wake_isospi(); adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_OFF, OW_OFF_ALL_CH); adBmsPollAdc(PLCADC); - adbms_wake(); + adbms_wake_isospi(); read_adbms_data(chips, RDCSALL, Rdcsall, ALL_GRP); } void start_c_adc_conv() { - adbms_wake(); + adbms_wake_isospi(); adBms6830_Adcv(RD_ON, CONTINUOUS, DCP_OFF, RSTF_ON, OW_OFF_ALL_CH); } diff --git a/Core/Src/segment.c b/Core/Src/segment.c index ac9a9de6..2c7cb6b8 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -44,7 +44,7 @@ void init_chip(cell_asic *chip) { set_REFON(chip, PWR_UP); // WARNING, THE ENUM IS WRONG, CHECK TABLE 102 - set_volt_adc_comp_thresh(chip, CVT_45mV); + set_volt_adc_comp_thresh(chip, CVT_135mV); chip->tx_cfga.flag_d = 0; // Short soak on ADAX @@ -207,6 +207,13 @@ void segment_retrieve_debug_data(acc_data_t *bmsdata) // read the above into status registers read_status_registers(bmsdata->chips); + + //segment_adc_comparison(bmsdata); +} + +void segment_restart(acc_data_t *bmsdata) { + soft_reset_chips(bmsdata->chips); + segment_init(bmsdata); } bool segment_is_balancing(cell_asic chips[NUM_CHIPS]) diff --git a/Core/Src/shep_tasks.c b/Core/Src/shep_tasks.c index a51bd754..89ebd856 100644 --- a/Core/Src/shep_tasks.c +++ b/Core/Src/shep_tasks.c @@ -29,9 +29,21 @@ const osThreadAttr_t get_segment_data_attrs = { .name = "Get Segment Data", void vGetSegmentData(void *pv_params) { acc_data_t *bmsdata = (acc_data_t *)pv_params; + + int i = 0; for (;;) { // printf("Get segment data\n"); segment_retrieve_data(bmsdata); + + if (DEBUG_MODE_ENABLED) { + segment_retrieve_debug_data(bmsdata); + } + + if (++i % (45 * SAMPLE_RATE) == 0) { + printf(" *********** REBOOTING SEGMENT\n\n"); + segment_restart(bmsdata); + } + osThreadFlagsSet(analyzer_thread, ANALYZER_FLAG); osDelay(1000 / SAMPLE_RATE); } @@ -111,12 +123,6 @@ void vDebugMode(void *pv_params) acc_data_t *bmsdata = (acc_data_t *)pv_params; while (69 < 420) { - // get_adc_comparison(bmsdata); - - // read_serial_id(bmsdata->chips); - - segment_retrieve_debug_data(bmsdata); - for (int chip = 0; chip < NUM_CHIPS; chip++) { uint8_t num_cells = get_num_cells(&bmsdata->chip_data[chip]); From a189aa7f9c4ad5e85551092f28bd1b5fc69771f2 Mon Sep 17 00:00:00 2001 From: Jack Rubacha Date: Fri, 24 Jan 2025 21:15:21 -0500 Subject: [PATCH 31/32] fmt --- Core/Src/adi_interaction.c | 8 +++++--- Core/Src/segment.c | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Core/Src/adi_interaction.c b/Core/Src/adi_interaction.c index 461cd219..e7b321a1 100644 --- a/Core/Src/adi_interaction.c +++ b/Core/Src/adi_interaction.c @@ -149,7 +149,8 @@ void adbms_wake_isospi() * @brief Wake the chip of every ADBMS6830 IC. Blocking wait about 1ms * NUM_CHIPS * */ -void adbms_wake_core() { +void adbms_wake_core() +{ for (uint8_t ic = 0; ic < NUM_CHIPS; ic++) { adBmsCsLow(); adBmsCsHigh(); @@ -228,10 +229,11 @@ void read_adbms_data(cell_asic chips[NUM_CHIPS], uint8_t command[2], TYPE type, // --- BEGIN WRITE COMMANDS --- -void soft_reset_chips(cell_asic chips[NUM_CHIPS]) { +void soft_reset_chips(cell_asic chips[NUM_CHIPS]) +{ write_adbms_data(chips, SRST, Comm, NONE); adbms_wake_core(); -} +} void write_config_regs(cell_asic chips[NUM_CHIPS]) { diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 2c7cb6b8..8370deff 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -211,7 +211,8 @@ void segment_retrieve_debug_data(acc_data_t *bmsdata) //segment_adc_comparison(bmsdata); } -void segment_restart(acc_data_t *bmsdata) { +void segment_restart(acc_data_t *bmsdata) +{ soft_reset_chips(bmsdata->chips); segment_init(bmsdata); } From d02da4a35d4684441a348a40deeadab4129dc9b0 Mon Sep 17 00:00:00 2001 From: Jack Rubacha Date: Fri, 24 Jan 2025 21:16:00 -0500 Subject: [PATCH 32/32] fmt --- Core/Inc/segment.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index 37309e67..5f899a74 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -46,7 +46,6 @@ void segment_configure_balancing( */ bool segment_is_balancing(cell_asic chips[NUM_CHIPS]); - /** * @brief Reset, then wake, then re-configure all chips * @@ -54,7 +53,6 @@ bool segment_is_balancing(cell_asic chips[NUM_CHIPS]); */ void segment_restart(acc_data_t *bmsdata); - /** * @brief Do a single shot, redundant C-ADC measurement and read * the contents of Status Register Group C, which contains the