cuatro power readout (#1869)

* refactor voltage / current reading

* fix bug and add readout to cuatro

* fix misra?

* just suppress then

---------

Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
Robbe Derks
2024-02-15 13:49:06 -08:00
committed by GitHub
parent 0a1ec8580e
commit 3cd0023bc1
17 changed files with 61 additions and 34 deletions

View File

@@ -180,7 +180,8 @@ const board board_black = {
.set_led = black_set_led,
.set_can_mode = black_set_can_mode,
.check_ignition = black_check_ignition,
.read_current = unused_read_current,
.read_voltage_mV = white_read_voltage_mV,
.read_current_mA = unused_read_current,
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_siren = unused_set_siren,

View File

@@ -12,7 +12,8 @@ typedef void (*board_enable_can_transceivers)(bool enabled);
typedef void (*board_set_led)(uint8_t color, bool enabled);
typedef void (*board_set_can_mode)(uint8_t mode);
typedef bool (*board_check_ignition)(void);
typedef uint32_t (*board_read_current)(void);
typedef uint32_t (*board_read_voltage_mV)(void);
typedef uint32_t (*board_read_current_mA)(void);
typedef void (*board_set_ir_power)(uint8_t percentage);
typedef void (*board_set_fan_enabled)(bool enabled);
typedef void (*board_set_siren)(bool enabled);
@@ -36,7 +37,8 @@ struct board {
board_set_led set_led;
board_set_can_mode set_can_mode;
board_check_ignition check_ignition;
board_read_current read_current;
board_read_voltage_mV read_voltage_mV;
board_read_current_mA read_current_mA;
board_set_ir_power set_ir_power;
board_set_fan_enabled set_fan_enabled;
board_set_siren set_siren;

View File

@@ -49,9 +49,21 @@ void cuatro_enable_can_transceivers(bool enabled) {
}
}
uint32_t cuatro_read_voltage_mV(void) {
return adc_get_mV(8) * 11U;
}
uint32_t cuatro_read_current_mA(void) {
return adc_get_mV(3) * 2U;
}
void cuatro_init(void) {
red_chiplet_init();
// Power readout
set_gpio_mode(GPIOC, 5, MODE_ANALOG);
set_gpio_mode(GPIOA, 6, MODE_ANALOG);
// CAN transceiver enables
set_gpio_pullup(GPIOB, 7, PULL_NONE);
set_gpio_mode(GPIOB, 7, MODE_OUTPUT);
@@ -108,7 +120,8 @@ const board board_cuatro = {
.set_led = cuatro_set_led,
.set_can_mode = red_chiplet_set_can_mode,
.check_ignition = red_check_ignition,
.read_current = unused_read_current,
.read_voltage_mV = cuatro_read_voltage_mV,
.read_current_mA = cuatro_read_current_mA,
.set_fan_enabled = tres_set_fan_enabled,
.set_ir_power = tres_set_ir_power,
.set_siren = unused_set_siren,

View File

@@ -212,7 +212,8 @@ const board board_dos = {
.set_led = dos_set_led,
.set_can_mode = dos_set_can_mode,
.check_ignition = dos_check_ignition,
.read_current = unused_read_current,
.read_voltage_mV = white_read_voltage_mV,
.read_current_mA = unused_read_current,
.set_fan_enabled = dos_set_fan_enabled,
.set_ir_power = dos_set_ir_power,
.set_siren = dos_set_siren,

View File

@@ -22,7 +22,8 @@ const board board_grey = {
.set_led = white_set_led,
.set_can_mode = white_set_can_mode,
.check_ignition = white_check_ignition,
.read_current = white_read_current,
.read_voltage_mV = white_read_voltage_mV,
.read_current_mA = white_read_current_mA,
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_siren = unused_set_siren,

View File

@@ -84,7 +84,8 @@ const board board_pedal = {
.set_led = pedal_set_led,
.set_can_mode = pedal_set_can_mode,
.check_ignition = pedal_check_ignition,
.read_current = unused_read_current,
.read_voltage_mV = unused_read_voltage,
.read_current_mA = unused_read_current,
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_siren = unused_set_siren,

View File

@@ -96,6 +96,10 @@ bool red_check_ignition(void) {
return harness_check_ignition();
}
uint32_t red_read_voltage_mV(void){
return adc_get_mV(2) * 11U; // TODO: is this correct?
}
void red_init(void) {
common_init_gpio();
@@ -188,7 +192,8 @@ const board board_red = {
.set_led = red_set_led,
.set_can_mode = red_set_can_mode,
.check_ignition = red_check_ignition,
.read_current = unused_read_current,
.read_voltage_mV = red_read_voltage_mV,
.read_current_mA = unused_read_current,
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_siren = unused_set_siren,

View File

@@ -87,7 +87,8 @@ const board board_tres = {
.set_led = red_set_led,
.set_can_mode = red_chiplet_set_can_mode,
.check_ignition = red_check_ignition,
.read_current = unused_read_current,
.read_voltage_mV = red_read_voltage_mV,
.read_current_mA = unused_read_current,
.set_fan_enabled = tres_set_fan_enabled,
.set_ir_power = tres_set_ir_power,
.set_siren = fake_siren_set,

View File

@@ -167,7 +167,7 @@ void uno_init(void) {
}
// Switch to phone usb mode if harness connection is powered by less than 7V
if((adc_get_mV(ADCCHAN_VIN) * VIN_READOUT_DIVIDER) < 7000U){
if(white_read_voltage_mV() < 7000U){
uno_set_usb_switch(true);
} else {
uno_set_usb_switch(false);
@@ -215,7 +215,8 @@ const board board_uno = {
.set_led = uno_set_led,
.set_can_mode = uno_set_can_mode,
.check_ignition = uno_check_ignition,
.read_current = unused_read_current,
.read_voltage_mV = white_read_voltage_mV,
.read_current_mA = unused_read_current,
.set_fan_enabled = uno_set_fan_enabled,
.set_ir_power = uno_set_ir_power,
.set_siren = unused_set_siren,

View File

@@ -13,6 +13,10 @@ void unused_set_siren(bool enabled) {
UNUSED(enabled);
}
uint32_t unused_read_voltage(void) {
return 0U;
}
uint32_t unused_read_current(void) {
return 0U;
}

View File

@@ -124,8 +124,13 @@ void white_set_can_mode(uint8_t mode){
}
}
uint32_t white_read_current(void){
return adc_get_raw(ADCCHAN_CURRENT);
uint32_t white_read_voltage_mV(void){
return adc_get_mV(12) * 11U;
}
uint32_t white_read_current_mA(void){
// This isn't in mA, but we're keeping it for backwards compatibility
return adc_get_raw(13);
}
bool white_check_ignition(void){
@@ -197,10 +202,9 @@ void white_grey_init(void) {
white_set_can_mode(CAN_MODE_NORMAL);
// Init usb power mode
uint32_t voltage = adc_get_mV(ADCCHAN_VIN) * VIN_READOUT_DIVIDER;
// Init in CDP mode only if panda is powered by 12V.
// Otherwise a PC would not be able to flash a standalone panda
if (voltage > 8000U) { // 8V threshold
if (white_read_voltage_mV() > 8000U) { // 8V threshold
white_set_usb_power_mode(USB_POWER_CDP);
} else {
white_set_usb_power_mode(USB_POWER_CLIENT);
@@ -239,7 +243,8 @@ const board board_white = {
.set_led = white_set_led,
.set_can_mode = white_set_can_mode,
.check_ignition = white_check_ignition,
.read_current = white_read_current,
.read_voltage_mV = white_read_voltage_mV,
.read_current_mA = white_read_current_mA,
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_siren = unused_set_siren,

View File

@@ -16,8 +16,6 @@
#define MAX_CAN_MSGS_PER_USB_BULK_TRANSFER 51U
#define MAX_CAN_MSGS_PER_SPI_BULK_TRANSFER 170U
#define VIN_READOUT_DIVIDER 11U
// USB definitions
#define USB_VID 0xBBAAU

View File

@@ -9,8 +9,8 @@ int get_health_pkt(void *dat) {
struct health_t * health = (struct health_t*)dat;
health->uptime_pkt = uptime_cnt;
health->voltage_pkt = adc_get_mV(ADCCHAN_VIN) * VIN_READOUT_DIVIDER;
health->current_pkt = current_board->read_current();
health->voltage_pkt = current_board->read_voltage_mV();
health->current_pkt = current_board->read_current_mA();
// Use the GPIO pin to determine ignition or use a CAN based logic
health->ignition_line_pkt = (uint8_t)(current_board->check_ignition());

View File

@@ -242,6 +242,9 @@ void TIM3_IRQ_Handler(void) {
// ***************************** main code *****************************
#define ADCCHAN_ACCEL0 10
#define ADCCHAN_ACCEL1 11
void pedal(void) {
// read/write
pdl0 = adc_get_raw(ADCCHAN_ACCEL0);

View File

@@ -1,12 +1,3 @@
// ACCEL1 = ADC10
// ACCEL2 = ADC11
// VOLT_S = ADC12
// CURR_S = ADC13
#define ADCCHAN_ACCEL0 10
#define ADCCHAN_ACCEL1 11
#define ADCCHAN_VIN 12
#define ADCCHAN_CURRENT 13
void register_set(volatile uint32_t *addr, uint32_t val, uint32_t mask);

View File

@@ -21,11 +21,12 @@ void clock_init(void) {
// Set power mode to direct SMPS power supply(depends on the board layout)
#ifndef STM32H723
register_set(&(PWR->CR3), PWR_CR3_SMPSEN, 0xFU); // powered only by SMPS
#endif
// Set VOS level (VOS3 to 170Mhz, VOS2 to 300Mhz, VOS1 to 400Mhz, VOS0 to 550Mhz)
register_set(&(PWR->D3CR), PWR_D3CR_VOS_1 | PWR_D3CR_VOS_0, 0xC000U); //VOS1, needed for 80Mhz CAN FD
while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0);
while ((PWR->CSR1 & PWR_CSR1_ACTVOS) != (PWR->D3CR & PWR_D3CR_VOS)); // check that VOS level was actually set
#endif
// Configure Flash ACR register LATENCY and WRHIGHFREQ (VOS0 range!)
register_set(&(FLASH->ACR), FLASH_ACR_LATENCY_2WS | 0x20U, 0x3FU); // VOS2, AXI 100MHz-150MHz
// enable external oscillator HSE

View File

@@ -1,6 +1,3 @@
// 5VOUT_S = ADC12_INP5
// VOLT_S = ADC1_INP2
#define ADCCHAN_VIN 2
void adc_init(void) {
ADC1->CR &= ~(ADC_CR_DEEPPWD); //Reset deep-power-down mode
@@ -18,17 +15,19 @@ void adc_init(void) {
}
uint16_t adc_get_raw(uint8_t channel) {
uint16_t res = 0U;
ADC1->SQR1 &= ~(ADC_SQR1_L);
ADC1->SQR1 = ((uint32_t) channel << 6U);
ADC1->SMPR1 = (0x2U << (channel * 3U));
// cppcheck-suppress misra-c2012-12.2; don't know how to fix this. if statement to check channel range does not work
ADC1->PCSEL_RES0 = (0x1U << channel);
ADC1->CFGR2 = (127U << ADC_CFGR2_OVSR_Pos) | (0x7U << ADC_CFGR2_OVSS_Pos) | ADC_CFGR2_ROVSE;
ADC1->CR |= ADC_CR_ADSTART;
while (!(ADC1->ISR & ADC_ISR_EOC));
uint16_t res = ADC1->DR;
res = ADC1->DR;
while (!(ADC1->ISR & ADC_ISR_EOS));
ADC1->ISR |= ADC_ISR_EOS;