Dependencies:   MMA7660 LM75B

Committer:
MACRUM
Date:
Sat Jun 30 01:40:30 2018 +0000
Revision:
0:119624335925
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:119624335925 1 /*
MACRUM 0:119624335925 2 * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
MACRUM 0:119624335925 3 * SPDX-License-Identifier: Apache-2.0
MACRUM 0:119624335925 4 * Licensed under the Apache License, Version 2.0 (the License); you may
MACRUM 0:119624335925 5 * not use this file except in compliance with the License.
MACRUM 0:119624335925 6 * You may obtain a copy of the License at
MACRUM 0:119624335925 7 *
MACRUM 0:119624335925 8 * http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:119624335925 9 *
MACRUM 0:119624335925 10 * Unless required by applicable law or agreed to in writing, software
MACRUM 0:119624335925 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
MACRUM 0:119624335925 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:119624335925 13 * See the License for the specific language governing permissions and
MACRUM 0:119624335925 14 * limitations under the License.
MACRUM 0:119624335925 15 */
MACRUM 0:119624335925 16 #include "ns_types.h"
MACRUM 0:119624335925 17 #include "ns_list.h"
MACRUM 0:119624335925 18 #include "timer_sys.h"
MACRUM 0:119624335925 19 #include "platform/arm_hal_interrupt.h"
MACRUM 0:119624335925 20 #include "platform/arm_hal_timer.h"
MACRUM 0:119624335925 21 #include "nsdynmemLIB.h"
MACRUM 0:119624335925 22 #include "eventOS_event.h"
MACRUM 0:119624335925 23 #include "eventOS_event_timer.h"
MACRUM 0:119624335925 24 #include "event.h"
MACRUM 0:119624335925 25 #include "eventOS_callback_timer.h"
MACRUM 0:119624335925 26
MACRUM 0:119624335925 27 #include "ns_timer.h"
MACRUM 0:119624335925 28
MACRUM 0:119624335925 29 #ifndef ST_MAX
MACRUM 0:119624335925 30 #define ST_MAX 6
MACRUM 0:119624335925 31 #endif
MACRUM 0:119624335925 32
MACRUM 0:119624335925 33 static sys_timer_struct_s startup_sys_timer_pool[ST_MAX];
MACRUM 0:119624335925 34
MACRUM 0:119624335925 35 #define TIMER_SLOTS_PER_MS 20
MACRUM 0:119624335925 36 NS_STATIC_ASSERT(1000 % EVENTOS_EVENT_TIMER_HZ == 0, "Need whole number of ms per tick")
MACRUM 0:119624335925 37 #define TIMER_SYS_TICK_PERIOD (1000 / EVENTOS_EVENT_TIMER_HZ) // milliseconds
MACRUM 0:119624335925 38
MACRUM 0:119624335925 39 // timer_sys_ticks must be read in critical section to guarantee
MACRUM 0:119624335925 40 // atomicity on 16-bit platforms
MACRUM 0:119624335925 41 static volatile uint32_t timer_sys_ticks;
MACRUM 0:119624335925 42
MACRUM 0:119624335925 43 static NS_LIST_DEFINE(system_timer_free, sys_timer_struct_s, event.link);
MACRUM 0:119624335925 44 static NS_LIST_DEFINE(system_timer_list, sys_timer_struct_s, event.link);
MACRUM 0:119624335925 45
MACRUM 0:119624335925 46
MACRUM 0:119624335925 47 static sys_timer_struct_s *sys_timer_dynamically_allocate(void);
MACRUM 0:119624335925 48 static void timer_sys_interrupt(void);
MACRUM 0:119624335925 49 static void timer_sys_add(sys_timer_struct_s *timer);
MACRUM 0:119624335925 50
MACRUM 0:119624335925 51 #ifndef NS_EVENTLOOP_USE_TICK_TIMER
MACRUM 0:119624335925 52 static int8_t platform_tick_timer_start(uint32_t period_ms);
MACRUM 0:119624335925 53 /* Implement platform tick timer using eventOS timer */
MACRUM 0:119624335925 54 // platform tick timer callback function
MACRUM 0:119624335925 55 static void (*tick_timer_callback)(void);
MACRUM 0:119624335925 56 static int8_t tick_timer_id = -1; // eventOS timer id for tick timer
MACRUM 0:119624335925 57
MACRUM 0:119624335925 58 // EventOS timer callback function
MACRUM 0:119624335925 59 static void tick_timer_eventOS_callback(int8_t timer_id, uint16_t slots)
MACRUM 0:119624335925 60 {
MACRUM 0:119624335925 61 // Not interested in timer id or slots
MACRUM 0:119624335925 62 (void)slots;
MACRUM 0:119624335925 63 // Call the tick timer callback
MACRUM 0:119624335925 64 if (tick_timer_callback != NULL && timer_id == tick_timer_id) {
MACRUM 0:119624335925 65 platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
MACRUM 0:119624335925 66 tick_timer_callback();
MACRUM 0:119624335925 67 }
MACRUM 0:119624335925 68 }
MACRUM 0:119624335925 69
MACRUM 0:119624335925 70 static int8_t platform_tick_timer_register(void (*tick_timer_cb)(void))
MACRUM 0:119624335925 71 {
MACRUM 0:119624335925 72 tick_timer_callback = tick_timer_cb;
MACRUM 0:119624335925 73 tick_timer_id = eventOS_callback_timer_register(tick_timer_eventOS_callback);
MACRUM 0:119624335925 74 return tick_timer_id;
MACRUM 0:119624335925 75 }
MACRUM 0:119624335925 76
MACRUM 0:119624335925 77 static int8_t platform_tick_timer_start(uint32_t period_ms)
MACRUM 0:119624335925 78 {
MACRUM 0:119624335925 79 return eventOS_callback_timer_start(tick_timer_id, TIMER_SLOTS_PER_MS * period_ms);
MACRUM 0:119624335925 80 }
MACRUM 0:119624335925 81
MACRUM 0:119624335925 82 static int8_t platform_tick_timer_stop(void)
MACRUM 0:119624335925 83 {
MACRUM 0:119624335925 84 return eventOS_callback_timer_stop(tick_timer_id);
MACRUM 0:119624335925 85 }
MACRUM 0:119624335925 86 #endif // !NS_EVENTLOOP_USE_TICK_TIMER
MACRUM 0:119624335925 87
MACRUM 0:119624335925 88 /*
MACRUM 0:119624335925 89 * Initializes timers and starts system timer
MACRUM 0:119624335925 90 */
MACRUM 0:119624335925 91 void timer_sys_init(void)
MACRUM 0:119624335925 92 {
MACRUM 0:119624335925 93 for (uint8_t i = 0; i < ST_MAX; i++) {
MACRUM 0:119624335925 94 ns_list_add_to_start(&system_timer_free, &startup_sys_timer_pool[i]);
MACRUM 0:119624335925 95 }
MACRUM 0:119624335925 96
MACRUM 0:119624335925 97 platform_tick_timer_register(timer_sys_interrupt);
MACRUM 0:119624335925 98 platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
MACRUM 0:119624335925 99 }
MACRUM 0:119624335925 100
MACRUM 0:119624335925 101
MACRUM 0:119624335925 102
MACRUM 0:119624335925 103 /*-------------------SYSTEM TIMER FUNCTIONS--------------------------*/
MACRUM 0:119624335925 104 void timer_sys_disable(void)
MACRUM 0:119624335925 105 {
MACRUM 0:119624335925 106 platform_tick_timer_stop();
MACRUM 0:119624335925 107 }
MACRUM 0:119624335925 108
MACRUM 0:119624335925 109 /*
MACRUM 0:119624335925 110 * Starts ticking system timer interrupts every 10ms
MACRUM 0:119624335925 111 */
MACRUM 0:119624335925 112 int8_t timer_sys_wakeup(void)
MACRUM 0:119624335925 113 {
MACRUM 0:119624335925 114 return platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
MACRUM 0:119624335925 115 }
MACRUM 0:119624335925 116
MACRUM 0:119624335925 117
MACRUM 0:119624335925 118 static void timer_sys_interrupt(void)
MACRUM 0:119624335925 119 {
MACRUM 0:119624335925 120 system_timer_tick_update(1);
MACRUM 0:119624335925 121 }
MACRUM 0:119624335925 122
MACRUM 0:119624335925 123
MACRUM 0:119624335925 124
MACRUM 0:119624335925 125 /* * * * * * * * * */
MACRUM 0:119624335925 126
MACRUM 0:119624335925 127 static sys_timer_struct_s *sys_timer_dynamically_allocate(void)
MACRUM 0:119624335925 128 {
MACRUM 0:119624335925 129 return ns_dyn_mem_alloc(sizeof(sys_timer_struct_s));
MACRUM 0:119624335925 130 }
MACRUM 0:119624335925 131
MACRUM 0:119624335925 132 static sys_timer_struct_s *timer_struct_get(void)
MACRUM 0:119624335925 133 {
MACRUM 0:119624335925 134 sys_timer_struct_s *timer;
MACRUM 0:119624335925 135 platform_enter_critical();
MACRUM 0:119624335925 136 timer = ns_list_get_first(&system_timer_free);
MACRUM 0:119624335925 137 if (timer) {
MACRUM 0:119624335925 138 ns_list_remove(&system_timer_free, timer);
MACRUM 0:119624335925 139 } else {
MACRUM 0:119624335925 140 timer = sys_timer_dynamically_allocate();
MACRUM 0:119624335925 141 }
MACRUM 0:119624335925 142 platform_exit_critical();
MACRUM 0:119624335925 143 return timer;
MACRUM 0:119624335925 144 }
MACRUM 0:119624335925 145
MACRUM 0:119624335925 146 void timer_sys_event_free(arm_event_storage_t *event)
MACRUM 0:119624335925 147 {
MACRUM 0:119624335925 148 platform_enter_critical();
MACRUM 0:119624335925 149 sys_timer_struct_s *timer = NS_CONTAINER_OF(event, sys_timer_struct_s, event);
MACRUM 0:119624335925 150 if (timer->period == 0) {
MACRUM 0:119624335925 151 // Non-periodic - return to free list
MACRUM 0:119624335925 152 ns_list_add_to_start(&system_timer_free, timer);
MACRUM 0:119624335925 153 } else {
MACRUM 0:119624335925 154 // Periodic - check due time of next launch
MACRUM 0:119624335925 155 timer->launch_time += timer->period;
MACRUM 0:119624335925 156 if (TICKS_BEFORE_OR_AT(timer->launch_time, timer_sys_ticks)) {
MACRUM 0:119624335925 157 // next event is overdue - queue event now
MACRUM 0:119624335925 158 eventOS_event_send_timer_allocated(&timer->event);
MACRUM 0:119624335925 159 } else {
MACRUM 0:119624335925 160 // add back to timer queue for the future
MACRUM 0:119624335925 161 timer_sys_add(timer);
MACRUM 0:119624335925 162 }
MACRUM 0:119624335925 163 }
MACRUM 0:119624335925 164 platform_exit_critical();
MACRUM 0:119624335925 165 }
MACRUM 0:119624335925 166
MACRUM 0:119624335925 167 void timer_sys_event_cancel_critical(struct arm_event_storage *event)
MACRUM 0:119624335925 168 {
MACRUM 0:119624335925 169 sys_timer_struct_s *timer = NS_CONTAINER_OF(event, sys_timer_struct_s, event);
MACRUM 0:119624335925 170 timer->period = 0;
MACRUM 0:119624335925 171 // If its unqueued it is on my timer list, otherwise it is in event-loop.
MACRUM 0:119624335925 172 if (event->state == ARM_LIB_EVENT_UNQUEUED) {
MACRUM 0:119624335925 173 ns_list_remove(&system_timer_list, timer);
MACRUM 0:119624335925 174 }
MACRUM 0:119624335925 175 }
MACRUM 0:119624335925 176
MACRUM 0:119624335925 177 uint32_t eventOS_event_timer_ticks(void)
MACRUM 0:119624335925 178 {
MACRUM 0:119624335925 179 uint32_t ret_val;
MACRUM 0:119624335925 180 // Enter/exit critical is a bit clunky, but necessary on 16-bit platforms,
MACRUM 0:119624335925 181 // which won't be able to do an atomic 32-bit read.
MACRUM 0:119624335925 182 platform_enter_critical();
MACRUM 0:119624335925 183 ret_val = timer_sys_ticks;
MACRUM 0:119624335925 184 platform_exit_critical();
MACRUM 0:119624335925 185 return ret_val;
MACRUM 0:119624335925 186 }
MACRUM 0:119624335925 187
MACRUM 0:119624335925 188 /* Called internally with lock held */
MACRUM 0:119624335925 189 static void timer_sys_add(sys_timer_struct_s *timer)
MACRUM 0:119624335925 190 {
MACRUM 0:119624335925 191 uint32_t at = timer->launch_time;
MACRUM 0:119624335925 192
MACRUM 0:119624335925 193 // Find first timer scheduled to run after us, and insert before it.
MACRUM 0:119624335925 194 // (This means timers scheduled for same time run in order of request)
MACRUM 0:119624335925 195 ns_list_foreach(sys_timer_struct_s, t, &system_timer_list) {
MACRUM 0:119624335925 196 if (TICKS_BEFORE(at, t->launch_time)) {
MACRUM 0:119624335925 197 ns_list_add_before(&system_timer_list, t, timer);
MACRUM 0:119624335925 198 return;
MACRUM 0:119624335925 199 }
MACRUM 0:119624335925 200 }
MACRUM 0:119624335925 201
MACRUM 0:119624335925 202 // Didn't insert before another timer, so must be last.
MACRUM 0:119624335925 203 ns_list_add_to_end(&system_timer_list, timer);
MACRUM 0:119624335925 204 }
MACRUM 0:119624335925 205
MACRUM 0:119624335925 206 /* Called internally with lock held */
MACRUM 0:119624335925 207 static arm_event_storage_t *eventOS_event_timer_request_at_(const arm_event_t *event, uint32_t at, uint32_t period)
MACRUM 0:119624335925 208 {
MACRUM 0:119624335925 209 // Because we use user-allocated events, they must get delivered to avoid
MACRUM 0:119624335925 210 // a leak. Previously this call queued timers for invalid tasks, then they
MACRUM 0:119624335925 211 // would go undelivered. Now it returns an error.
MACRUM 0:119624335925 212 if (!event_tasklet_handler_id_valid(event->receiver)) {
MACRUM 0:119624335925 213 return NULL;
MACRUM 0:119624335925 214 }
MACRUM 0:119624335925 215
MACRUM 0:119624335925 216 sys_timer_struct_s *timer = timer_struct_get();
MACRUM 0:119624335925 217 if (!timer) {
MACRUM 0:119624335925 218 return NULL;
MACRUM 0:119624335925 219 }
MACRUM 0:119624335925 220
MACRUM 0:119624335925 221 timer->event.data = *event;
MACRUM 0:119624335925 222 timer->event.allocator = ARM_LIB_EVENT_TIMER;
MACRUM 0:119624335925 223 timer->event.state = ARM_LIB_EVENT_UNQUEUED;
MACRUM 0:119624335925 224 timer->launch_time = at;
MACRUM 0:119624335925 225 timer->period = period;
MACRUM 0:119624335925 226
MACRUM 0:119624335925 227 if (TICKS_BEFORE_OR_AT(at, timer_sys_ticks)) {
MACRUM 0:119624335925 228 eventOS_event_send_timer_allocated(&timer->event);
MACRUM 0:119624335925 229 } else {
MACRUM 0:119624335925 230 timer_sys_add(timer);
MACRUM 0:119624335925 231 }
MACRUM 0:119624335925 232
MACRUM 0:119624335925 233 return &timer->event;
MACRUM 0:119624335925 234 }
MACRUM 0:119624335925 235
MACRUM 0:119624335925 236 arm_event_storage_t *eventOS_event_timer_request_at(const arm_event_t *event, uint32_t at)
MACRUM 0:119624335925 237 {
MACRUM 0:119624335925 238 platform_enter_critical();
MACRUM 0:119624335925 239
MACRUM 0:119624335925 240 arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, at, 0);
MACRUM 0:119624335925 241
MACRUM 0:119624335925 242 platform_exit_critical();
MACRUM 0:119624335925 243
MACRUM 0:119624335925 244 return ret;
MACRUM 0:119624335925 245 }
MACRUM 0:119624335925 246
MACRUM 0:119624335925 247 arm_event_storage_t *eventOS_event_timer_request_in(const arm_event_t *event, int32_t in)
MACRUM 0:119624335925 248 {
MACRUM 0:119624335925 249 platform_enter_critical();
MACRUM 0:119624335925 250
MACRUM 0:119624335925 251 arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, timer_sys_ticks + in, 0);
MACRUM 0:119624335925 252
MACRUM 0:119624335925 253 platform_exit_critical();
MACRUM 0:119624335925 254
MACRUM 0:119624335925 255 return ret;
MACRUM 0:119624335925 256
MACRUM 0:119624335925 257 }
MACRUM 0:119624335925 258
MACRUM 0:119624335925 259 arm_event_storage_t *eventOS_event_timer_request_every(const arm_event_t *event, int32_t period)
MACRUM 0:119624335925 260 {
MACRUM 0:119624335925 261 if (period <= 0) {
MACRUM 0:119624335925 262 return NULL;
MACRUM 0:119624335925 263 }
MACRUM 0:119624335925 264
MACRUM 0:119624335925 265 platform_enter_critical();
MACRUM 0:119624335925 266
MACRUM 0:119624335925 267 arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, timer_sys_ticks + period, period);
MACRUM 0:119624335925 268
MACRUM 0:119624335925 269 platform_exit_critical();
MACRUM 0:119624335925 270
MACRUM 0:119624335925 271 return ret;
MACRUM 0:119624335925 272
MACRUM 0:119624335925 273 }
MACRUM 0:119624335925 274
MACRUM 0:119624335925 275 int8_t eventOS_event_timer_request(uint8_t event_id, uint8_t event_type, int8_t tasklet_id, uint32_t time)
MACRUM 0:119624335925 276 {
MACRUM 0:119624335925 277 const arm_event_t event = {
MACRUM 0:119624335925 278 .event_id = event_id,
MACRUM 0:119624335925 279 .event_type = event_type,
MACRUM 0:119624335925 280 .receiver = tasklet_id,
MACRUM 0:119624335925 281 .sender = 0,
MACRUM 0:119624335925 282 .data_ptr = NULL,
MACRUM 0:119624335925 283 .event_data = 0,
MACRUM 0:119624335925 284 .priority = ARM_LIB_MED_PRIORITY_EVENT,
MACRUM 0:119624335925 285 };
MACRUM 0:119624335925 286
MACRUM 0:119624335925 287 // Legacy time behaviour preserved
MACRUM 0:119624335925 288
MACRUM 0:119624335925 289 // Note that someone wanting 20ms gets 2 ticks, thanks to this test. 30ms would be 4 ticks.
MACRUM 0:119624335925 290 // And why shouldn't they be able to get a 1-tick callback?
MACRUM 0:119624335925 291 if (time > 2 * TIMER_SYS_TICK_PERIOD) {
MACRUM 0:119624335925 292 time /= TIMER_SYS_TICK_PERIOD;
MACRUM 0:119624335925 293 // XXX Why this? Someone wanting 50ms shouldn't get 6 ticks. Round to nearest, maybe?
MACRUM 0:119624335925 294 time++;
MACRUM 0:119624335925 295 } else {
MACRUM 0:119624335925 296 time = 2;
MACRUM 0:119624335925 297 }
MACRUM 0:119624335925 298
MACRUM 0:119624335925 299 platform_enter_critical();
MACRUM 0:119624335925 300 arm_event_storage_t *ret = eventOS_event_timer_request_at_(&event, timer_sys_ticks + time, 0);
MACRUM 0:119624335925 301 platform_exit_critical();
MACRUM 0:119624335925 302 return ret?0:-1;
MACRUM 0:119624335925 303 }
MACRUM 0:119624335925 304
MACRUM 0:119624335925 305 int8_t eventOS_event_timer_cancel(uint8_t event_id, int8_t tasklet_id)
MACRUM 0:119624335925 306 {
MACRUM 0:119624335925 307 platform_enter_critical();
MACRUM 0:119624335925 308
MACRUM 0:119624335925 309 /* First check pending timers */
MACRUM 0:119624335925 310 ns_list_foreach(sys_timer_struct_s, cur, &system_timer_list) {
MACRUM 0:119624335925 311 if (cur->event.data.receiver == tasklet_id && cur->event.data.event_id == event_id) {
MACRUM 0:119624335925 312 eventOS_cancel(&cur->event);
MACRUM 0:119624335925 313 goto done;
MACRUM 0:119624335925 314 }
MACRUM 0:119624335925 315 }
MACRUM 0:119624335925 316
MACRUM 0:119624335925 317 /* No pending timer, so check for already-pending event */
MACRUM 0:119624335925 318 arm_event_storage_t *event = eventOS_event_find_by_id_critical(tasklet_id, event_id);
MACRUM 0:119624335925 319 if (event && event->allocator == ARM_LIB_EVENT_TIMER) {
MACRUM 0:119624335925 320 eventOS_cancel(event);
MACRUM 0:119624335925 321 goto done;
MACRUM 0:119624335925 322 }
MACRUM 0:119624335925 323
MACRUM 0:119624335925 324 /* No match found */
MACRUM 0:119624335925 325 platform_exit_critical();
MACRUM 0:119624335925 326 return -1;
MACRUM 0:119624335925 327
MACRUM 0:119624335925 328 done:
MACRUM 0:119624335925 329 platform_exit_critical();
MACRUM 0:119624335925 330 return 0;
MACRUM 0:119624335925 331 }
MACRUM 0:119624335925 332
MACRUM 0:119624335925 333 uint32_t eventOS_event_timer_shortest_active_timer(void)
MACRUM 0:119624335925 334 {
MACRUM 0:119624335925 335 uint32_t ret_val = 0;
MACRUM 0:119624335925 336
MACRUM 0:119624335925 337 platform_enter_critical();
MACRUM 0:119624335925 338 sys_timer_struct_s *first = ns_list_get_first(&system_timer_list);
MACRUM 0:119624335925 339 if (first == NULL) {
MACRUM 0:119624335925 340 // Weird API has 0 for "no events"
MACRUM 0:119624335925 341 ret_val = 0;
MACRUM 0:119624335925 342 } else if (TICKS_BEFORE_OR_AT(first->launch_time, timer_sys_ticks)) {
MACRUM 0:119624335925 343 // Which means an immediate/overdue event has to be 1
MACRUM 0:119624335925 344 ret_val = 1;
MACRUM 0:119624335925 345 } else {
MACRUM 0:119624335925 346 ret_val = first->launch_time - timer_sys_ticks;
MACRUM 0:119624335925 347 }
MACRUM 0:119624335925 348
MACRUM 0:119624335925 349 platform_exit_critical();
MACRUM 0:119624335925 350 return eventOS_event_timer_ticks_to_ms(ret_val);
MACRUM 0:119624335925 351 }
MACRUM 0:119624335925 352
MACRUM 0:119624335925 353 void system_timer_tick_update(uint32_t ticks)
MACRUM 0:119624335925 354 {
MACRUM 0:119624335925 355 platform_enter_critical();
MACRUM 0:119624335925 356 //Keep runtime time
MACRUM 0:119624335925 357 timer_sys_ticks += ticks;
MACRUM 0:119624335925 358 ns_list_foreach_safe(sys_timer_struct_s, cur, &system_timer_list) {
MACRUM 0:119624335925 359 if (TICKS_BEFORE_OR_AT(cur->launch_time, timer_sys_ticks)) {
MACRUM 0:119624335925 360 // Unthread from our list
MACRUM 0:119624335925 361 ns_list_remove(&system_timer_list, cur);
MACRUM 0:119624335925 362 // Make it an event (can't fail - no allocation)
MACRUM 0:119624335925 363 // event system will call our timer_sys_event_free on event delivery.
MACRUM 0:119624335925 364 eventOS_event_send_timer_allocated(&cur->event);
MACRUM 0:119624335925 365 } else {
MACRUM 0:119624335925 366 // List is ordered, so as soon as we see a later event, we're done.
MACRUM 0:119624335925 367 break;
MACRUM 0:119624335925 368 }
MACRUM 0:119624335925 369 }
MACRUM 0:119624335925 370
MACRUM 0:119624335925 371 platform_exit_critical();
MACRUM 0:119624335925 372 }
MACRUM 0:119624335925 373