Skip to content

Commit b275fc5

Browse files
committed
[NUCLEO_F103RB] Change ticker to use one timer...
and add another pwm output.
1 parent 0110c3e commit b275fc5

File tree

3 files changed

+80
-83
lines changed

3 files changed

+80
-83
lines changed

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/PeripheralNames.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,10 @@ typedef enum {
6262

6363
typedef enum {
6464
PWM_2 = (int)TIM2_BASE,
65-
PWM_3 = (int)TIM3_BASE
65+
PWM_3 = (int)TIM3_BASE,
66+
PWM_4 = (int)TIM4_BASE
6667
} PWMName;
6768

68-
typedef enum {
69-
CAN_1 = (int)CAN1_BASE
70-
} CANName;
71-
7269
#ifdef __cplusplus
7370
}
7471
#endif

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/pwmout_api.c

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,13 @@
3333
#include "pinmap.h"
3434
#include "error.h"
3535

36-
// Only TIM2 and TIM3 can be used (TIM1 and TIM4 are used by the us_ticker)
3736
static const PinMap PinMap_PWM[] = {
38-
// TIM2 default
39-
//{PA_2, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM2_CH3 - ARDUINO D1
40-
//{PA_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM2_CH4 - ARDUINO D0
4137
// TIM2 full remap
4238
{PB_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 5)}, // TIM2fr_CH2 - ARDUINO D3
43-
//{PB_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 5)}, // TIM2fr_CH3 - ARDUINO D6
44-
// TIM3 default
45-
//{PA_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH1 - ARDUINO D12
46-
//{PA_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH2 - ARDUINO D11
47-
// TIM3 full remap
48-
//{PC_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM3fr_CH2 - ARDUINO D9
4939
// TIM3 partial remap
5040
{PB_4, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 7)}, // TIM3pr_CH1 - ARDUINO D5
41+
// TIM4 default
42+
{PB_6, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH1 - ARDUINO D10
5143
{NC, NC, 0}
5244
};
5345

@@ -62,7 +54,8 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
6254
// Enable TIM clock
6355
if (obj->pwm == PWM_2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
6456
if (obj->pwm == PWM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
65-
57+
if (obj->pwm == PWM_4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
58+
6659
// Configure GPIO
6760
pinmap_pinout(pin, PinMap_PWM);
6861

@@ -87,10 +80,7 @@ void pwmout_write(pwmout_t* obj, float value) {
8780
} else if (value > 1.0) {
8881
value = 1.0;
8982
}
90-
91-
//while(TIM_GetFlagStatus(tim, TIM_FLAG_Update) == RESET);
92-
//TIM_ClearFlag(tim, TIM_FLAG_Update);
93-
83+
9484
obj->pulse = (uint32_t)((float)obj->period * value);
9585

9686
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
@@ -99,7 +89,7 @@ void pwmout_write(pwmout_t* obj, float value) {
9989
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
10090

10191
// Configure channel 1
102-
if (obj->pin == PB_4) {
92+
if ((obj->pin == PB_4) || (obj->pin == PB_6)) {
10393
TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
10494
TIM_OC1Init(tim, &TIM_OCInitStructure);
10595
}
@@ -109,18 +99,6 @@ void pwmout_write(pwmout_t* obj, float value) {
10999
TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
110100
TIM_OC2Init(tim, &TIM_OCInitStructure);
111101
}
112-
113-
// Configure channel 3
114-
//if (obj->pin == PB_10) {
115-
// TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
116-
// TIM_OC3Init(tim, &TIM_OCInitStructure);
117-
//}
118-
119-
// Configure channel 4
120-
//if (obj->pin == PA_3) {
121-
// TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
122-
// TIM_OC4Init(tim, &TIM_OCInitStructure);
123-
//}
124102
}
125103

126104
float pwmout_read(pwmout_t* obj) {

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/us_ticker.c

Lines changed: 72 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,60 +29,77 @@
2929
#include "us_ticker_api.h"
3030
#include "PeripheralNames.h"
3131

32-
// Timers selection:
33-
// The Master timer clocks the Slave timer
32+
// Timer selection:
33+
#define TIM_MST TIM1
34+
#define TIM_MST_UP_IRQ TIM1_UP_IRQn
35+
#define TIM_MST_OC_IRQ TIM1_CC_IRQn
36+
#define TIM_MST_RCC RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE)
3437

35-
#define TIM_MST TIM1
36-
#define TIM_MST_IRQ TIM1_CC_IRQn
37-
#define TIM_MST_RCC RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE)
38+
static int us_ticker_inited = 0;
39+
static uint32_t SlaveCounter = 0;
40+
static uint32_t us_ticker_int_counter = 0;
41+
static uint16_t us_ticker_int_remainder = 0;
3842

39-
#define TIM_SLV TIM4
40-
#define TIM_SLV_IRQ TIM4_IRQn
41-
#define TIM_SLV_RCC RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE)
42-
43-
#define MST_SLV_ITR TIM_TS_ITR0
44-
45-
int us_ticker_inited = 0;
43+
// Used to increment the slave counter
44+
static void tim_update_irq_handler(void) {
45+
SlaveCounter++;
46+
if (TIM_GetITStatus(TIM_MST, TIM_IT_Update) == SET) {
47+
TIM_ClearITPendingBit(TIM_MST, TIM_IT_Update);
48+
}
49+
}
4650

47-
void us_ticker_init(void) {
51+
// Used by interrupt system
52+
static void tim_oc_irq_handler(void) {
53+
// Clear interrupt flag
54+
if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
55+
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
56+
}
4857

49-
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
50-
TIM_OCInitTypeDef TIM_OCInitStructure;
58+
if (us_ticker_int_counter > 0) {
59+
TIM_SetCompare1(TIM_MST, 0xFFFF);
60+
us_ticker_int_counter--;
61+
} else {
62+
if (us_ticker_int_remainder > 0) {
63+
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder);
64+
us_ticker_int_remainder = 0;
65+
} else {
66+
// This function is going to disable the interrupts if there are
67+
// no other events in the queue
68+
us_ticker_irq_handler();
69+
}
70+
}
71+
}
5172

73+
void us_ticker_init(void) {
74+
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
75+
5276
if (us_ticker_inited) return;
5377
us_ticker_inited = 1;
5478

55-
// Enable Timers clock
79+
// Enable Timer clock
5680
TIM_MST_RCC;
57-
TIM_SLV_RCC;
5881

59-
// Master and Slave timers time base configuration
82+
// Configure time base
6083
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
6184
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
6285
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
6386
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
6487
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
6588
TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure);
66-
TIM_TimeBaseStructure.TIM_Prescaler = 0;
67-
TIM_TimeBaseInit(TIM_SLV, &TIM_TimeBaseStructure);
68-
69-
// Master timer configuration
70-
TIM_OCStructInit(&TIM_OCInitStructure);
71-
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
72-
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
73-
TIM_OCInitStructure.TIM_Pulse = 0;
74-
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
75-
TIM_OC1Init(TIM_MST, &TIM_OCInitStructure);
76-
TIM_SelectMasterSlaveMode(TIM_MST, TIM_MasterSlaveMode_Enable);
77-
TIM_SelectOutputTrigger(TIM_MST, TIM_TRGOSource_Update);
7889

79-
// Slave timer configuration
80-
TIM_SelectSlaveMode(TIM_SLV, TIM_SlaveMode_External1);
81-
// The connection between Master and Slave is done here
82-
TIM_SelectInputTrigger(TIM_SLV, MST_SLV_ITR);
90+
// Configure interrupts
91+
TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE);
92+
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
93+
94+
// For 32-bit counter
95+
NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler);
96+
NVIC_EnableIRQ(TIM_MST_UP_IRQ);
97+
98+
// For ouput compare
99+
NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler);
100+
NVIC_EnableIRQ(TIM_MST_OC_IRQ);
83101

84-
// Enable timers
85-
TIM_Cmd(TIM_SLV, ENABLE);
102+
// Enable timer
86103
TIM_Cmd(TIM_MST, ENABLE);
87104
}
88105

@@ -94,10 +111,10 @@ uint32_t us_ticker_read() {
94111
// previous (incorrect) value of Slave and the new value of Master, which would return a
95112
// value in the past. Avoid this by computing consecutive values of the timer until they
96113
// are properly ordered.
97-
counter = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16);
114+
counter = (uint32_t)(SlaveCounter << 16);
98115
counter += (uint32_t)TIM_GetCounter(TIM_MST);
99116
while (1) {
100-
counter2 = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16);
117+
counter2 = (uint32_t)(SlaveCounter << 16);
101118
counter2 += (uint32_t)TIM_GetCounter(TIM_MST);
102119
if (counter2 > counter) {
103120
break;
@@ -108,26 +125,31 @@ uint32_t us_ticker_read() {
108125
}
109126

110127
void us_ticker_set_interrupt(unsigned int timestamp) {
111-
if (timestamp > 0xFFFF) {
112-
TIM_SetCompare1(TIM_SLV, (uint16_t)((timestamp >> 16) & 0xFFFF));
113-
TIM_ITConfig(TIM_SLV, TIM_IT_CC1, ENABLE);
114-
NVIC_SetVector(TIM_SLV_IRQ, (uint32_t)us_ticker_irq_handler);
115-
NVIC_EnableIRQ(TIM_SLV_IRQ);
128+
int delta = (int)(timestamp - us_ticker_read());
129+
130+
if (delta <= 0) { // This event was in the past
131+
us_ticker_irq_handler();
132+
return;
116133
}
117134
else {
118-
TIM_SetCompare1(TIM_MST, (uint16_t)timestamp);
119-
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
120-
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)us_ticker_irq_handler);
121-
NVIC_EnableIRQ(TIM_MST_IRQ);
135+
us_ticker_int_counter = (uint32_t)(delta >> 16);
136+
us_ticker_int_remainder = (uint16_t)(delta & 0xFFFF);
137+
if (us_ticker_int_counter > 0) { // means delta > 0xFFFF
138+
TIM_SetCompare1(TIM_MST, 0xFFFF);
139+
us_ticker_int_counter--;
140+
} else {
141+
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder);
142+
us_ticker_int_remainder = 0;
143+
}
122144
}
123145
}
124146

125147
void us_ticker_disable_interrupt(void) {
126148
TIM_ITConfig(TIM_MST, TIM_IT_CC1, DISABLE);
127-
TIM_ITConfig(TIM_SLV, TIM_IT_CC1, DISABLE);
128149
}
129150

130151
void us_ticker_clear_interrupt(void) {
131-
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
132-
TIM_ClearITPendingBit(TIM_SLV, TIM_IT_CC1);
152+
if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
153+
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
154+
}
133155
}

0 commit comments

Comments
 (0)