cc3200: Improve interrupt handling and fix bug in HAL_Delay().

This commit is contained in:
Daniel Campora 2015-07-05 22:26:12 +02:00
parent 194c8c761e
commit fa655ce196
4 changed files with 32 additions and 21 deletions

View File

@ -45,6 +45,7 @@
#include "mpexception.h" #include "mpexception.h"
#include "telnet.h" #include "telnet.h"
#include "pybuart.h" #include "pybuart.h"
#include "utils.h"
#ifdef USE_FREERTOS #ifdef USE_FREERTOS
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -107,16 +108,23 @@ uint32_t HAL_GetTick(void) {
} }
void HAL_Delay(uint32_t delay) { void HAL_Delay(uint32_t delay) {
#ifdef USE_FREERTOS // only if we are not within interrupt context
vTaskDelay (delay / portTICK_PERIOD_MS); if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0) {
#else #ifdef USE_FREERTOS
uint32_t start = HAL_tickCount; vTaskDelay (delay / portTICK_PERIOD_MS);
// Wraparound of tick is taken care of by 2's complement arithmetic. #else
while (HAL_tickCount - start < delay) { uint32_t start = HAL_tickCount;
// Enter sleep mode, waiting for (at least) the SysTick interrupt. // wraparound of tick is taken care of by 2's complement arithmetic.
__WFI(); 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) { void mp_hal_set_interrupt_char (int c) {

View File

@ -24,6 +24,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "std.h"
#include "py/mpconfig.h" #include "py/mpconfig.h"
#include MICROPY_HAL_H #include MICROPY_HAL_H
#include "py/obj.h" #include "py/obj.h"
@ -124,10 +126,8 @@ uint mpcallback_translate_priority (uint priority) {
void mpcallback_handler (mp_obj_t self_in) { void mpcallback_handler (mp_obj_t self_in) {
mpcallback_obj_t *self = self_in; mpcallback_obj_t *self = self_in;
if (self && self->handler != mp_const_none) { 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 // 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(); gc_lock();
nlr_buf_t nlr; nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) { 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 // uncaught exception; disable the callback so that it doesn't run again
self->methods->disable (self->parent); self->methods->disable (self->parent);
self->handler = mp_const_none; self->handler = mp_const_none;
// printing an exception here will cause a stack overflow that will end up in // signal the error using the heart beat led and print an
// a hard fault, so is better to signal the uncaught (probably non-recoverable) // exception message as well
// exception by blinking the system led instead.
mperror_signal_error(); 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(); gc_unlock();
enable_irq(primsk);
} }
} }

View File

@ -125,7 +125,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
/// \function sleep(seconds) /// \function sleep(seconds)
/// Sleep for the given number of seconds. /// Sleep for the given number of seconds.
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { 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; return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);

View File

@ -89,8 +89,8 @@
/****************************************************************************** /******************************************************************************
DEFINE CONSTANTS DEFINE CONSTANTS
******************************************************************************/ ******************************************************************************/
#define PYBUART_TX_WAIT_MS 1 #define PYBUART_TX_WAIT_US (50)
#define PYBUART_TX_MAX_TIMEOUT_MS 5 #define PYBUART_TX_MAX_TIMEOUT_MS (5)
/****************************************************************************** /******************************************************************************
DECLARE PRIVATE FUNCTIONS DECLARE PRIVATE FUNCTIONS
@ -156,10 +156,10 @@ bool uart_tx_char(pyb_uart_obj_t *self, int c) {
uint32_t timeout = 0; uint32_t timeout = 0;
while (!MAP_UARTCharPutNonBlocking(self->reg, c)) { 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; return false;
} }
HAL_Delay (PYBUART_TX_WAIT_MS); UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_TX_WAIT_US));
} }
return true; return true;
} }