From 43bde4138de95e8385a5fe3f3a9850f0729a1ce2 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 4 Aug 2023 14:28:23 -0700 Subject: [PATCH] jungle: SBU provisioning tests (#1553) * jungle: SBU provisioning tests * update can_send * cleanup * fix misra * space --- .github/workflows/test.yaml | 2 ++ board/drivers/gpio.h | 6 ++++++ board/jungle/boards/board_declarations.h | 10 ++++++++- board/jungle/boards/board_v1.h | 8 +++++--- board/jungle/boards/board_v2.h | 17 +++++++++++----- board/jungle/main.c | 26 +++++++++++++++++++----- 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index df7ca751..cd18ec35 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -48,6 +48,8 @@ jobs: run: ${{ env.RUN }} "ENABLE_SPI=1 scons -j4" - name: Build with UBSan run: ${{ env.RUN }} "scons -j4 --ubsan" + - name: Build jungle firmware with FINAL_PROVISIONING support + run: ${{ env.RUN }} "FINAL_PROVISIONING=1 scons -j4 board/jungle" unit_tests: name: unit tests diff --git a/board/drivers/gpio.h b/board/drivers/gpio.h index 88af9319..fe3194f3 100644 --- a/board/drivers/gpio.h +++ b/board/drivers/gpio.h @@ -74,6 +74,12 @@ void gpio_set_all_output(const gpio_t *pins, uint8_t num_pins, bool enabled) { } } +void gpio_set_bitmask(const gpio_t *pins, uint8_t num_pins, uint32_t bitmask) { + for (uint8_t i = 0; i < num_pins; i++) { + set_gpio_output(pins[i].bank, pins[i].pin, (bitmask >> i) & 1U); + } +} + // Detection with internal pullup #define PULL_EFFECTIVE_DELAY 4096 bool detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) { diff --git a/board/jungle/boards/board_declarations.h b/board/jungle/boards/board_declarations.h index a02b906b..dcb6ac24 100644 --- a/board/jungle/boards/board_declarations.h +++ b/board/jungle/boards/board_declarations.h @@ -5,6 +5,7 @@ typedef void (*board_board_tick)(void); typedef bool (*board_get_button)(void); typedef void (*board_set_panda_power)(bool enabled); typedef void (*board_set_ignition)(bool enabled); +typedef void (*board_set_individual_ignition)(uint8_t bitmask); typedef void (*board_set_harness_orientation)(uint8_t orientation); typedef void (*board_set_can_mode)(uint8_t mode); typedef void (*board_enable_can_transciever)(uint8_t transciever, bool enabled); @@ -14,6 +15,7 @@ typedef uint16_t (*board_get_sbu_mV)(uint8_t channel, uint8_t sbu); struct board { const char *board_type; const bool has_canfd; + const bool has_sbu_sense; const uint16_t avdd_mV; board_init init; board_set_led set_led; @@ -21,6 +23,7 @@ struct board { board_get_button get_button; board_set_panda_power set_panda_power; board_set_ignition set_ignition; + board_set_individual_ignition set_individual_ignition; board_set_harness_orientation set_harness_orientation; board_set_can_mode set_can_mode; board_enable_can_transciever enable_can_transciever; @@ -59,4 +62,9 @@ struct board { // ********************* Globals ********************** uint8_t harness_orientation = HARNESS_ORIENTATION_NONE; uint8_t can_mode = CAN_MODE_NORMAL; -bool ignition = false; +uint8_t ignition = 0U; + + +void unused_set_individual_ignition(uint8_t bitmask) { + UNUSED(bitmask); +} \ No newline at end of file diff --git a/board/jungle/boards/board_v1.h b/board/jungle/boards/board_v1.h index 5ad574fa..1dc95ad1 100644 --- a/board/jungle/boards/board_v1.h +++ b/board/jungle/boards/board_v1.h @@ -56,13 +56,13 @@ void board_v1_set_harness_orientation(uint8_t orientation) { break; case HARNESS_ORIENTATION_1: set_gpio_output(GPIOA, 2, false); - set_gpio_output(GPIOA, 3, ignition); + set_gpio_output(GPIOA, 3, (ignition != 0U)); set_gpio_output(GPIOA, 4, true); set_gpio_output(GPIOA, 5, false); harness_orientation = orientation; break; case HARNESS_ORIENTATION_2: - set_gpio_output(GPIOA, 2, ignition); + set_gpio_output(GPIOA, 2, (ignition != 0U)); set_gpio_output(GPIOA, 3, false); set_gpio_output(GPIOA, 4, false); set_gpio_output(GPIOA, 5, true); @@ -85,7 +85,7 @@ bool board_v1_get_button(void) { } void board_v1_set_ignition(bool enabled) { - ignition = enabled; + ignition = enabled ? 0xFFU : 0U; board_v1_set_harness_orientation(harness_orientation); } @@ -153,6 +153,7 @@ void board_v1_tick(void) {} const board board_v1 = { .board_type = "V1", .has_canfd = false, + .has_sbu_sense = false, .avdd_mV = 3300U, .init = &board_v1_init, .set_led = &board_v1_set_led, @@ -160,6 +161,7 @@ const board board_v1 = { .get_button = &board_v1_get_button, .set_panda_power = &board_v1_set_panda_power, .set_ignition = &board_v1_set_ignition, + .set_individual_ignition = &unused_set_individual_ignition, .set_harness_orientation = &board_v1_set_harness_orientation, .set_can_mode = &board_v1_set_can_mode, .enable_can_transciever = &board_v1_enable_can_transciever, diff --git a/board/jungle/boards/board_v2.h b/board/jungle/boards/board_v2.h index e4749673..c6174796 100644 --- a/board/jungle/boards/board_v2.h +++ b/board/jungle/boards/board_v2.h @@ -90,12 +90,12 @@ void board_v2_set_harness_orientation(uint8_t orientation) { case HARNESS_ORIENTATION_1: gpio_set_all_output(sbu1_ignition_pins, sizeof(sbu1_ignition_pins) / sizeof(gpio_t), false); gpio_set_all_output(sbu1_relay_pins, sizeof(sbu1_relay_pins) / sizeof(gpio_t), true); - gpio_set_all_output(sbu2_ignition_pins, sizeof(sbu2_ignition_pins) / sizeof(gpio_t), ignition); + gpio_set_bitmask(sbu2_ignition_pins, sizeof(sbu2_ignition_pins) / sizeof(gpio_t), ignition); gpio_set_all_output(sbu2_relay_pins, sizeof(sbu2_relay_pins) / sizeof(gpio_t), false); harness_orientation = orientation; break; case HARNESS_ORIENTATION_2: - gpio_set_all_output(sbu1_ignition_pins, sizeof(sbu1_ignition_pins) / sizeof(gpio_t), ignition); + gpio_set_bitmask(sbu1_ignition_pins, sizeof(sbu1_ignition_pins) / sizeof(gpio_t), ignition); gpio_set_all_output(sbu1_relay_pins, sizeof(sbu1_relay_pins) / sizeof(gpio_t), false); gpio_set_all_output(sbu2_ignition_pins, sizeof(sbu2_ignition_pins) / sizeof(gpio_t), false); gpio_set_all_output(sbu2_relay_pins, sizeof(sbu2_relay_pins) / sizeof(gpio_t), true); @@ -156,7 +156,12 @@ bool board_v2_get_button(void) { } void board_v2_set_ignition(bool enabled) { - ignition = enabled; + ignition = enabled ? 0xFFU : 0U; + board_v2_set_harness_orientation(harness_orientation); +} + +void board_v2_set_individual_ignition(uint8_t bitmask) { + ignition = bitmask; board_v2_set_harness_orientation(harness_orientation); } @@ -192,7 +197,7 @@ float board_v2_get_channel_power(uint8_t channel) { return ret; } -uint16_t board_v1_get_sbu_mV(uint8_t channel, uint8_t sbu) { +uint16_t board_v2_get_sbu_mV(uint8_t channel, uint8_t sbu) { uint16_t ret = 0U; if ((channel >= 1U) && (channel <= 6U)) { switch(sbu){ @@ -263,6 +268,7 @@ void board_v2_tick(void) {} const board board_v2 = { .board_type = "V2", .has_canfd = true, + .has_sbu_sense = true, .avdd_mV = 3300U, .init = &board_v2_init, .set_led = &board_v2_set_led, @@ -270,9 +276,10 @@ const board board_v2 = { .get_button = &board_v2_get_button, .set_panda_power = &board_v2_set_panda_power, .set_ignition = &board_v2_set_ignition, + .set_individual_ignition = &board_v2_set_individual_ignition, .set_harness_orientation = &board_v2_set_harness_orientation, .set_can_mode = &board_v2_set_can_mode, .enable_can_transciever = &board_v2_enable_can_transciever, .get_channel_power = &board_v2_get_channel_power, - .get_sbu_mV = &board_v1_get_sbu_mV, + .get_sbu_mV = &board_v2_get_sbu_mV, }; \ No newline at end of file diff --git a/board/jungle/main.c b/board/jungle/main.c index 806fbd3f..1d39074a 100644 --- a/board/jungle/main.c +++ b/board/jungle/main.c @@ -49,7 +49,7 @@ void __attribute__ ((noinline)) enable_fpu(void) { } // called at 8Hz -uint8_t loop_counter = 0U; +uint32_t loop_counter = 0U; uint16_t button_press_cnt = 0U; void tick_handler(void) { if (TICK_TIMER->SR != 0) { @@ -93,12 +93,28 @@ void tick_handler(void) { } #ifdef FINAL_PROVISIONING - // ign on for 0.3s, off for 0.2s - const bool ign = (loop_counter % (3+2)) < 3; - if (ign != ignition) { - current_board->set_ignition(ign); + // Ignition blinking + uint8_t ignition_bitmask = 0U; + for (uint8_t i = 0U; i < 6U; i++) { + ignition_bitmask |= ((loop_counter % 12U) < ((uint32_t) i + 2U)) << i; + } + current_board->set_individual_ignition(ignition_bitmask); + + // SBU voltage reporting + if (current_board->has_sbu_sense) { + for (uint8_t i = 0U; i < 6U; i++) { + CANPacket_t pkt = { 0 }; + pkt.data_len_code = 8U; + pkt.addr = 0x100U + i; + *(uint16_t *) &pkt.data[0] = current_board->get_sbu_mV(i + 1U, SBU1); + *(uint16_t *) &pkt.data[2] = current_board->get_sbu_mV(i + 1U, SBU2); + pkt.data[4] = (ignition_bitmask >> i) & 1U; + can_set_checksum(&pkt); + can_send(&pkt, 0U, false); + } } #else + // toggle ignition on button press static bool prev_button_status = false; if (!current_button_status && prev_button_status && button_press_cnt < 10){ current_board->set_ignition(!ignition);