30
30
#include <stddef.h>
31
31
#include "timer.h"
32
32
33
- #define US_TIMER TIMER0
34
- #define US_TICKER TIMER1
35
-
36
- static int us_ticker_inited = 0 ;
37
-
33
+ static bool us_ticker_inited = false;
38
34
static void us_timer_init (void );
39
35
40
- static uint32_t us_ticker_target = 0 ;
41
- static volatile uint32_t msb_counter = 0 ;
42
-
43
36
void us_ticker_init (void )
44
37
{
45
38
if (!us_ticker_inited ) {
@@ -54,15 +47,12 @@ void us_ticker_init(void)
54
47
* The NCS36510 does not have a 32 bit timer nor the option to chain timers,
55
48
* which is why a software timer is required to get 32-bit word length.
56
49
******************************************************************************/
57
- /* TODO - Need some sort of load value/prescale calculation for non-32MHz clock */
58
- /* TODO - Add msb_counter rollover protection at 16 bits count? */
59
- /* TODO - How is overflow handled? */
60
50
61
- /* Timer 0 for free running time */
51
+ /* TImer 0 - timer ISR */
62
52
extern void us_timer_isr (void )
63
53
{
54
+ /* Clear IRQ flag */
64
55
TIM0REG -> CLEAR = 0 ;
65
- msb_counter ++ ;
66
56
}
67
57
68
58
/* Initializing TIMER 0(TImer) and TIMER 1(Ticker) */
@@ -87,8 +77,7 @@ static void us_timer_init(void)
87
77
TIM1REG -> LOAD = 0xFFFF ;
88
78
89
79
/* set timer prescale 32 (1 us), mode & enable */
90
- TIM1REG -> CONTROL .WORD = ((CLK_DIVIDER_32 << TIMER_PRESCALE_BIT_POS ) |
91
- (TIME_MODE_PERIODIC << TIMER_MODE_BIT_POS ));
80
+ TIM1REG -> CONTROL .WORD = ((CLK_DIVIDER_32 << TIMER_PRESCALE_BIT_POS ));
92
81
93
82
/* Register & enable interrupt associated with the timer */
94
83
NVIC_SetVector (Tim0_IRQn ,(uint32_t )us_timer_isr );
@@ -108,36 +97,22 @@ static void us_timer_init(void)
108
97
/* Reads 32 bit timer's current value (16 bit s/w timer | 16 bit h/w timer) */
109
98
uint32_t us_ticker_read ()
110
99
{
111
- uint32_t retval , tim0cval ;
112
-
113
100
if (!us_ticker_inited ) {
114
101
us_timer_init ();
115
102
}
116
103
117
104
/* Get the current tick from the hw and sw timers */
118
- tim0cval = TIM0REG -> VALUE ; /* read current time */
119
- retval = (0xFFFF - tim0cval ); /* subtract down count */
120
-
121
- NVIC_DisableIRQ (Tim0_IRQn );
122
- if (TIM0REG -> CONTROL .BITS .INT ) {
123
- TIM0REG -> CLEAR = 0 ;
124
- msb_counter ++ ;
125
- tim0cval = TIM0REG -> VALUE ; /* read current time again after interrupt */
126
- retval = (0xFFFF - tim0cval );
127
- }
128
- retval |= msb_counter << 16 ; /* add software bits */
129
- NVIC_EnableIRQ (Tim0_IRQn );
130
- return retval ;
105
+ uint32_t tim0cval = TIM0REG -> VALUE ; /* read current time */
106
+ return (0xFFFF - tim0cval ); /* subtract down count */
131
107
}
132
108
133
109
/*******************************************************************************
134
110
* Event Timer
135
111
*
136
- * Schedules interrupts at given (32bit )us interval of time. It uses TIMER1.
112
+ * Schedules interrupts at given (16bit )us interval of time. It uses TIMER1.
137
113
* The NCS36510 does not have a 32 bit timer nor the option to chain timers,
138
114
* which is why a software timer is required to get 32-bit word length.
139
115
*******************************************************************************/
140
- /* TODO - Need some sort of load value/prescale calculation for non-32MHz clock */
141
116
142
117
/* TImer 1 disbale interrupt */
143
118
void us_ticker_disable_interrupt (void )
@@ -153,57 +128,35 @@ void us_ticker_clear_interrupt(void)
153
128
TIM1REG -> CLEAR = 0 ;
154
129
}
155
130
156
- /* Setting TImer 1 (ticker) */
157
- inline static void ticker_set (uint32_t count )
158
- {
159
- /* Disable TIMER1, load the new value, and re-enable */
160
- TIM1REG -> CONTROL .BITS .ENABLE = 0 ;
161
- TIM1REG -> LOAD = count ;
162
- TIM1REG -> CONTROL .BITS .ENABLE = 1 ;
163
- }
164
-
165
131
/* TImer 1 - ticker ISR */
166
132
extern void us_ticker_isr (void )
167
133
{
168
134
/* Clear IRQ flag */
169
135
TIM1REG -> CLEAR = 0 ;
170
-
171
- int32_t delta = us_ticker_target - us_ticker_read ();
172
- if (delta <= 0 ) {
173
- TIM1REG -> CONTROL .BITS .ENABLE = False ;
174
- us_ticker_irq_handler ();
175
- } else {
176
- // Clamp at max value of timer
177
- if (delta > 0xFFFF ) {
178
- delta = 0xFFFF ;
179
- }
180
-
181
- ticker_set (delta );
182
- }
136
+ us_ticker_irq_handler ();
183
137
}
184
138
185
139
/* Set timer 1 ticker interrupt */
186
140
void us_ticker_set_interrupt (timestamp_t timestamp )
187
141
{
188
- us_ticker_target = (uint32_t )timestamp ;
189
- int32_t delta = us_ticker_target - us_ticker_read ();
142
+ int32_t delta = timestamp - us_ticker_read ();
190
143
144
+ // This event was in the past.
145
+ // Set the interrupt as pending, but don't process it here.
146
+ // This prevents a recurive loop under heavy load
147
+ // which can lead to a stack overflow.
191
148
if (delta <= 0 ) {
192
- /* This event was in the past */
193
- //us_ticker_irq_handler();
194
- // This event was in the past.
195
- // Set the interrupt as pending, but don't process it here.
196
- // This prevents a recurive loop under heavy load
197
- // which can lead to a stack overflow.
198
149
NVIC_SetPendingIRQ (Tim1_IRQn );
199
-
200
150
return ;
201
151
}
202
152
203
- // Clamp at max value of timer
204
- if (delta > 0xFFFF ) {
205
- delta = 0xFFFF ;
153
+ /* Clamp to 16 bits */
154
+ if (delta > 0xffff ) {
155
+ delta = 0xffff ;
206
156
}
207
157
208
- ticker_set (delta );
158
+ /* Disable TIMER1, load the new value, and re-enable */
159
+ TIM1REG -> CONTROL .BITS .ENABLE = 0 ;
160
+ TIM1REG -> LOAD = (uint16_t )delta ;
161
+ TIM1REG -> CONTROL .BITS .ENABLE = 1 ;
209
162
}
0 commit comments