Skip to content

Commit a12be91

Browse files
committed
stmhal: Add timer module; move servo PWM from TIM2 to TIM5.
As per issue adafruit#257, servo is better on TIM5 because TIM2 is connected to more GPIO.
1 parent 69dee59 commit a12be91

10 files changed

Lines changed: 233 additions & 87 deletions

File tree

stmhal/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ SRC_C = \
6161
usbd_msc_storage.c \
6262
pendsv.c \
6363
systick.c \
64+
timer.c \
6465
led.c \
6566
pin.c \
6667
pin_map.c \
@@ -98,7 +99,6 @@ SRC_C = \
9899
adc.c \
99100
i2c.c \
100101

101-
# timer.c \
102102
# pybwlan.c \
103103
104104
SRC_S = \

stmhal/led.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
#include <stdio.h>
22
#include <stm32f4xx_hal.h>
3-
#include "usbd_cdc_msc_hid.h"
4-
#include "usbd_cdc_interface.h"
53

64
#include "nlr.h"
75
#include "misc.h"
86
#include "mpconfig.h"
97
#include "qstr.h"
108
#include "obj.h"
119
#include "runtime.h"
10+
#include "timer.h"
1211
#include "led.h"
1312
#include "pin.h"
1413
#include "build/pins.h"
@@ -54,6 +53,8 @@ void led_init(void) {
5453
// LED4 (blue) is on PB4 which is TIM3_CH1
5554
// we use PWM on this channel to fade the LED
5655

56+
// LED3 (yellow) is on PA15 which has TIM2_CH1, so we could PWM that as well
57+
5758
// GPIO configuration
5859
GPIO_InitStructure.Pin = MICROPY_HW_LED4.pin_mask;
5960
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;

stmhal/main.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "readline.h"
2323
#include "pyexec.h"
2424
#include "usart.h"
25+
#include "timer.h"
2526
#include "led.h"
2627
#include "exti.h"
2728
#include "usrsw.h"
@@ -38,7 +39,6 @@
3839
#include "dac.h"
3940
#include "pin.h"
4041
#if 0
41-
#include "timer.h"
4242
#include "pybwlan.h"
4343
#endif
4444

@@ -177,6 +177,7 @@ int main(void) {
177177

178178
// basic sub-system init
179179
pendsv_init();
180+
timer_tim3_init();
180181
led_init();
181182
switch_init0();
182183

@@ -409,6 +410,11 @@ int main(void) {
409410
rng_init();
410411
#endif
411412

413+
#if MICROPY_HW_ENABLE_TIMER
414+
// timer
415+
//timer_init();
416+
#endif
417+
412418
// I2C
413419
i2c_init();
414420

@@ -422,13 +428,6 @@ int main(void) {
422428
servo_init();
423429
#endif
424430

425-
#if 0
426-
#if MICROPY_HW_ENABLE_TIMER
427-
// timer
428-
timer_init();
429-
#endif
430-
#endif
431-
432431
#if MICROPY_HW_ENABLE_DAC
433432
// DAC
434433
dac_init();

stmhal/servo.c

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
#include "qstr.h"
99
#include "obj.h"
1010
#include "runtime.h"
11+
#include "timer.h"
1112
#include "servo.h"
1213

1314
// this servo driver uses hardware PWM to drive servos on PA0, PA1, PA2, PA3 = X1, X2, X3, X4
1415
// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively
1516
// they are both 32-bit counters with 16-bit prescaler
16-
// we use TIM2
17+
// we use TIM5
1718

1819
#define PYB_SERVO_NUM (4)
1920

@@ -30,23 +31,8 @@ STATIC const mp_obj_type_t servo_obj_type;
3031

3132
STATIC pyb_servo_obj_t pyb_servo_obj[PYB_SERVO_NUM];
3233

33-
TIM_HandleTypeDef TIM2_Handle;
34-
3534
void servo_init(void) {
36-
// TIM2 clock enable
37-
__TIM2_CLK_ENABLE();
38-
39-
// set up and enable interrupt
40-
HAL_NVIC_SetPriority(TIM2_IRQn, 6, 0);
41-
HAL_NVIC_EnableIRQ(TIM2_IRQn);
42-
43-
// PWM clock configuration
44-
TIM2_Handle.Instance = TIM2;
45-
TIM2_Handle.Init.Period = 2000; // timer cycles at 50Hz
46-
TIM2_Handle.Init.Prescaler = ((SystemCoreClock / 2) / 100000) - 1; // timer runs at 100kHz
47-
TIM2_Handle.Init.ClockDivision = 0;
48-
TIM2_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
49-
HAL_TIM_PWM_Init(&TIM2_Handle);
35+
timer_tim5_init();
5036

5137
// reset servo objects
5238
for (int i = 0; i < PYB_SERVO_NUM; i++) {
@@ -74,17 +60,17 @@ void servo_timer_irq_callback(void) {
7460
need_it = true;
7561
}
7662
switch (s->servo_id) {
77-
case 1: TIM2->CCR1 = s->pulse_cur; break;
78-
case 2: TIM2->CCR2 = s->pulse_cur; break;
79-
case 3: TIM2->CCR3 = s->pulse_cur; break;
80-
case 4: TIM2->CCR4 = s->pulse_cur; break;
63+
case 1: TIM5->CCR1 = s->pulse_cur; break;
64+
case 2: TIM5->CCR2 = s->pulse_cur; break;
65+
case 3: TIM5->CCR3 = s->pulse_cur; break;
66+
case 4: TIM5->CCR4 = s->pulse_cur; break;
8167
}
8268
}
8369
}
8470
if (need_it) {
85-
__HAL_TIM_ENABLE_IT(&TIM2_Handle, TIM_IT_UPDATE);
71+
__HAL_TIM_ENABLE_IT(&TIM5_Handle, TIM_IT_UPDATE);
8672
} else {
87-
__HAL_TIM_DISABLE_IT(&TIM2_Handle, TIM_IT_UPDATE);
73+
__HAL_TIM_DISABLE_IT(&TIM5_Handle, TIM_IT_UPDATE);
8874
}
8975
}
9076

@@ -105,7 +91,7 @@ STATIC void servo_init_channel(pyb_servo_obj_t *s) {
10591
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
10692
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
10793
GPIO_InitStructure.Pull = GPIO_NOPULL;
108-
GPIO_InitStructure.Alternate = GPIO_AF1_TIM2;
94+
GPIO_InitStructure.Alternate = GPIO_AF2_TIM5;
10995
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
11096

11197
// PWM mode configuration
@@ -114,10 +100,10 @@ STATIC void servo_init_channel(pyb_servo_obj_t *s) {
114100
oc_init.Pulse = s->pulse_cur; // units of 10us
115101
oc_init.OCPolarity = TIM_OCPOLARITY_HIGH;
116102
oc_init.OCFastMode = TIM_OCFAST_DISABLE;
117-
HAL_TIM_PWM_ConfigChannel(&TIM2_Handle, &oc_init, channel);
103+
HAL_TIM_PWM_ConfigChannel(&TIM5_Handle, &oc_init, channel);
118104

119105
// start PWM
120-
HAL_TIM_PWM_Start(&TIM2_Handle, channel);
106+
HAL_TIM_PWM_Start(&TIM5_Handle, channel);
121107
}
122108

123109
/******************************************************************************/
@@ -129,10 +115,10 @@ STATIC mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) {
129115
if (v < 50) { v = 50; }
130116
if (v > 250) { v = 250; }
131117
switch (p) {
132-
case 1: TIM2->CCR1 = v; break;
133-
case 2: TIM2->CCR2 = v; break;
134-
case 3: TIM2->CCR3 = v; break;
135-
case 4: TIM2->CCR4 = v; break;
118+
case 1: TIM5->CCR1 = v; break;
119+
case 2: TIM5->CCR2 = v; break;
120+
case 3: TIM5->CCR3 = v; break;
121+
case 4: TIM5->CCR4 = v; break;
136122
}
137123
return mp_const_none;
138124
}
@@ -142,8 +128,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(pyb_servo_set_obj, pyb_servo_set);
142128
STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) {
143129
int pe = mp_obj_get_int(period);
144130
int pu = mp_obj_get_int(pulse);
145-
TIM2->ARR = pe;
146-
TIM2->CCR3 = pu;
131+
TIM5->ARR = pe;
132+
TIM5->CCR3 = pu;
147133
return mp_const_none;
148134
}
149135

stmhal/servo.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
extern TIM_HandleTypeDef TIM2_Handle;
2-
31
void servo_init(void);
42
void servo_timer_irq_callback(void);
53

stmhal/stm32f4xx_hal_msp.c

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,39 +38,19 @@
3838

3939
/* Includes ------------------------------------------------------------------*/
4040
#include "stm32f4xx_hal.h"
41-
#include "usbd_cdc_msc_hid.h"
42-
#include "usbd_cdc_interface.h"
4341

4442
#include "misc.h"
4543
#include "mpconfig.h"
4644
#include "qstr.h"
4745
#include "obj.h"
4846
#include "servo.h"
4947

50-
TIM_HandleTypeDef TIM3_Handle;
51-
5248
/**
5349
* @brief Initializes the Global MSP.
5450
* @param None
5551
* @retval None
5652
*/
5753
void HAL_MspInit(void) {
58-
// set up the timer for USBD CDC
59-
__TIM3_CLK_ENABLE();
60-
61-
TIM3_Handle.Instance = TIM3;
62-
TIM3_Handle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
63-
TIM3_Handle.Init.Prescaler = 84-1;
64-
TIM3_Handle.Init.ClockDivision = 0;
65-
TIM3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
66-
HAL_TIM_Base_Init(&TIM3_Handle);
67-
68-
HAL_NVIC_SetPriority(TIM3_IRQn, 6, 0);
69-
HAL_NVIC_EnableIRQ(TIM3_IRQn);
70-
71-
if (HAL_TIM_Base_Start(&TIM3_Handle) != HAL_OK) {
72-
/* Starting Error */
73-
}
7454
}
7555

7656
/**
@@ -79,9 +59,6 @@ void HAL_MspInit(void) {
7959
* @retval None
8060
*/
8161
void HAL_MspDeInit(void) {
82-
// reset TIM3 timer
83-
__TIM3_FORCE_RESET();
84-
__TIM3_RELEASE_RESET();
8562
}
8663

8764
/**
@@ -146,14 +123,6 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
146123
__HAL_RCC_RTC_DISABLE();
147124
}
148125

149-
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
150-
if (htim == &TIM3_Handle) {
151-
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
152-
} else if (htim == &TIM2_Handle) {
153-
servo_timer_irq_callback();
154-
}
155-
}
156-
157126
/**
158127
* @}
159128
*/

stmhal/stm32f4xx_it.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,13 @@
4242

4343
#include "stm32f4xx_it.h"
4444
#include "stm32f4xx_hal.h"
45-
#include "usbd_cdc_msc_hid.h"
46-
#include "usbd_cdc_interface.h"
4745

4846
#include "misc.h"
4947
#include "mpconfig.h"
5048
#include "qstr.h"
5149
#include "obj.h"
5250
#include "exti.h"
53-
#include "servo.h"
51+
#include "timer.h"
5452

5553
/** @addtogroup STM32F4xx_HAL_Examples
5654
* @{
@@ -351,12 +349,12 @@ void RTC_WKUP_IRQHandler(void) {
351349
Handle_EXTI_Irq(EXTI_RTC_WAKEUP);
352350
}
353351

354-
void TIM2_IRQHandler(void) {
355-
HAL_TIM_IRQHandler(&TIM2_Handle);
356-
}
357-
358352
void TIM3_IRQHandler(void) {
359353
HAL_TIM_IRQHandler(&TIM3_Handle);
360354
}
361355

356+
void TIM5_IRQHandler(void) {
357+
HAL_TIM_IRQHandler(&TIM5_Handle);
358+
}
359+
362360
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

0 commit comments

Comments
 (0)