Old version
Fork of nRF51822 by
Diff: nordic/app_common/app_timer.cpp
- Revision:
- 37:c29c330d942c
- Parent:
- 0:eff01767de02
- Child:
- 56:a1071b629aa3
--- a/nordic/app_common/app_timer.cpp Thu Jul 03 10:01:02 2014 +0100 +++ b/nordic/app_common/app_timer.cpp Mon Jul 07 13:43:31 2014 +0100 @@ -19,6 +19,7 @@ //#include "nrf_delay.h" #include "mbed.h" #include "app_util.h" +#include "app_util_platform.h" #define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOW /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */ @@ -217,7 +218,7 @@ static void timer_list_insert(app_timer_id_t timer_id) { timer_node_t * p_timer = &mp_nodes[timer_id]; - + if (m_timer_id_head == TIMER_NULL) { m_timer_id_head = timer_id; @@ -227,7 +228,7 @@ if (p_timer->ticks_to_expire <= mp_nodes[m_timer_id_head].ticks_to_expire) { mp_nodes[m_timer_id_head].ticks_to_expire -= p_timer->ticks_to_expire; - + p_timer->next = m_timer_id_head; m_timer_id_head = timer_id; } @@ -240,7 +241,7 @@ ticks_to_expire = p_timer->ticks_to_expire; previous = m_timer_id_head; current = m_timer_id_head; - + while ((current != TIMER_NULL) && (ticks_to_expire > mp_nodes[current].ticks_to_expire)) { ticks_to_expire -= mp_nodes[current].ticks_to_expire; @@ -274,7 +275,7 @@ // Find the timer's position in timer list previous = m_timer_id_head; current = previous; - + while (current != TIMER_NULL) { if (current == timer_id) @@ -351,44 +352,44 @@ */ static void timer_timeouts_check(void) { - // Handle expired of timer + // Handle expired of timer if (m_timer_id_head != TIMER_NULL) { app_timer_id_t timer_id; uint32_t ticks_elapsed; uint32_t ticks_expired; - // Initialize actual elapsed ticks being consumed to 0 + // Initialize actual elapsed ticks being consumed to 0 ticks_expired = 0; // ticks_elapsed is collected here, job will use it ticks_elapsed = ticks_diff_get(rtc1_counter_get(), m_ticks_latest); - // Auto variable containing the head of timers expiring + // Auto variable containing the head of timers expiring timer_id = m_timer_id_head; - // Expire all timers within ticks_elapsed and collect ticks_expired + // Expire all timers within ticks_elapsed and collect ticks_expired while (timer_id != TIMER_NULL) { timer_node_t * p_timer; - // Auto variable for current timer node + // Auto variable for current timer node p_timer = &mp_nodes[timer_id]; - // Do nothing if timer did not expire + // Do nothing if timer did not expire if (ticks_elapsed < p_timer->ticks_to_expire) { break; } - // Decrement ticks_elapsed and collect expired ticks + // Decrement ticks_elapsed and collect expired ticks ticks_elapsed -= p_timer->ticks_to_expire; ticks_expired += p_timer->ticks_to_expire; - // Move to next timer + // Move to next timer timer_id = p_timer->next; - // Execute Task + // Execute Task timeout_handler_exec(p_timer); } @@ -424,10 +425,10 @@ */ static bool elapsed_ticks_acquire(uint32_t * p_ticks_elapsed) { - // Pick the elapsed value from queue + // Pick the elapsed value from queue if (m_ticks_elapsed_q_read_ind != m_ticks_elapsed_q_write_ind) { - // Dequeue elapsed value + // Dequeue elapsed value m_ticks_elapsed_q_read_ind++; if (m_ticks_elapsed_q_read_ind == CONTEXT_QUEUE_SIZE_MAX) { @@ -443,7 +444,7 @@ } else { - // No elapsed value in queue + // No elapsed value in queue *p_ticks_elapsed = 0; return false; } @@ -467,13 +468,13 @@ { timer_user_t * p_user = &mp_users[user_id]; uint8_t user_ops_first = p_user->first; - + while (user_ops_first != p_user->last) { timer_node_t * p_timer; timer_user_op_t * p_user_op = &p_user->p_user_op_queue[user_ops_first]; - // Traverse to next operation in queue + // Traverse to next operation in queue user_ops_first++; if (user_ops_first == p_user->user_op_queue_size) { @@ -491,7 +492,7 @@ p_timer->is_running = false; } break; - + case TIMER_USER_OP_TYPE_STOP_ALL: // Delete list of running timers, and mark all timers as not running while (m_timer_id_head != TIMER_NULL) @@ -502,7 +503,7 @@ m_timer_id_head = p_head->next; } break; - + default: // No implementation needed. break; @@ -532,17 +533,17 @@ timer_node_t * p_timer; app_timer_id_t id_expired; - // Auto variable for current timer node + // Auto variable for current timer node p_timer = &mp_nodes[m_timer_id_head]; - // Do nothing if timer did not expire + // Do nothing if timer did not expire if (ticks_elapsed < p_timer->ticks_to_expire) { p_timer->ticks_to_expire -= ticks_elapsed; break; } - // Decrement ticks_elapsed and collect expired ticks + // Decrement ticks_elapsed and collect expired ticks ticks_elapsed -= p_timer->ticks_to_expire; ticks_expired += p_timer->ticks_to_expire; @@ -550,11 +551,11 @@ p_timer->ticks_to_expire = 0; p_timer->is_running = false; - // Remove the expired timer from head + // Remove the expired timer from head id_expired = m_timer_id_head; m_timer_id_head = p_timer->next; - // Timer will be restarted if periodic + // Timer will be restarted if periodic if (p_timer->ticks_periodic_interval != 0) { p_timer->ticks_at_start = (ticks_previous + ticks_expired) & MAX_RTC_COUNTER_VAL; @@ -585,7 +586,7 @@ { timer_user_t * p_user = &mp_users[user_id]; - // Handle insertions of timers + // Handle insertions of timers while ((restart_list_head != TIMER_NULL) || (p_user->first != p_user->last)) { app_timer_id_t id_start; @@ -621,14 +622,14 @@ p_timer->p_context = p_user_op->params.start.p_context; } - // Prepare the node to be inserted + // Prepare the node to be inserted if ( ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL) < (MAX_RTC_COUNTER_VAL / 2) ) { - p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) + + p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) + p_timer->ticks_first_interval; } else @@ -651,11 +652,11 @@ p_timer->is_running = true; p_timer->next = TIMER_NULL; - // Insert into list + // Insert into list timer_list_insert(id_start); } } - + return (m_timer_id_head != timer_id_old_head); } @@ -664,7 +665,7 @@ */ static void compare_reg_update(app_timer_id_t timer_id_head_old) { - // Setup the timeout for timers on the head of the list + // Setup the timeout for timers on the head of the list if (m_timer_id_head != TIMER_NULL) { uint32_t ticks_to_expire = mp_nodes[m_timer_id_head].ticks_to_expire; @@ -680,7 +681,7 @@ cc += (ticks_elapsed < ticks_to_expire) ? ticks_to_expire : ticks_elapsed; cc &= MAX_RTC_COUNTER_VAL; - + rtc1_compare0_set(cc); uint32_t post_counter_val = rtc1_counter_get(); @@ -717,24 +718,24 @@ bool ticks_have_elapsed; bool compare_update; app_timer_id_t timer_id_head_old; - + // Back up the previous known tick and previous list head ticks_previous = m_ticks_latest; timer_id_head_old = m_timer_id_head; - + // Get number of elapsed ticks ticks_have_elapsed = elapsed_ticks_acquire(&ticks_elapsed); // Handle list deletions compare_update = list_deletions_handler(); - + // Handle expired timers if (ticks_have_elapsed) { expired_timers_handler(ticks_elapsed, ticks_previous, &restart_list_head); compare_update = true; } - + // Handle list insertions if (list_insertions_handler(restart_list_head)) { @@ -768,10 +769,10 @@ * @return Pointer to allocated queue entry, or NULL if queue is full. */ static timer_user_op_t * user_op_alloc(timer_user_t * p_user, app_timer_id_t * p_last_index) -{ +{ app_timer_id_t last; timer_user_op_t * p_user_op; - + last = p_user->last + 1; if (last == p_user->user_op_queue_size) { @@ -783,10 +784,10 @@ // Queue is full. return NULL; } - - *p_last_index = last; + + *p_last_index = last; p_user_op = &p_user->p_user_op_queue[p_user->last]; - + return p_user_op; } @@ -808,21 +809,21 @@ void * p_context) { app_timer_id_t last_index; - + timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); if (p_user_op == NULL) { return NRF_ERROR_NO_MEM; } - + p_user_op->op_type = TIMER_USER_OP_TYPE_START; p_user_op->timer_id = timer_id; p_user_op->params.start.ticks_at_start = rtc1_counter_get(); p_user_op->params.start.ticks_first_interval = timeout_initial; p_user_op->params.start.ticks_periodic_interval = timeout_periodic; p_user_op->params.start.p_context = p_context; - - user_op_enque(&mp_users[user_id], last_index); + + user_op_enque(&mp_users[user_id], last_index); timer_list_handler_sched(); @@ -841,17 +842,17 @@ static uint32_t timer_stop_op_schedule(timer_user_id_t user_id, app_timer_id_t timer_id) { app_timer_id_t last_index; - + timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); if (p_user_op == NULL) { return NRF_ERROR_NO_MEM; } - + p_user_op->op_type = TIMER_USER_OP_TYPE_STOP; p_user_op->timer_id = timer_id; - - user_op_enque(&mp_users[user_id], last_index); + + user_op_enque(&mp_users[user_id], last_index); timer_list_handler_sched(); @@ -866,17 +867,17 @@ static uint32_t timer_stop_all_op_schedule(timer_user_id_t user_id) { app_timer_id_t last_index; - + timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); if (p_user_op == NULL) { return NRF_ERROR_NO_MEM; } - + p_user_op->op_type = TIMER_USER_OP_TYPE_STOP_ALL; p_user_op->timer_id = TIMER_NULL; - - user_op_enque(&mp_users[user_id], last_index); + + user_op_enque(&mp_users[user_id], last_index); timer_list_handler_sched(); @@ -929,29 +930,29 @@ { return NRF_ERROR_INVALID_PARAM; } - + // Stop RTC to prevent any running timers from expiring (in case of reinitialization) rtc1_stop(); - + m_evt_schedule_func = evt_schedule_func; // Initialize timer node array m_node_array_size = max_timers; mp_nodes = (timer_node_t *) p_buffer; - + for (i = 0; i < max_timers; i++) { mp_nodes[i].state = STATE_FREE; mp_nodes[i].is_running = false; } - + // Skip timer node array p_buffer = &((uint8_t *)p_buffer)[max_timers * sizeof(timer_node_t)]; - + // Initialize users array m_user_array_size = APP_TIMER_INT_LEVELS; mp_users = (timer_user_t *) p_buffer; - + // Skip user array p_buffer = &((uint8_t *)p_buffer)[APP_TIMER_INT_LEVELS * sizeof(timer_user_t)]; @@ -959,12 +960,12 @@ for (i = 0; i < APP_TIMER_INT_LEVELS; i++) { timer_user_t * p_user = &mp_users[i]; - + p_user->first = 0; p_user->last = 0; p_user->user_op_queue_size = op_queues_size; p_user->p_user_op_queue = (timer_user_op_t *) p_buffer; - + // Skip operation queue p_buffer = &((uint8_t *)p_buffer)[op_queues_size * sizeof(timer_user_op_t)]; } @@ -980,7 +981,7 @@ rtc1_init(prescaler); m_ticks_latest = rtc1_counter_get(); - + return NRF_SUCCESS; } @@ -1003,8 +1004,8 @@ if (p_timer_id == NULL) { return NRF_ERROR_INVALID_PARAM; - } - + } + // Find free timer for (i = 0; i < m_node_array_size; i++) { @@ -1013,12 +1014,12 @@ mp_nodes[i].state = STATE_ALLOCATED; mp_nodes[i].mode = mode; mp_nodes[i].p_timeout_handler = timeout_handler; - + *p_timer_id = i; return NRF_SUCCESS; } } - + return NRF_ERROR_NO_MEM; } @@ -1032,22 +1033,22 @@ timer_user_id_t ret; STATIC_ASSERT(APP_TIMER_INT_LEVELS == 3); - + switch (current_int_priority_get()) { case APP_IRQ_PRIORITY_HIGH: ret = APP_HIGH_USER_ID; break; - + case APP_IRQ_PRIORITY_LOW: ret = APP_LOW_USER_ID; break; - + default: ret = THREAD_MODE_USER_ID; break; } - + return ret; } @@ -1055,7 +1056,7 @@ uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context) { uint32_t timeout_periodic; - + // Check state and parameters if (mp_nodes == NULL) { @@ -1069,7 +1070,7 @@ { return NRF_ERROR_INVALID_STATE; } - + // Schedule timer start operation timeout_periodic = (mp_nodes[timer_id].mode == APP_TIMER_MODE_REPEATED) ? timeout_ticks : 0; @@ -1096,7 +1097,7 @@ { return NRF_ERROR_INVALID_STATE; } - + // Schedule timer stop operation return timer_stop_op_schedule(user_id_get(), timer_id); }