diff --git a/libraries/core/inc/misc.h b/libraries/core/inc/misc.h index b28286632..0addbd2f6 100644 --- a/libraries/core/inc/misc.h +++ b/libraries/core/inc/misc.h @@ -4,7 +4,7 @@ #define SIZEOF_ARRAY(arr) (sizeof((arr)) / sizeof((arr)[0])) #define SIZEOF_FIELD(type, field) (sizeof(((type *)0)->field)) // Casts void * to uint8_t * -#define VOID_PTR_UINT8(x) (_Generic((x), void * : (uint8_t *)(x), default : (x))) +#define VOID_PTR_UINT8(x) (_Generic((x), void *: (uint8_t *)(x), default: (x))) #define SWAP_UINT16(x) (uint16_t)(((uint16_t)(x) >> 8) | ((uint16_t)(x) << 8)) #define STRINGIFY_(x) #x diff --git a/libraries/ms-common/inc/delay.h b/libraries/ms-common/inc/delay.h index 9f5e2b665..1c749f89c 100644 --- a/libraries/ms-common/inc/delay.h +++ b/libraries/ms-common/inc/delay.h @@ -16,4 +16,4 @@ void delay_ms(uint32_t t); void non_blocking_delay_ms(uint32_t t); // Delay for a period in seconds. -#define delay_s(time) delay_ms((time)*1000) +#define delay_s(time) delay_ms((time) * 1000) diff --git a/libraries/ms-common/inc/flash.h b/libraries/ms-common/inc/flash.h index 2cef7f5a5..5ea01ef12 100644 --- a/libraries/ms-common/inc/flash.h +++ b/libraries/ms-common/inc/flash.h @@ -13,7 +13,7 @@ #define FLASH_ADDR_TO_PAGE(addr) \ (((uintptr_t)(addr) - (uintptr_t)FLASH_BASE_ADDR) / FLASH_PAGE_BYTES) -#define FLASH_PAGE_TO_ADDR(page) ((uintptr_t)(page)*FLASH_PAGE_BYTES + (uintptr_t)FLASH_BASE_ADDR) +#define FLASH_PAGE_TO_ADDR(page) ((uintptr_t)(page) * FLASH_PAGE_BYTES + (uintptr_t)FLASH_BASE_ADDR) #define FLASH_WRITE_BYTES FLASH_MCU_WRITE_BYTES #define FLASH_PAGE_BYTES FLASH_MCU_PAGE_BYTES diff --git a/libraries/ms-drivers/inc/max17261_fuel_gauge.h b/libraries/ms-drivers/inc/max17261_fuel_gauge.h index af5c8a059..8856c3f2a 100644 --- a/libraries/ms-drivers/inc/max17261_fuel_gauge.h +++ b/libraries/ms-drivers/inc/max17261_fuel_gauge.h @@ -24,7 +24,9 @@ typedef struct { uint32_t pack_design_cap_mah; uint16_t cell_empty_voltage_v; - uint16_t charge_term_current_ma; // ref end-of-charge detection https://web.archive.org/web/20220121025712mp_/https://pdfserv.maximintegrated.com/en/an/user-guide-6597-max1726x-m5-ez-rev3-p4.pdf + uint16_t + charge_term_current_ma; // ref end-of-charge detection + // https://web.archive.org/web/20220121025712mp_/https://pdfserv.maximintegrated.com/en/an/user-guide-6597-max1726x-m5-ez-rev3-p4.pdf uint16_t i_thresh_max_a; int16_t i_thresh_min_a; @@ -108,7 +110,8 @@ StatusCode max17261_temp(Max17261Storage *storage, uint16_t *temp_c); * @param settings - populated settings struct * @return STATUS_CODE_OK on success */ -StatusCode max17261_init(Max17261Storage *storage, Max17261Settings *settings, Max27261Params *params); +StatusCode max17261_init(Max17261Storage *storage, Max17261Settings *settings, + Max27261Params *params); StatusCode max17261_set_learned_params(Max17261Storage *storage, Max27261Params *params); StatusCode max17261_get_learned_params(Max17261Storage *storage, Max27261Params *params); diff --git a/libraries/ms-drivers/src/max17261_fuel_gauge.c b/libraries/ms-drivers/src/max17261_fuel_gauge.c index a4814b3fb..65cd653c3 100644 --- a/libraries/ms-drivers/src/max17261_fuel_gauge.c +++ b/libraries/ms-drivers/src/max17261_fuel_gauge.c @@ -2,16 +2,18 @@ #include -#include "log.h" #include "delay.h" +#include "log.h" // See Table 3 on pg.18 of the datasheet -#define PCT_LSB (1.0f / 256) // (%) LSBit is 1/256% -#define CAP_LSB (5.0f / storage->settings->sense_resistor_mohms) // (mAh) LSBit is 5 mili Volt hrs / Rsense (mAh) -#define TIM_LSB (5625U) // (ms) LSBit is 5625ms -#define CUR_LSB (1.5625f / storage->settings->sense_resistor_mohms) // (mA) LSBit is 1.5625uA / Rsense -#define VOLT_LSB (1.25f / 16) // (mV) LSBit is 1.25mV / 16 -#define TEMP_LSB (1.0f / 256) // (C) LSBit is 1 / 256 C +#define PCT_LSB (1.0f / 256) // (%) LSBit is 1/256% +#define CAP_LSB \ + (5.0f / storage->settings->sense_resistor_mohms) // (mAh) LSBit is 5 mili Volt hrs / Rsense (mAh) +#define TIM_LSB (5625U) // (ms) LSBit is 5625ms +#define CUR_LSB \ + (1.5625f / storage->settings->sense_resistor_mohms) // (mA) LSBit is 1.5625uA / Rsense +#define VOLT_LSB (1.25f / 16) // (mV) LSBit is 1.25mV / 16 +#define TEMP_LSB (1.0f / 256) // (C) LSBit is 1 / 256 C static StatusCode max17261_get_reg(Max17261Storage *storage, Max17261Registers reg, uint16_t *value) { @@ -42,7 +44,7 @@ StatusCode max17261_state_of_charge(Max17261Storage *storage, uint16_t *soc_pct) uint16_t reg = 0; max17261_get_reg(storage, MAX17261_STATUS, ®); if (reg & (1 << 7)) { - max17261_set_reg(storage, MAX17261_STATUS, reg & (uint16_t)~(1 << 7)); + max17261_set_reg(storage, MAX17261_STATUS, reg & (uint16_t) ~(1 << 7)); } uint16_t status = 0; @@ -65,7 +67,7 @@ StatusCode max17261_full_capacity(Max17261Storage *storage, uint32_t *full_cap_m uint16_t full_cap_reg_val = 0; status_ok_or_return(max17261_get_reg(storage, MAX17261_FULL_CAP_REP, &full_cap_reg_val)); *full_cap_mAh = full_cap_reg_val * CAP_LSB; - + uint16_t design = 0; max17261_get_reg(storage, MAX17261_DESIGN_CAP, &design); LOG_DEBUG("DES CAP: %d\n", design); @@ -97,7 +99,7 @@ StatusCode max17261_current(Max17261Storage *storage, int16_t *current_ua) { StatusCode max17261_voltage(Max17261Storage *storage, uint16_t *vcell_mv) { uint16_t vcell_reg_val = 0; status_ok_or_return(max17261_get_reg(storage, MAX17261_VCELL, &vcell_reg_val)); - *vcell_mv = (uint16_t)((float)(vcell_reg_val) * VOLT_LSB); + *vcell_mv = (uint16_t)((float)(vcell_reg_val)*VOLT_LSB); return STATUS_CODE_OK; } @@ -121,25 +123,26 @@ StatusCode max17261_get_learned_params(Max17261Storage *storage, Max27261Params StatusCode max17261_set_learned_params(Max17261Storage *storage, Max27261Params *params) { status_ok_or_return(max17261_set_reg(storage, MAX17261_R_COMP0, params->rcomp0)); status_ok_or_return(max17261_set_reg(storage, MAX17261_TEMP_CO, params->tempco)); - //status_ok_or_return(max17261_set_reg(storage, MAX17261_FULL_CAP_REP, params->fullcaprep)); + // status_ok_or_return(max17261_set_reg(storage, MAX17261_FULL_CAP_REP, params->fullcaprep)); status_ok_or_return(max17261_set_reg(storage, MAX17261_CYCLES, params->cycles)); status_ok_or_return(max17261_set_reg(storage, MAX17261_FULL_CAP_NOM, params->fullcapnom)); return STATUS_CODE_OK; } -StatusCode max17261_init(Max17261Storage *storage, Max17261Settings *settings, Max27261Params *params) { +StatusCode max17261_init(Max17261Storage *storage, Max17261Settings *settings, + Max27261Params *params) { if (settings->i2c_port >= NUM_I2C_PORTS) { return STATUS_CODE_INVALID_ARGS; } storage->settings = settings; - // ** Based on https://web.archive.org/web/20240330212616/https://pdfserv.maximintegrated.com/en/an/MAX1726x-Software-Implementation-user-guide.pdf + // ** Based on + // https://web.archive.org/web/20240330212616/https://pdfserv.maximintegrated.com/en/an/MAX1726x-Software-Implementation-user-guide.pdf // Step 0 - check if already configured uint16_t status = 0; status_ok_or_return(max17261_get_reg(storage, MAX17261_STATUS, &status)); if ((status & 0x0002) != 0) { - // Step 1 -- delay until FSTAT.DNR bit == 0 uint16_t fstat = 0; status_ok_or_return(max17261_get_reg(storage, MAX17261_FSTAT, &fstat)); @@ -153,20 +156,23 @@ StatusCode max17261_init(Max17261Storage *storage, Max17261Settings *settings, M // Step 2 -- disable hibernation uint16_t hibcfg = 0; status_ok_or_return(max17261_get_reg(storage, MAX17261_HIB_CFG, &hibcfg)); - status_ok_or_return(max17261_set_reg(storage, MAX17261_SOFT_WAKEUP, 0x90)); // wakup ic + status_ok_or_return(max17261_set_reg(storage, MAX17261_SOFT_WAKEUP, 0x90)); // wakup ic status_ok_or_return(max17261_set_reg(storage, MAX17261_HIB_CFG, 0x0)); // disable hibernation - status_ok_or_return(max17261_set_reg(storage, MAX17261_SOFT_WAKEUP, 0x0)); // clear wakeup command - - delay_ms(10); // delay that seems to make it work, TODO ???? + status_ok_or_return( + max17261_set_reg(storage, MAX17261_SOFT_WAKEUP, 0x0)); // clear wakeup command - // Step 2.1 -- configure - status_ok_or_return(max17261_set_reg(storage, MAX17261_DESIGN_CAP, settings->pack_design_cap_mah / (uint32_t) CAP_LSB)); - status_ok_or_return(max17261_set_reg(storage, MAX17261_I_CHG_TERM, settings->charge_term_current_ma / CUR_LSB)); - status_ok_or_return(max17261_set_reg(storage, MAX17261_V_EMPTY, settings->cell_empty_voltage_v / VOLT_LSB)); - - status_ok_or_return(max17261_set_reg(storage, MAX17261_SOC_HOLD, 0x0)); // disable SOCHold, not relevant to us + delay_ms(10); // delay that seems to make it work, TODO ???? + // Step 2.1 -- configure + status_ok_or_return(max17261_set_reg(storage, MAX17261_DESIGN_CAP, + settings->pack_design_cap_mah / (uint32_t)CAP_LSB)); + status_ok_or_return( + max17261_set_reg(storage, MAX17261_I_CHG_TERM, settings->charge_term_current_ma / CUR_LSB)); + status_ok_or_return( + max17261_set_reg(storage, MAX17261_V_EMPTY, settings->cell_empty_voltage_v / VOLT_LSB)); + status_ok_or_return( + max17261_set_reg(storage, MAX17261_SOC_HOLD, 0x0)); // disable SOCHold, not relevant to us uint16_t modelcfg = /*refresh*/ (1 << 15) | /*R100*/ (0 << 13) | /*RChg*/ (0 << 10) | (1 << 3); status_ok_or_return(max17261_set_reg(storage, MAX17261_MODEL_I_CFG, modelcfg)); @@ -181,28 +187,30 @@ StatusCode max17261_init(Max17261Storage *storage, Max17261Settings *settings, M // Configure alerts uint16_t config = 0; status_ok_or_return(max17261_get_reg(storage, MAX17261_CONFIG, &config)); - config |= (1 << 2); // enable alerts - config |= (1 << 4); // thermal alerts + config |= (1 << 2); // enable alerts + config |= (1 << 4); // thermal alerts // config |= (1 << 8); // external temp measurement TODO: hardware / uncomment status_ok_or_return(max17261_set_reg(storage, MAX17261_CONFIG, config)); uint16_t current_th = (settings->i_thresh_max_a << 8) & (settings->i_thresh_min_a & 0x00FF); status_ok_or_return(max17261_set_reg(storage, MAX17261_I_ALRT_TH, current_th)); - status_ok_or_return(max17261_set_reg(storage, MAX17261_TEMP_ALRT_THRSH, (settings->temp_thresh_max_c < 8))); - + status_ok_or_return( + max17261_set_reg(storage, MAX17261_TEMP_ALRT_THRSH, (settings->temp_thresh_max_c < 8))); + // Disable voltage alert (handled by AFE) status_ok_or_return(max17261_set_reg(storage, MAX17261_VOLT_ALRT_THRSH, 0xFF00)); // Disable state of charge alerting status_ok_or_return(max17261_set_reg(storage, MAX17261_SOC_ALRT_THRSH, 0xFF00)); // enable hibernation - status_ok_or_return(max17261_set_reg(storage, MAX17261_HIB_CFG, hibcfg)); + status_ok_or_return(max17261_set_reg(storage, MAX17261_HIB_CFG, hibcfg)); } // Step 3 status_ok_or_return(max17261_get_reg(storage, MAX17261_STATUS, &status)); - status_ok_or_return(max17261_set_reg(storage, MAX17261_STATUS, status & (uint16_t)~(1 << 1))); // clear status POR bit + status_ok_or_return(max17261_set_reg(storage, MAX17261_STATUS, + status & (uint16_t) ~(1 << 1))); // clear status POR bit if (params) { status_ok_or_return(max17261_set_learned_params(storage, params)); diff --git a/projects/bms_carrier/inc/current_sense.h b/projects/bms_carrier/inc/current_sense.h index 4e5c7496a..4ded016da 100644 --- a/projects/bms_carrier/inc/current_sense.h +++ b/projects/bms_carrier/inc/current_sense.h @@ -16,15 +16,15 @@ #define SENSE_RESISTOR_MOHM (0.5) -#define PACK_CAPACITY_MAH (160000) // 14V test module, TODO change to reflect pack +#define PACK_CAPACITY_MAH (160000) // 14V test module, TODO change to reflect pack -#define CELL_EMPTY_VOLTAGE_MV 2500 // LG M50T datasheet +#define CELL_EMPTY_VOLTAGE_MV 2500 // LG M50T datasheet -#define CHARGE_TERMINATION_CURRENT_MA 150 // just a guess, TODO verify +#define CHARGE_TERMINATION_CURRENT_MA 150 // just a guess, TODO verify // Thresholds for ALRT Pin #define CURRENT_SENSE_MAX_CURRENT_A (58.2f) -#define CURRENT_SENSE_MIN_CURRENT_A (27.0f) // Actually -27 +#define CURRENT_SENSE_MIN_CURRENT_A (27.0f) // Actually -27 #define CURRENT_SENSE_MAX_TEMP_C (60U) #define CURRENT_SENSE_MAX_VOLTAGE_V (150U) #define ALRT_PIN_V_RES_MICRO_V (400) diff --git a/projects/bms_carrier/src/current_sense.c b/projects/bms_carrier/src/current_sense.c index a02912670..aa644b4e4 100644 --- a/projects/bms_carrier/src/current_sense.c +++ b/projects/bms_carrier/src/current_sense.c @@ -1,16 +1,16 @@ #include "current_sense.h" -#include #include +#include #include "bms.h" #include "bms_carrier_setters.h" #include "exported_enums.h" #include "fault_bps.h" #include "gpio_it.h" -#include "persist.h" #include "interrupt.h" #include "log.h" +#include "persist.h" #include "tasks.h" // Update stored learned params every 30 sec @@ -72,9 +72,9 @@ StatusCode prv_fuel_gauge_read() { // Commit params info periodically if (xTaskGetTickCount() > s_last_params_update + pdMS_TO_TICKS(UPDATE_FLASH_PARAMS_PERIOD_MS)) { LOG_DEBUG("Updating params\n"); - s_last_params_update = xTaskGetTickCount(); - max17261_get_learned_params(&s_fuel_guage_storage, &s_fuel_params); - persist_commit(&s_persist); + s_last_params_update = xTaskGetTickCount(); + max17261_get_learned_params(&s_fuel_guage_storage, &s_fuel_params); + persist_commit(&s_persist); } return status; } @@ -90,7 +90,7 @@ TASK(current_sense, TASK_STACK_256) { // fault_bps_set(BMS_FAULT_COMMS_LOSS_CURR_SENSE); } else if (notification & 1 << KILLSWITCH_IT) { fault_bps_set(BMS_FAULT_KILLSWITCH); - } + } prv_fuel_gauge_read(); send_task_end(); } @@ -150,7 +150,7 @@ StatusCode current_sense_init(BmsStorage *bms_storage, I2CSettings *i2c_settings persist_init(&s_persist, CURRENT_SENSE_STORE_FLASH, &s_fuel_params, sizeof(s_fuel_params), false); status_ok_or_return(max17261_init(&s_fuel_guage_storage, &s_fuel_gauge_settings, &s_fuel_params)); - + tasks_init_task(current_sense, TASK_PRIORITY(2), NULL); return STATUS_CODE_OK; } diff --git a/projects/bms_carrier/src/main.c b/projects/bms_carrier/src/main.c index c88430816..cb82876b3 100644 --- a/projects/bms_carrier/src/main.c +++ b/projects/bms_carrier/src/main.c @@ -40,16 +40,16 @@ void pre_loop_init() { fault_bps_init(&bms_storage.bps_storage); current_sense_init(&bms_storage, &i2c_settings, FUEL_GAUGE_CYCLE_TIME_MS); // cell_sense_init(&bms_storage.ltc_afe_storage); - //aux_sense_init(&bms_storage.aux_storage); - //init_bms_relays(); - //bms_fan_init(&bms_storage); + // aux_sense_init(&bms_storage.aux_storage); + // init_bms_relays(); + // bms_fan_init(&bms_storage); } void run_fast_cycle() {} void run_medium_cycle() { - //run_can_rx_cycle(); - //wait_tasks(1); + // run_can_rx_cycle(); + // wait_tasks(1); // cell_conversions(); // wait_tasks(1); @@ -57,15 +57,15 @@ void run_medium_cycle() { wait_tasks(1); // cell_sense_run(); - //aux_sense_run(); - //bms_run_fan(); + // aux_sense_run(); + // bms_run_fan(); - //run_can_tx_cycle(); - //wait_tasks(1); + // run_can_tx_cycle(); + // wait_tasks(1); } void run_slow_cycle() { - //cell_discharge(&bms_storage.ltc_afe_storage); + // cell_discharge(&bms_storage.ltc_afe_storage); if (fault_bps_get()) { LOG_DEBUG("FAULT_BITMASK: %d\n", fault_bps_get());