diff --git a/stmhal/irq.h b/stmhal/irq.h index f3a8a2cc9eacc..41a61abeabb17 100644 --- a/stmhal/irq.h +++ b/stmhal/irq.h @@ -126,12 +126,12 @@ MP_DECLARE_CONST_FUN_OBJ(pyb_irq_stats_obj); #define IRQ_PRI_OTG_HS 6 #define IRQ_SUBPRI_OTG_HS 0 +#define IRQ_PRI_TIM2 6 +#define IRQ_SUBPRI_TIM2 0 + #define IRQ_PRI_TIM3 6 #define IRQ_SUBPRI_TIM3 0 -#define IRQ_PRI_TIM5 6 -#define IRQ_SUBPRI_TIM5 0 - #define IRQ_PRI_CAN 7 #define IRQ_SUBPRI_CAN 0 diff --git a/stmhal/servo.c b/stmhal/servo.c index 382b48f67a071..28271d5dc7826 100644 --- a/stmhal/servo.c +++ b/stmhal/servo.c @@ -38,10 +38,10 @@ /// /// Servo controls standard hobby servos with 3-wires (ground, power, signal). -// this servo driver uses hardware PWM to drive servos on PA0, PA1, PA2, PA3 = X1, X2, X3, X4 -// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively -// they are both 32-bit counters with 16-bit prescaler -// we use TIM5 +// this servo driver uses hardware PWM to drive servos on PA0, PA1, PA2, PB11 = X1, X2, X3, X4 +// TIM2 has CH1, CH2, CH3, CH4 on PA0, PA1, PA2, PB11 respectively +// it is a 32-bit counters with 16-bit prescaler +// Note: the use of TIM2 is specific to Tilda, the pyboard used TIM5 #define PYB_SERVO_NUM (4) @@ -62,7 +62,7 @@ typedef struct _pyb_servo_obj_t { STATIC pyb_servo_obj_t pyb_servo_obj[PYB_SERVO_NUM]; void servo_init(void) { - timer_tim5_init(); + timer_tim2_init(); // reset servo objects for (int i = 0; i < PYB_SERVO_NUM; i++) { @@ -103,17 +103,17 @@ void servo_timer_irq_callback(void) { } // set the pulse width switch (s->servo_id) { - case 1: TIM5->CCR1 = s->pulse_cur; break; - case 2: TIM5->CCR2 = s->pulse_cur; break; - case 3: TIM5->CCR3 = s->pulse_cur; break; - case 4: TIM5->CCR4 = s->pulse_cur; break; + case 1: TIM2->CCR1 = s->pulse_cur; break; + case 2: TIM2->CCR2 = s->pulse_cur; break; + case 3: TIM2->CCR3 = s->pulse_cur; break; + case 4: TIM2->CCR4 = s->pulse_cur; break; } } } if (need_it) { - __HAL_TIM_ENABLE_IT(&TIM5_Handle, TIM_IT_UPDATE); + __HAL_TIM_ENABLE_IT(&TIM2_Handle, TIM_IT_UPDATE); } else { - __HAL_TIM_DISABLE_IT(&TIM5_Handle, TIM_IT_UPDATE); + __HAL_TIM_DISABLE_IT(&TIM2_Handle, TIM_IT_UPDATE); } } @@ -124,7 +124,7 @@ STATIC void servo_init_channel(pyb_servo_obj_t *s) { case 1: pin = GPIO_PIN_0; channel = TIM_CHANNEL_1; break; case 2: pin = GPIO_PIN_1; channel = TIM_CHANNEL_2; break; case 3: pin = GPIO_PIN_2; channel = TIM_CHANNEL_3; break; - case 4: pin = GPIO_PIN_3; channel = TIM_CHANNEL_4; break; + case 4: pin = GPIO_PIN_11; channel = TIM_CHANNEL_4; break; default: return; } @@ -134,8 +134,12 @@ STATIC void servo_init_channel(pyb_servo_obj_t *s) { GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Speed = GPIO_SPEED_FAST; GPIO_InitStructure.Pull = GPIO_NOPULL; - GPIO_InitStructure.Alternate = GPIO_AF2_TIM5; - HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_InitStructure.Alternate = GPIO_AF1_TIM2; + if (s->servo_id == 4) { + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + } else { + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + } // PWM mode configuration TIM_OC_InitTypeDef oc_init; @@ -143,10 +147,10 @@ STATIC void servo_init_channel(pyb_servo_obj_t *s) { oc_init.Pulse = s->pulse_cur; // units of 10us oc_init.OCPolarity = TIM_OCPOLARITY_HIGH; oc_init.OCFastMode = TIM_OCFAST_DISABLE; - HAL_TIM_PWM_ConfigChannel(&TIM5_Handle, &oc_init, channel); + HAL_TIM_PWM_ConfigChannel(&TIM2_Handle, &oc_init, channel); // start PWM - HAL_TIM_PWM_Start(&TIM5_Handle, channel); + HAL_TIM_PWM_Start(&TIM2_Handle, channel); } /******************************************************************************/ @@ -158,10 +162,10 @@ STATIC mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) { if (v < 50) { v = 50; } if (v > 250) { v = 250; } switch (p) { - case 1: TIM5->CCR1 = v; break; - case 2: TIM5->CCR2 = v; break; - case 3: TIM5->CCR3 = v; break; - case 4: TIM5->CCR4 = v; break; + case 1: TIM2->CCR1 = v; break; + case 2: TIM2->CCR2 = v; break; + case 3: TIM2->CCR3 = v; break; + case 4: TIM2->CCR4 = v; break; } return mp_const_none; } @@ -171,8 +175,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(pyb_servo_set_obj, pyb_servo_set); STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) { int pe = mp_obj_get_int(period); int pu = mp_obj_get_int(pulse); - TIM5->ARR = pe; - TIM5->CCR3 = pu; + TIM2->ARR = pe; + TIM2->CCR3 = pu; return mp_const_none; } diff --git a/stmhal/stm32_it.c b/stmhal/stm32_it.c index c9af20ce5892d..0b7bae6ed2058 100644 --- a/stmhal/stm32_it.c +++ b/stmhal/stm32_it.c @@ -559,6 +559,7 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) { void TIM2_IRQHandler(void) { IRQ_ENTER(TIM2_IRQn); timer_irq_handler(2); + HAL_TIM_IRQHandler(&TIM2_Handle); IRQ_EXIT(TIM2_IRQn); } @@ -577,7 +578,6 @@ void TIM4_IRQHandler(void) { void TIM5_IRQHandler(void) { IRQ_ENTER(TIM5_IRQn); timer_irq_handler(5); - HAL_TIM_IRQHandler(&TIM5_Handle); IRQ_EXIT(TIM5_IRQn); } diff --git a/stmhal/timer.c b/stmhal/timer.c index f1f14f3315333..4088e0ddd0738 100644 --- a/stmhal/timer.c +++ b/stmhal/timer.c @@ -68,7 +68,7 @@ /// tim.callback(lambda t: ...) # set callback for update interrupt (t=tim instance) /// tim.callback(None) # clear callback /// -/// *Note:* Timer 3 is used for fading the blue LED. Timer 5 controls +/// *Note:* Timer 3 is used for fading the blue LED. Timer 2 controls /// the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing. /// It is recommended to use the other timers in your programs. @@ -78,7 +78,7 @@ // TIM3: // - LED 4, PWM to set the LED intensity // -// TIM5: +// TIM2: // - servo controller, PWM // // TIM6: @@ -142,7 +142,7 @@ typedef struct _pyb_timer_obj_t { #define TIMER_CNT_MASK(self) ((self)->is_32bit ? 0xffffffff : 0xffff) #define TIMER_CHANNEL(self) ((((self)->channel) - 1) << 2) -TIM_HandleTypeDef TIM5_Handle; +TIM_HandleTypeDef TIM2_Handle; TIM_HandleTypeDef TIM6_Handle; #define PYB_TIMER_OBJ_ALL_NUM MP_ARRAY_SIZE(MP_STATE_PORT(pyb_timer_obj_all)) @@ -167,24 +167,24 @@ void timer_deinit(void) { } } -// TIM5 is set-up for the servo controller +// TIM2 is set-up for the servo controller // This function inits but does not start the timer -void timer_tim5_init(void) { - // TIM5 clock enable - __TIM5_CLK_ENABLE(); +void timer_tim2_init(void) { + // TIM2 clock enable + __TIM2_CLK_ENABLE(); // set up and enable interrupt - HAL_NVIC_SetPriority(TIM5_IRQn, IRQ_PRI_TIM5, IRQ_SUBPRI_TIM5); - HAL_NVIC_EnableIRQ(TIM5_IRQn); + HAL_NVIC_SetPriority(TIM2_IRQn, IRQ_PRI_TIM2, IRQ_SUBPRI_TIM2); + HAL_NVIC_EnableIRQ(TIM2_IRQn); // PWM clock configuration - TIM5_Handle.Instance = TIM5; - TIM5_Handle.Init.Period = 2000 - 1; // timer cycles at 50Hz - TIM5_Handle.Init.Prescaler = (timer_get_source_freq(5) / 100000) - 1; // timer runs at 100kHz - TIM5_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TIM5_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; + TIM2_Handle.Instance = TIM2; + TIM2_Handle.Init.Period = 2000 - 1; // timer cycles at 50Hz + TIM2_Handle.Init.Prescaler = (timer_get_source_freq(2) / 100000) - 1; // timer runs at 100kHz + TIM2_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + TIM2_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; - HAL_TIM_PWM_Init(&TIM5_Handle); + HAL_TIM_PWM_Init(&TIM2_Handle); } #if defined(TIM6) @@ -218,7 +218,7 @@ TIM_HandleTypeDef *timer_tim6_init(uint freq) { // Interrupt dispatch void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { - if (htim == &TIM5_Handle) { + if (htim == &TIM2_Handle) { servo_timer_irq_callback(); } } diff --git a/stmhal/timer.h b/stmhal/timer.h index a18d7cf104027..80ee40e90d195 100644 --- a/stmhal/timer.h +++ b/stmhal/timer.h @@ -24,12 +24,12 @@ * THE SOFTWARE. */ -extern TIM_HandleTypeDef TIM5_Handle; +extern TIM_HandleTypeDef TIM2_Handle; extern const mp_obj_type_t pyb_timer_type; void timer_init0(void); -void timer_tim5_init(void); +void timer_tim2_init(void); TIM_HandleTypeDef *timer_tim6_init(uint freq); void timer_deinit(void); uint32_t timer_get_source_freq(uint32_t tim_id);