summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/machine_timer.c2
-rw-r--r--ports/stm32/mpconfigport.h2
-rw-r--r--ports/stm32/softtimer.c59
-rw-r--r--ports/stm32/softtimer.h5
4 files changed, 26 insertions, 42 deletions
diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c
index 22fa67d7d..1e9be4262 100644
--- a/ports/stm32/machine_timer.c
+++ b/ports/stm32/machine_timer.c
@@ -77,7 +77,7 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar
STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
machine_timer_obj_t *self = m_new_obj(machine_timer_obj_t);
- self->base.type = &machine_timer_type;
+ self->pairheap.base.type = &machine_timer_type;
// Get timer id (only soft timer (-1) supported at the moment)
mp_int_t id = -1;
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index 55f09f81f..2e4fc0406 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -281,7 +281,7 @@ struct _mp_bluetooth_nimble_root_pointers_t;
\
mp_obj_t pyb_extint_callback[PYB_EXTI_NUM_VECTORS]; \
\
- struct _soft_timer_entry_t *soft_timer_head; \
+ struct _soft_timer_entry_t *soft_timer_heap; \
\
/* pointers to all Timer objects (if they have been created) */ \
struct _pyb_timer_obj_t *pyb_timer_obj_all[MICROPY_HW_MAX_TIMER]; \
diff --git a/ports/stm32/softtimer.c b/ports/stm32/softtimer.c
index c598bac17..60c2709d9 100644
--- a/ports/stm32/softtimer.c
+++ b/ports/stm32/softtimer.c
@@ -37,7 +37,13 @@ extern __IO uint32_t uwTick;
volatile uint32_t soft_timer_next;
void soft_timer_deinit(void) {
- MP_STATE_PORT(soft_timer_head) = NULL;
+ MP_STATE_PORT(soft_timer_heap) = NULL;
+}
+
+STATIC int soft_timer_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
+ soft_timer_entry_t *e1 = (soft_timer_entry_t*)n1;
+ soft_timer_entry_t *e2 = (soft_timer_entry_t*)n2;
+ return TICKS_DIFF(e1->expiry_ms, e2->expiry_ms) < 0;
}
STATIC void soft_timer_schedule_systick(uint32_t ticks_ms) {
@@ -54,59 +60,38 @@ STATIC void soft_timer_schedule_systick(uint32_t ticks_ms) {
// Must be executed at IRQ_PRI_PENDSV
void soft_timer_handler(void) {
uint32_t ticks_ms = uwTick;
- soft_timer_entry_t *head = MP_STATE_PORT(soft_timer_head);
- while (head != NULL && TICKS_DIFF(head->expiry_ms, ticks_ms) <= 0) {
- mp_sched_schedule(head->callback, MP_OBJ_FROM_PTR(head));
- if (head->mode == SOFT_TIMER_MODE_PERIODIC) {
- head->expiry_ms += head->delta_ms;
- // Shift this node along to its new position
- soft_timer_entry_t *cur = head;
- while (cur->next != NULL && TICKS_DIFF(head->expiry_ms, cur->next->expiry_ms) >= 0) {
- cur = cur->next;
- }
- if (cur != head) {
- soft_timer_entry_t *next = head->next;
- head->next = cur->next;
- cur->next = head;
- head = next;
- }
- } else {
- head = head->next;
+ soft_timer_entry_t *heap = MP_STATE_PORT(soft_timer_heap);
+ while (heap != NULL && TICKS_DIFF(heap->expiry_ms, ticks_ms) <= 0) {
+ soft_timer_entry_t *entry = heap;
+ heap = (soft_timer_entry_t*)mp_pairheap_pop(soft_timer_lt, &heap->pairheap);
+ mp_sched_schedule(entry->callback, MP_OBJ_FROM_PTR(entry));
+ if (entry->mode == SOFT_TIMER_MODE_PERIODIC) {
+ entry->expiry_ms += entry->delta_ms;
+ heap = (soft_timer_entry_t*)mp_pairheap_push(soft_timer_lt, &heap->pairheap, &entry->pairheap);
}
}
- MP_STATE_PORT(soft_timer_head) = head;
- if (head == NULL) {
+ MP_STATE_PORT(soft_timer_heap) = heap;
+ if (heap == NULL) {
// No more timers left, set largest delay possible
soft_timer_next = uwTick;
} else {
// Set soft_timer_next so SysTick calls us back at the correct time
- soft_timer_schedule_systick(head->expiry_ms);
+ soft_timer_schedule_systick(heap->expiry_ms);
}
}
void soft_timer_insert(soft_timer_entry_t *entry) {
uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV);
- soft_timer_entry_t **head_ptr = &MP_STATE_PORT(soft_timer_head);
- while (*head_ptr != NULL && TICKS_DIFF(entry->expiry_ms, (*head_ptr)->expiry_ms) >= 0) {
- head_ptr = &(*head_ptr)->next;
- }
- entry->next = *head_ptr;
- *head_ptr = entry;
- if (head_ptr == &MP_STATE_PORT(soft_timer_head)) {
+ MP_STATE_PORT(soft_timer_heap) = (soft_timer_entry_t*)mp_pairheap_push(soft_timer_lt, &MP_STATE_PORT(soft_timer_heap)->pairheap, &entry->pairheap);
+ if (entry == MP_STATE_PORT(soft_timer_heap)) {
// This new timer became the earliest one so set soft_timer_next
- soft_timer_schedule_systick((*head_ptr)->expiry_ms);
+ soft_timer_schedule_systick(entry->expiry_ms);
}
restore_irq_pri(irq_state);
}
void soft_timer_remove(soft_timer_entry_t *entry) {
uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV);
- soft_timer_entry_t **cur = &MP_STATE_PORT(soft_timer_head);
- while (*cur != NULL) {
- if (*cur == entry) {
- *cur = entry->next;
- break;
- }
- }
+ MP_STATE_PORT(soft_timer_heap) = (soft_timer_entry_t*)mp_pairheap_delete(soft_timer_lt, &MP_STATE_PORT(soft_timer_heap)->pairheap, &entry->pairheap);
restore_irq_pri(irq_state);
}
diff --git a/ports/stm32/softtimer.h b/ports/stm32/softtimer.h
index 2550446d8..a80d9087b 100644
--- a/ports/stm32/softtimer.h
+++ b/ports/stm32/softtimer.h
@@ -26,14 +26,13 @@
#ifndef MICROPY_INCLUDED_STM32_SOFTTIMER_H
#define MICROPY_INCLUDED_STM32_SOFTTIMER_H
-#include "py/obj.h"
+#include "py/pairheap.h"
#define SOFT_TIMER_MODE_ONE_SHOT (1)
#define SOFT_TIMER_MODE_PERIODIC (2)
typedef struct _soft_timer_entry_t {
- mp_obj_base_t base; // so struct can be used as an object and still be traced by GC
- struct _soft_timer_entry_t *next;
+ mp_pairheap_t pairheap;
uint32_t mode;
uint32_t expiry_ms;
uint32_t delta_ms; // for periodic mode