00001
00021
00022
00023
00024
00025 #include <stddef.h>
00026 #include "co_int.h"
00027 #include "co_bool.h"
00028 #include "dbg_assert.h"
00029
00030 #include "ke_config.h"
00031 #include "ke_mem.h"
00032 #include "ke_env.h"
00033 #include "ke_event.h"
00034 #include "ke_timer.h"
00035 #include "ke_task.h"
00036 #include "dbg.h"
00037
00038 #include "hal_machw.h"
00039
00040
00048 static void ke_timer_hw_set(struct ke_timer *timer)
00049 {
00050 GLOBAL_INT_DISABLE();
00051 if (timer)
00052 {
00053 uint32_t timer_msk;
00054
00055
00056 nxmac_abs_timer_set(HAL_KE_TIMER, timer->time);
00057
00058
00059 timer_msk = nxmac_timers_int_un_mask_get();
00060 if (!(timer_msk & HAL_KE_TIMER_BIT))
00061 {
00062
00063
00064 nxmac_timers_int_event_clear(HAL_KE_TIMER_BIT);
00065 nxmac_timers_int_un_mask_set(timer_msk | HAL_KE_TIMER_BIT);
00066 }
00067 }
00068 else
00069 {
00070
00071 nxmac_timers_int_un_mask_set(nxmac_timers_int_un_mask_get() & ~HAL_KE_TIMER_BIT);
00072 }
00073 GLOBAL_INT_RESTORE();
00074 }
00075
00086 static bool cmp_abs_time(struct co_list_hdr const * timerA, struct co_list_hdr const * timerB)
00087 {
00088 uint32_t timeA = ((struct ke_timer*)timerA)->time;
00089 uint32_t timeB = ((struct ke_timer*)timerB)->time;
00090
00091 return (((uint32_t)(timeA - timeB)) > KE_TIMER_DELAY_MAX);
00092 }
00093
00104 static bool cmp_timer_id(struct co_list_hdr const * timer, uint32_t timer_task)
00105 {
00106
00107 ke_msg_id_t timer_id = timer_task >> 16;
00108 ke_task_id_t task_id = timer_task & 0xFFFF;
00109
00110
00111 return (timer_id == ((struct ke_timer*)timer)->id)
00112 && (task_id == ((struct ke_timer*)timer)->task);
00113 }
00114
00115
00135 void ke_timer_set(ke_msg_id_t const timer_id,
00136 ke_task_id_t const task_id,
00137 uint32_t const delay)
00138 {
00139 bool hw_prog = false;
00140
00141
00142 ASSERT_ERR(delay > 0);
00143 ASSERT_ERR(delay < KE_TIMER_DELAY_MAX);
00144
00145
00146 struct ke_timer *first = (struct ke_timer *) ke_env.queue_timer.first;
00147 if (first && (first->id == timer_id) && (first->task == task_id))
00148
00149 hw_prog = true;
00150
00151
00152 struct ke_timer *timer = (struct ke_timer*)
00153 ke_queue_extract(&ke_env.queue_timer, cmp_timer_id, (uint32_t)timer_id << 16 | task_id);
00154
00155 if (timer == NULL)
00156 {
00157
00158 timer = (struct ke_timer*) ke_malloc(sizeof(struct ke_timer));
00159 ASSERT_ERR(timer);
00160 timer->id = timer_id;
00161 timer->task = task_id;
00162 }
00163
00164
00165 uint32_t abs_time = ke_time() + delay;
00166 timer->time = abs_time;
00167
00168
00169 co_list_insert(&ke_env.queue_timer,
00170 (struct co_list_hdr*) timer,
00171 cmp_abs_time);
00172
00173
00174 if (hw_prog || (ke_env.queue_timer.first == (struct co_list_hdr*) timer))
00175 {
00176 ke_timer_hw_set((struct ke_timer *)ke_env.queue_timer.first);
00177 }
00178
00179
00180 if (ke_time_past(abs_time))
00181 {
00182
00183 ke_evt_set(KE_EVT_KE_TIMER_BIT);
00184 }
00185 }
00186
00187
00199 void ke_timer_clear(ke_msg_id_t const timer_id,
00200 ke_task_id_t const task_id)
00201 {
00202 struct ke_timer *timer = (struct ke_timer *) ke_env.queue_timer.first;
00203
00204 if (ke_env.queue_timer.first != NULL)
00205 {
00206 if ((timer->id == timer_id) && (timer->task == task_id))
00207 {
00208
00209 ke_queue_pop(&ke_env.queue_timer);
00210
00211 struct ke_timer *first = (struct ke_timer *) ke_env.queue_timer.first;
00212
00213
00214 ke_timer_hw_set(first);
00215
00216
00217 ASSERT_ERR(!first || !ke_time_past(first->time));
00218 }
00219 else
00220 {
00221 timer = (struct ke_timer *)
00222 ke_queue_extract(&ke_env.queue_timer, cmp_timer_id,
00223 (uint32_t)timer_id << 16 | task_id);
00224 }
00225
00226 if (timer != NULL)
00227 {
00228
00229 ke_free(timer);
00230 }
00231 }
00232 }
00233
00234
00248 void ke_timer_schedule(int dummy)
00249 {
00250 struct ke_timer *timer;
00251
00252 for(;;)
00253 {
00254 ke_evt_clear(KE_EVT_KE_TIMER_BIT);
00255
00256
00257 timer = (struct ke_timer*) ke_env.queue_timer.first;
00258
00259 if (!timer)
00260 {
00261
00262 ke_timer_hw_set(NULL);
00263 break;
00264 }
00265
00266 if (!ke_time_past(timer->time - 50))
00267 {
00268
00269 ke_timer_hw_set(timer);
00270
00271
00272
00273
00274 if (!ke_time_past(timer->time))
00275 break;
00276 }
00277
00278
00279 timer = (struct ke_timer*) ke_queue_pop(&ke_env.queue_timer);
00280
00281
00282 ke_msg_send_basic(timer->id, timer->task, TASK_NONE);
00283
00284
00285 ke_free(timer);
00286 }
00287
00288
00289 }
00304 bool ke_timer_active(ke_msg_id_t const timer_id, ke_task_id_t const task_id)
00305 {
00306 struct ke_timer *timer;
00307 bool result;
00308
00309
00310 timer = (struct ke_timer*) ke_env.queue_timer.first;
00311
00312
00313 while (timer != NULL)
00314 {
00315 if ((timer->id == timer_id) &&
00316 (timer->task == task_id) )
00317 {
00318
00319 break;
00320 }
00321
00322
00323 timer = timer->next;
00324 }
00325
00326
00327 if (timer != NULL)
00328 result = true;
00329 else
00330 result = false;
00331
00332 return(result);
00333 }
00334
00340 void ke_timer_reset(void)
00341 {
00342 struct ke_timer *timer;
00343
00344
00345 nxmac_timers_int_un_mask_set(nxmac_timers_int_un_mask_get() & ~HAL_KE_TIMER_BIT);
00346
00347
00348 ke_evt_clear(KE_EVT_KE_TIMER_BIT);
00349
00350 for(;;)
00351 {
00352
00353 timer = (struct ke_timer*) ke_queue_pop(&ke_env.queue_timer);
00354 if (timer == NULL)
00355 break;
00356
00357
00358 ke_free(timer);
00359 }
00360 }
00361