Containers (STL-compatible) StateMachines MessageBus and more for Embedded Systems. See www.etlcpp.com

Committer:
bobbery
Date:
Fri Mar 16 16:34:18 2018 +0000
Revision:
0:b47c2a7920c2
Works after using gcc_generic undef CAPACITY and replacing nullptr by std::nullptr

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bobbery 0:b47c2a7920c2 1 /******************************************************************************
bobbery 0:b47c2a7920c2 2 The MIT License(MIT)
bobbery 0:b47c2a7920c2 3
bobbery 0:b47c2a7920c2 4 Embedded Template Library.
bobbery 0:b47c2a7920c2 5 https://github.com/ETLCPP/etl
bobbery 0:b47c2a7920c2 6 https://www.etlcpp.com
bobbery 0:b47c2a7920c2 7
bobbery 0:b47c2a7920c2 8 Copyright(c) 2017 jwellbelove
bobbery 0:b47c2a7920c2 9
bobbery 0:b47c2a7920c2 10 Permission is hereby granted, free of charge, to any person obtaining a copy
bobbery 0:b47c2a7920c2 11 of this software and associated documentation files(the "Software"), to deal
bobbery 0:b47c2a7920c2 12 in the Software without restriction, including without limitation the rights
bobbery 0:b47c2a7920c2 13 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
bobbery 0:b47c2a7920c2 14 copies of the Software, and to permit persons to whom the Software is
bobbery 0:b47c2a7920c2 15 furnished to do so, subject to the following conditions :
bobbery 0:b47c2a7920c2 16
bobbery 0:b47c2a7920c2 17 The above copyright notice and this permission notice shall be included in all
bobbery 0:b47c2a7920c2 18 copies or substantial portions of the Software.
bobbery 0:b47c2a7920c2 19
bobbery 0:b47c2a7920c2 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
bobbery 0:b47c2a7920c2 21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
bobbery 0:b47c2a7920c2 22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
bobbery 0:b47c2a7920c2 23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
bobbery 0:b47c2a7920c2 24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
bobbery 0:b47c2a7920c2 25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
bobbery 0:b47c2a7920c2 26 SOFTWARE.
bobbery 0:b47c2a7920c2 27 ******************************************************************************/
bobbery 0:b47c2a7920c2 28
bobbery 0:b47c2a7920c2 29 #include <stdint.h>
bobbery 0:b47c2a7920c2 30 #include <assert.h>
bobbery 0:b47c2a7920c2 31
bobbery 0:b47c2a7920c2 32 #include "ecl_timer.h"
bobbery 0:b47c2a7920c2 33
bobbery 0:b47c2a7920c2 34 //*****************************************************************************
bobbery 0:b47c2a7920c2 35 // Internal timer list
bobbery 0:b47c2a7920c2 36 //*****************************************************************************
bobbery 0:b47c2a7920c2 37
bobbery 0:b47c2a7920c2 38 static ecl_timer_id_t head;
bobbery 0:b47c2a7920c2 39 static ecl_timer_id_t tail;
bobbery 0:b47c2a7920c2 40 static ecl_timer_id_t current;
bobbery 0:b47c2a7920c2 41
bobbery 0:b47c2a7920c2 42 static struct ecl_timer_config* ptimers;
bobbery 0:b47c2a7920c2 43
bobbery 0:b47c2a7920c2 44 static void ecl_timer_list_init(struct ecl_timer_config* const ptimers_)
bobbery 0:b47c2a7920c2 45 {
bobbery 0:b47c2a7920c2 46 ptimers = ptimers_;
bobbery 0:b47c2a7920c2 47 head = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 48 tail = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 49 current = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 50 }
bobbery 0:b47c2a7920c2 51
bobbery 0:b47c2a7920c2 52 //*******************************
bobbery 0:b47c2a7920c2 53 static struct ecl_timer_config* ecl_timer_list_front()
bobbery 0:b47c2a7920c2 54 {
bobbery 0:b47c2a7920c2 55 return &ptimers[head];
bobbery 0:b47c2a7920c2 56 }
bobbery 0:b47c2a7920c2 57
bobbery 0:b47c2a7920c2 58 //*******************************
bobbery 0:b47c2a7920c2 59 static ecl_timer_id_t ecl_timer_list_begin()
bobbery 0:b47c2a7920c2 60 {
bobbery 0:b47c2a7920c2 61 current = head;
bobbery 0:b47c2a7920c2 62 return current;
bobbery 0:b47c2a7920c2 63 }
bobbery 0:b47c2a7920c2 64
bobbery 0:b47c2a7920c2 65 //*******************************
bobbery 0:b47c2a7920c2 66 static ecl_timer_id_t ecl_timer_list_next(ecl_timer_id_t last)
bobbery 0:b47c2a7920c2 67 {
bobbery 0:b47c2a7920c2 68 current = ptimers[last].next;
bobbery 0:b47c2a7920c2 69 return current;
bobbery 0:b47c2a7920c2 70 }
bobbery 0:b47c2a7920c2 71
bobbery 0:b47c2a7920c2 72 //*******************************
bobbery 0:b47c2a7920c2 73 static int ecl_timer_list_empty()
bobbery 0:b47c2a7920c2 74 {
bobbery 0:b47c2a7920c2 75 return head == ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 76 }
bobbery 0:b47c2a7920c2 77
bobbery 0:b47c2a7920c2 78 //*******************************
bobbery 0:b47c2a7920c2 79 // Inserts the timer at the correct delta position
bobbery 0:b47c2a7920c2 80 //*******************************
bobbery 0:b47c2a7920c2 81 static void ecl_timer_list_insert(ecl_timer_id_t id_)
bobbery 0:b47c2a7920c2 82 {
bobbery 0:b47c2a7920c2 83 struct ecl_timer_config* ptimer = &ptimers[id_];
bobbery 0:b47c2a7920c2 84
bobbery 0:b47c2a7920c2 85 if (head == ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 86 {
bobbery 0:b47c2a7920c2 87 // No entries yet.
bobbery 0:b47c2a7920c2 88 head = id_;
bobbery 0:b47c2a7920c2 89 tail = id_;
bobbery 0:b47c2a7920c2 90 ptimer->previous = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 91 ptimer->next = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 92 }
bobbery 0:b47c2a7920c2 93 else
bobbery 0:b47c2a7920c2 94 {
bobbery 0:b47c2a7920c2 95 // We already have entries.
bobbery 0:b47c2a7920c2 96 ecl_timer_id_t test_id = ecl_timer_list_begin();
bobbery 0:b47c2a7920c2 97
bobbery 0:b47c2a7920c2 98 while (test_id != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 99 {
bobbery 0:b47c2a7920c2 100 struct ecl_timer_config* ptest = &ptimers[test_id];
bobbery 0:b47c2a7920c2 101
bobbery 0:b47c2a7920c2 102 // Find the correct place to insert.
bobbery 0:b47c2a7920c2 103 if (ptimer->delta <= ptest->delta)
bobbery 0:b47c2a7920c2 104 {
bobbery 0:b47c2a7920c2 105 if (ptest->id == head)
bobbery 0:b47c2a7920c2 106 {
bobbery 0:b47c2a7920c2 107 head = ptimer->id;
bobbery 0:b47c2a7920c2 108 }
bobbery 0:b47c2a7920c2 109
bobbery 0:b47c2a7920c2 110 // Insert before ptest->
bobbery 0:b47c2a7920c2 111 ptimer->previous = ptest->previous;
bobbery 0:b47c2a7920c2 112 ptest->previous = ptimer->id;
bobbery 0:b47c2a7920c2 113 ptimer->next = ptest->id;
bobbery 0:b47c2a7920c2 114
bobbery 0:b47c2a7920c2 115 // Adjust the next delta to compensate.
bobbery 0:b47c2a7920c2 116 ptest->delta -= ptimer->delta;
bobbery 0:b47c2a7920c2 117
bobbery 0:b47c2a7920c2 118 if (ptimer->previous != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 119 {
bobbery 0:b47c2a7920c2 120 ptimers[ptimer->previous].next = ptimer->id;
bobbery 0:b47c2a7920c2 121 }
bobbery 0:b47c2a7920c2 122 break;
bobbery 0:b47c2a7920c2 123 }
bobbery 0:b47c2a7920c2 124 else
bobbery 0:b47c2a7920c2 125 {
bobbery 0:b47c2a7920c2 126 ptimer->delta -= ptest->delta;
bobbery 0:b47c2a7920c2 127 }
bobbery 0:b47c2a7920c2 128
bobbery 0:b47c2a7920c2 129 test_id = ecl_timer_list_next(test_id);
bobbery 0:b47c2a7920c2 130 }
bobbery 0:b47c2a7920c2 131
bobbery 0:b47c2a7920c2 132 // Reached the end?
bobbery 0:b47c2a7920c2 133 if (test_id == ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 134 {
bobbery 0:b47c2a7920c2 135 // Tag on to the tail.
bobbery 0:b47c2a7920c2 136 ptimers[tail].next = ptimer->id;
bobbery 0:b47c2a7920c2 137 ptimer->previous = tail;
bobbery 0:b47c2a7920c2 138 ptimer->next = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 139 tail = ptimer->id;
bobbery 0:b47c2a7920c2 140 }
bobbery 0:b47c2a7920c2 141 }
bobbery 0:b47c2a7920c2 142 }
bobbery 0:b47c2a7920c2 143
bobbery 0:b47c2a7920c2 144 //*******************************
bobbery 0:b47c2a7920c2 145 static void ecl_timer_list_remove(ecl_timer_id_t id_, int has_expired)
bobbery 0:b47c2a7920c2 146 {
bobbery 0:b47c2a7920c2 147 struct ecl_timer_config* ptimer = &ptimers[id_];
bobbery 0:b47c2a7920c2 148
bobbery 0:b47c2a7920c2 149 if (head == id_)
bobbery 0:b47c2a7920c2 150 {
bobbery 0:b47c2a7920c2 151 head = ptimer->next;
bobbery 0:b47c2a7920c2 152 }
bobbery 0:b47c2a7920c2 153 else
bobbery 0:b47c2a7920c2 154 {
bobbery 0:b47c2a7920c2 155 ptimers[ptimer->previous].next = ptimer->next;
bobbery 0:b47c2a7920c2 156 }
bobbery 0:b47c2a7920c2 157
bobbery 0:b47c2a7920c2 158 if (tail == id_)
bobbery 0:b47c2a7920c2 159 {
bobbery 0:b47c2a7920c2 160 tail = ptimer->previous;
bobbery 0:b47c2a7920c2 161 }
bobbery 0:b47c2a7920c2 162 else
bobbery 0:b47c2a7920c2 163 {
bobbery 0:b47c2a7920c2 164 ptimers[ptimer->next].previous = ptimer->previous;
bobbery 0:b47c2a7920c2 165 }
bobbery 0:b47c2a7920c2 166
bobbery 0:b47c2a7920c2 167 if (!has_expired)
bobbery 0:b47c2a7920c2 168 {
bobbery 0:b47c2a7920c2 169 // Adjust the next delta.
bobbery 0:b47c2a7920c2 170 if (ptimer->next != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 171 {
bobbery 0:b47c2a7920c2 172 ptimers[ptimer->next].delta += ptimer->delta;
bobbery 0:b47c2a7920c2 173 }
bobbery 0:b47c2a7920c2 174 }
bobbery 0:b47c2a7920c2 175
bobbery 0:b47c2a7920c2 176 ptimer->previous = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 177 ptimer->next = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 178 ptimer->delta = ECL_TIMER_INACTIVE;
bobbery 0:b47c2a7920c2 179 }
bobbery 0:b47c2a7920c2 180
bobbery 0:b47c2a7920c2 181 //*******************************
bobbery 0:b47c2a7920c2 182 static void ecl_timer_list_clear()
bobbery 0:b47c2a7920c2 183 {
bobbery 0:b47c2a7920c2 184 ecl_timer_id_t id = ecl_timer_list_begin();
bobbery 0:b47c2a7920c2 185
bobbery 0:b47c2a7920c2 186 while (id != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 187 {
bobbery 0:b47c2a7920c2 188 struct ecl_timer_config* ptimer = &ptimers[id];
bobbery 0:b47c2a7920c2 189 id = ecl_timer_list_next(id);
bobbery 0:b47c2a7920c2 190 ptimer->next = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 191 }
bobbery 0:b47c2a7920c2 192
bobbery 0:b47c2a7920c2 193 head = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 194 tail = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 195 current = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 196 }
bobbery 0:b47c2a7920c2 197
bobbery 0:b47c2a7920c2 198 //*****************************************************************************
bobbery 0:b47c2a7920c2 199 // Timer Framework
bobbery 0:b47c2a7920c2 200 //*****************************************************************************
bobbery 0:b47c2a7920c2 201
bobbery 0:b47c2a7920c2 202 //*******************************************
bobbery 0:b47c2a7920c2 203 /// Default initialisation.
bobbery 0:b47c2a7920c2 204 //*******************************************
bobbery 0:b47c2a7920c2 205 void ecl_timer_data_init_default(struct ecl_timer_config* ptimer_data_)
bobbery 0:b47c2a7920c2 206 {
bobbery 0:b47c2a7920c2 207 assert(ptimer_data_ != 0);
bobbery 0:b47c2a7920c2 208
bobbery 0:b47c2a7920c2 209 ptimer_data_->pcallback = 0;
bobbery 0:b47c2a7920c2 210 ptimer_data_->period = 0;
bobbery 0:b47c2a7920c2 211 ptimer_data_->delta = ECL_TIMER_INACTIVE;
bobbery 0:b47c2a7920c2 212 ptimer_data_->id = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 213 ptimer_data_->previous = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 214 ptimer_data_->next = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 215 ptimer_data_->repeating = ECL_TIMER_REPEATING;
bobbery 0:b47c2a7920c2 216 }
bobbery 0:b47c2a7920c2 217
bobbery 0:b47c2a7920c2 218 //*******************************************
bobbery 0:b47c2a7920c2 219 /// Parameterised initialisation.
bobbery 0:b47c2a7920c2 220 //*******************************************
bobbery 0:b47c2a7920c2 221 void ecl_timer_data_init(struct ecl_timer_config* ptimer_data_,
bobbery 0:b47c2a7920c2 222 ecl_timer_id_t id_,
bobbery 0:b47c2a7920c2 223 void (*pcallback_)(),
bobbery 0:b47c2a7920c2 224 ecl_timer_time_t period_,
bobbery 0:b47c2a7920c2 225 ecl_timer_mode_t repeating_)
bobbery 0:b47c2a7920c2 226 {
bobbery 0:b47c2a7920c2 227 assert(ptimer_data_ != 0);
bobbery 0:b47c2a7920c2 228 assert(pcallback_ != 0);
bobbery 0:b47c2a7920c2 229
bobbery 0:b47c2a7920c2 230 ptimer_data_->pcallback = pcallback_;
bobbery 0:b47c2a7920c2 231 ptimer_data_->period = period_;
bobbery 0:b47c2a7920c2 232 ptimer_data_->delta = ECL_TIMER_INACTIVE;
bobbery 0:b47c2a7920c2 233 ptimer_data_->id = id_;
bobbery 0:b47c2a7920c2 234 ptimer_data_->previous = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 235 ptimer_data_->next = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 236 ptimer_data_->repeating = repeating_;
bobbery 0:b47c2a7920c2 237 }
bobbery 0:b47c2a7920c2 238
bobbery 0:b47c2a7920c2 239 //*******************************************
bobbery 0:b47c2a7920c2 240 /// Returns true if the timer is active.
bobbery 0:b47c2a7920c2 241 //*******************************************
bobbery 0:b47c2a7920c2 242 ecl_timer_result_t ecl_timer_is_active(struct ecl_timer_config* ptimer_data_)
bobbery 0:b47c2a7920c2 243 {
bobbery 0:b47c2a7920c2 244 assert(ptimer_data_ != 0);
bobbery 0:b47c2a7920c2 245
bobbery 0:b47c2a7920c2 246 return (ptimer_data_->delta != ECL_TIMER_INACTIVE) ? ECL_TIMER_PASS : ECL_TIMER_FAIL;
bobbery 0:b47c2a7920c2 247 }
bobbery 0:b47c2a7920c2 248
bobbery 0:b47c2a7920c2 249 //*******************************************
bobbery 0:b47c2a7920c2 250 /// Sets the timer to the inactive state.
bobbery 0:b47c2a7920c2 251 //*******************************************
bobbery 0:b47c2a7920c2 252 void ecl_set_timer_inactive(struct ecl_timer_config* ptimer_data_)
bobbery 0:b47c2a7920c2 253 {
bobbery 0:b47c2a7920c2 254 assert(ptimer_data_ != 0);
bobbery 0:b47c2a7920c2 255
bobbery 0:b47c2a7920c2 256 ptimer_data_->delta = ECL_TIMER_INACTIVE;
bobbery 0:b47c2a7920c2 257 }
bobbery 0:b47c2a7920c2 258
bobbery 0:b47c2a7920c2 259 struct ecl_time_config
bobbery 0:b47c2a7920c2 260 {
bobbery 0:b47c2a7920c2 261 struct ecl_timer_config* ptimers;
bobbery 0:b47c2a7920c2 262 uint_least8_t max_timers;
bobbery 0:b47c2a7920c2 263 volatile ecl_timer_enable_t enabled;
bobbery 0:b47c2a7920c2 264 ECL_TIMER_TIMER_SEMAPHORE process_semaphore;
bobbery 0:b47c2a7920c2 265 volatile uint_least8_t registered_timers;
bobbery 0:b47c2a7920c2 266 };
bobbery 0:b47c2a7920c2 267
bobbery 0:b47c2a7920c2 268 static struct ecl_time_config ecl;
bobbery 0:b47c2a7920c2 269
bobbery 0:b47c2a7920c2 270 void ecl_timer_init(struct ecl_timer_config* ptimers_, uint_least8_t max_timers_)
bobbery 0:b47c2a7920c2 271 {
bobbery 0:b47c2a7920c2 272 assert(ptimers_ != 0);
bobbery 0:b47c2a7920c2 273
bobbery 0:b47c2a7920c2 274 ecl.ptimers = ptimers_;
bobbery 0:b47c2a7920c2 275 ecl.max_timers = max_timers_;
bobbery 0:b47c2a7920c2 276 ecl.enabled = 0;
bobbery 0:b47c2a7920c2 277 ecl.process_semaphore = 0;
bobbery 0:b47c2a7920c2 278 ecl.registered_timers = 0;
bobbery 0:b47c2a7920c2 279
bobbery 0:b47c2a7920c2 280 int i;
bobbery 0:b47c2a7920c2 281 for (i = 0; i < max_timers_; ++i)
bobbery 0:b47c2a7920c2 282 {
bobbery 0:b47c2a7920c2 283 ecl_timer_data_init_default(&ecl.ptimers[i]);
bobbery 0:b47c2a7920c2 284 }
bobbery 0:b47c2a7920c2 285
bobbery 0:b47c2a7920c2 286 ecl_timer_list_init(ecl.ptimers);
bobbery 0:b47c2a7920c2 287 }
bobbery 0:b47c2a7920c2 288
bobbery 0:b47c2a7920c2 289 //*******************************************
bobbery 0:b47c2a7920c2 290 /// Register a ptimer->
bobbery 0:b47c2a7920c2 291 //*******************************************
bobbery 0:b47c2a7920c2 292 ecl_timer_id_t ecl_timer_register(void (*pcallback_)(),
bobbery 0:b47c2a7920c2 293 ecl_timer_time_t period_,
bobbery 0:b47c2a7920c2 294 ecl_timer_mode_t repeating_)
bobbery 0:b47c2a7920c2 295 {
bobbery 0:b47c2a7920c2 296 assert(pcallback_ != 0);
bobbery 0:b47c2a7920c2 297 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 298
bobbery 0:b47c2a7920c2 299 ecl_timer_id_t id = ECL_TIMER_NO_TIMER;
bobbery 0:b47c2a7920c2 300
bobbery 0:b47c2a7920c2 301 ECL_TIMER_DISABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 302
bobbery 0:b47c2a7920c2 303 int is_space = (ecl.registered_timers < ecl.max_timers);
bobbery 0:b47c2a7920c2 304
bobbery 0:b47c2a7920c2 305 if (is_space)
bobbery 0:b47c2a7920c2 306 {
bobbery 0:b47c2a7920c2 307 // Search for the free space.
bobbery 0:b47c2a7920c2 308 uint_least8_t i;
bobbery 0:b47c2a7920c2 309 for (i = 0; i < ecl.max_timers; ++i)
bobbery 0:b47c2a7920c2 310 {
bobbery 0:b47c2a7920c2 311 struct ecl_timer_config* ptimer = &ecl.ptimers[i];
bobbery 0:b47c2a7920c2 312
bobbery 0:b47c2a7920c2 313 if (ptimer->id == ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 314 {
bobbery 0:b47c2a7920c2 315 // Create in-place.
bobbery 0:b47c2a7920c2 316 ecl_timer_data_init(ptimer, i, pcallback_, period_, repeating_);
bobbery 0:b47c2a7920c2 317 ++ecl.registered_timers;
bobbery 0:b47c2a7920c2 318 id = i;
bobbery 0:b47c2a7920c2 319 break;
bobbery 0:b47c2a7920c2 320 }
bobbery 0:b47c2a7920c2 321 }
bobbery 0:b47c2a7920c2 322 }
bobbery 0:b47c2a7920c2 323
bobbery 0:b47c2a7920c2 324 ECL_TIMER_ENABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 325
bobbery 0:b47c2a7920c2 326 return id;
bobbery 0:b47c2a7920c2 327 }
bobbery 0:b47c2a7920c2 328
bobbery 0:b47c2a7920c2 329 //*******************************************
bobbery 0:b47c2a7920c2 330 /// Unregister a ptimer->
bobbery 0:b47c2a7920c2 331 //*******************************************
bobbery 0:b47c2a7920c2 332 ecl_timer_result_t ecl_timer_unregister(ecl_timer_id_t id_)
bobbery 0:b47c2a7920c2 333 {
bobbery 0:b47c2a7920c2 334 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 335
bobbery 0:b47c2a7920c2 336 ecl_timer_result_t result = ECL_TIMER_FAIL;
bobbery 0:b47c2a7920c2 337
bobbery 0:b47c2a7920c2 338 if (id_ != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 339 {
bobbery 0:b47c2a7920c2 340 ECL_TIMER_DISABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 341
bobbery 0:b47c2a7920c2 342 struct ecl_timer_config* ptimer = &ecl.ptimers[id_];
bobbery 0:b47c2a7920c2 343
bobbery 0:b47c2a7920c2 344 if (ptimer->id != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 345 {
bobbery 0:b47c2a7920c2 346 if (ecl_timer_is_active(ptimer))
bobbery 0:b47c2a7920c2 347 {
bobbery 0:b47c2a7920c2 348 ecl_timer_list_remove(ptimer->id, 0);
bobbery 0:b47c2a7920c2 349
bobbery 0:b47c2a7920c2 350 // Reset in-place.
bobbery 0:b47c2a7920c2 351 ecl_timer_data_init_default(ptimer);
bobbery 0:b47c2a7920c2 352 --ecl.registered_timers;
bobbery 0:b47c2a7920c2 353
bobbery 0:b47c2a7920c2 354 result = ECL_TIMER_PASS;
bobbery 0:b47c2a7920c2 355 }
bobbery 0:b47c2a7920c2 356 }
bobbery 0:b47c2a7920c2 357
bobbery 0:b47c2a7920c2 358 ECL_TIMER_ENABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 359 }
bobbery 0:b47c2a7920c2 360
bobbery 0:b47c2a7920c2 361 return result;
bobbery 0:b47c2a7920c2 362 }
bobbery 0:b47c2a7920c2 363
bobbery 0:b47c2a7920c2 364 //*******************************************
bobbery 0:b47c2a7920c2 365 /// Enable/disable the ptimer->
bobbery 0:b47c2a7920c2 366 //*******************************************
bobbery 0:b47c2a7920c2 367 void ecl_timer_enable(ecl_timer_enable_t state_)
bobbery 0:b47c2a7920c2 368 {
bobbery 0:b47c2a7920c2 369 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 370 assert((state_ == ECL_TIMER_ENABLED) || (state_ == ECL_TIMER_DISABLED));
bobbery 0:b47c2a7920c2 371
bobbery 0:b47c2a7920c2 372 ecl.enabled = state_;
bobbery 0:b47c2a7920c2 373 }
bobbery 0:b47c2a7920c2 374
bobbery 0:b47c2a7920c2 375 //*******************************************
bobbery 0:b47c2a7920c2 376 /// Get the enable/disable state.
bobbery 0:b47c2a7920c2 377 //*******************************************
bobbery 0:b47c2a7920c2 378 ecl_timer_result_t ecl_timer_is_running()
bobbery 0:b47c2a7920c2 379 {
bobbery 0:b47c2a7920c2 380 return ecl.enabled;
bobbery 0:b47c2a7920c2 381 }
bobbery 0:b47c2a7920c2 382
bobbery 0:b47c2a7920c2 383 //*******************************************
bobbery 0:b47c2a7920c2 384 /// Clears the timer of data.
bobbery 0:b47c2a7920c2 385 //*******************************************
bobbery 0:b47c2a7920c2 386 void ecl_timer_clear()
bobbery 0:b47c2a7920c2 387 {
bobbery 0:b47c2a7920c2 388 ECL_TIMER_DISABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 389
bobbery 0:b47c2a7920c2 390 ecl_timer_list_clear();
bobbery 0:b47c2a7920c2 391
bobbery 0:b47c2a7920c2 392 int i;
bobbery 0:b47c2a7920c2 393 for (i = 0; i < ecl.max_timers; ++i)
bobbery 0:b47c2a7920c2 394 {
bobbery 0:b47c2a7920c2 395 ecl_timer_data_init_default(&ecl.ptimers[i]);
bobbery 0:b47c2a7920c2 396 }
bobbery 0:b47c2a7920c2 397
bobbery 0:b47c2a7920c2 398 ecl.registered_timers = 0;
bobbery 0:b47c2a7920c2 399
bobbery 0:b47c2a7920c2 400 ECL_TIMER_ENABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 401 }
bobbery 0:b47c2a7920c2 402
bobbery 0:b47c2a7920c2 403 //*******************************************
bobbery 0:b47c2a7920c2 404 // Called by the timer service to indicate the
bobbery 0:b47c2a7920c2 405 // amount of time that has elapsed since the last successful call to 'tick'.
bobbery 0:b47c2a7920c2 406 // Returns true if the tick was processed, false if not.
bobbery 0:b47c2a7920c2 407 //*******************************************
bobbery 0:b47c2a7920c2 408 ecl_timer_result_t ecl_timer_tick(uint32_t count)
bobbery 0:b47c2a7920c2 409 {
bobbery 0:b47c2a7920c2 410 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 411
bobbery 0:b47c2a7920c2 412 if (ecl.enabled)
bobbery 0:b47c2a7920c2 413 {
bobbery 0:b47c2a7920c2 414 if (ECL_TIMER_PROCESSING_ENABLED(ecl.process_semaphore))
bobbery 0:b47c2a7920c2 415 {
bobbery 0:b47c2a7920c2 416 // We have something to do?
bobbery 0:b47c2a7920c2 417 int has_active = !ecl_timer_list_empty();
bobbery 0:b47c2a7920c2 418
bobbery 0:b47c2a7920c2 419 if (has_active)
bobbery 0:b47c2a7920c2 420 {
bobbery 0:b47c2a7920c2 421 while (has_active && (count >= ecl_timer_list_front()->delta))
bobbery 0:b47c2a7920c2 422 {
bobbery 0:b47c2a7920c2 423 struct ecl_timer_config* ptimer = ecl_timer_list_front();
bobbery 0:b47c2a7920c2 424
bobbery 0:b47c2a7920c2 425 count -= ptimer->delta;
bobbery 0:b47c2a7920c2 426
bobbery 0:b47c2a7920c2 427 ecl_timer_list_remove(ptimer->id, 1);
bobbery 0:b47c2a7920c2 428
bobbery 0:b47c2a7920c2 429 if (ptimer->repeating)
bobbery 0:b47c2a7920c2 430 {
bobbery 0:b47c2a7920c2 431 // Reinsert the ptimer->
bobbery 0:b47c2a7920c2 432 ptimer->delta = ptimer->period;
bobbery 0:b47c2a7920c2 433 ecl_timer_list_insert(ptimer->id);
bobbery 0:b47c2a7920c2 434 }
bobbery 0:b47c2a7920c2 435
bobbery 0:b47c2a7920c2 436 if (ptimer->pcallback != 0)
bobbery 0:b47c2a7920c2 437 {
bobbery 0:b47c2a7920c2 438 // Call the C callback.
bobbery 0:b47c2a7920c2 439 (ptimer->pcallback)();
bobbery 0:b47c2a7920c2 440 }
bobbery 0:b47c2a7920c2 441
bobbery 0:b47c2a7920c2 442 has_active = !ecl_timer_list_empty();
bobbery 0:b47c2a7920c2 443 }
bobbery 0:b47c2a7920c2 444
bobbery 0:b47c2a7920c2 445 if (has_active)
bobbery 0:b47c2a7920c2 446 {
bobbery 0:b47c2a7920c2 447 // Subtract any remainder from the next due timeout.
bobbery 0:b47c2a7920c2 448 ecl_timer_list_front()->delta -= count;
bobbery 0:b47c2a7920c2 449 }
bobbery 0:b47c2a7920c2 450 }
bobbery 0:b47c2a7920c2 451
bobbery 0:b47c2a7920c2 452 return ECL_TIMER_PASS;
bobbery 0:b47c2a7920c2 453 }
bobbery 0:b47c2a7920c2 454 }
bobbery 0:b47c2a7920c2 455
bobbery 0:b47c2a7920c2 456 return ECL_TIMER_FAIL;
bobbery 0:b47c2a7920c2 457 }
bobbery 0:b47c2a7920c2 458
bobbery 0:b47c2a7920c2 459 //*******************************************
bobbery 0:b47c2a7920c2 460 /// Starts a timer
bobbery 0:b47c2a7920c2 461 //*******************************************
bobbery 0:b47c2a7920c2 462 ecl_timer_result_t ecl_timer_start(ecl_timer_id_t id_, ecl_timer_start_t immediate_)
bobbery 0:b47c2a7920c2 463 {
bobbery 0:b47c2a7920c2 464 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 465
bobbery 0:b47c2a7920c2 466 ECL_TIMER_DISABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 467
bobbery 0:b47c2a7920c2 468 ecl_timer_result_t result = ECL_TIMER_FAIL;
bobbery 0:b47c2a7920c2 469
bobbery 0:b47c2a7920c2 470 // Valid timer id?
bobbery 0:b47c2a7920c2 471 if (id_ != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 472 {
bobbery 0:b47c2a7920c2 473 struct ecl_timer_config* ptimer = &ecl.ptimers[id_];
bobbery 0:b47c2a7920c2 474
bobbery 0:b47c2a7920c2 475 // Registered timer?
bobbery 0:b47c2a7920c2 476 if (ptimer->id != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 477 {
bobbery 0:b47c2a7920c2 478 // Has a valid period.
bobbery 0:b47c2a7920c2 479 if (ptimer->period != ECL_TIMER_INACTIVE)
bobbery 0:b47c2a7920c2 480 {
bobbery 0:b47c2a7920c2 481 if (ecl_timer_is_active(ptimer))
bobbery 0:b47c2a7920c2 482 {
bobbery 0:b47c2a7920c2 483 ecl_timer_list_remove(ptimer->id, 0);
bobbery 0:b47c2a7920c2 484 }
bobbery 0:b47c2a7920c2 485
bobbery 0:b47c2a7920c2 486 ptimer->delta = immediate_ ? 0 : ptimer->period;
bobbery 0:b47c2a7920c2 487 ecl_timer_list_insert(ptimer->id);
bobbery 0:b47c2a7920c2 488
bobbery 0:b47c2a7920c2 489 result = ECL_TIMER_PASS;
bobbery 0:b47c2a7920c2 490 }
bobbery 0:b47c2a7920c2 491 }
bobbery 0:b47c2a7920c2 492 }
bobbery 0:b47c2a7920c2 493
bobbery 0:b47c2a7920c2 494 ECL_TIMER_ENABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 495
bobbery 0:b47c2a7920c2 496 return result;
bobbery 0:b47c2a7920c2 497 }
bobbery 0:b47c2a7920c2 498
bobbery 0:b47c2a7920c2 499 //*******************************************
bobbery 0:b47c2a7920c2 500 /// Stops a timer
bobbery 0:b47c2a7920c2 501 //*******************************************
bobbery 0:b47c2a7920c2 502 ecl_timer_result_t ecl_timer_stop(ecl_timer_id_t id_)
bobbery 0:b47c2a7920c2 503 {
bobbery 0:b47c2a7920c2 504 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 505
bobbery 0:b47c2a7920c2 506 ECL_TIMER_DISABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 507
bobbery 0:b47c2a7920c2 508 ecl_timer_result_t result = ECL_TIMER_FAIL;
bobbery 0:b47c2a7920c2 509
bobbery 0:b47c2a7920c2 510 // Valid timer id?
bobbery 0:b47c2a7920c2 511 if (id_ != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 512 {
bobbery 0:b47c2a7920c2 513 struct ecl_timer_config* ptimer = &ecl.ptimers[id_];
bobbery 0:b47c2a7920c2 514
bobbery 0:b47c2a7920c2 515 // Registered timer?
bobbery 0:b47c2a7920c2 516 if (ptimer->id != ECL_TIMER_NO_TIMER)
bobbery 0:b47c2a7920c2 517 {
bobbery 0:b47c2a7920c2 518 if (ecl_timer_is_active(ptimer))
bobbery 0:b47c2a7920c2 519 {
bobbery 0:b47c2a7920c2 520 ecl_timer_list_remove(ptimer->id, 0);
bobbery 0:b47c2a7920c2 521 result = ECL_TIMER_PASS;
bobbery 0:b47c2a7920c2 522 }
bobbery 0:b47c2a7920c2 523 }
bobbery 0:b47c2a7920c2 524 }
bobbery 0:b47c2a7920c2 525
bobbery 0:b47c2a7920c2 526 ECL_TIMER_ENABLE_PROCESSING(ecl.process_semaphore);
bobbery 0:b47c2a7920c2 527
bobbery 0:b47c2a7920c2 528 return result;
bobbery 0:b47c2a7920c2 529 }
bobbery 0:b47c2a7920c2 530
bobbery 0:b47c2a7920c2 531 //*******************************************
bobbery 0:b47c2a7920c2 532 /// Sets a timer's period.
bobbery 0:b47c2a7920c2 533 //*******************************************
bobbery 0:b47c2a7920c2 534 ecl_timer_result_t ecl_timer_set_period(ecl_timer_id_t id_, ecl_timer_time_t period_)
bobbery 0:b47c2a7920c2 535 {
bobbery 0:b47c2a7920c2 536 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 537
bobbery 0:b47c2a7920c2 538 if (ecl_timer_stop(id_))
bobbery 0:b47c2a7920c2 539 {
bobbery 0:b47c2a7920c2 540 ecl.ptimers[id_].period = period_;
bobbery 0:b47c2a7920c2 541 return ecl_timer_start(id_, 0);
bobbery 0:b47c2a7920c2 542 }
bobbery 0:b47c2a7920c2 543
bobbery 0:b47c2a7920c2 544 return ECL_TIMER_FAIL;
bobbery 0:b47c2a7920c2 545 }
bobbery 0:b47c2a7920c2 546
bobbery 0:b47c2a7920c2 547 //*******************************************
bobbery 0:b47c2a7920c2 548 /// Sets a timer's mode.
bobbery 0:b47c2a7920c2 549 //*******************************************
bobbery 0:b47c2a7920c2 550 ecl_timer_result_t ecl_timer_set_mode(ecl_timer_id_t id_, ecl_timer_mode_t repeating_)
bobbery 0:b47c2a7920c2 551 {
bobbery 0:b47c2a7920c2 552 assert(ecl.ptimers != 0);
bobbery 0:b47c2a7920c2 553
bobbery 0:b47c2a7920c2 554 if (ecl_timer_stop(id_))
bobbery 0:b47c2a7920c2 555 {
bobbery 0:b47c2a7920c2 556 ecl.ptimers[id_].repeating = repeating_;
bobbery 0:b47c2a7920c2 557 return ecl_timer_start(id_, 0);
bobbery 0:b47c2a7920c2 558 }
bobbery 0:b47c2a7920c2 559
bobbery 0:b47c2a7920c2 560 return ECL_TIMER_FAIL;
bobbery 0:b47c2a7920c2 561 }
bobbery 0:b47c2a7920c2 562
bobbery 0:b47c2a7920c2 563
bobbery 0:b47c2a7920c2 564
bobbery 0:b47c2a7920c2 565
bobbery 0:b47c2a7920c2 566