29
29
#include "us_ticker_api.h"
30
30
#include "PeripheralNames.h"
31
31
32
+ // Timers selection:
33
+ // The Master timer clocks the Slave timer
34
+
35
+ #define TIM_MST TIM1
36
+ #define TIM_MST_IRQ TIM1_CC_IRQn
37
+ #define TIM_MST_RCC RCC_APB2Periph_TIM1
38
+
39
+ #define TIM_SLV TIM4
40
+ #define TIM_SLV_IRQ TIM4_IRQn
41
+ #define TIM_SLV_RCC RCC_APB1Periph_TIM4
42
+
43
+ #define MST_SLV_ITR TIM_TS_ITR0
44
+
32
45
int us_ticker_inited = 0 ;
33
46
34
47
void us_ticker_init (void ) {
@@ -40,78 +53,79 @@ void us_ticker_init(void) {
40
53
us_ticker_inited = 1 ;
41
54
42
55
// Enable Timers clock
43
- RCC_APB2PeriphClockCmd (RCC_APB2Periph_TIM1 , ENABLE );
44
- RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM4 , ENABLE );
56
+ RCC_APB2PeriphClockCmd (TIM_MST_RCC , ENABLE );
57
+ RCC_APB1PeriphClockCmd (TIM_SLV_RCC , ENABLE );
45
58
46
- // Time base configuration
47
- // TIM1 is used as "master", "TIM4" as "slave". TIM4 is clocked by TIM1.
59
+ // Master and Slave timers time base configuration
48
60
TIM_TimeBaseStructInit (& TIM_TimeBaseStructure );
49
61
TIM_TimeBaseStructure .TIM_Period = 0xFFFF ;
50
62
TIM_TimeBaseStructure .TIM_Prescaler = (uint16_t )(SystemCoreClock / 1000000 ) - 1 ; // 1 µs tick
51
63
TIM_TimeBaseStructure .TIM_ClockDivision = 0 ;
52
64
TIM_TimeBaseStructure .TIM_CounterMode = TIM_CounterMode_Up ;
53
- TIM_TimeBaseInit (TIM1 , & TIM_TimeBaseStructure );
65
+ TIM_TimeBaseInit (TIM_MST , & TIM_TimeBaseStructure );
54
66
TIM_TimeBaseStructure .TIM_Prescaler = 0 ;
55
- TIM_TimeBaseInit (TIM4 , & TIM_TimeBaseStructure );
67
+ TIM_TimeBaseInit (TIM_SLV , & TIM_TimeBaseStructure );
56
68
57
69
// Master timer configuration
58
70
TIM_OCStructInit (& TIM_OCInitStructure );
59
71
TIM_OCInitStructure .TIM_OCMode = TIM_OCMode_Toggle ;
60
72
TIM_OCInitStructure .TIM_OutputState = TIM_OutputState_Enable ;
61
73
TIM_OCInitStructure .TIM_Pulse = 0 ;
62
74
TIM_OCInitStructure .TIM_OCPolarity = TIM_OCPolarity_High ;
63
- TIM_OC1Init (TIM1 , & TIM_OCInitStructure );
64
- TIM_SelectMasterSlaveMode (TIM1 , TIM_MasterSlaveMode_Enable );
65
- TIM_SelectOutputTrigger (TIM1 , TIM_TRGOSource_Update );
75
+ TIM_OC1Init (TIM_MST , & TIM_OCInitStructure );
76
+ TIM_SelectMasterSlaveMode (TIM_MST , TIM_MasterSlaveMode_Enable );
77
+ TIM_SelectOutputTrigger (TIM_MST , TIM_TRGOSource_Update );
66
78
67
79
// Slave timer configuration
68
- TIM_SelectSlaveMode (TIM4 , TIM_SlaveMode_External1 );
69
- TIM_SelectInputTrigger (TIM4 , TIM_TS_ITR0 );
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 );
70
83
71
84
// Enable timers
72
- TIM_Cmd (TIM4 , ENABLE );
73
- TIM_Cmd (TIM1 , ENABLE );
85
+ TIM_Cmd (TIM_SLV , ENABLE );
86
+ TIM_Cmd (TIM_MST , ENABLE );
74
87
}
75
88
76
89
uint32_t us_ticker_read () {
77
90
uint32_t counter , counter2 ;
78
91
if (!us_ticker_inited ) us_ticker_init ();
79
- // A situation might appear when TIM1 overflows right after TIM4 is read and before the
80
- // new (overflowed) value of TIM1 is read, which would make the code below consider the
81
- // previous (incorrect) value of TIM4 and the new value of TIM1 , which would return a
92
+ // A situation might appear when Master overflows right after Slave is read and before the
93
+ // new (overflowed) value of Master is read. Which would make the code below consider the
94
+ // previous (incorrect) value of Slave and the new value of Master , which would return a
82
95
// value in the past. Avoid this by computing consecutive values of the timer until they
83
96
// are properly ordered.
84
- counter = counter2 = (uint32_t )((uint32_t )TIM_GetCounter (TIM4 ) << 16 ) + (uint32_t )TIM_GetCounter (TIM1 );
97
+ counter = counter2 = (uint32_t )((uint32_t )TIM_GetCounter (TIM_SLV ) << 16 ) + (uint32_t )TIM_GetCounter (TIM_MST );
85
98
while (1 ) {
86
- counter2 = (uint32_t )((uint32_t )TIM_GetCounter (TIM4 ) << 16 ) + (uint32_t )TIM_GetCounter (TIM1 );
87
- if (counter2 > counter )
99
+ counter2 = (uint32_t )((uint32_t )TIM_GetCounter (TIM_SLV ) << 16 ) + (uint32_t )TIM_GetCounter (TIM_MST );
100
+ if (counter2 > counter ) {
88
101
break ;
102
+ }
89
103
counter = counter2 ;
90
104
}
91
105
return counter2 ;
92
106
}
93
107
94
108
void us_ticker_set_interrupt (unsigned int timestamp ) {
95
109
if (timestamp > 0xFFFF ) {
96
- TIM_SetCompare1 (TIM4 , (uint16_t )((timestamp >> 16 ) & 0xFFFF ));
97
- TIM_ITConfig (TIM4 , TIM_IT_CC1 , ENABLE );
98
- NVIC_SetVector (TIM4_IRQn , (uint32_t )us_ticker_irq_handler );
99
- NVIC_EnableIRQ (TIM4_IRQn );
110
+ TIM_SetCompare1 (TIM_SLV , (uint16_t )((timestamp >> 16 ) & 0xFFFF ));
111
+ TIM_ITConfig (TIM_SLV , TIM_IT_CC1 , ENABLE );
112
+ NVIC_SetVector (TIM_SLV_IRQ , (uint32_t )us_ticker_irq_handler );
113
+ NVIC_EnableIRQ (TIM_SLV_IRQ );
100
114
}
101
115
else {
102
- TIM_SetCompare1 (TIM1 , (uint16_t )timestamp );
103
- TIM_ITConfig (TIM1 , TIM_IT_CC1 , ENABLE );
104
- NVIC_SetVector (TIM1_CC_IRQn , (uint32_t )us_ticker_irq_handler );
105
- NVIC_EnableIRQ (TIM1_CC_IRQn );
116
+ TIM_SetCompare1 (TIM_MST , (uint16_t )timestamp );
117
+ TIM_ITConfig (TIM_MST , TIM_IT_CC1 , ENABLE );
118
+ NVIC_SetVector (TIM_MST_IRQ , (uint32_t )us_ticker_irq_handler );
119
+ NVIC_EnableIRQ (TIM_MST_IRQ );
106
120
}
107
121
}
108
122
109
123
void us_ticker_disable_interrupt (void ) {
110
- TIM_ITConfig (TIM1 , TIM_IT_CC1 , DISABLE );
111
- TIM_ITConfig (TIM4 , TIM_IT_CC1 , DISABLE );
124
+ TIM_ITConfig (TIM_MST , TIM_IT_CC1 , DISABLE );
125
+ TIM_ITConfig (TIM_SLV , TIM_IT_CC1 , DISABLE );
112
126
}
113
127
114
128
void us_ticker_clear_interrupt (void ) {
115
- TIM_ClearITPendingBit (TIM1 , TIM_IT_CC1 );
116
- TIM_ClearITPendingBit (TIM4 , TIM_IT_CC1 );
129
+ TIM_ClearITPendingBit (TIM_MST , TIM_IT_CC1 );
130
+ TIM_ClearITPendingBit (TIM_SLV , TIM_IT_CC1 );
117
131
}
0 commit comments