diff --git a/SConscript b/SConscript index de77092038..b5b3e82d7f 100644 --- a/SConscript +++ b/SConscript @@ -61,7 +61,9 @@ def to_c_uint32(x): return "{" + 'U,'.join(map(str, nums)) + "U}" -def build_project(project_name, project, main, extra_flags): +def build_project(project_name, project, main, extra_flags, extra_sources=None): + if extra_sources is None: + extra_sources = [] project_dir = Dir(f'./board/obj/{project_name}/') flags = project["FLAGS"] + extra_flags + common_flags + [ @@ -115,7 +117,8 @@ def build_project(project_name, project, main, extra_flags): # Build + sign main (aka app) main_elf = env.Program(f"{project_dir}/main.elf", [ startup, - main + main, + *extra_sources, ], LINKFLAGS=[f"-Wl,--section-start,.isr_vector={project['APP_START_ADDRESS']}"] + flags) main_bin = env.Objcopy(f"{project_dir}/main.bin", main_elf) sign_py = File(f"./board/crypto/sign.py").srcnode().relpath @@ -161,7 +164,10 @@ common_flags += [f"-DHEALTH_PACKET_VERSION=0x{hh:08X}U", f"-DCAN_PACKET_VERSION_ f"-DJUNGLE_HEALTH_PACKET_VERSION=0x{jh:08X}U"] # panda fw -build_project("panda_h7", base_project_h7, "./board/main.c", []) +build_project("panda_h7", base_project_h7, "./board/main.c", [], [ + "./board/drivers/bootkick.c", + "./board/drivers/simple_watchdog.c", +]) # panda jungle fw flags = [ diff --git a/board/drivers/bootkick.c b/board/drivers/bootkick.c new file mode 100644 index 0000000000..116f7f8dd0 --- /dev/null +++ b/board/drivers/bootkick.c @@ -0,0 +1,99 @@ +#include "stm32h7xx.h" + +#include "board/drivers/bootkick.h" +#include "board/main_declarations.h" +#include "board/boards/board_declarations.h" + +#define HARNESS_STATUS_NC 0U + +typedef struct uart_ring { + volatile uint16_t w_ptr_tx; + volatile uint16_t r_ptr_tx; + uint8_t *elems_tx; + uint32_t tx_fifo_size; + volatile uint16_t w_ptr_rx; + volatile uint16_t r_ptr_rx; + uint8_t *elems_rx; + uint32_t rx_fifo_size; + USART_TypeDef *uart; + void (*callback)(struct uart_ring*); + bool overwrite; +} uart_ring; + +struct harness_t { + uint8_t status; + uint16_t sbu1_voltage_mV; + uint16_t sbu2_voltage_mV; + bool relay_driven; + bool sbu_adc_lock; +}; + +extern struct harness_t harness; +extern uart_ring uart_ring_som_debug; + +bool bootkick_reset_triggered = false; + +void bootkick_tick(bool ignition, bool recent_heartbeat) { + static uint16_t bootkick_last_serial_ptr = 0; + static uint8_t waiting_to_boot_countdown = 0; + static uint8_t boot_reset_countdown = 0; + static uint8_t bootkick_harness_status_prev = HARNESS_STATUS_NC; + static bool bootkick_ign_prev = false; + static BootState boot_state = BOOT_BOOTKICK; + BootState boot_state_prev = boot_state; + const bool harness_inserted = (harness.status != bootkick_harness_status_prev) && (harness.status != HARNESS_STATUS_NC); + + if ((ignition && !bootkick_ign_prev) || harness_inserted) { + // bootkick on rising edge of ignition or harness insertion + boot_state = BOOT_BOOTKICK; + } else if (recent_heartbeat) { + // disable bootkick once openpilot is up + boot_state = BOOT_STANDBY; + } else { + + } + + /* + Ensure SOM boots in case it goes into QDL mode. Reset behavior: + * shouldn't trigger on the first boot after power-on + * only try reset once per bootkick, i.e. don't keep trying until booted + * only try once per panda boot, since openpilot will reset panda on startup + * once BOOT_RESET is triggered, it stays until countdown is finished + */ + if (!bootkick_reset_triggered && (boot_state == BOOT_BOOTKICK) && (boot_state_prev == BOOT_STANDBY)) { + waiting_to_boot_countdown = 20U; + } + if (waiting_to_boot_countdown > 0U) { + bool serial_activity = uart_ring_som_debug.w_ptr_tx != bootkick_last_serial_ptr; + if (serial_activity || current_board->read_som_gpio() || (boot_state != BOOT_BOOTKICK)) { + waiting_to_boot_countdown = 0U; + } else { + // try a reset + if (waiting_to_boot_countdown == 1U) { + boot_reset_countdown = 5U; + } + } + } + + // handle reset state + if (boot_reset_countdown > 0U) { + boot_state = BOOT_RESET; + bootkick_reset_triggered = true; + } else { + if (boot_state == BOOT_RESET) { + boot_state = BOOT_BOOTKICK; + } + } + + // update state + bootkick_ign_prev = ignition; + bootkick_harness_status_prev = harness.status; + bootkick_last_serial_ptr = uart_ring_som_debug.w_ptr_tx; + if (waiting_to_boot_countdown > 0U) { + waiting_to_boot_countdown--; + } + if (boot_reset_countdown > 0U) { + boot_reset_countdown--; + } + current_board->set_bootkick(boot_state); +} diff --git a/board/drivers/bootkick.h b/board/drivers/bootkick.h index 4bf990391b..4793056c55 100644 --- a/board/drivers/bootkick.h +++ b/board/drivers/bootkick.h @@ -1,68 +1,7 @@ -#include "board/drivers/drivers.h" +#pragma once -bool bootkick_reset_triggered = false; +#include -void bootkick_tick(bool ignition, bool recent_heartbeat) { - static uint16_t bootkick_last_serial_ptr = 0; - static uint8_t waiting_to_boot_countdown = 0; - static uint8_t boot_reset_countdown = 0; - static uint8_t bootkick_harness_status_prev = HARNESS_STATUS_NC; - static bool bootkick_ign_prev = false; - static BootState boot_state = BOOT_BOOTKICK; - BootState boot_state_prev = boot_state; - const bool harness_inserted = (harness.status != bootkick_harness_status_prev) && (harness.status != HARNESS_STATUS_NC); +extern bool bootkick_reset_triggered; - if ((ignition && !bootkick_ign_prev) || harness_inserted) { - // bootkick on rising edge of ignition or harness insertion - boot_state = BOOT_BOOTKICK; - } else if (recent_heartbeat) { - // disable bootkick once openpilot is up - boot_state = BOOT_STANDBY; - } else { - - } - - /* - Ensure SOM boots in case it goes into QDL mode. Reset behavior: - * shouldn't trigger on the first boot after power-on - * only try reset once per bootkick, i.e. don't keep trying until booted - * only try once per panda boot, since openpilot will reset panda on startup - * once BOOT_RESET is triggered, it stays until countdown is finished - */ - if (!bootkick_reset_triggered && (boot_state == BOOT_BOOTKICK) && (boot_state_prev == BOOT_STANDBY)) { - waiting_to_boot_countdown = 20U; - } - if (waiting_to_boot_countdown > 0U) { - bool serial_activity = uart_ring_som_debug.w_ptr_tx != bootkick_last_serial_ptr; - if (serial_activity || current_board->read_som_gpio() || (boot_state != BOOT_BOOTKICK)) { - waiting_to_boot_countdown = 0U; - } else { - // try a reset - if (waiting_to_boot_countdown == 1U) { - boot_reset_countdown = 5U; - } - } - } - - // handle reset state - if (boot_reset_countdown > 0U) { - boot_state = BOOT_RESET; - bootkick_reset_triggered = true; - } else { - if (boot_state == BOOT_RESET) { - boot_state = BOOT_BOOTKICK; - } - } - - // update state - bootkick_ign_prev = ignition; - bootkick_harness_status_prev = harness.status; - bootkick_last_serial_ptr = uart_ring_som_debug.w_ptr_tx; - if (waiting_to_boot_countdown > 0U) { - waiting_to_boot_countdown--; - } - if (boot_reset_countdown > 0U) { - boot_reset_countdown--; - } - current_board->set_bootkick(boot_state); -} +void bootkick_tick(bool ignition, bool recent_heartbeat); diff --git a/board/drivers/drivers.h b/board/drivers/drivers.h index c61506707a..f5e0cf85f9 100644 --- a/board/drivers/drivers.h +++ b/board/drivers/drivers.h @@ -211,12 +211,6 @@ void init_registers(void); // ******************** simple_watchdog ******************** -typedef struct simple_watchdog_state_t { - uint32_t fault; - uint32_t last_ts; - uint32_t threshold; -} simple_watchdog_state_t; - void simple_watchdog_kick(void); void simple_watchdog_init(uint32_t fault, uint32_t threshold); diff --git a/board/drivers/gpio.h b/board/drivers/gpio.h index aea604254e..70a0ab0c24 100644 --- a/board/drivers/gpio.h +++ b/board/drivers/gpio.h @@ -53,7 +53,9 @@ void set_gpio_alternate(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) void set_gpio_pullup(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) { ENTER_CRITICAL(); uint32_t tmp = GPIO->PUPDR; + // cppcheck-suppress misra-c2012-12.2; pin is a GPIO pin index tmp &= ~(3U << (pin * 2U)); + // cppcheck-suppress misra-c2012-12.2; pin is a GPIO pin index tmp |= (mode << (pin * 2U)); register_set(&(GPIO->PUPDR), tmp, 0xFFFFFFFFU); EXIT_CRITICAL(); diff --git a/board/drivers/simple_watchdog.c b/board/drivers/simple_watchdog.c new file mode 100644 index 0000000000..097da44ad1 --- /dev/null +++ b/board/drivers/simple_watchdog.c @@ -0,0 +1,37 @@ +#include "board/drivers/simple_watchdog.h" + +#include + +#include "stm32h7xx.h" + +#include "board/main_declarations.h" +#include "board/sys/sys.h" + +typedef struct simple_watchdog_state_t { + uint32_t fault; + uint32_t last_ts; + uint32_t threshold; +} simple_watchdog_state_t; + +uint32_t get_ts_elapsed(uint32_t ts, uint32_t ts_last); +uint32_t microsecond_timer_get(void); + +static simple_watchdog_state_t wd_state; + +void simple_watchdog_kick(void) { + uint32_t ts = microsecond_timer_get(); + + uint32_t et = get_ts_elapsed(ts, wd_state.last_ts); + if (et > wd_state.threshold) { + print("WD timeout 0x"); puth(et); print("\n"); + fault_occurred(wd_state.fault); + } + + wd_state.last_ts = ts; +} + +void simple_watchdog_init(uint32_t fault, uint32_t threshold) { + wd_state.fault = fault; + wd_state.threshold = threshold; + wd_state.last_ts = microsecond_timer_get(); +} diff --git a/board/drivers/simple_watchdog.h b/board/drivers/simple_watchdog.h index 7668402fec..d73fdab1c2 100644 --- a/board/drivers/simple_watchdog.h +++ b/board/drivers/simple_watchdog.h @@ -1,21 +1,6 @@ -#include "board/drivers/drivers.h" +#pragma once -static simple_watchdog_state_t wd_state; +#include -void simple_watchdog_kick(void) { - uint32_t ts = microsecond_timer_get(); - - uint32_t et = get_ts_elapsed(ts, wd_state.last_ts); - if (et > wd_state.threshold) { - print("WD timeout 0x"); puth(et); print("\n"); - fault_occurred(wd_state.fault); - } - - wd_state.last_ts = ts; -} - -void simple_watchdog_init(uint32_t fault, uint32_t threshold) { - wd_state.fault = fault; - wd_state.threshold = threshold; - wd_state.last_ts = microsecond_timer_get(); -} +void simple_watchdog_kick(void); +void simple_watchdog_init(uint32_t fault, uint32_t threshold); diff --git a/board/main.c b/board/main.c index e3e9807479..044582c555 100644 --- a/board/main.c +++ b/board/main.c @@ -4,8 +4,6 @@ #include "board/drivers/led.h" #include "board/drivers/pwm.h" #include "board/drivers/usb.h" -#include "board/drivers/simple_watchdog.h" -#include "board/drivers/bootkick.h" #include "board/early_init.h" #include "board/provision.h"