From 1a7060af25957bfd4238ee847f7818a1a2293561 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Tue, 5 Nov 2019 16:23:59 -0500 Subject: [PATCH 1/3] Add us delay --- .../common-hal/microcontroller/__init__.c | 26 +++++++++++++++---- ports/stm32f4/mphalport.h | 2 -- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c index 4a6fdc3883..af7718724d 100644 --- a/ports/stm32f4/common-hal/microcontroller/__init__.c +++ b/ports/stm32f4/common-hal/microcontroller/__init__.c @@ -42,14 +42,30 @@ // This routine should work even when interrupts are disabled. Used by OneWire // for precise timing. void common_hal_mcu_delay_us(uint32_t delay) { - //TODO: implement equivalent of mp_hal_delay_us(delay); - //this is fairly annoying in the STM32 HAL + // sys freq is always a multiple of 2MHz, so division here won't lose precision + const uint32_t ucount = HAL_RCC_GetSysClockFreq() / 2000000 * delay / 2; + for (uint32_t count = 0; ++count <= ucount;) { } -void common_hal_mcu_disable_interrupts() { +volatile uint32_t nesting_count = 0; +void common_hal_mcu_disable_interrupts(void) { + __disable_irq(); + __DMB(); + nesting_count++; } -void common_hal_mcu_enable_interrupts() { +void common_hal_mcu_enable_interrupts(void) { + if (nesting_count == 0) { + // This is very very bad because it means there was mismatched disable/enables so we + // "HardFault". + HardFault_Handler(); + } + nesting_count--; + if (nesting_count > 0) { + return; + } + __DMB(); + __enable_irq(); } void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { @@ -58,7 +74,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { } void common_hal_mcu_reset(void) { - filesystem_flush(); + filesystem_flush(); //TODO: implement as part of flash improvements NVIC_SystemReset(); } diff --git a/ports/stm32f4/mphalport.h b/ports/stm32f4/mphalport.h index 131f2751dc..d184138f78 100644 --- a/ports/stm32f4/mphalport.h +++ b/ports/stm32f4/mphalport.h @@ -33,8 +33,6 @@ #include "lib/utils/interrupt_char.h" #include "py/mpconfig.h" -//extern nrfx_uarte_t serial_instance; - extern volatile uint64_t ticks_ms; #define mp_hal_ticks_ms() ((mp_uint_t) ticks_ms) From 3f8b4727f5492cd5d4c18dd10a033f19de92d643 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Mon, 11 Nov 2019 14:58:45 -0500 Subject: [PATCH 2/3] Revise us delay to include interrupt/non-interrupt versions --- .../common-hal/microcontroller/__init__.c | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c index af7718724d..1ac8f474cb 100644 --- a/ports/stm32f4/common-hal/microcontroller/__init__.c +++ b/ports/stm32f4/common-hal/microcontroller/__init__.c @@ -39,15 +39,39 @@ #include "supervisor/filesystem.h" #include "supervisor/shared/safe_mode.h" -// This routine should work even when interrupts are disabled. Used by OneWire -// for precise timing. +#include "stm32f4xx_hal.h" + +//tested divisor value for busy loop in us delay +#define LOOP_TICKS 12 + +STATIC uint32_t get_us(void) { + uint32_t ticks_per_us = HAL_RCC_GetSysClockFreq()/1000000; + uint32_t micros, sys_cycles; + do { + micros = ticks_ms; + sys_cycles = SysTick->VAL; //counts backwards + } while (micros != ticks_ms); //try again if ticks_ms rolled over + return (micros * 1000) + (ticks_per_us * 1000 - sys_cycles) / ticks_per_us; +} + void common_hal_mcu_delay_us(uint32_t delay) { - // sys freq is always a multiple of 2MHz, so division here won't lose precision - const uint32_t ucount = HAL_RCC_GetSysClockFreq() / 2000000 * delay / 2; - for (uint32_t count = 0; ++count <= ucount;) { + if (__get_PRIMASK() == 0x00000000) { + //by default use ticks_ms + uint32_t start = get_us(); + while (get_us()-start < delay) { + __asm__ __volatile__("nop"); + } + } else { + //when SysTick is disabled, approximate with busy loop + const uint32_t ucount = HAL_RCC_GetSysClockFreq() / 1000000 * delay / LOOP_TICKS; + (void)start; + for (uint32_t count = 0; ++count <= ucount;) { + } + } } volatile uint32_t nesting_count = 0; + void common_hal_mcu_disable_interrupts(void) { __disable_irq(); __DMB(); @@ -58,7 +82,7 @@ void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { // This is very very bad because it means there was mismatched disable/enables so we // "HardFault". - HardFault_Handler(); + asm("bkpt"); } nesting_count--; if (nesting_count > 0) { From c38086fc4a14bc4d93d63ffe35451efdf95a0ed2 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Mon, 11 Nov 2019 15:04:22 -0500 Subject: [PATCH 3/3] fix typo --- ports/stm32f4/common-hal/microcontroller/__init__.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c index 1ac8f474cb..c7493a4d60 100644 --- a/ports/stm32f4/common-hal/microcontroller/__init__.c +++ b/ports/stm32f4/common-hal/microcontroller/__init__.c @@ -64,7 +64,6 @@ void common_hal_mcu_delay_us(uint32_t delay) { } else { //when SysTick is disabled, approximate with busy loop const uint32_t ucount = HAL_RCC_GetSysClockFreq() / 1000000 * delay / LOOP_TICKS; - (void)start; for (uint32_t count = 0; ++count <= ucount;) { } }