Toyomasa Watarai
/
Mbed-example-WS-W27
simple-mbed-cloud-client/mbed-cloud-client/sal-stack-nanostack-eventloop/source/ns_timer.c@0:119624335925, 2018-06-30 (annotated)
- Committer:
- MACRUM
- Date:
- Sat Jun 30 01:40:30 2018 +0000
- Revision:
- 0:119624335925
Initial commit
Who changed what in which revision?
User | Revision | Line number | New 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 | |
MACRUM | 0:119624335925 | 17 | #include "ns_types.h" |
MACRUM | 0:119624335925 | 18 | #include "ns_list.h" |
MACRUM | 0:119624335925 | 19 | #include "ns_timer.h" |
MACRUM | 0:119624335925 | 20 | #include "eventOS_callback_timer.h" |
MACRUM | 0:119624335925 | 21 | #include "platform/arm_hal_interrupt.h" |
MACRUM | 0:119624335925 | 22 | #include "platform/arm_hal_timer.h" |
MACRUM | 0:119624335925 | 23 | #include "nsdynmemLIB.h" |
MACRUM | 0:119624335925 | 24 | |
MACRUM | 0:119624335925 | 25 | #ifndef NS_EXCLUDE_HIGHRES_TIMER |
MACRUM | 0:119624335925 | 26 | typedef enum ns_timer_state_e { |
MACRUM | 0:119624335925 | 27 | NS_TIMER_ACTIVE = 0, // Will run on the next HAL interrupt |
MACRUM | 0:119624335925 | 28 | NS_TIMER_HOLD, // Will run on a later HAL interrupt |
MACRUM | 0:119624335925 | 29 | NS_TIMER_RUN_INTERRUPT, // Running on the interrupt we're currently handling |
MACRUM | 0:119624335925 | 30 | NS_TIMER_STOP // Timer not scheduled ("start" not called since last callback) |
MACRUM | 0:119624335925 | 31 | } ns_timer_state_e; |
MACRUM | 0:119624335925 | 32 | |
MACRUM | 0:119624335925 | 33 | typedef struct ns_timer_struct { |
MACRUM | 0:119624335925 | 34 | int8_t ns_timer_id; |
MACRUM | 0:119624335925 | 35 | ns_timer_state_e timer_state; |
MACRUM | 0:119624335925 | 36 | uint16_t slots; |
MACRUM | 0:119624335925 | 37 | uint16_t remaining_slots; |
MACRUM | 0:119624335925 | 38 | void (*interrupt_handler)(int8_t, uint16_t); |
MACRUM | 0:119624335925 | 39 | ns_list_link_t link; |
MACRUM | 0:119624335925 | 40 | } ns_timer_struct; |
MACRUM | 0:119624335925 | 41 | |
MACRUM | 0:119624335925 | 42 | static NS_LIST_DEFINE(ns_timer_list, ns_timer_struct, link); |
MACRUM | 0:119624335925 | 43 | |
MACRUM | 0:119624335925 | 44 | #define NS_TIMER_RUNNING 1 |
MACRUM | 0:119624335925 | 45 | static uint8_t ns_timer_state = 0; |
MACRUM | 0:119624335925 | 46 | |
MACRUM | 0:119624335925 | 47 | #ifdef ATMEGA256RFR2 |
MACRUM | 0:119624335925 | 48 | #define COMPENSATION 3 |
MACRUM | 0:119624335925 | 49 | #define COMPENSATION_TUNE 1 |
MACRUM | 0:119624335925 | 50 | #else |
MACRUM | 0:119624335925 | 51 | #define COMPENSATION 0 |
MACRUM | 0:119624335925 | 52 | #define COMPENSATION_TUNE 0 |
MACRUM | 0:119624335925 | 53 | #endif |
MACRUM | 0:119624335925 | 54 | |
MACRUM | 0:119624335925 | 55 | static void ns_timer_interrupt_handler(void); |
MACRUM | 0:119624335925 | 56 | static ns_timer_struct *ns_timer_get_pointer_to_timer_struct(int8_t timer_id); |
MACRUM | 0:119624335925 | 57 | static bool ns_timer_initialized = 0; |
MACRUM | 0:119624335925 | 58 | |
MACRUM | 0:119624335925 | 59 | int8_t eventOS_callback_timer_register(void (*timer_interrupt_handler)(int8_t, uint16_t)) |
MACRUM | 0:119624335925 | 60 | { |
MACRUM | 0:119624335925 | 61 | int8_t retval = -1; |
MACRUM | 0:119624335925 | 62 | |
MACRUM | 0:119624335925 | 63 | if (!ns_timer_initialized) { |
MACRUM | 0:119624335925 | 64 | /*Set interrupt handler in HAL driver*/ |
MACRUM | 0:119624335925 | 65 | platform_timer_set_cb(ns_timer_interrupt_handler); |
MACRUM | 0:119624335925 | 66 | ns_timer_initialized = 1; |
MACRUM | 0:119624335925 | 67 | } |
MACRUM | 0:119624335925 | 68 | |
MACRUM | 0:119624335925 | 69 | /*Find first free timer ID in timer list*/ |
MACRUM | 0:119624335925 | 70 | /*(Note use of uint8_t to avoid overflow if we reach 0x7F)*/ |
MACRUM | 0:119624335925 | 71 | for (uint8_t i = 0; i <= INT8_MAX; i++) { |
MACRUM | 0:119624335925 | 72 | if (!ns_timer_get_pointer_to_timer_struct(i)) { |
MACRUM | 0:119624335925 | 73 | retval = i; |
MACRUM | 0:119624335925 | 74 | break; |
MACRUM | 0:119624335925 | 75 | } |
MACRUM | 0:119624335925 | 76 | } |
MACRUM | 0:119624335925 | 77 | |
MACRUM | 0:119624335925 | 78 | if (retval == -1) { |
MACRUM | 0:119624335925 | 79 | return -1; |
MACRUM | 0:119624335925 | 80 | } |
MACRUM | 0:119624335925 | 81 | |
MACRUM | 0:119624335925 | 82 | ns_timer_struct *new_timer = ns_dyn_mem_alloc(sizeof(ns_timer_struct)); |
MACRUM | 0:119624335925 | 83 | if (!new_timer) { |
MACRUM | 0:119624335925 | 84 | return -1; |
MACRUM | 0:119624335925 | 85 | } |
MACRUM | 0:119624335925 | 86 | |
MACRUM | 0:119624335925 | 87 | /*Initialise new timer*/ |
MACRUM | 0:119624335925 | 88 | new_timer->ns_timer_id = retval; |
MACRUM | 0:119624335925 | 89 | new_timer->timer_state = NS_TIMER_STOP; |
MACRUM | 0:119624335925 | 90 | new_timer->remaining_slots = 0; |
MACRUM | 0:119624335925 | 91 | new_timer->interrupt_handler = timer_interrupt_handler; |
MACRUM | 0:119624335925 | 92 | |
MACRUM | 0:119624335925 | 93 | // Critical section sufficient as long as list can't be reordered from |
MACRUM | 0:119624335925 | 94 | // interrupt, otherwise will need to cover whole routine |
MACRUM | 0:119624335925 | 95 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 96 | ns_list_add_to_end(&ns_timer_list, new_timer); |
MACRUM | 0:119624335925 | 97 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 98 | |
MACRUM | 0:119624335925 | 99 | /*Return timer ID*/ |
MACRUM | 0:119624335925 | 100 | return retval; |
MACRUM | 0:119624335925 | 101 | } |
MACRUM | 0:119624335925 | 102 | |
MACRUM | 0:119624335925 | 103 | int8_t eventOS_callback_timer_unregister(int8_t ns_timer_id) |
MACRUM | 0:119624335925 | 104 | { |
MACRUM | 0:119624335925 | 105 | ns_timer_struct *current_timer; |
MACRUM | 0:119624335925 | 106 | |
MACRUM | 0:119624335925 | 107 | current_timer = ns_timer_get_pointer_to_timer_struct(ns_timer_id); |
MACRUM | 0:119624335925 | 108 | if (!current_timer) { |
MACRUM | 0:119624335925 | 109 | return -1; |
MACRUM | 0:119624335925 | 110 | } |
MACRUM | 0:119624335925 | 111 | |
MACRUM | 0:119624335925 | 112 | // Critical section sufficient as long as list can't be reordered from |
MACRUM | 0:119624335925 | 113 | // interrupt, otherwise will need to cover whole routine |
MACRUM | 0:119624335925 | 114 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 115 | ns_list_remove(&ns_timer_list, current_timer); |
MACRUM | 0:119624335925 | 116 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 117 | |
MACRUM | 0:119624335925 | 118 | ns_dyn_mem_free(current_timer); |
MACRUM | 0:119624335925 | 119 | return 0; |
MACRUM | 0:119624335925 | 120 | } |
MACRUM | 0:119624335925 | 121 | |
MACRUM | 0:119624335925 | 122 | |
MACRUM | 0:119624335925 | 123 | static int8_t ns_timer_start_pl_timer(uint16_t pl_timer_start_slots) |
MACRUM | 0:119624335925 | 124 | { |
MACRUM | 0:119624335925 | 125 | /*Don't start timer with 0 slots*/ |
MACRUM | 0:119624335925 | 126 | if (!pl_timer_start_slots) { |
MACRUM | 0:119624335925 | 127 | pl_timer_start_slots = 1; |
MACRUM | 0:119624335925 | 128 | } |
MACRUM | 0:119624335925 | 129 | |
MACRUM | 0:119624335925 | 130 | /*Start HAL timer*/ |
MACRUM | 0:119624335925 | 131 | platform_timer_start(pl_timer_start_slots); |
MACRUM | 0:119624335925 | 132 | /*Set HAL timer state to running*/ |
MACRUM | 0:119624335925 | 133 | ns_timer_state |= NS_TIMER_RUNNING; |
MACRUM | 0:119624335925 | 134 | return 0; |
MACRUM | 0:119624335925 | 135 | } |
MACRUM | 0:119624335925 | 136 | |
MACRUM | 0:119624335925 | 137 | int8_t ns_timer_sleep(void) |
MACRUM | 0:119624335925 | 138 | { |
MACRUM | 0:119624335925 | 139 | int8_t ret_val = -1; |
MACRUM | 0:119624335925 | 140 | if (ns_timer_state & NS_TIMER_RUNNING) { |
MACRUM | 0:119624335925 | 141 | /*Start HAL timer*/ |
MACRUM | 0:119624335925 | 142 | platform_timer_disable(); |
MACRUM | 0:119624335925 | 143 | /*Set HAL timer state to running*/ |
MACRUM | 0:119624335925 | 144 | ns_timer_state &= ~NS_TIMER_RUNNING; |
MACRUM | 0:119624335925 | 145 | ret_val = 0; |
MACRUM | 0:119624335925 | 146 | } |
MACRUM | 0:119624335925 | 147 | return ret_val; |
MACRUM | 0:119624335925 | 148 | } |
MACRUM | 0:119624335925 | 149 | |
MACRUM | 0:119624335925 | 150 | static int8_t ns_timer_get_next_running_to(void) |
MACRUM | 0:119624335925 | 151 | { |
MACRUM | 0:119624335925 | 152 | uint8_t hold_count = 0; |
MACRUM | 0:119624335925 | 153 | ns_timer_struct *first_timer = NULL; |
MACRUM | 0:119624335925 | 154 | |
MACRUM | 0:119624335925 | 155 | /*Find hold-labelled timer with the least remaining slots*/ |
MACRUM | 0:119624335925 | 156 | ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 157 | if (current_timer->timer_state == NS_TIMER_HOLD) { |
MACRUM | 0:119624335925 | 158 | if (!first_timer || current_timer->remaining_slots < first_timer->remaining_slots) { |
MACRUM | 0:119624335925 | 159 | first_timer = current_timer; |
MACRUM | 0:119624335925 | 160 | } |
MACRUM | 0:119624335925 | 161 | /*For optimisation, count the found timers*/ |
MACRUM | 0:119624335925 | 162 | hold_count++; |
MACRUM | 0:119624335925 | 163 | } |
MACRUM | 0:119624335925 | 164 | } |
MACRUM | 0:119624335925 | 165 | |
MACRUM | 0:119624335925 | 166 | if (!first_timer) { |
MACRUM | 0:119624335925 | 167 | return 0; |
MACRUM | 0:119624335925 | 168 | } |
MACRUM | 0:119624335925 | 169 | |
MACRUM | 0:119624335925 | 170 | /*If hold-labelled timer found, set it active and start the HAL driver*/ |
MACRUM | 0:119624335925 | 171 | hold_count--; |
MACRUM | 0:119624335925 | 172 | first_timer->timer_state = NS_TIMER_ACTIVE; |
MACRUM | 0:119624335925 | 173 | /*Compensate time spent in timer function*/ |
MACRUM | 0:119624335925 | 174 | if (first_timer->remaining_slots > COMPENSATION) { |
MACRUM | 0:119624335925 | 175 | first_timer->remaining_slots -= COMPENSATION; |
MACRUM | 0:119624335925 | 176 | } |
MACRUM | 0:119624335925 | 177 | /*Start HAL timer*/ |
MACRUM | 0:119624335925 | 178 | ns_timer_start_pl_timer(first_timer->remaining_slots); |
MACRUM | 0:119624335925 | 179 | |
MACRUM | 0:119624335925 | 180 | /*Update other hold-labelled timers*/ |
MACRUM | 0:119624335925 | 181 | ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 182 | if (hold_count == 0) { // early termination optimisation |
MACRUM | 0:119624335925 | 183 | break; |
MACRUM | 0:119624335925 | 184 | } |
MACRUM | 0:119624335925 | 185 | if (current_timer->timer_state == NS_TIMER_HOLD) { |
MACRUM | 0:119624335925 | 186 | if (current_timer->remaining_slots == first_timer->remaining_slots) { |
MACRUM | 0:119624335925 | 187 | current_timer->timer_state = NS_TIMER_ACTIVE; |
MACRUM | 0:119624335925 | 188 | } else { |
MACRUM | 0:119624335925 | 189 | current_timer->remaining_slots -= first_timer->remaining_slots; |
MACRUM | 0:119624335925 | 190 | /*Compensate time spent in timer function*/ |
MACRUM | 0:119624335925 | 191 | if (current_timer->remaining_slots > COMPENSATION) { |
MACRUM | 0:119624335925 | 192 | current_timer->remaining_slots -= COMPENSATION; |
MACRUM | 0:119624335925 | 193 | } |
MACRUM | 0:119624335925 | 194 | } |
MACRUM | 0:119624335925 | 195 | hold_count--; |
MACRUM | 0:119624335925 | 196 | } |
MACRUM | 0:119624335925 | 197 | } |
MACRUM | 0:119624335925 | 198 | |
MACRUM | 0:119624335925 | 199 | return 0; |
MACRUM | 0:119624335925 | 200 | } |
MACRUM | 0:119624335925 | 201 | |
MACRUM | 0:119624335925 | 202 | |
MACRUM | 0:119624335925 | 203 | static ns_timer_struct *ns_timer_get_pointer_to_timer_struct(int8_t timer_id) |
MACRUM | 0:119624335925 | 204 | { |
MACRUM | 0:119624335925 | 205 | /*Find timer with the given ID*/ |
MACRUM | 0:119624335925 | 206 | ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 207 | if (current_timer->ns_timer_id == timer_id) { |
MACRUM | 0:119624335925 | 208 | return current_timer; |
MACRUM | 0:119624335925 | 209 | } |
MACRUM | 0:119624335925 | 210 | } |
MACRUM | 0:119624335925 | 211 | return NULL; |
MACRUM | 0:119624335925 | 212 | } |
MACRUM | 0:119624335925 | 213 | |
MACRUM | 0:119624335925 | 214 | int8_t eventOS_callback_timer_start(int8_t ns_timer_id, uint16_t slots) |
MACRUM | 0:119624335925 | 215 | { |
MACRUM | 0:119624335925 | 216 | int8_t ret_val = 0; |
MACRUM | 0:119624335925 | 217 | uint16_t pl_timer_remaining_slots; |
MACRUM | 0:119624335925 | 218 | ns_timer_struct *timer; |
MACRUM | 0:119624335925 | 219 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 220 | |
MACRUM | 0:119624335925 | 221 | /*Find timer to be activated*/ |
MACRUM | 0:119624335925 | 222 | timer = ns_timer_get_pointer_to_timer_struct(ns_timer_id); |
MACRUM | 0:119624335925 | 223 | if (!timer) { |
MACRUM | 0:119624335925 | 224 | ret_val = -1; |
MACRUM | 0:119624335925 | 225 | goto exit; |
MACRUM | 0:119624335925 | 226 | } |
MACRUM | 0:119624335925 | 227 | |
MACRUM | 0:119624335925 | 228 | // XXX this assumes the timer currently isn't running? |
MACRUM | 0:119624335925 | 229 | // Is event.c relying on this restarting HAL timer after ns_timer_sleep()? |
MACRUM | 0:119624335925 | 230 | |
MACRUM | 0:119624335925 | 231 | /*If any timers are active*/ |
MACRUM | 0:119624335925 | 232 | if (ns_timer_state & NS_TIMER_RUNNING) { |
MACRUM | 0:119624335925 | 233 | /*Get remaining slots of the currently activated timeout*/ |
MACRUM | 0:119624335925 | 234 | pl_timer_remaining_slots = platform_timer_get_remaining_slots(); |
MACRUM | 0:119624335925 | 235 | |
MACRUM | 0:119624335925 | 236 | /*New timeout is shorter than currently enabled timeout*/ |
MACRUM | 0:119624335925 | 237 | if (pl_timer_remaining_slots > slots) { |
MACRUM | 0:119624335925 | 238 | /*Start HAL timer*/ |
MACRUM | 0:119624335925 | 239 | ns_timer_start_pl_timer(slots - 0); |
MACRUM | 0:119624335925 | 240 | |
MACRUM | 0:119624335925 | 241 | ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 242 | /*Switch active timers to hold*/ |
MACRUM | 0:119624335925 | 243 | if (current_timer->timer_state == NS_TIMER_ACTIVE) { |
MACRUM | 0:119624335925 | 244 | current_timer->timer_state = NS_TIMER_HOLD; |
MACRUM | 0:119624335925 | 245 | current_timer->remaining_slots = 0; |
MACRUM | 0:119624335925 | 246 | } |
MACRUM | 0:119624335925 | 247 | /*Update hold-labelled timers*/ |
MACRUM | 0:119624335925 | 248 | if (current_timer->timer_state == NS_TIMER_HOLD) { |
MACRUM | 0:119624335925 | 249 | current_timer->remaining_slots += (pl_timer_remaining_slots - slots); |
MACRUM | 0:119624335925 | 250 | /*Compensate time spent in timer function*/ |
MACRUM | 0:119624335925 | 251 | if (current_timer->remaining_slots > (COMPENSATION - COMPENSATION_TUNE)) { |
MACRUM | 0:119624335925 | 252 | current_timer->remaining_slots -= (COMPENSATION - COMPENSATION_TUNE); |
MACRUM | 0:119624335925 | 253 | } |
MACRUM | 0:119624335925 | 254 | } |
MACRUM | 0:119624335925 | 255 | } |
MACRUM | 0:119624335925 | 256 | /*Mark active and start the timer*/ |
MACRUM | 0:119624335925 | 257 | timer->timer_state = NS_TIMER_ACTIVE; |
MACRUM | 0:119624335925 | 258 | timer->slots = slots; |
MACRUM | 0:119624335925 | 259 | timer->remaining_slots = slots; |
MACRUM | 0:119624335925 | 260 | } |
MACRUM | 0:119624335925 | 261 | |
MACRUM | 0:119624335925 | 262 | /*New timeout is longer than currently enabled timeout*/ |
MACRUM | 0:119624335925 | 263 | else if (pl_timer_remaining_slots < slots) { |
MACRUM | 0:119624335925 | 264 | /*Mark hold and update remaining slots*/ |
MACRUM | 0:119624335925 | 265 | timer->timer_state = NS_TIMER_HOLD; |
MACRUM | 0:119624335925 | 266 | timer->slots = slots; |
MACRUM | 0:119624335925 | 267 | timer->remaining_slots = (slots - pl_timer_remaining_slots); |
MACRUM | 0:119624335925 | 268 | } |
MACRUM | 0:119624335925 | 269 | /*New timeout is equal to currently enabled timeout*/ |
MACRUM | 0:119624335925 | 270 | else { |
MACRUM | 0:119624335925 | 271 | /*Mark it active and it will be handled in next interrupt*/ |
MACRUM | 0:119624335925 | 272 | timer->timer_state = NS_TIMER_ACTIVE; |
MACRUM | 0:119624335925 | 273 | timer->slots = slots; |
MACRUM | 0:119624335925 | 274 | timer->remaining_slots = slots; |
MACRUM | 0:119624335925 | 275 | } |
MACRUM | 0:119624335925 | 276 | } else { |
MACRUM | 0:119624335925 | 277 | /*No timers running*/ |
MACRUM | 0:119624335925 | 278 | timer->timer_state = NS_TIMER_HOLD; |
MACRUM | 0:119624335925 | 279 | timer->slots = slots; |
MACRUM | 0:119624335925 | 280 | timer->remaining_slots = slots; |
MACRUM | 0:119624335925 | 281 | /*Start next timeout*/ |
MACRUM | 0:119624335925 | 282 | ns_timer_get_next_running_to(); |
MACRUM | 0:119624335925 | 283 | } |
MACRUM | 0:119624335925 | 284 | exit: |
MACRUM | 0:119624335925 | 285 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 286 | return ret_val; |
MACRUM | 0:119624335925 | 287 | } |
MACRUM | 0:119624335925 | 288 | |
MACRUM | 0:119624335925 | 289 | static void ns_timer_interrupt_handler(void) |
MACRUM | 0:119624335925 | 290 | { |
MACRUM | 0:119624335925 | 291 | uint8_t i = 0; |
MACRUM | 0:119624335925 | 292 | |
MACRUM | 0:119624335925 | 293 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 294 | /*Clear timer running state*/ |
MACRUM | 0:119624335925 | 295 | ns_timer_state &= ~NS_TIMER_RUNNING; |
MACRUM | 0:119624335925 | 296 | /*Mark active timers as NS_TIMER_RUN_INTERRUPT, interrupt functions are called at the end of this function*/ |
MACRUM | 0:119624335925 | 297 | ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 298 | if (current_timer->timer_state == NS_TIMER_ACTIVE) { |
MACRUM | 0:119624335925 | 299 | current_timer->timer_state = NS_TIMER_RUN_INTERRUPT; |
MACRUM | 0:119624335925 | 300 | /*For optimisation, count the found timers*/ |
MACRUM | 0:119624335925 | 301 | i++; |
MACRUM | 0:119624335925 | 302 | } |
MACRUM | 0:119624335925 | 303 | } |
MACRUM | 0:119624335925 | 304 | |
MACRUM | 0:119624335925 | 305 | /*Start next timeout*/ |
MACRUM | 0:119624335925 | 306 | ns_timer_get_next_running_to(); |
MACRUM | 0:119624335925 | 307 | |
MACRUM | 0:119624335925 | 308 | /*Call interrupt functions*/ |
MACRUM | 0:119624335925 | 309 | ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 310 | if (i == 0) { |
MACRUM | 0:119624335925 | 311 | break; |
MACRUM | 0:119624335925 | 312 | } |
MACRUM | 0:119624335925 | 313 | if (current_timer->timer_state == NS_TIMER_RUN_INTERRUPT) { |
MACRUM | 0:119624335925 | 314 | current_timer->timer_state = NS_TIMER_STOP; |
MACRUM | 0:119624335925 | 315 | current_timer->interrupt_handler(current_timer->ns_timer_id, current_timer->slots); |
MACRUM | 0:119624335925 | 316 | i--; |
MACRUM | 0:119624335925 | 317 | } |
MACRUM | 0:119624335925 | 318 | } |
MACRUM | 0:119624335925 | 319 | |
MACRUM | 0:119624335925 | 320 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 321 | } |
MACRUM | 0:119624335925 | 322 | |
MACRUM | 0:119624335925 | 323 | int8_t eventOS_callback_timer_stop(int8_t ns_timer_id) |
MACRUM | 0:119624335925 | 324 | { |
MACRUM | 0:119624335925 | 325 | uint16_t pl_timer_remaining_slots; |
MACRUM | 0:119624335925 | 326 | bool active_timer_found = false; |
MACRUM | 0:119624335925 | 327 | ns_timer_struct *current_timer; |
MACRUM | 0:119624335925 | 328 | ns_timer_struct *first_timer = NULL; |
MACRUM | 0:119624335925 | 329 | int8_t retval = -1; |
MACRUM | 0:119624335925 | 330 | |
MACRUM | 0:119624335925 | 331 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 332 | /*Find timer with given timer ID*/ |
MACRUM | 0:119624335925 | 333 | current_timer = ns_timer_get_pointer_to_timer_struct(ns_timer_id); |
MACRUM | 0:119624335925 | 334 | if (!current_timer) { |
MACRUM | 0:119624335925 | 335 | goto exit; |
MACRUM | 0:119624335925 | 336 | } |
MACRUM | 0:119624335925 | 337 | |
MACRUM | 0:119624335925 | 338 | retval = 0; |
MACRUM | 0:119624335925 | 339 | |
MACRUM | 0:119624335925 | 340 | /*Check if already stopped*/ |
MACRUM | 0:119624335925 | 341 | if (current_timer->timer_state == NS_TIMER_STOP) { |
MACRUM | 0:119624335925 | 342 | goto exit; |
MACRUM | 0:119624335925 | 343 | } |
MACRUM | 0:119624335925 | 344 | |
MACRUM | 0:119624335925 | 345 | current_timer->timer_state = NS_TIMER_STOP; |
MACRUM | 0:119624335925 | 346 | current_timer->remaining_slots = 0; |
MACRUM | 0:119624335925 | 347 | |
MACRUM | 0:119624335925 | 348 | /*Check if some timer is already active*/ |
MACRUM | 0:119624335925 | 349 | ns_list_foreach(ns_timer_struct, curr_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 350 | if (curr_timer->timer_state == NS_TIMER_ACTIVE) { |
MACRUM | 0:119624335925 | 351 | active_timer_found = true; |
MACRUM | 0:119624335925 | 352 | break; |
MACRUM | 0:119624335925 | 353 | } |
MACRUM | 0:119624335925 | 354 | } |
MACRUM | 0:119624335925 | 355 | /*If no active timers found, start one*/ |
MACRUM | 0:119624335925 | 356 | if (!active_timer_found) { |
MACRUM | 0:119624335925 | 357 | pl_timer_remaining_slots = platform_timer_get_remaining_slots(); |
MACRUM | 0:119624335925 | 358 | /*Find hold-labelled timer with the least remaining slots*/ |
MACRUM | 0:119624335925 | 359 | ns_list_foreach(ns_timer_struct, cur_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 360 | if (cur_timer->timer_state == NS_TIMER_HOLD) { |
MACRUM | 0:119624335925 | 361 | cur_timer->remaining_slots += pl_timer_remaining_slots; |
MACRUM | 0:119624335925 | 362 | |
MACRUM | 0:119624335925 | 363 | if (!first_timer || cur_timer->remaining_slots < first_timer->remaining_slots) { |
MACRUM | 0:119624335925 | 364 | first_timer = cur_timer; |
MACRUM | 0:119624335925 | 365 | } |
MACRUM | 0:119624335925 | 366 | } |
MACRUM | 0:119624335925 | 367 | } |
MACRUM | 0:119624335925 | 368 | /*If hold-labelled timer found, set it active and start the HAL driver*/ |
MACRUM | 0:119624335925 | 369 | if (first_timer) { |
MACRUM | 0:119624335925 | 370 | first_timer->timer_state = NS_TIMER_ACTIVE; |
MACRUM | 0:119624335925 | 371 | /*Start HAL timer*/ |
MACRUM | 0:119624335925 | 372 | ns_timer_start_pl_timer(first_timer->remaining_slots); |
MACRUM | 0:119624335925 | 373 | /*If some of the other hold-labelled timers have the same remaining slots as the timer_tmp, mark them active*/ |
MACRUM | 0:119624335925 | 374 | ns_list_foreach(ns_timer_struct, cur_timer, &ns_timer_list) { |
MACRUM | 0:119624335925 | 375 | if (cur_timer->timer_state == NS_TIMER_HOLD) { |
MACRUM | 0:119624335925 | 376 | if (cur_timer->remaining_slots == first_timer->remaining_slots) { |
MACRUM | 0:119624335925 | 377 | cur_timer->timer_state = NS_TIMER_ACTIVE; |
MACRUM | 0:119624335925 | 378 | } else { |
MACRUM | 0:119624335925 | 379 | cur_timer->remaining_slots -= first_timer->remaining_slots; |
MACRUM | 0:119624335925 | 380 | } |
MACRUM | 0:119624335925 | 381 | } |
MACRUM | 0:119624335925 | 382 | } |
MACRUM | 0:119624335925 | 383 | } |
MACRUM | 0:119624335925 | 384 | } |
MACRUM | 0:119624335925 | 385 | |
MACRUM | 0:119624335925 | 386 | exit: |
MACRUM | 0:119624335925 | 387 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 388 | |
MACRUM | 0:119624335925 | 389 | return retval; |
MACRUM | 0:119624335925 | 390 | } |
MACRUM | 0:119624335925 | 391 | #endif // NS_EXCLUDE_HIGHRES_TIMER |