shared/runtime/softtimer: Use consistently the same clock source.

Before, both uwTick and mp_hal_ticks_ms() were used as clock source.  That
assumes, that these two are synchronous and start with the same value,
which may be not the case for all ports.  If the lag between uwTick and
mp_hal_ticks_ms() is larger than the timer interval, the timer would either
rush up until the times are synchronous, or not start until uwTick wraps
over.

As suggested by @dpgeorge, MICROPY_SOFT_TIMER_TICKS_MS is now used in
softtimer.c, which has to be defined in a port's mpconfigport.h with
the variable that holds the SysTick counter.

Note that it's not possible to switch everything in softtimer.c to use
mp_hal_ticks_ms() because the logic in SysTick_Handler that schedules
soft_timer_handler() uses (eg on mimxrt) the uwTick variable directly
(named systick_ms there), and mp_hal_ticks_ms() uses a different source
timer.  Thus it is made fully configurable.
This commit is contained in:
robert-hh 2023-02-12 14:15:08 +01:00 committed by Damien George
parent 68d049ea5e
commit de1f1dd164
6 changed files with 9 additions and 9 deletions

View File

@ -92,6 +92,7 @@ uint32_t trng_random_u32(void);
#define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SPI (1)
#define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1)
#define MICROPY_PY_MACHINE_TIMER (1) #define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_SOFT_TIMER_TICKS_MS systick_ms
#define MICROPY_PY_ONEWIRE (1) #define MICROPY_PY_ONEWIRE (1)
#define MICROPY_PY_UPLATFORM (1) #define MICROPY_PY_UPLATFORM (1)

View File

@ -120,6 +120,7 @@
#define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB) #define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB)
#define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1)
#define MICROPY_PY_MACHINE_TIMER (1) #define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_SOFT_TIMER_TICKS_MS uwTick
#endif #endif
#define MICROPY_HW_SOFTSPI_MIN_DELAY (0) #define MICROPY_HW_SOFTSPI_MIN_DELAY (0)
#define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (48000000 / 48) #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (48000000 / 48)

View File

@ -98,6 +98,7 @@
#define MICROPY_HW_SOFTSPI_MIN_DELAY (1) #define MICROPY_HW_SOFTSPI_MIN_DELAY (1)
#define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (1000000) #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (1000000)
#define MICROPY_PY_MACHINE_TIMER (1) #define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_SOFT_TIMER_TICKS_MS systick_ms
#define MICROPY_PY_OS_DUPTERM (3) #define MICROPY_PY_OS_DUPTERM (3)
#define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_BITSTREAM (1)
#define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PULSE (1)

View File

@ -43,10 +43,6 @@ uint64_t mp_hal_ticks_us_64(void);
void mp_hal_set_interrupt_char(int c); void mp_hal_set_interrupt_char(int c);
// Define an alias fo systick_ms, because the shared softtimer.c uses
// the symbol uwTick for the systick ms counter.
#define uwTick systick_ms
#define mp_hal_delay_us_fast mp_hal_delay_us #define mp_hal_delay_us_fast mp_hal_delay_us
static inline uint64_t mp_hal_ticks_ms_64(void) { static inline uint64_t mp_hal_ticks_ms_64(void) {

View File

@ -127,6 +127,7 @@
#define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB) #define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB)
#define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1)
#define MICROPY_PY_MACHINE_TIMER (1) #define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_SOFT_TIMER_TICKS_MS uwTick
#endif #endif
#define MICROPY_HW_SOFTSPI_MIN_DELAY (0) #define MICROPY_HW_SOFTSPI_MIN_DELAY (0)
#define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (HAL_RCC_GetSysClockFreq() / 48) #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (HAL_RCC_GetSysClockFreq() / 48)

View File

@ -33,7 +33,7 @@
#define TICKS_PERIOD 0x80000000 #define TICKS_PERIOD 0x80000000
#define TICKS_DIFF(t1, t0) ((int32_t)(((t1 - t0 + TICKS_PERIOD / 2) & (TICKS_PERIOD - 1)) - TICKS_PERIOD / 2)) #define TICKS_DIFF(t1, t0) ((int32_t)(((t1 - t0 + TICKS_PERIOD / 2) & (TICKS_PERIOD - 1)) - TICKS_PERIOD / 2))
extern __IO uint32_t uwTick; extern __IO uint32_t MICROPY_SOFT_TIMER_TICKS_MS;
volatile uint32_t soft_timer_next; volatile uint32_t soft_timer_next;
@ -50,7 +50,7 @@ STATIC int soft_timer_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
STATIC void soft_timer_schedule_systick(uint32_t ticks_ms) { STATIC void soft_timer_schedule_systick(uint32_t ticks_ms) {
uint32_t irq_state = disable_irq(); uint32_t irq_state = disable_irq();
uint32_t uw_tick = uwTick; uint32_t uw_tick = MICROPY_SOFT_TIMER_TICKS_MS;
if (TICKS_DIFF(ticks_ms, uw_tick) <= 0) { if (TICKS_DIFF(ticks_ms, uw_tick) <= 0) {
soft_timer_next = uw_tick + 1; soft_timer_next = uw_tick + 1;
} else { } else {
@ -77,7 +77,7 @@ void soft_timer_deinit(void) {
// Must be executed at IRQ_PRI_PENDSV // Must be executed at IRQ_PRI_PENDSV
void soft_timer_handler(void) { void soft_timer_handler(void) {
uint32_t ticks_ms = uwTick; uint32_t ticks_ms = MICROPY_SOFT_TIMER_TICKS_MS;
soft_timer_entry_t *heap = soft_timer_heap; soft_timer_entry_t *heap = soft_timer_heap;
while (heap != NULL && TICKS_DIFF(heap->expiry_ms, ticks_ms) <= 0) { while (heap != NULL && TICKS_DIFF(heap->expiry_ms, ticks_ms) <= 0) {
soft_timer_entry_t *entry = heap; soft_timer_entry_t *entry = heap;
@ -95,7 +95,7 @@ void soft_timer_handler(void) {
soft_timer_heap = heap; soft_timer_heap = heap;
if (heap == NULL) { if (heap == NULL) {
// No more timers left, set largest delay possible // No more timers left, set largest delay possible
soft_timer_next = uwTick; soft_timer_next = MICROPY_SOFT_TIMER_TICKS_MS;
} else { } else {
// Set soft_timer_next so SysTick calls us back at the correct time // Set soft_timer_next so SysTick calls us back at the correct time
soft_timer_schedule_systick(heap->expiry_ms); soft_timer_schedule_systick(heap->expiry_ms);
@ -130,7 +130,7 @@ void soft_timer_static_init(soft_timer_entry_t *entry, uint16_t mode, uint32_t d
void soft_timer_insert(soft_timer_entry_t *entry, uint32_t initial_delta_ms) { void soft_timer_insert(soft_timer_entry_t *entry, uint32_t initial_delta_ms) {
mp_pairheap_init_node(soft_timer_lt, &entry->pairheap); mp_pairheap_init_node(soft_timer_lt, &entry->pairheap);
entry->expiry_ms = mp_hal_ticks_ms() + initial_delta_ms; entry->expiry_ms = MICROPY_SOFT_TIMER_TICKS_MS + initial_delta_ms;
uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV); uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV);
soft_timer_heap = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &soft_timer_heap->pairheap, &entry->pairheap); soft_timer_heap = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &soft_timer_heap->pairheap, &entry->pairheap);
if (entry == soft_timer_heap) { if (entry == soft_timer_heap) {