summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/mpconfigport.h6
-rw-r--r--ports/stm32/timer.c142
2 files changed, 81 insertions, 67 deletions
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index 21142c17b..abeaa56f6 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -232,9 +232,11 @@ extern const struct _mp_obj_module_t mp_module_onewire;
#if defined(MCU_SERIES_F7)
#define PYB_EXTI_NUM_VECTORS (24)
+#define MICROPY_HW_MAX_TIMER (17)
#define MICROPY_HW_MAX_UART (8)
#else
#define PYB_EXTI_NUM_VECTORS (23)
+#define MICROPY_HW_MAX_TIMER (14)
#define MICROPY_HW_MAX_UART (6)
#endif
@@ -254,8 +256,8 @@ extern const struct _mp_obj_module_t mp_module_onewire;
\
mp_obj_t pyb_extint_callback[PYB_EXTI_NUM_VECTORS]; \
\
- /* Used to do callbacks to Python code on interrupt */ \
- struct _pyb_timer_obj_t *pyb_timer_obj_all[14]; \
+ /* pointers to all Timer objects (if they have been created) */ \
+ struct _pyb_timer_obj_t *pyb_timer_obj_all[MICROPY_HW_MAX_TIMER]; \
\
/* stdio is repeated on this UART object if it's not null */ \
struct _pyb_uart_obj_t *pyb_stdio_uart; \
diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c
index 00e9c2a83..f24c2e6bf 100644
--- a/ports/stm32/timer.c
+++ b/ports/stm32/timer.c
@@ -629,6 +629,62 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
return mp_const_none;
}
+// This table encodes the timer instance and irq number.
+// It assumes that timer instance pointer has the lower 8 bits cleared.
+#define TIM_ENTRY(id, irq) [id - 1] = (uint32_t)TIM##id | irq
+STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {
+ #if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
+ TIM_ENTRY(1, TIM1_UP_TIM10_IRQn),
+ #elif defined(MCU_SERIES_L4)
+ TIM_ENTRY(1, TIM1_UP_TIM16_IRQn),
+ #endif
+ TIM_ENTRY(2, TIM2_IRQn),
+ TIM_ENTRY(3, TIM3_IRQn),
+ TIM_ENTRY(4, TIM4_IRQn),
+ TIM_ENTRY(5, TIM5_IRQn),
+ #if defined(TIM6)
+ TIM_ENTRY(6, TIM6_DAC_IRQn),
+ #endif
+ #if defined(TIM7)
+ TIM_ENTRY(7, TIM7_IRQn),
+ #endif
+ #if defined(TIM8)
+ #if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
+ TIM_ENTRY(8, TIM8_UP_TIM13_IRQn),
+ #elif defined(MCU_SERIES_L4)
+ TIM_ENTRY(8, TIM8_UP_IRQn),
+ #endif
+ #endif
+ #if defined(TIM9)
+ TIM_ENTRY(9, TIM1_BRK_TIM9_IRQn),
+ #endif
+ #if defined(TIM10)
+ TIM_ENTRY(10, TIM1_UP_TIM10_IRQn),
+ #endif
+ #if defined(TIM11)
+ TIM_ENTRY(11, TIM1_TRG_COM_TIM11_IRQn),
+ #endif
+ #if defined(TIM12)
+ TIM_ENTRY(12, TIM8_BRK_TIM12_IRQn),
+ #endif
+ #if defined(TIM13)
+ TIM_ENTRY(13, TIM8_UP_TIM13_IRQn),
+ #endif
+ #if defined(TIM14)
+ TIM_ENTRY(14, TIM8_TRG_COM_TIM14_IRQn),
+ #endif
+ #if defined(TIM15)
+ TIM_ENTRY(15, TIM1_BRK_TIM15_IRQn),
+ #endif
+ #if defined(TIM16)
+ TIM_ENTRY(16, TIM1_UP_TIM16_IRQn),
+ #endif
+ #if defined(TIM17)
+ TIM_ENTRY(17, TIM1_TRG_COM_TIM17_IRQn),
+ #endif
+};
+#undef TIM_ENTRY
+
/// \classmethod \constructor(id, ...)
/// Construct a new timer object of the given id. If additional
/// arguments are given, then the timer is initialised by `init(...)`.
@@ -637,74 +693,30 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, size_t n_args, siz
// check arguments
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
- // create new Timer object
- pyb_timer_obj_t *tim = m_new_obj(pyb_timer_obj_t);
- memset(tim, 0, sizeof(*tim));
-
- tim->base.type = &pyb_timer_type;
- tim->callback = mp_const_none;
- tim->channel = NULL;
-
- // get TIM number
- tim->tim_id = mp_obj_get_int(args[0]);
- tim->is_32bit = false;
+ // get the timer id
+ mp_int_t tim_id = mp_obj_get_int(args[0]);
- switch (tim->tim_id) {
- #if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
- case 1: tim->tim.Instance = TIM1; tim->irqn = TIM1_UP_TIM10_IRQn; break;
- #elif defined(MCU_SERIES_L4)
- case 1: tim->tim.Instance = TIM1; tim->irqn = TIM1_UP_TIM16_IRQn; break;
- #endif
- case 2: tim->tim.Instance = TIM2; tim->irqn = TIM2_IRQn; tim->is_32bit = true; break;
- case 3: tim->tim.Instance = TIM3; tim->irqn = TIM3_IRQn; break;
- case 4: tim->tim.Instance = TIM4; tim->irqn = TIM4_IRQn; break;
- case 5: tim->tim.Instance = TIM5; tim->irqn = TIM5_IRQn; tim->is_32bit = true; break;
- #if defined(TIM6)
- case 6: tim->tim.Instance = TIM6; tim->irqn = TIM6_DAC_IRQn; break;
- #endif
- #if defined(TIM7)
- case 7: tim->tim.Instance = TIM7; tim->irqn = TIM7_IRQn; break;
- #endif
- #if defined(TIM8)
- #if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
- case 8: tim->tim.Instance = TIM8; tim->irqn = TIM8_UP_TIM13_IRQn; break;
- #elif defined(MCU_SERIES_L4)
- case 8: tim->tim.Instance = TIM8; tim->irqn = TIM8_UP_IRQn; break;
- #endif
- #endif
- #if defined(TIM9)
- case 9: tim->tim.Instance = TIM9; tim->irqn = TIM1_BRK_TIM9_IRQn; break;
- #endif
- #if defined(TIM10)
- case 10: tim->tim.Instance = TIM10; tim->irqn = TIM1_UP_TIM10_IRQn; break;
- #endif
- #if defined(TIM11)
- case 11: tim->tim.Instance = TIM11; tim->irqn = TIM1_TRG_COM_TIM11_IRQn; break;
- #endif
- #if defined(TIM12)
- case 12: tim->tim.Instance = TIM12; tim->irqn = TIM8_BRK_TIM12_IRQn; break;
- #endif
- #if defined(TIM13)
- case 13: tim->tim.Instance = TIM13; tim->irqn = TIM8_UP_TIM13_IRQn; break;
- #endif
- #if defined(TIM14)
- case 14: tim->tim.Instance = TIM14; tim->irqn = TIM8_TRG_COM_TIM14_IRQn; break;
- #endif
- #if defined(TIM15)
- case 15: tim->tim.Instance = TIM15; tim->irqn = TIM1_BRK_TIM15_IRQn; break;
- #endif
- #if defined(TIM16)
- case 16: tim->tim.Instance = TIM16; tim->irqn = TIM1_UP_TIM16_IRQn; break;
- #endif
- #if defined(TIM17)
- case 17: tim->tim.Instance = TIM17; tim->irqn = TIM1_TRG_COM_TIM17_IRQn; break;
- #endif
- default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Timer(%d) doesn't exist", tim->tim_id));
+ // check if the timer exists
+ if (tim_id <= 0 || tim_id > MICROPY_HW_MAX_TIMER || tim_instance_table[tim_id - 1] == 0) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Timer(%d) doesn't exist", tim_id));
}
- // set the global variable for interrupt callbacks
- if (tim->tim_id - 1 < PYB_TIMER_OBJ_ALL_NUM) {
- MP_STATE_PORT(pyb_timer_obj_all)[tim->tim_id - 1] = tim;
+ pyb_timer_obj_t *tim;
+ if (MP_STATE_PORT(pyb_timer_obj_all)[tim_id - 1] == NULL) {
+ // create new Timer object
+ tim = m_new_obj(pyb_timer_obj_t);
+ memset(tim, 0, sizeof(*tim));
+ tim->base.type = &pyb_timer_type;
+ tim->tim_id = tim_id;
+ tim->is_32bit = tim_id == 2 || tim_id == 5;
+ tim->callback = mp_const_none;
+ uint32_t ti = tim_instance_table[tim_id - 1];
+ tim->tim.Instance = (TIM_TypeDef*)(ti & 0xffffff00);
+ tim->irqn = ti & 0xff;
+ MP_STATE_PORT(pyb_timer_obj_all)[tim_id - 1] = tim;
+ } else {
+ // reference existing Timer object
+ tim = MP_STATE_PORT(pyb_timer_obj_all)[tim_id - 1];
}
if (n_args > 1 || n_kw > 0) {