stm32: Add initial support for STM32L0xx MCUs.

This commit is contained in:
Damien George
2019-07-05 17:24:59 +10:00
parent fa5c0b819c
commit 23d9c6a0fd
13 changed files with 264 additions and 35 deletions

View File

@@ -427,6 +427,8 @@ STATIC mp_obj_t compute_percent_from_pwm_value(uint32_t period, uint32_t cmp) {
#endif
}
#if !defined(STM32L0)
// Computes the 8-bit value for the DTG field in the BDTR register.
//
// 1 tick = 1 count of the timer's clock (source_freq) divided by div.
@@ -486,6 +488,8 @@ STATIC void config_deadtime(pyb_timer_obj_t *self, mp_int_t ticks, mp_int_t brk)
HAL_TIMEx_ConfigBreakDeadTime(&self->tim, &deadTimeConfig);
}
#endif
TIM_HandleTypeDef *pyb_timer_get_handle(mp_obj_t timer) {
if (mp_obj_get_type(timer) != &pyb_timer_type) {
mp_raise_ValueError("need a Timer object");
@@ -514,6 +518,7 @@ STATIC void pyb_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_
self->tim.Init.ClockDivision == TIM_CLOCKDIVISION_DIV4 ? 4 :
self->tim.Init.ClockDivision == TIM_CLOCKDIVISION_DIV2 ? 2 : 1);
#if !defined(STM32L0)
#if defined(IS_TIM_ADVANCED_INSTANCE)
if (IS_TIM_ADVANCED_INSTANCE(self->tim.Instance))
#elif defined(IS_TIM_BREAK_INSTANCE)
@@ -531,6 +536,7 @@ STATIC void pyb_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_
mp_printf(print, ", brk=BRK_OFF");
}
}
#endif
mp_print_str(print, ")");
}
}
@@ -630,11 +636,15 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
args[ARG_div].u_int == 4 ? TIM_CLOCKDIVISION_DIV4 :
TIM_CLOCKDIVISION_DIV1;
#if !defined(STM32L0)
init->RepetitionCounter = 0;
#endif
// enable TIM clock
switch (self->tim_id) {
#if defined(TIM1)
case 1: __HAL_RCC_TIM1_CLK_ENABLE(); break;
#endif
case 2: __HAL_RCC_TIM2_CLK_ENABLE(); break;
#if defined(TIM3)
case 3: __HAL_RCC_TIM3_CLK_ENABLE(); break;
@@ -681,22 +691,40 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
#if defined(TIM17)
case 17: __HAL_RCC_TIM17_CLK_ENABLE(); break;
#endif
#if defined(TIM18)
case 18: __HAL_RCC_TIM18_CLK_ENABLE(); break;
#endif
#if defined(TIM19)
case 19: __HAL_RCC_TIM19_CLK_ENABLE(); break;
#endif
#if defined(TIM20)
case 20: __HAL_RCC_TIM20_CLK_ENABLE(); break;
#endif
#if defined(TIM21)
case 21: __HAL_RCC_TIM21_CLK_ENABLE(); break;
#endif
#if defined(TIM22)
case 22: __HAL_RCC_TIM22_CLK_ENABLE(); break;
#endif
}
// set IRQ priority (if not a special timer)
if (self->tim_id != 5) {
NVIC_SetPriority(IRQn_NONNEG(self->irqn), IRQ_PRI_TIMX);
if (self->tim_id == 1) {
#if defined(TIM1)
NVIC_SetPriority(TIM1_CC_IRQn, IRQ_PRI_TIMX);
#if defined(TIM8)
#endif
} else if (self->tim_id == 8) {
#if defined(TIM8)
NVIC_SetPriority(TIM8_CC_IRQn, IRQ_PRI_TIMX);
#endif
#endif
}
}
// init TIM
HAL_TIM_Base_Init(&self->tim);
#if !defined(STM32L0)
#if defined(IS_TIM_ADVANCED_INSTANCE)
if (IS_TIM_ADVANCED_INSTANCE(self->tim.Instance)) {
#elif defined(IS_TIM_BREAK_INSTANCE)
@@ -707,6 +735,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
config_deadtime(self, args[ARG_deadtime].u_int, args[ARG_brk].u_int);
}
#endif
// Enable ARPE so that the auto-reload register is buffered.
// This allows to smoothly change the frequency of the timer.
@@ -726,6 +755,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
// 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(TIM1)
#if defined(STM32F0)
TIM_ENTRY(1, TIM1_BRK_UP_TRG_COM_IRQn),
#elif defined(STM32F4) || defined(STM32F7)
@@ -733,6 +763,7 @@ STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {
#elif defined(STM32L4)
TIM_ENTRY(1, TIM1_UP_TIM16_IRQn),
#endif
#endif
TIM_ENTRY(2, TIM2_IRQn),
#if defined(TIM3)
TIM_ENTRY(3, TIM3_IRQn),
@@ -1054,10 +1085,12 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
oc_config.Pulse = args[3].u_int;
}
oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
oc_config.OCFastMode = TIM_OCFAST_DISABLE;
#if !defined(STM32L0)
oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
oc_config.OCIdleState = TIM_OCIDLESTATE_SET;
oc_config.OCNIdleState = TIM_OCNIDLESTATE_SET;
#endif
HAL_TIM_PWM_ConfigChannel(&self->tim, &oc_config, TIMER_CHANNEL(chan));
if (chan->callback == mp_const_none) {
@@ -1065,10 +1098,12 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
} else {
pyb_timer_channel_callback(MP_OBJ_FROM_PTR(chan), chan->callback);
}
#if !defined(STM32L0)
// Start the complimentary channel too (if its supported)
if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) {
HAL_TIMEx_PWMN_Start(&self->tim, TIMER_CHANNEL(chan));
}
#endif
break;
}
@@ -1085,14 +1120,16 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
if (oc_config.OCPolarity == 0xffffffff) {
oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
}
oc_config.OCFastMode = TIM_OCFAST_DISABLE;
#if !defined(STM32L0)
if (oc_config.OCPolarity == TIM_OCPOLARITY_HIGH) {
oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
} else {
oc_config.OCNPolarity = TIM_OCNPOLARITY_LOW;
}
oc_config.OCFastMode = TIM_OCFAST_DISABLE;
oc_config.OCIdleState = TIM_OCIDLESTATE_SET;
oc_config.OCNIdleState = TIM_OCNIDLESTATE_SET;
#endif
if (!IS_TIM_OC_POLARITY(oc_config.OCPolarity)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid polarity (%d)", oc_config.OCPolarity));
@@ -1103,10 +1140,12 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
} else {
pyb_timer_channel_callback(MP_OBJ_FROM_PTR(chan), chan->callback);
}
#if !defined(STM32L0)
// Start the complimentary channel too (if its supported)
if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) {
HAL_TIMEx_OCN_Start(&self->tim, TIMER_CHANNEL(chan));
}
#endif
break;
}
@@ -1155,8 +1194,12 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid polarity (%d)", enc_config.IC1Polarity));
}
// Only Timers 1, 2, 3, 4, 5, and 8 support encoder mode
if (self->tim.Instance != TIM1
&& self->tim.Instance != TIM2
if (
#if defined(TIM1)
self->tim.Instance != TIM1
&&
#endif
self->tim.Instance != TIM2
#if defined(TIM3)
&& self->tim.Instance != TIM3
#endif
@@ -1426,15 +1469,18 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback)
self->callback = mp_const_none;
} else if (mp_obj_is_callable(callback)) {
self->callback = callback;
uint8_t tim_id = self->timer->tim_id;
__HAL_TIM_CLEAR_IT(&self->timer->tim, TIMER_IRQ_MASK(self->channel));
if (tim_id == 1) {
#if defined(TIM1)
if (self->timer->tim_id == 1) {
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
#if defined(TIM8) // STM32F401 doesn't have a TIM8
} else if (tim_id == 8) {
HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);
} else
#endif
} else {
#if defined(TIM8) // STM32F401 doesn't have a TIM8
if (self->timer->tim_id == 8) {
HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);
} else
#endif
{
HAL_NVIC_EnableIRQ(self->timer->irqn);
}
// start timer, so that it interrupts on overflow