diff --git a/ports/stm32/boardctrl.c b/ports/stm32/boardctrl.c index 02a3759991..406a983814 100644 --- a/ports/stm32/boardctrl.c +++ b/ports/stm32/boardctrl.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include + #include "py/runtime.h" #include "py/objstr.h" #include "py/mphal.h" @@ -33,6 +35,26 @@ #include "led.h" #include "usrsw.h" +NORETURN void boardctrl_fatal_error(const char *msg) { + for (volatile uint delay = 0; delay < 10000000; delay++) { + } + led_state(1, 1); + led_state(2, 1); + led_state(3, 1); + led_state(4, 1); + mp_hal_stdout_tx_strn("\nFATAL ERROR:\n", 14); + mp_hal_stdout_tx_strn(msg, strlen(msg)); + for (uint i = 0;;) { + led_toggle(((i++) & 3) + 1); + for (volatile uint delay = 0; delay < 10000000; delay++) { + } + if (i >= 16) { + // to conserve power + __WFI(); + } + } +} + STATIC void flash_error(int n) { for (int i = 0; i < n; i++) { led_state(PYB_LED_RED, 1); diff --git a/ports/stm32/boardctrl.h b/ports/stm32/boardctrl.h index afd4ab8510..8f4ce30eff 100644 --- a/ports/stm32/boardctrl.h +++ b/ports/stm32/boardctrl.h @@ -33,6 +33,10 @@ #define MICROPY_BOARD_PENDSV_ENTRIES #endif +#ifndef MICROPY_BOARD_FATAL_ERROR +#define MICROPY_BOARD_FATAL_ERROR boardctrl_fatal_error +#endif + #ifndef MICROPY_BOARD_STARTUP #define MICROPY_BOARD_STARTUP powerctrl_check_enter_bootloader #endif @@ -110,6 +114,7 @@ typedef struct _boardctrl_state_t { bool log_soft_reset; } boardctrl_state_t; +NORETURN void boardctrl_fatal_error(const char *msg); void boardctrl_maybe_enter_mboot(size_t n_args, const void *args); void boardctrl_before_soft_reset_loop(boardctrl_state_t *state); void boardctrl_top_soft_reset_loop(boardctrl_state_t *state); diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 875584be8a..54d9b05be1 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -97,41 +97,21 @@ STATIC pyb_uart_obj_t pyb_uart_repl_obj; STATIC uint8_t pyb_uart_repl_rxbuf[MICROPY_HW_UART_REPL_RXBUF]; #endif -void NORETURN __fatal_error(const char *msg) { - for (volatile uint delay = 0; delay < 10000000; delay++) { - } - led_state(1, 1); - led_state(2, 1); - led_state(3, 1); - led_state(4, 1); - mp_hal_stdout_tx_strn("\nFATAL ERROR:\n", 14); - mp_hal_stdout_tx_strn(msg, strlen(msg)); - for (uint i = 0;;) { - led_toggle(((i++) & 3) + 1); - for (volatile uint delay = 0; delay < 10000000; delay++) { - } - if (i >= 16) { - // to conserve power - __WFI(); - } - } -} - void nlr_jump_fail(void *val) { printf("FATAL: uncaught exception %p\n", val); mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val)); - __fatal_error(""); + MICROPY_BOARD_FATAL_ERROR(""); } void abort(void) { - __fatal_error("abort"); + MICROPY_BOARD_FATAL_ERROR("abort"); } #ifndef NDEBUG void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) { (void)func; printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line); - __fatal_error(""); + MICROPY_BOARD_FATAL_ERROR(""); } #endif diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index 34e78d2616..acedac7a59 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -339,8 +339,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { if (ret == -MP_EINVAL) { mp_raise_ValueError(MP_ERROR_TEXT("invalid freq")); } else if (ret < 0) { - void NORETURN __fatal_error(const char *msg); - __fatal_error("can't change freq"); + MICROPY_BOARD_FATAL_ERROR("can't change freq"); } return mp_const_none; #endif diff --git a/ports/stm32/pybthread.c b/ports/stm32/pybthread.c index 603bc2e4ec..3af0112fad 100644 --- a/ports/stm32/pybthread.c +++ b/ports/stm32/pybthread.c @@ -28,6 +28,7 @@ #include #include "py/obj.h" +#include "boardctrl.h" #include "gccollect.h" #include "irq.h" #include "pybthread.h" @@ -42,8 +43,6 @@ #define RAISE_IRQ_PRI() raise_irq_pri(IRQ_PRI_PENDSV) #define RESTORE_IRQ_PRI(state) restore_irq_pri(state) -extern void __fatal_error(const char *); - volatile int pyb_thread_enabled; pyb_thread_t *volatile pyb_thread_all; pyb_thread_t *volatile pyb_thread_cur; @@ -57,7 +56,7 @@ static inline void pyb_thread_add_to_runable(pyb_thread_t *thread) { static inline void pyb_thread_remove_from_runable(pyb_thread_t *thread) { if (thread->run_next == thread) { - __fatal_error("deadlock"); + MICROPY_BOARD_FATAL_ERROR("deadlock"); } thread->run_prev->run_next = thread->run_next; thread->run_next->run_prev = thread->run_prev; @@ -112,7 +111,7 @@ STATIC void pyb_thread_terminate(void) { SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; enable_irq(irq_state); // should not return - __fatal_error("could not terminate"); + MICROPY_BOARD_FATAL_ERROR("could not terminate"); } uint32_t pyb_thread_new(pyb_thread_t *thread, void *stack, size_t stack_len, void *entry, void *arg) { diff --git a/ports/stm32/sdram.c b/ports/stm32/sdram.c index 4ca79f270c..65a949770e 100644 --- a/ports/stm32/sdram.c +++ b/ports/stm32/sdram.c @@ -50,7 +50,6 @@ #ifdef FMC_SDRAM_BANK static void sdram_init_seq(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *command); -extern void __fatal_error(const char *msg); bool sdram_init(void) { SDRAM_HandleTypeDef hsdram; @@ -325,7 +324,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) { snprintf(error_buffer, sizeof(error_buffer), "Data bus test failed at 0x%p expected 0x%x found 0x%lx", &mem_base[0], (1 << i), ((volatile uint32_t *)mem_base)[0]); - __fatal_error(error_buffer); + MICROPY_BOARD_FATAL_ERROR(error_buffer); #endif return false; } @@ -340,7 +339,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) { snprintf(error_buffer, sizeof(error_buffer), "Address bus test failed at 0x%p expected 0x%x found 0x%x", &mem_base[i], pattern, mem_base[i]); - __fatal_error(error_buffer); + MICROPY_BOARD_FATAL_ERROR(error_buffer); #endif return false; } @@ -355,7 +354,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) { snprintf(error_buffer, sizeof(error_buffer), "Address bus overlap at 0x%p expected 0x%x found 0x%x", &mem_base[i], pattern, mem_base[i]); - __fatal_error(error_buffer); + MICROPY_BOARD_FATAL_ERROR(error_buffer); #endif return false; } @@ -376,7 +375,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) { snprintf(error_buffer, sizeof(error_buffer), "Address bus slow test failed at 0x%p expected 0x%x found 0x%x", &mem_base[i], ((i % 2) ? pattern : antipattern), mem_base[i]); - __fatal_error(error_buffer); + MICROPY_BOARD_FATAL_ERROR(error_buffer); #endif return false; } diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 55c772efb4..2f89f67deb 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -83,7 +83,6 @@ #include "i2c.h" #include "usb.h" -extern void __fatal_error(const char *); #if defined(MICROPY_HW_USB_FS) extern PCD_HandleTypeDef pcd_fs_handle; #endif @@ -192,7 +191,7 @@ void HardFault_C_Handler(ExceptionRegisters_t *regs) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { - __fatal_error("HardFault"); + MICROPY_BOARD_FATAL_ERROR("HardFault"); } } @@ -246,7 +245,7 @@ void NMI_Handler(void) { void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { - __fatal_error("MemManage"); + MICROPY_BOARD_FATAL_ERROR("MemManage"); } } @@ -258,7 +257,7 @@ void MemManage_Handler(void) { void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { - __fatal_error("BusFault"); + MICROPY_BOARD_FATAL_ERROR("BusFault"); } } @@ -270,7 +269,7 @@ void BusFault_Handler(void) { void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { - __fatal_error("UsageFault"); + MICROPY_BOARD_FATAL_ERROR("UsageFault"); } } diff --git a/ports/stm32/system_stm32.c b/ports/stm32/system_stm32.c index e67c32738c..08f071cd27 100644 --- a/ports/stm32/system_stm32.c +++ b/ports/stm32/system_stm32.c @@ -76,12 +76,11 @@ */ #include "py/mphal.h" +#include "boardctrl.h" #include "powerctrl.h" #if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) -void __fatal_error(const char *msg); - /** * @brief System Clock Configuration * @@ -390,7 +389,7 @@ MP_WEAK void SystemClock_Config(void) { #endif if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - __fatal_error("HAL_RCC_OscConfig"); + MICROPY_BOARD_FATAL_ERROR("HAL_RCC_OscConfig"); } #if defined(MICROPY_HW_CLK_PLL2M) @@ -478,20 +477,20 @@ MP_WEAK void SystemClock_Config(void) { #endif if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { - __fatal_error("HAL_RCCEx_PeriphCLKConfig"); + MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig"); } #endif // defined(STM32H7) #if defined(STM32F7) /* Activate the OverDrive to reach the 200 MHz Frequency */ if (HAL_PWREx_EnableOverDrive() != HAL_OK) { - __fatal_error("HAL_PWREx_EnableOverDrive"); + MICROPY_BOARD_FATAL_ERROR("HAL_PWREx_EnableOverDrive"); } #endif #if defined(STM32G4) if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8) != HAL_OK) { - __fatal_error("HAL_RCC_ClockConfig"); + MICROPY_BOARD_FATAL_ERROR("HAL_RCC_ClockConfig"); } PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC12 @@ -503,14 +502,14 @@ MP_WEAK void SystemClock_Config(void) { PeriphClkInitStruct.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { - __fatal_error("HAL_RCCEx_PeriphCLKConfig"); + MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig"); } #else uint32_t vco_out = RCC_OscInitStruct.PLL.PLLN * (MICROPY_HW_CLK_VALUE / 1000000) / RCC_OscInitStruct.PLL.PLLM; uint32_t sysclk_mhz = vco_out / RCC_OscInitStruct.PLL.PLLP; bool need_pll48 = vco_out % 48 != 0; if (powerctrl_rcc_clock_config_pll(&RCC_ClkInitStruct, sysclk_mhz, need_pll48) != 0) { - __fatal_error("HAL_RCC_ClockConfig"); + MICROPY_BOARD_FATAL_ERROR("HAL_RCC_ClockConfig"); } #endif @@ -572,7 +571,7 @@ MP_WEAK void SystemClock_Config(void) { | RCC_PLLSAI1_ADC1CLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { - __fatal_error("HAL_RCCEx_PeriphCLKConfig"); + MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig"); } __PWR_CLK_ENABLE(); diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index adcbe88368..34d8246d5f 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -112,8 +112,6 @@ #endif -extern void NORETURN __fatal_error(const char *msg); - typedef struct _pyb_uart_irq_map_t { uint16_t irq_en; uint16_t flag; @@ -152,7 +150,7 @@ void uart_init0(void) { RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2; RCC_PeriphClkInit.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) { - __fatal_error("HAL_RCCEx_PeriphCLKConfig"); + MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig"); } #endif }