From fa655ce196ad82e3b8664dcd0ba78328ecaa9a58 Mon Sep 17 00:00:00 2001 From: Daniel Campora Date: Sun, 5 Jul 2015 22:26:12 +0200 Subject: [PATCH] cc3200: Improve interrupt handling and fix bug in HAL_Delay(). --- cc3200/hal/cc3200_hal.c | 26 +++++++++++++++++--------- cc3200/misc/mpcallback.c | 14 +++++++------- cc3200/mods/modutime.c | 5 ++++- cc3200/mods/pybuart.c | 8 ++++---- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/cc3200/hal/cc3200_hal.c b/cc3200/hal/cc3200_hal.c index 3860641161..671af3cf9c 100644 --- a/cc3200/hal/cc3200_hal.c +++ b/cc3200/hal/cc3200_hal.c @@ -45,6 +45,7 @@ #include "mpexception.h" #include "telnet.h" #include "pybuart.h" +#include "utils.h" #ifdef USE_FREERTOS #include "FreeRTOS.h" @@ -107,16 +108,23 @@ uint32_t HAL_GetTick(void) { } void HAL_Delay(uint32_t delay) { -#ifdef USE_FREERTOS - vTaskDelay (delay / portTICK_PERIOD_MS); -#else - uint32_t start = HAL_tickCount; - // Wraparound of tick is taken care of by 2's complement arithmetic. - while (HAL_tickCount - start < delay) { - // Enter sleep mode, waiting for (at least) the SysTick interrupt. - __WFI(); + // only if we are not within interrupt context + if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0) { + #ifdef USE_FREERTOS + vTaskDelay (delay / portTICK_PERIOD_MS); + #else + uint32_t start = HAL_tickCount; + // wraparound of tick is taken care of by 2's complement arithmetic. + while (HAL_tickCount - start < delay) { + // enter sleep mode, waiting for (at least) the SysTick interrupt. + __WFI(); + } + #endif + } else { + for (int ms = 1; ms <= delay; ms++) { + UtilsDelay(UTILS_DELAY_US_TO_COUNT(ms * 1000)); + } } -#endif } void mp_hal_set_interrupt_char (int c) { diff --git a/cc3200/misc/mpcallback.c b/cc3200/misc/mpcallback.c index 5c23abe66c..35342a0ccf 100644 --- a/cc3200/misc/mpcallback.c +++ b/cc3200/misc/mpcallback.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include "std.h" + #include "py/mpconfig.h" #include MICROPY_HAL_H #include "py/obj.h" @@ -124,10 +126,8 @@ uint mpcallback_translate_priority (uint priority) { void mpcallback_handler (mp_obj_t self_in) { mpcallback_obj_t *self = self_in; if (self && self->handler != mp_const_none) { - // disable interrupts to avoid nesting - uint primsk = disable_irq(); // when executing code within a handler we must lock the GC to prevent - // any memory allocations. We must also catch any exceptions. + // any memory allocations. gc_lock(); nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { @@ -138,13 +138,13 @@ void mpcallback_handler (mp_obj_t self_in) { // uncaught exception; disable the callback so that it doesn't run again self->methods->disable (self->parent); self->handler = mp_const_none; - // printing an exception here will cause a stack overflow that will end up in - // a hard fault, so is better to signal the uncaught (probably non-recoverable) - // exception by blinking the system led instead. + // signal the error using the heart beat led and print an + // exception message as well mperror_signal_error(); + printf("Uncaught exception in callback handler\n"); + mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } gc_unlock(); - enable_irq(primsk); } } diff --git a/cc3200/mods/modutime.c b/cc3200/mods/modutime.c index f828fca9ae..d69e5c4e2e 100644 --- a/cc3200/mods/modutime.c +++ b/cc3200/mods/modutime.c @@ -125,7 +125,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); /// \function sleep(seconds) /// Sleep for the given number of seconds. STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { - HAL_Delay(mp_obj_get_int(seconds_o) * 1000); + int32_t sleep_s = mp_obj_get_int(seconds_o); + if (sleep_s > 0) { + HAL_Delay(sleep_s * 1000); + } return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c index 41a0a2ec34..f4ac2881a1 100644 --- a/cc3200/mods/pybuart.c +++ b/cc3200/mods/pybuart.c @@ -89,8 +89,8 @@ /****************************************************************************** DEFINE CONSTANTS ******************************************************************************/ -#define PYBUART_TX_WAIT_MS 1 -#define PYBUART_TX_MAX_TIMEOUT_MS 5 +#define PYBUART_TX_WAIT_US (50) +#define PYBUART_TX_MAX_TIMEOUT_MS (5) /****************************************************************************** DECLARE PRIVATE FUNCTIONS @@ -156,10 +156,10 @@ bool uart_tx_char(pyb_uart_obj_t *self, int c) { uint32_t timeout = 0; while (!MAP_UARTCharPutNonBlocking(self->reg, c)) { - if (timeout++ > (PYBUART_TX_MAX_TIMEOUT_MS / PYBUART_TX_WAIT_MS)) { + if (timeout++ > ((PYBUART_TX_MAX_TIMEOUT_MS * 1000) / PYBUART_TX_WAIT_US)) { return false; } - HAL_Delay (PYBUART_TX_WAIT_MS); + UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_TX_WAIT_US)); } return true; }