Skip to content

Commit 32764eb

Browse files
committed
Merge pull request #177 from bcostm/master
Change us_ticker timer (32-bit) on Nucleo L152RE and F401RE
2 parents 0007856 + de4e1be commit 32764eb

File tree

5 files changed

+30
-210
lines changed

5 files changed

+30
-210
lines changed

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/PinNames.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ typedef enum {
9393
PB_8 = 0x18,
9494
PB_9 = 0x19,
9595
PB_10 = 0x1A,
96-
PB_11 = 0x1B,
9796
PB_12 = 0x1C,
9897
PB_13 = 0x1D,
9998
PB_14 = 0x1E,

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/sleep.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,12 @@ static TIM_HandleTypeDef TimMasterHandle;
3535

3636
void sleep(void)
3737
{
38-
// Disable us_ticker update interrupt
39-
TimMasterHandle.Instance = TIM1;
40-
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
41-
4238
// Request to enter SLEEP mode
4339
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
44-
45-
// Re-enable us_ticker update interrupt
46-
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
4740
}
4841

4942
void deepsleep(void)
5043
{
51-
// Disable us_ticker update interrupt
52-
TimMasterHandle.Instance = TIM1;
53-
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
54-
5544
// Request to enter STOP mode with regulator in low power mode
5645
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
57-
58-
// Re-enable us_ticker update interrupt
59-
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
6046
}

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

Lines changed: 15 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -30,138 +30,53 @@
3030
#include "PeripheralNames.h"
3131
#include "stm32f4xx_hal.h"
3232

33-
// Timer selection:
34-
#define TIM_MST TIM1
35-
#define TIM_MST_UP_IRQ TIM1_UP_TIM10_IRQn
36-
#define TIM_MST_OC_IRQ TIM1_CC_IRQn
37-
#define TIM_MST_RCC __TIM1_CLK_ENABLE()
33+
// 32-bit timer selection
34+
#define TIM_MST TIM5
35+
#define TIM_MST_IRQ TIM5_IRQn
36+
#define TIM_MST_RCC __TIM5_CLK_ENABLE()
3837

3938
static TIM_HandleTypeDef TimMasterHandle;
40-
41-
static int us_ticker_inited = 0;
42-
static volatile uint32_t SlaveCounter = 0;
43-
static volatile uint32_t oc_int_part = 0;
44-
static volatile uint16_t oc_rem_part = 0;
45-
46-
void set_compare(uint16_t count) {
47-
// Set new output compare value
48-
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, count);
49-
// Enable IT
50-
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
51-
}
52-
53-
// Used to increment the slave counter
54-
static void tim_update_irq_handler(void) {
55-
if (__HAL_TIM_GET_ITSTATUS(&TimMasterHandle, TIM_IT_UPDATE) == SET) {
56-
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_UPDATE);
57-
__HAL_TIM_SetCounter(&TimMasterHandle, 0); // Reset counter !!!
58-
SlaveCounter++;
59-
}
60-
}
61-
62-
// Used by interrupt system
63-
static void tim_oc_irq_handler(void) {
64-
uint16_t cval = TIM_MST->CNT;
65-
66-
// Clear interrupt flag
67-
if (__HAL_TIM_GET_ITSTATUS(&TimMasterHandle, TIM_IT_CC1) == SET) {
68-
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
69-
}
70-
71-
if (oc_rem_part > 0) {
72-
set_compare(oc_rem_part); // Finish the remaining time left
73-
oc_rem_part = 0;
74-
}
75-
else {
76-
if (oc_int_part > 0) {
77-
set_compare(0xFFFF);
78-
oc_rem_part = cval; // To finish the counter loop the next time
79-
oc_int_part--;
80-
}
81-
else {
82-
us_ticker_irq_handler();
83-
}
84-
}
85-
}
39+
static int us_ticker_inited = 0;
8640

8741
void us_ticker_init(void) {
8842
if (us_ticker_inited) return;
8943
us_ticker_inited = 1;
9044

91-
// Enable Timer clock
45+
// Enable timer clock
9246
TIM_MST_RCC;
9347

9448
// Configure time base
9549
TimMasterHandle.Instance = TIM_MST;
96-
TimMasterHandle.Init.Period = 0xFFFF;
50+
TimMasterHandle.Init.Period = 0xFFFFFFFF;
9751
TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
9852
TimMasterHandle.Init.ClockDivision = 0;
9953
TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
10054
TimMasterHandle.Init.RepetitionCounter = 0;
10155
HAL_TIM_OC_Init(&TimMasterHandle);
102-
103-
// Configure interrupts
104-
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
105-
106-
// Update interrupt used for 32-bit counter
107-
NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler);
108-
NVIC_EnableIRQ(TIM_MST_UP_IRQ);
10956

110-
// Output compare interrupt used for timeout feature
111-
NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler);
112-
NVIC_EnableIRQ(TIM_MST_OC_IRQ);
57+
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)us_ticker_irq_handler);
58+
NVIC_EnableIRQ(TIM_MST_IRQ);
11359

11460
// Enable timer
11561
HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
11662
}
11763

11864
uint32_t us_ticker_read() {
119-
uint32_t counter, counter2;
12065
if (!us_ticker_inited) us_ticker_init();
121-
// A situation might appear when Master overflows right after Slave is read and before the
122-
// new (overflowed) value of Master is read. Which would make the code below consider the
123-
// previous (incorrect) value of Slave and the new value of Master, which would return a
124-
// value in the past. Avoid this by computing consecutive values of the timer until they
125-
// are properly ordered.
126-
counter = (uint32_t)(SlaveCounter << 16);
127-
counter += TIM_MST->CNT;
128-
while (1) {
129-
counter2 = (uint32_t)(SlaveCounter << 16);
130-
counter2 += TIM_MST->CNT;
131-
if (counter2 > counter) {
132-
break;
133-
}
134-
counter = counter2;
135-
}
136-
return counter2;
66+
return TIM_MST->CNT;
13767
}
13868

13969
void us_ticker_set_interrupt(unsigned int timestamp) {
140-
int delta = (int)(timestamp - us_ticker_read());
141-
uint16_t cval = TIM_MST->CNT;
142-
143-
if (delta <= 0) { // This event was in the past
144-
us_ticker_irq_handler();
145-
}
146-
else {
147-
oc_int_part = (uint32_t)(delta >> 16);
148-
oc_rem_part = (uint16_t)(delta & 0xFFFF);
149-
if (oc_rem_part <= (0xFFFF - cval)) {
150-
set_compare(cval + oc_rem_part);
151-
oc_rem_part = 0;
152-
} else {
153-
set_compare(0xFFFF);
154-
oc_rem_part = oc_rem_part - (0xFFFF - cval);
155-
}
156-
}
70+
// Set new output compare value
71+
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, timestamp);
72+
// Enable IT
73+
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
15774
}
15875

15976
void us_ticker_disable_interrupt(void) {
16077
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
16178
}
16279

16380
void us_ticker_clear_interrupt(void) {
164-
if (__HAL_TIM_GET_ITSTATUS(&TimMasterHandle, TIM_IT_CC1) == SET) {
165-
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
166-
}
81+
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
16782
}

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/sleep.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,11 @@ static void SetSysClock_HSI(void)
102102
// MCU SLEEP mode
103103
void sleep(void)
104104
{
105-
// Disable us_ticker update interrupt
106-
TIM_ITConfig(TIM9, TIM_IT_Update, DISABLE);
107-
108105
// Enable PWR clock
109106
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
110107

111108
// Request to enter SLEEP mode with regulator ON
112109
PWR_EnterSleepMode(PWR_Regulator_ON, PWR_SLEEPEntry_WFI);
113-
114-
// Re-enable us_ticker update interrupt
115-
TIM_ITConfig(TIM9, TIM_IT_Update, ENABLE);
116110
}
117111

118112
// MCU STOP mode (Regulator in LP mode, LSI, HSI and HSE OFF)

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

Lines changed: 15 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -29,127 +29,53 @@
2929
#include "us_ticker_api.h"
3030
#include "PeripheralNames.h"
3131

32-
// Timer selection:
33-
#define TIM_MST TIM9
34-
#define TIM_MST_IRQ TIM9_IRQn
35-
#define TIM_MST_RCC RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE)
32+
// 32-bit timer selection
33+
#define TIM_MST TIM5
34+
#define TIM_MST_IRQ TIM5_IRQn
35+
#define TIM_MST_RCC RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE)
3636

37-
static int us_ticker_inited = 0;
38-
static volatile uint32_t SlaveCounter = 0;
39-
static volatile uint32_t oc_int_part = 0;
40-
static volatile uint16_t oc_rem_part = 0;
41-
42-
void set_compare(uint16_t count) {
43-
// Set new output compare value
44-
TIM_SetCompare1(TIM_MST, count);
45-
// Enable IT
46-
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
47-
}
48-
49-
static void tim_update_oc_irq_handler(void) {
50-
uint16_t cval = TIM_MST->CNT;
51-
52-
// Update interrupt: increment the slave counter
53-
if (TIM_GetITStatus(TIM_MST, TIM_IT_Update) == SET) {
54-
TIM_ClearITPendingBit(TIM_MST, TIM_IT_Update);
55-
SlaveCounter++;
56-
}
57-
58-
// Output compare interrupt: used by interrupt system
59-
if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
60-
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
61-
if (oc_rem_part > 0) {
62-
set_compare(oc_rem_part); // Finish the remaining time left
63-
oc_rem_part = 0;
64-
}
65-
else {
66-
if (oc_int_part > 0) {
67-
set_compare(0xFFFF);
68-
oc_rem_part = cval; // To finish the counter loop the next time
69-
oc_int_part--;
70-
}
71-
else {
72-
us_ticker_irq_handler();
73-
}
74-
}
75-
}
76-
}
37+
static int us_ticker_inited = 0;
7738

7839
void us_ticker_init(void) {
7940
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
8041

8142
if (us_ticker_inited) return;
8243
us_ticker_inited = 1;
8344

84-
// Enable Timer clock
45+
// Enable timer clock
8546
TIM_MST_RCC;
8647

8748
// Configure time base
8849
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
89-
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
50+
TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF;
9051
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
9152
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
9253
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
9354
TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure);
94-
95-
// Configure interrupts
96-
TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE);
97-
98-
// For 32-bit counter and output compare
99-
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)tim_update_oc_irq_handler);
55+
56+
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)us_ticker_irq_handler);
10057
NVIC_EnableIRQ(TIM_MST_IRQ);
10158

10259
// Enable timer
10360
TIM_Cmd(TIM_MST, ENABLE);
10461
}
10562

10663
uint32_t us_ticker_read() {
107-
uint32_t counter, counter2;
10864
if (!us_ticker_inited) us_ticker_init();
109-
// A situation might appear when Master overflows right after Slave is read and before the
110-
// new (overflowed) value of Master is read. Which would make the code below consider the
111-
// previous (incorrect) value of Slave and the new value of Master, which would return a
112-
// value in the past. Avoid this by computing consecutive values of the timer until they
113-
// are properly ordered.
114-
counter = (uint32_t)(SlaveCounter << 16);
115-
counter += TIM_MST->CNT;
116-
while (1) {
117-
counter2 = (uint32_t)(SlaveCounter << 16);
118-
counter2 += TIM_MST->CNT;
119-
if (counter2 > counter) {
120-
break;
121-
}
122-
counter = counter2;
123-
}
124-
return counter2;
65+
return TIM_MST->CNT;
12566
}
12667

12768
void us_ticker_set_interrupt(unsigned int timestamp) {
128-
int delta = (int)(timestamp - us_ticker_read());
129-
uint16_t cval = TIM_MST->CNT;
130-
131-
if (delta <= 0) { // This event was in the past
132-
us_ticker_irq_handler();
133-
}
134-
else {
135-
oc_int_part = (uint32_t)(delta >> 16);
136-
oc_rem_part = (uint16_t)(delta & 0xFFFF);
137-
if (oc_rem_part <= (0xFFFF - cval)) {
138-
set_compare(cval + oc_rem_part);
139-
oc_rem_part = 0;
140-
} else {
141-
set_compare(0xFFFF);
142-
oc_rem_part = oc_rem_part - (0xFFFF - cval);
143-
}
144-
}
69+
// Set new output compare value
70+
TIM_SetCompare1(TIM_MST, timestamp);
71+
// Enable IT
72+
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
14573
}
14674

14775
void us_ticker_disable_interrupt(void) {
14876
TIM_ITConfig(TIM_MST, TIM_IT_CC1, DISABLE);
14977
}
15078

15179
void us_ticker_clear_interrupt(void) {
152-
if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
153-
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
154-
}
80+
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
15581
}

0 commit comments

Comments
 (0)