Skip to content

Commit 492b558

Browse files
committed
ncs36510: Adopt 16-bit ticker/timer
1 parent edcd011 commit 492b558

File tree

1 file changed

+20
-67
lines changed

1 file changed

+20
-67
lines changed

targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c

Lines changed: 20 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,9 @@
3030
#include <stddef.h>
3131
#include "timer.h"
3232

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;
3834
static void us_timer_init(void);
3935

40-
static uint32_t us_ticker_target = 0;
41-
static volatile uint32_t msb_counter = 0;
42-
4336
void us_ticker_init(void)
4437
{
4538
if (!us_ticker_inited) {
@@ -54,15 +47,12 @@ void us_ticker_init(void)
5447
* The NCS36510 does not have a 32 bit timer nor the option to chain timers,
5548
* which is why a software timer is required to get 32-bit word length.
5649
******************************************************************************/
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? */
6050

61-
/* Timer 0 for free running time */
51+
/* TImer 0 - timer ISR */
6252
extern void us_timer_isr(void)
6353
{
54+
/* Clear IRQ flag */
6455
TIM0REG->CLEAR = 0;
65-
msb_counter++;
6656
}
6757

6858
/* Initializing TIMER 0(TImer) and TIMER 1(Ticker) */
@@ -87,8 +77,7 @@ static void us_timer_init(void)
8777
TIM1REG->LOAD = 0xFFFF;
8878

8979
/* 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));
9281

9382
/* Register & enable interrupt associated with the timer */
9483
NVIC_SetVector(Tim0_IRQn,(uint32_t)us_timer_isr);
@@ -108,36 +97,22 @@ static void us_timer_init(void)
10897
/* Reads 32 bit timer's current value (16 bit s/w timer | 16 bit h/w timer) */
10998
uint32_t us_ticker_read()
11099
{
111-
uint32_t retval, tim0cval;
112-
113100
if (!us_ticker_inited) {
114101
us_timer_init();
115102
}
116103

117104
/* 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 */
131107
}
132108

133109
/*******************************************************************************
134110
* Event Timer
135111
*
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.
137113
* The NCS36510 does not have a 32 bit timer nor the option to chain timers,
138114
* which is why a software timer is required to get 32-bit word length.
139115
*******************************************************************************/
140-
/* TODO - Need some sort of load value/prescale calculation for non-32MHz clock */
141116

142117
/* TImer 1 disbale interrupt */
143118
void us_ticker_disable_interrupt(void)
@@ -153,57 +128,35 @@ void us_ticker_clear_interrupt(void)
153128
TIM1REG->CLEAR = 0;
154129
}
155130

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-
165131
/* TImer 1 - ticker ISR */
166132
extern void us_ticker_isr(void)
167133
{
168134
/* Clear IRQ flag */
169135
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();
183137
}
184138

185139
/* Set timer 1 ticker interrupt */
186140
void us_ticker_set_interrupt(timestamp_t timestamp)
187141
{
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();
190143

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.
191148
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.
198149
NVIC_SetPendingIRQ(Tim1_IRQn);
199-
200150
return;
201151
}
202152

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;
206156
}
207157

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;
209162
}

0 commit comments

Comments
 (0)