diff options
Diffstat (limited to 'ports/esp8266')
-rw-r--r-- | ports/esp8266/esp_init_data.c | 2 | ||||
-rw-r--r-- | ports/esp8266/esp_mphal.h | 9 | ||||
-rw-r--r-- | ports/esp8266/main.c | 62 | ||||
-rw-r--r-- | ports/esp8266/modmachine.c | 34 | ||||
-rw-r--r-- | ports/esp8266/mpconfigport.h | 3 |
5 files changed, 77 insertions, 33 deletions
diff --git a/ports/esp8266/esp_init_data.c b/ports/esp8266/esp_init_data.c index c369ed58f5..a3dd6ffed1 100644 --- a/ports/esp8266/esp_init_data.c +++ b/ports/esp8266/esp_init_data.c @@ -30,7 +30,7 @@ #include "user_interface.h" #include "extmod/misc.h" -NORETURN void call_user_start(void); +MP_NORETURN void call_user_start(void); void ets_printf(const char *fmt, ...); extern char flashchip; diff --git a/ports/esp8266/esp_mphal.h b/ports/esp8266/esp_mphal.h index 0a4f92ac0b..fb2e441c97 100644 --- a/ports/esp8266/esp_mphal.h +++ b/ports/esp8266/esp_mphal.h @@ -27,11 +27,20 @@ #include "user_interface.h" #include "py/ringbuf.h" #include "shared/runtime/interrupt_char.h" +#include "ets_alt_task.h" #include "xtirq.h" #define MICROPY_BEGIN_ATOMIC_SECTION() esp_disable_irq() #define MICROPY_END_ATOMIC_SECTION(state) esp_enable_irq(state) +// During machine.time_pulse_us, feed WDT every now and then. +#define MICROPY_PY_MACHINE_TIME_PULSE_US_HOOK(dt) \ + do { \ + if ((dt & 0xffff) == 0xffff && !ets_loop_dont_feed_sw_wdt) { \ + system_soft_wdt_feed(); \ + } \ + } while (0) + void mp_sched_keyboard_interrupt(void); struct _mp_print_t; diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c index 2dd7c1dece..da712fce9b 100644 --- a/ports/esp8266/main.c +++ b/ports/esp8266/main.c @@ -49,6 +49,64 @@ static char heap[38 * 1024]; +#if MICROPY_HW_HARD_FAULT_DEBUG + +static void format_hex(uint32_t hex, char *buffer) { + static const char table[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + int offset = 7; + uint32_t value = hex; + while (offset >= 0) { + buffer[offset--] = table[value & 0x0F]; + value >>= 4; + } +} + +static void print_reset_info(void) { + struct rst_info *rst_info = system_get_rst_info(); + if ((rst_info->reason == REASON_WDT_RST) || (rst_info->reason == REASON_EXCEPTION_RST) || (rst_info->reason == REASON_SOFT_WDT_RST)) { + char buffer[8]; + mp_hal_stdout_tx_str("\r\n\r\nThe system restarted due to an error.\r\n\r\nReason: "); + switch (rst_info->reason) { + case REASON_WDT_RST: + mp_hal_stdout_tx_str("WDT"); + break; + + case REASON_EXCEPTION_RST: + mp_hal_stdout_tx_str("EXCEPTION"); + break; + + case REASON_SOFT_WDT_RST: + mp_hal_stdout_tx_str("SOFT_WDT"); + break; + + default: + assert(!"Should not ever get here."); + break; + } + mp_hal_stdout_tx_str(" Cause: "); + format_hex(rst_info->exccause, buffer); + mp_hal_stdout_tx_strn(buffer, sizeof(buffer)); + mp_hal_stdout_tx_str(" EPC1: "); + format_hex(rst_info->epc1, buffer); + mp_hal_stdout_tx_strn(buffer, sizeof(buffer)); + mp_hal_stdout_tx_str(" EPC2: "); + format_hex(rst_info->epc2, buffer); + mp_hal_stdout_tx_strn(buffer, sizeof(buffer)); + mp_hal_stdout_tx_str(" EPC3: "); + format_hex(rst_info->epc3, buffer); + mp_hal_stdout_tx_strn(buffer, sizeof(buffer)); + mp_hal_stdout_tx_str(" Exception Vector address: "); + format_hex(rst_info->excvaddr, buffer); + mp_hal_stdout_tx_strn(buffer, sizeof(buffer)); + mp_hal_stdout_tx_str(" DEPC: "); + format_hex(rst_info->depc, buffer); + mp_hal_stdout_tx_strn(buffer, sizeof(buffer)); + mp_hal_stdout_tx_str("\r\n\r\n"); + } +} + +#endif + static void mp_reset(void) { mp_stack_set_top((void *)0x40000000); mp_stack_set_limit(8192); @@ -114,6 +172,10 @@ void init_done(void) { pyexec_event_repl_init(); #endif + #if MICROPY_HW_HARD_FAULT_DEBUG + print_reset_info(); + #endif + #if !MICROPY_REPL_EVENT_DRIVEN soft_reset: for (;;) { diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c index 23ccf8cebf..d43fe38245 100644 --- a/ports/esp8266/modmachine.c +++ b/ports/esp8266/modmachine.c @@ -33,7 +33,6 @@ #include "os_type.h" #include "osapi.h" #include "etshal.h" -#include "ets_alt_task.h" #include "user_interface.h" // #define MACHINE_WAKE_IDLE (0x01) @@ -71,7 +70,7 @@ static void mp_machine_set_freq(size_t n_args, const mp_obj_t *args) { system_update_cpu_freq(freq); } -NORETURN static void mp_machine_reset(void) { +MP_NORETURN static void mp_machine_reset(void) { system_restart(); // we must not return @@ -114,7 +113,7 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { } } -NORETURN static void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args) { +MP_NORETURN static void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args) { // default to sleep forever uint32_t sleep_us = 0; @@ -327,32 +326,3 @@ MP_DEFINE_CONST_OBJ_TYPE( print, esp_timer_print, locals_dict, &esp_timer_locals_dict ); - -// Custom version of this function that feeds system WDT if necessary -mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) { - int nchanges = 2; - uint32_t start = system_get_time(); // in microseconds - for (;;) { - uint32_t dt = system_get_time() - start; - - // Check if pin changed to wanted value - if (mp_hal_pin_read(pin) == pulse_level) { - if (--nchanges == 0) { - return dt; - } - pulse_level = 1 - pulse_level; - start = system_get_time(); - continue; - } - - // Check for timeout - if (dt >= timeout_us) { - return (mp_uint_t)-nchanges; - } - - // Only feed WDT every now and then, to make sure edge timing is accurate - if ((dt & 0xffff) == 0xffff && !ets_loop_dont_feed_sw_wdt) { - system_soft_wdt_feed(); - } - } -} diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 83d80a7c96..03f3bb643d 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -117,6 +117,9 @@ #define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define MICROPY_ESP8266_APA102 (1) +// Print error information at reboot time if the board crashed. +#define MICROPY_HW_HARD_FAULT_DEBUG (0) + // No blocking wait-for-event on ESP8266, only non-blocking pump of the "OS" event // loop // |