Example

Dependencies:   FXAS21002 FXOS8700Q

Committer:
maygup01
Date:
Tue Nov 19 09:49:38 2019 +0000
Revision:
0:11cc2b7889af
Example

Who changed what in which revision?

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