leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Committer:
leothedragon
Date:
Tue May 04 08:55:12 2021 +0000
Revision:
0:8f0bb79ddd48
nmn

Who changed what in which revision?

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