Skip to content

Commit 10ea63b

Browse files
committed
Ticker: add fire interrupt now function
fire_interrupt function should be used for events in the past. As we have now 64bit timestamp, we can figure out what is in the past, and ask a target to invoke an interrupt immediately. The previous attemps in the target HAL tickers were not ideal, as it can wrap around easily (16 or 32 bit counters). This new functionality should solve this problem. set_interrupt for tickers in HAL code should not handle anything but the next match interrupt. If it was in the past is handled by the upper layer. It is possible that we are setting next event to the close future, so once it is set it is already in the past. Therefore we add a check after set interrupt to verify it is in future. If it is not, we fire interrupt immediately. This results in two events - first one immediate, correct one. The second one might be scheduled in far future (almost entire ticker range), that should be discarded. The specification for the fire_interrupts are: - should set pending bit for the ticker interrupt (as soon as possible), the event we are scheduling is already in the past, and we do not want to skip any events - no arguments are provided, neither return value, not needed - ticker should be initialized prior calling this function (no need to check if it is already initialized) All our targets provide this new functionality, removing old misleading if (timestamp is in the past) checks.
1 parent aae62bd commit 10ea63b

File tree

68 files changed

+499
-357
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+499
-357
lines changed

hal/lp_ticker_api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ void lp_ticker_disable_interrupt(void);
7474
*/
7575
void lp_ticker_clear_interrupt(void);
7676

77+
/** Set pending interrupt that should be fired right away.
78+
*
79+
* The ticker should be initialized prior calling this function.
80+
*/
81+
void lp_ticker_fire_interrupt(void);
82+
7783
/**@}*/
7884

7985
#ifdef __cplusplus

hal/mbed_lp_ticker_api.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ static const ticker_interface_t lp_interface = {
2525
.disable_interrupt = lp_ticker_disable_interrupt,
2626
.clear_interrupt = lp_ticker_clear_interrupt,
2727
.set_interrupt = lp_ticker_set_interrupt,
28+
.fire_interrupt = lp_ticker_fire_interrupt,
2829
};
2930

3031
static const ticker_data_t lp_data = {

hal/mbed_ticker_api.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,23 @@ static void schedule_interrupt(const ticker_data_t *const ticker)
117117

118118
// if the event at the head of the queue is in the past then schedule
119119
// it immediately.
120-
if (next_event_timestamp < present) {
121-
relative_timeout = 0;
120+
if (next_event_timestamp <= present) {
121+
ticker->interface->fire_interrupt();
122+
return;
122123
} else if ((next_event_timestamp - present) < MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA) {
123124
relative_timeout = next_event_timestamp - present;
124125
}
125126
}
126127

127-
ticker->interface->set_interrupt(ticker->queue->present_time + relative_timeout);
128+
us_timestamp_t new_match_time = ticker->queue->present_time + relative_timeout;
129+
ticker->interface->set_interrupt(new_match_time);
130+
// there could be a delay, reread the time, check if it was set in the past
131+
// As result, if it is already in the past, we fire it immediately
132+
update_present_time(ticker);
133+
us_timestamp_t present = ticker->queue->present_time;
134+
if (present >= new_match_time) {
135+
ticker->interface->fire_interrupt();
136+
}
128137
}
129138

130139
void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler)

hal/mbed_us_ticker_api.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static const ticker_interface_t us_interface = {
2323
.disable_interrupt = us_ticker_disable_interrupt,
2424
.clear_interrupt = us_ticker_clear_interrupt,
2525
.set_interrupt = us_ticker_set_interrupt,
26+
.fire_interrupt = us_ticker_fire_interrupt,
2627
};
2728

2829
static const ticker_data_t us_data = {

hal/ticker_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ typedef struct {
6060
void (*disable_interrupt)(void); /**< Disable interrupt function */
6161
void (*clear_interrupt)(void); /**< Clear interrupt function */
6262
void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */
63+
void (*fire_interrupt)(void); /**< Fire interrupt right-away */
6364
} ticker_interface_t;
6465

6566
/** Ticker's event queue structure

hal/us_ticker_api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ void us_ticker_disable_interrupt(void);
7272
*/
7373
void us_ticker_clear_interrupt(void);
7474

75+
/** Set pending interrupt that should be fired right away.
76+
*
77+
* The ticker should be initialized prior calling this function.
78+
*/
79+
void us_ticker_fire_interrupt(void);
80+
7581
/**@}*/
7682

7783
#ifdef __cplusplus

targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,24 @@ uint32_t lp_ticker_read(void)
115115
*/
116116
void lp_ticker_set_interrupt(timestamp_t timestamp)
117117
{
118-
int32_t delta = 0;
119-
120118
/* Verify if lp_ticker has been not Initialized */
121119
if (lp_ticker_initialized == 0)
122120
lp_ticker_init();
123121

124122
/* Calculate the delta */
125-
delta = (int32_t)(timestamp - lp_ticker_read());
126-
/* Check if the event was in the past */
127-
if (delta <= 0) {
128-
/* This event was in the past */
129-
DualTimer_SetInterrupt_1(DUALTIMER0, 0,
130-
DUALTIMER_COUNT_32 | DUALTIMER_ONESHOT);
131-
return;
132-
}
123+
uint32_t delta = timestamp - lp_ticker_read();
133124

134125
/* Enable interrupt on SingleTimer1 */
135126
DualTimer_SetInterrupt_1(DUALTIMER0, delta,
136127
DUALTIMER_COUNT_32 | DUALTIMER_ONESHOT);
137128
}
138129

130+
void lp_ticker_fire_interrupt(void)
131+
{
132+
uint32_t lp_ticker_irqn = DualTimer_GetIRQn(DUALTIMER0);
133+
NVIC_SetPendingIRQ((IRQn_Type)lp_ticker_irqn);
134+
}
135+
139136
/**
140137
* Disable low power ticker interrupt
141138
*/

targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,19 @@ uint32_t us_ticker_read() {
9191
}
9292

9393
void us_ticker_set_interrupt(timestamp_t timestamp) {
94-
int32_t delta = 0;
95-
9694
if (!us_ticker_inited)
9795
us_ticker_init();
98-
delta = (int32_t)(timestamp - us_ticker_read());
99-
/* Check if the event was in the past */
100-
if (delta <= 0) {
101-
/* This event was in the past */
102-
Timer_SetInterrupt(TIMER0, 0);
103-
return;
104-
}
10596

106-
/* If the event was not in the past enable interrupt */
97+
uint32_t delta = timestamp - us_ticker_read();
10798
Timer_SetInterrupt(TIMER0, delta);
10899
}
109100

101+
void us_ticker_fire_interrupt(void)
102+
{
103+
uint32_t us_ticker_irqn1 = Timer_GetIRQn(TIMER1);
104+
NVIC_SetPendingIRQ((IRQn_Type)us_ticker_irqn1);
105+
}
106+
110107
void us_ticker_disable_interrupt(void) {
111108
Timer_DisableInterrupt(TIMER0);
112109
}

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/us_ticker.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,23 @@ uint32_t us_ticker_read()
108108

109109
void us_ticker_set_interrupt(timestamp_t timestamp)
110110
{
111-
int32_t delta = 0;
111+
uint32_t delta = 0;
112112

113113
if (!us_ticker_drv_data.inited) {
114114
us_ticker_init();
115115
}
116116

117-
delta = (int32_t)(timestamp - us_ticker_read());
117+
delta = timestamp - us_ticker_read();
118118

119-
/* Check if the event was in the past */
120-
if (delta <= 0) {
121-
/* This event was in the past */
122-
Timer_SetInterrupt(TIMER0, 0);
123-
} else {
124-
/* If the event was not in the past enable interrupt */
125-
Timer_SetInterrupt(TIMER0, delta);
126-
}
119+
/* If the event was not in the past enable interrupt */
120+
Timer_SetInterrupt(TIMER0, delta);
121+
122+
}
123+
124+
void us_ticker_fire_interrupt(void)
125+
{
126+
uint32_t us_ticker_irqn1 = Timer_GetIRQn(TIMER1);
127+
NVIC_SetPendingIRQ((IRQn_Type)us_ticker_irqn1);
127128
}
128129

129130
void us_ticker_disable_interrupt(void)

targets/TARGET_ARM_SSG/TARGET_IOTSS/us_ticker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ void us_ticker_set_interrupt(timestamp_t timestamp) {
6969
US_TICKER_TIMER1->TimerControl |= 0x80; //enable timer
7070
}
7171

72+
void us_ticker_fire_interrupt(void)
73+
{
74+
NVIC_SetPendingIRQ(US_TICKER_TIMER_IRQn);
75+
}
76+
7277
void us_ticker_disable_interrupt(void) {
7378

7479
US_TICKER_TIMER1->TimerControl &= 0xDF;

0 commit comments

Comments
 (0)