Skip to content

Commit

Permalink
Mitch bms refactor (#287)
Browse files Browse the repository at this point in the history
* tmp

* pwm update

* tmp

* tmp

* Current Sense Update

* stop fail when current sense isn't connected

* update pd

* fix message ids, add afe logging

* thermistor refactor - updates with retries

* Changes to run on hw, format

* x86 fixes

* lint
  • Loading branch information
mitchellostler authored Jun 17, 2024
1 parent 6c628b8 commit bb14e1a
Show file tree
Hide file tree
Showing 33 changed files with 506 additions and 361 deletions.
6 changes: 3 additions & 3 deletions libraries/codegen/boards/bms_carrier.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
---
Messages:
battery_status:
id: 0
id: 1
critical: true
target:
centre_console:
watchdog: 0
power_distribution:
watchdog: 3
power_distribution:
watchdog: 5
signals:
fault:
length: 16
Expand Down
8 changes: 4 additions & 4 deletions libraries/codegen/boards/centre_console.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
---
Messages:
cc_info:
id: 4
id: 5
critical: true
target:
motor_controller:
Expand All @@ -30,7 +30,7 @@ Messages:
hazard_enabled:
length: 8
cc_pedal:
id: 2
id: 3
critical: true
target:
motor_controller:
Expand All @@ -43,7 +43,7 @@ Messages:
brake_output:
length: 8
cc_steering:
id: 5
id: 6
critical: true
target:
power_distribution:
Expand All @@ -54,4 +54,4 @@ Messages:
input_cc:
length: 8 # (cc_toggle | cc_increse | cc_decrease)
input_lights:
length: 8
length: 8
2 changes: 1 addition & 1 deletion libraries/codegen/boards/motor_controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
length: 16

mc_status:
id: 3
id: 4
critical: true
target:
centre_console:
Expand Down
2 changes: 1 addition & 1 deletion libraries/codegen/boards/power_distribution.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
current:
length: 16
pd_status:
id: 1
id: 2
critical: true
target:
centre_console:
Expand Down
2 changes: 1 addition & 1 deletion libraries/codegen/templates/system_can.dbc.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ BU_:

{% for message in messages -%}

BO_ {% if message.critical %} {{message.id * 0x20 + boards.index(message.sender)}} {% endif %} {% if not message.critical %} {{message.id}} {% endif %}{{message.name}}: {{message.signals | sum("length") // 8 }} {{message.sender}}
BO_ {% if message.critical %} {{message.id}} {% endif %} {% if not message.critical %} {{message.id * 0x20 + boards.index(message.sender)}} {% endif %}{{message.name}}: {{message.signals | sum("length") // 8 }} {{message.sender}}

{%- for signal in message.signals %}
SG_ {{signal.name}} : {{signal.start_bit}}|{{signal.length}}@1+ ({{signal["scale"]}},{{signal["offset"]}}) [{{signal["min"]}}|{{signal["max"]}}] "{{signal["unit"]}}" {{signal.receiver | join(", ")}}
Expand Down
4 changes: 2 additions & 2 deletions libraries/ms-common/inc/pwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ StatusCode pwm_init(PwmTimer timer, uint16_t period_us);
uint16_t pwm_get_period(PwmTimer timer);

// Sets the pulse width in us of the PWM timer. Use for high resolution control.
StatusCode pwm_set_pulse(PwmTimer timer, uint16_t pulse_width_us);
StatusCode pwm_set_pulse(PwmTimer timer, uint16_t pulse_width_us, uint8_t channel);

// Sets the duty cycle, in units of 1%, of the PWM timer. This wraps
// pwm_set_pulse doing the necessary math to convert from 0-100% to the fraction
// of the period.
StatusCode pwm_set_dc(PwmTimer timer, uint16_t dc);
StatusCode pwm_set_dc(PwmTimer timer, uint16_t dc, uint8_t channel);

// Gets the duty cycle of the PWM timer.
uint16_t pwm_get_dc(PwmTimer timer);
41 changes: 25 additions & 16 deletions libraries/ms-common/src/arm/pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "stm32f10x_rcc.h"
#include "stm32f10x_tim.h"

#define NUM_CHANNELS 4
typedef enum APBClk {
APB1 = 0,
APB2,
Expand Down Expand Up @@ -102,7 +103,7 @@ uint16_t pwm_get_period(PwmTimer timer) {
return s_period_us[timer];
}

StatusCode pwm_set_pulse(PwmTimer timer, uint16_t pulse_width_us) {
StatusCode pwm_set_pulse(PwmTimer timer, uint16_t pulse_width_us, uint8_t channel) {
if (timer >= NUM_PWM_TIMERS) {
return status_msg(STATUS_CODE_INVALID_ARGS, "Invalid timer id");
} else if (s_period_us[timer] == 0) {
Expand All @@ -116,28 +117,36 @@ StatusCode pwm_set_pulse(PwmTimer timer, uint16_t pulse_width_us) {
.TIM_Pulse = pulse_width_us,
.TIM_OutputState = TIM_OutputState_Enable,
.TIM_OCPolarity = TIM_OCPolarity_High,
.TIM_OutputNState = TIM_OutputNState_Enable,
.TIM_OutputNState = TIM_OutputNState_Disable,
.TIM_OCNPolarity = TIM_OCNPolarity_High,
};

// Enable PWM on all channels.

TIM_OC1Init(s_timer_def[timer], &oc_init);
TIM_OC1PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);

TIM_OC2Init(s_timer_def[timer], &oc_init);
TIM_OC2PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);

TIM_OC3Init(s_timer_def[timer], &oc_init);
TIM_OC3PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);

TIM_OC4Init(s_timer_def[timer], &oc_init);
TIM_OC4PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);
switch (channel) {
case 1:
TIM_OC1Init(s_timer_def[timer], &oc_init);
TIM_OC1PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);
break;
case 2:
TIM_OC2Init(s_timer_def[timer], &oc_init);
TIM_OC2PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);
break;
case 3:
TIM_OC3Init(s_timer_def[timer], &oc_init);
TIM_OC3PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);
break;
case 4:
TIM_OC4Init(s_timer_def[timer], &oc_init);
TIM_OC4PreloadConfig(s_timer_def[timer], TIM_OCPreload_Enable);
break;
default:
break;
}

return STATUS_CODE_OK;
}

StatusCode pwm_set_dc(PwmTimer timer, uint16_t dc) {
StatusCode pwm_set_dc(PwmTimer timer, uint16_t dc, uint8_t channel) {
if (timer >= NUM_PWM_TIMERS) {
return status_msg(STATUS_CODE_INVALID_ARGS, "Invalid timer id");
} else if (dc > 100) {
Expand All @@ -152,7 +161,7 @@ StatusCode pwm_set_dc(PwmTimer timer, uint16_t dc) {
}
}

return pwm_set_pulse(timer, pulse_width);
return pwm_set_pulse(timer, pulse_width, channel);
}

uint16_t pwm_get_dc(PwmTimer timer) {
Expand Down
6 changes: 5 additions & 1 deletion libraries/ms-common/src/tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ StatusCode tasks_init_task(Task *task, TaskPriority priority, void *context) {
task->context = context;
task->handle = xTaskCreateStatic(prv_task, task->name, task->stack_size, task, priority,
task->stack, &task->tcb);
configASSERT(task->handle != NULL); // make sure it was created
if (task->handle == NULL) {
LOG_CRITICAL("Failed to create Task %s", task->name); // make sure it was created
} else {
LOG_DEBUG("Create Task %s", task->name); // make sure it was created
}
return STATUS_CODE_OK;
}

Expand Down
9 changes: 4 additions & 5 deletions libraries/ms-common/src/x86/pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,20 @@ uint16_t pwm_get_period(PwmTimer timer) {
}
return pwm[timer].period;
}

StatusCode pwm_set_pulse(PwmTimer timer, uint16_t pulse_width_ms) {
StatusCode pwm_set_pulse(PwmTimer timer, uint16_t pulse_width_us, uint8_t channel) {
if (timer >= NUM_PWM_TIMERS) {
return status_msg(STATUS_CODE_INVALID_ARGS, "Invalid timer id");
} else if (pwm[timer].period == 0) {
return status_msg(STATUS_CODE_UNINITIALIZED, "Pwm must be initialized.");
} else if (pulse_width_ms > pwm[timer].period) {
} else if (pulse_width_us > pwm[timer].period) {
return status_msg(STATUS_CODE_INVALID_ARGS, "Pulse width must be leq period.");
}
// Store pulse width as a duty cycle
pwm[timer].duty = (pulse_width_ms * 100) / pwm[timer].period;
pwm[timer].duty = (pulse_width_us * 100) / pwm[timer].period;
return STATUS_CODE_OK;
}

StatusCode pwm_set_dc(PwmTimer timer, uint16_t dc) {
StatusCode pwm_set_dc(PwmTimer timer, uint16_t dc, uint8_t channel) {
if (timer >= NUM_PWM_TIMERS) {
return status_msg(STATUS_CODE_INVALID_ARGS, "Invalid timer id");
} else if (dc > 100) {
Expand Down
36 changes: 26 additions & 10 deletions libraries/ms-drivers/inc/max17261_fuel_gauge.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,33 @@ typedef struct {
I2CPort i2c_port;
I2CAddress i2c_address;

uint16_t design_capacity; // LSB = 5.0 (micro Volt Hours / R Sense)
uint16_t empty_voltage; // Only a 9-bit field, LSB = 78.125 (micro Volts)
uint16_t charge_term_current; // LSB = 1.5625 (micro Volts / R Sense)
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 i_thresh_max;
int16_t i_thresh_min;
uint16_t temp_thresh_max;
uint16_t i_thresh_max_a;
int16_t i_thresh_min_a;
uint16_t temp_thresh_max_c;

float r_sense_mohms; // Rsense in micro ohms
float sense_resistor_mohms;
} Max17261Settings;

typedef struct {
Max17261Settings *settings;
} Max17261Storage;

// Storage for parameters learned by fuel guage
// Must be stored in flash to keep up to date after power cycle
typedef struct Max27261Params {
uint16_t rcomp0;
uint16_t tempco;
uint16_t fullcaprep;
uint16_t cycles;
uint16_t fullcapnom;
} Max27261Params;

/* @brief Gets the current state of charge given by the max17261 in percentage
* @param storage - a pointer to an already initialized Max17261Storage struct
* @param soc_pct - state of charge in percentage will be returned in this var
Expand All @@ -49,14 +61,14 @@ StatusCode max17261_state_of_charge(Max17261Storage *storage, uint16_t *soc_pct)
* @param soc_pct - remaining capactity in micro amp hours returned in this var
* @return STATUS_CODE_OK on success
*/
StatusCode max17261_remaining_capacity(Max17261Storage *storage, uint32_t *rem_cap_uAhr);
StatusCode max17261_remaining_capacity(Max17261Storage *storage, uint32_t *rem_cap_mAh);

/* @brief Gets the full charge capacity of the battery in micro amp hours
* @param storage - a pointer to an already initialized Max17261Storage struct
* @param soc_pct - full charge capacitry in micro amp hours returned in this var
* @return STATUS_CODE_OK on success
*/
StatusCode max17261_full_capacity(Max17261Storage *storage, uint16_t *full_cap_uAhr);
StatusCode max17261_full_capacity(Max17261Storage *storage, uint32_t *full_cap_mAh);

/* @brief Gets the time to empty in milliseconds
* @param storage - a pointer to an already initialized Max17261Storage struct
Expand Down Expand Up @@ -98,4 +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);
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);
2 changes: 2 additions & 0 deletions libraries/ms-drivers/inc/max17261_fuel_gauge_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ typedef enum {
MAX17261_VF_REM_CAP,
MAX17261_QH = 0x4D,

MAX17261_SOFT_WAKEUP = 0x60,

MAX17261_STATUS2 = 0xB0,
MAX17261_POWER,
MAX17261_ID, // UserMem2
Expand Down
56 changes: 25 additions & 31 deletions libraries/ms-drivers/src/ltc_afe_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ static void prv_calc_offsets(LtcAfeStorage *afe) {
// Similarly, we do the opposite mapping for discharge.
LtcAfeSettings *settings = &afe->settings;
size_t cell_index = 0;
size_t aux_index = 0;
for (size_t device = 0; device < settings->num_devices; device++) {
for (size_t device_cell = 0; device_cell < LTC_AFE_MAX_CELLS_PER_DEVICE; device_cell++) {
size_t cell = device * LTC_AFE_MAX_CELLS_PER_DEVICE + device_cell;
Expand All @@ -174,12 +173,6 @@ static void prv_calc_offsets(LtcAfeStorage *afe) {
afe->discharge_cell_lookup[cell_index] = cell;
afe->cell_result_lookup[cell] = cell_index++;
}

if ((settings->aux_bitset[device] >> device_cell) & 0x1) {
// Cell input enabled - store the index that this input should be stored in
// when copying to the result array
afe->aux_result_lookup[cell] = aux_index++;
}
}
}
}
Expand Down Expand Up @@ -233,33 +226,34 @@ StatusCode ltc_afe_impl_read_cells(LtcAfeStorage *afe) {
LtcAfeSettings *settings = &afe->settings;
for (uint8_t cell_reg = 0; cell_reg < NUM_LTC_AFE_VOLTAGE_REGISTERS; ++cell_reg) {
LtcAfeVoltageRegisterGroup voltage_register[LTC_AFE_MAX_DEVICES] = { 0 };
prv_read_voltage(afe, cell_reg, voltage_register);
status_ok_or_return(prv_read_voltage(afe, cell_reg, voltage_register));

for (uint8_t device = 0; device < settings->num_devices; ++device) {
for (uint16_t cell = 0; cell < LTC6811_CELLS_IN_REG; ++cell) {
// LSB of the reading is 100 uV
uint16_t voltage = voltage_register[device].reg.voltages[cell];
uint16_t device_cell = cell + (cell_reg * LTC6811_CELLS_IN_REG);
uint16_t index = device * LTC_AFE_MAX_CELLS_PER_DEVICE + device_cell;

if ((settings->cell_bitset[device] >> device_cell) & 0x1) {
// Input enabled - store result
afe->cell_voltages[afe->cell_result_lookup[index]] = voltage;
}
}

// the Packet Error Code is transmitted after the cell data (see p.45)
uint16_t received_pec = SWAP_UINT16(voltage_register[device].pec);
uint16_t data_pec = crc15_calculate((uint8_t *)&voltage_register[device], 6);
if (received_pec != data_pec) {
// return early on failure
LOG_DEBUG("Communication Failed with device: %d\n\r", device);
LOG_DEBUG("RECEIVED_PEC: %d\n\r", received_pec);
LOG_DEBUG("DATA_PEC: %d\n\r", data_pec);
LOG_DEBUG("Voltage: %d %d %d\n\r", voltage_register[device].reg.voltages[0],
voltage_register[device].reg.voltages[1],
voltage_register[device].reg.voltages[2]);
return status_code(STATUS_CODE_INTERNAL_ERROR);
}

for (uint16_t cell = 0; cell < LTC6811_CELLS_IN_REG; ++cell) {
// LSB of the reading is 100 uV
uint16_t voltage = voltage_register[device].reg.voltages[cell];
uint16_t device_cell = cell + (cell_reg * LTC6811_CELLS_IN_REG);
uint16_t index = device * LTC_AFE_MAX_CELLS_PER_DEVICE + device_cell;

if ((settings->cell_bitset[device] >> device_cell) & 0x1) {
// Input enabled - store result
afe->cell_voltages[afe->cell_result_lookup[index]] = voltage;
}
}
}
}

Expand All @@ -271,19 +265,10 @@ StatusCode ltc_afe_impl_read_aux(LtcAfeStorage *afe, uint8_t thermistor) {
LtcAfeAuxRegisterGroupPacket register_data[LTC_AFE_MAX_DEVICES] = { 0 };

size_t len = settings->num_devices * sizeof(LtcAfeAuxRegisterGroupPacket);
prv_read_register(afe, LTC_AFE_REGISTER_AUX_B, (uint8_t *)register_data, len);
status_ok_or_return(
prv_read_register(afe, LTC_AFE_REGISTER_AUX_B, (uint8_t *)register_data, len));

for (uint16_t device = 0; device < settings->num_devices; ++device) {
// data comes in in the form { 1, 1, 2, 2, 3, 3, PEC, PEC }
// we only care about GPIO4 and the PEC
uint16_t voltage = register_data[device].reg.voltages[0];

if ((settings->aux_bitset[device] >> thermistor) & 0x1) {
// Input enabled - store result
uint16_t index = device * LTC_AFE_MAX_CELLS_PER_DEVICE + thermistor;
afe->aux_voltages[afe->aux_result_lookup[index]] = voltage;
}

uint16_t received_pec = SWAP_UINT16(register_data[device].pec);
uint16_t data_pec = crc15_calculate((uint8_t *)&register_data[device], 6);
if (received_pec != data_pec) {
Expand All @@ -292,6 +277,15 @@ StatusCode ltc_afe_impl_read_aux(LtcAfeStorage *afe, uint8_t thermistor) {
LOG_DEBUG("DATA_PEC: %d\n\r", data_pec);
return status_code(STATUS_CODE_INTERNAL_ERROR);
}
// data comes in in the form { 1, 1, 2, 2, 3, 3, PEC, PEC }
// we only care about GPIO4 and the PEC
uint16_t voltage = register_data[device].reg.voltages[0];

if ((settings->aux_bitset[device] >> thermistor) & 0x1) {
// Input enabled - store result
uint16_t index = device * LTC_AFE_MAX_THERMISTORS_PER_DEVICE + thermistor;
afe->aux_voltages[index] = voltage;
}
}
return STATUS_CODE_OK;
}
Expand Down
Loading

0 comments on commit bb14e1a

Please sign in to comment.