18
18
#include "hal/ticker_api.h"
19
19
#include "platform/mbed_critical.h"
20
20
21
- #define MBED_MIN (x ,y ) (((x)<(y))?(x):(y))
22
-
23
- static void update_interrupt (const ticker_data_t * const ticker );
24
- static void update_current_timestamp (const ticker_data_t * const ticker );
21
+ static void schedule_interrupt (const ticker_data_t * const ticker );
22
+ static void update_present_time (const ticker_data_t * const ticker );
25
23
26
24
/*
27
25
* Initialize a ticker instance.
@@ -38,11 +36,11 @@ static void initialize(const ticker_data_t *ticker)
38
36
39
37
ticker -> queue -> event_handler = NULL ;
40
38
ticker -> queue -> head = NULL ;
41
- ticker -> queue -> timestamp = 0 ;
39
+ ticker -> queue -> present_time = 0 ;
42
40
ticker -> queue -> initialized = true;
43
41
44
- update_current_timestamp (ticker );
45
- update_interrupt (ticker );
42
+ update_present_time (ticker );
43
+ schedule_interrupt (ticker );
46
44
}
47
45
48
46
/**
@@ -54,22 +52,29 @@ static void set_handler(const ticker_data_t *const ticker, ticker_event_handler
54
52
}
55
53
56
54
/*
57
- * Convert a low res timestamp to a high res timestamp. An high resolution
58
- * timestamp is used as the reference point to convert the low res timestamp
59
- * into an high res one.
60
- *
61
- * It is important to note that the result will **never** be in the past. If the
62
- * value of the low res timetamp is less than the low res part of the reference
63
- * timestamp then an overflow is
55
+ * Convert a 32 bit timestamp into a 64 bit timestamp.
56
+ *
57
+ * A 64 bit timestamp is used as the point of time of reference while the
58
+ * timestamp to convert is relative to this point of time.
59
+ *
60
+ * The lower 32 bits of the timestamp returned will be equal to the timestamp to
61
+ * convert.
64
62
*
65
- * @param ref: The timestamp of reference.
66
- * @param relative_timestamp: The timestamp to convert.
63
+ * If the timestamp to convert is less than the lower 32 bits of the time
64
+ * reference then the timestamp to convert is seen as an overflowed value and
65
+ * the upper 32 bit of the timestamp returned will be equal to the upper 32 bit
66
+ * of the reference point + 1.
67
+ * Otherwise, the upper 32 bit returned will be equal to the upper 32 bit of the
68
+ * reference point.
69
+ *
70
+ * @param ref: The 64 bit timestamp of reference.
71
+ * @param timestamp: The timestamp to convert.
67
72
*/
68
- static us_timestamp_t convert_relative_timestamp (us_timestamp_t ref , timestamp_t relative_timestamp )
73
+ static us_timestamp_t convert_timestamp (us_timestamp_t ref , timestamp_t timestamp )
69
74
{
70
- bool overflow = relative_timestamp < ((timestamp_t ) ref ) ? true : false;
75
+ bool overflow = timestamp < ((timestamp_t ) ref ) ? true : false;
71
76
72
- us_timestamp_t result = (ref & ~((us_timestamp_t )UINT32_MAX )) | relative_timestamp ;
77
+ us_timestamp_t result = (ref & ~((us_timestamp_t )UINT32_MAX )) | timestamp ;
73
78
if (overflow ) {
74
79
result += (1ULL <<32 );
75
80
}
@@ -78,38 +83,42 @@ static us_timestamp_t convert_relative_timestamp(us_timestamp_t ref, timestamp_t
78
83
}
79
84
80
85
/**
81
- * update the current timestamp value of a ticker.
86
+ * Update the present timestamp value of a ticker.
82
87
*/
83
- static void update_current_timestamp (const ticker_data_t * const ticker )
88
+ static void update_present_time (const ticker_data_t * const ticker )
84
89
{
85
- ticker -> queue -> timestamp = convert_relative_timestamp (
86
- ticker -> queue -> timestamp ,
90
+ ticker -> queue -> present_time = convert_timestamp (
91
+ ticker -> queue -> present_time ,
87
92
ticker -> interface -> read ()
88
93
);
89
94
}
90
95
91
96
/**
92
- * update the interrupt with the appropriate timestamp.
93
- * if there is no interrupt scheduled or the next event to execute is in more
94
- * than MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA us from now then the
95
- * interrupt will be set to MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA us from now.
96
- * Otherwise the interrupt will be set to head->timestamp - queue->timestamp us.
97
+ * Compute the time when the interrupt has to be triggered and schedule it.
98
+ *
99
+ * If there is no event in the queue or the next event to execute is in more
100
+ * than MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA us from now then the ticker
101
+ * irq will be scheduled in MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA us.
102
+ * Otherwise the irq will be scheduled to happen when the running counter reach
103
+ * the timestamp of the first event in the queue.
104
+ *
105
+ * @note If there is no event in the queue then the interrupt is scheduled to
106
+ * in MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA. This is necessary to keep track
107
+ * of the timer overflow.
97
108
*/
98
- static void update_interrupt (const ticker_data_t * const ticker )
109
+ static void schedule_interrupt (const ticker_data_t * const ticker )
99
110
{
100
- update_current_timestamp (ticker );
101
- uint32_t diff = MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA ;
102
-
103
- if (ticker -> queue -> head ) {
104
- diff = MBED_MIN (
105
- ( ticker -> queue -> head -> timestamp - ticker -> queue -> timestamp ),
106
- MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA
107
- );
111
+ update_present_time (ticker );
112
+ uint32_t duration = MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA ;
113
+
114
+ if (ticker -> queue -> head ) {
115
+ us_timestamp_t event_interval = ( ticker -> queue -> head -> timestamp - ticker -> queue -> present_time );
116
+ if ( event_interval < MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA ) {
117
+ duration = event_interval ;
118
+ }
108
119
}
109
120
110
- ticker -> interface -> set_interrupt (
111
- ticker -> queue -> timestamp + diff
112
- );
121
+ ticker -> interface -> set_interrupt (ticker -> queue -> present_time + duration );
113
122
}
114
123
115
124
void ticker_set_handler (const ticker_data_t * const ticker , ticker_event_handler handler )
@@ -129,9 +138,9 @@ void ticker_irq_handler(const ticker_data_t *const ticker)
129
138
}
130
139
131
140
// update the current timestamp used by the queue
132
- update_current_timestamp (ticker );
141
+ update_present_time (ticker );
133
142
134
- if (ticker -> queue -> head -> timestamp <= ticker -> queue -> timestamp ) {
143
+ if (ticker -> queue -> head -> timestamp <= ticker -> queue -> present_time ) {
135
144
// This event was in the past:
136
145
// point to the following one and execute its handler
137
146
ticker_event_t * p = ticker -> queue -> head ;
@@ -146,18 +155,17 @@ void ticker_irq_handler(const ticker_data_t *const ticker)
146
155
}
147
156
}
148
157
149
- update_interrupt (ticker );
158
+ schedule_interrupt (ticker );
150
159
}
151
160
152
161
void ticker_insert_event (const ticker_data_t * const ticker , ticker_event_t * obj , timestamp_t timestamp , uint32_t id )
153
162
{
154
- /* disable interrupts for the duration of the function */
155
163
core_util_critical_section_enter ();
156
164
157
165
// update the current timestamp
158
- update_current_timestamp (ticker );
159
- us_timestamp_t absolute_timestamp = convert_relative_timestamp (
160
- ticker -> queue -> timestamp ,
166
+ update_present_time (ticker );
167
+ us_timestamp_t absolute_timestamp = convert_timestamp (
168
+ ticker -> queue -> present_time ,
161
169
timestamp
162
170
);
163
171
core_util_critical_section_exit ();
@@ -171,15 +179,14 @@ void ticker_insert_event(const ticker_data_t *const ticker, ticker_event_t *obj,
171
179
172
180
void ticker_insert_event_us (const ticker_data_t * const ticker , ticker_event_t * obj , us_timestamp_t timestamp , uint32_t id )
173
181
{
174
- /* disable interrupts for the duration of the function */
175
182
core_util_critical_section_enter ();
176
183
177
184
// update the current timestamp
178
- update_current_timestamp (ticker );
185
+ update_present_time (ticker );
179
186
180
187
// filter out timestamp in the past
181
- if (timestamp < ticker -> queue -> timestamp ) {
182
- update_interrupt (ticker );
188
+ if (timestamp < ticker -> queue -> present_time ) {
189
+ schedule_interrupt (ticker );
183
190
return ;
184
191
}
185
192
@@ -211,7 +218,7 @@ void ticker_insert_event_us(const ticker_data_t *const ticker, ticker_event_t *o
211
218
prev -> next = obj ;
212
219
}
213
220
214
- update_interrupt (ticker );
221
+ schedule_interrupt (ticker );
215
222
216
223
core_util_critical_section_exit ();
217
224
}
@@ -224,7 +231,7 @@ void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj)
224
231
if (ticker -> queue -> head == obj ) {
225
232
// first in the list, so just drop me
226
233
ticker -> queue -> head = obj -> next ;
227
- update_interrupt (ticker );
234
+ schedule_interrupt (ticker );
228
235
} else {
229
236
// find the object before me, then drop me
230
237
ticker_event_t * p = ticker -> queue -> head ;
@@ -247,8 +254,8 @@ timestamp_t ticker_read(const ticker_data_t *const ticker)
247
254
248
255
us_timestamp_t ticker_read_us (const ticker_data_t * const ticker )
249
256
{
250
- update_current_timestamp (ticker );
251
- return ticker -> queue -> timestamp ;
257
+ update_present_time (ticker );
258
+ return ticker -> queue -> present_time ;
252
259
}
253
260
254
261
int ticker_get_next_timestamp (const ticker_data_t * const data , timestamp_t * timestamp )
0 commit comments