/**@brief Function for scheduling a Timer Start operation. * * @param[in] user_id Id of user calling this function. * @param[in] timer_id Id of timer to start. * @param[in] timeout_initial Time (in ticks) to first timer expiry. * @param[in] timeout_periodic Time (in ticks) between periodic expiries. * @param[in] p_context General purpose pointer. Will be passed to the timeout handler when * the timer expires. * @return NRF_SUCCESS on success, otherwise an error code. */ static uint32_t timer_start_op_schedule(timer_user_id_t user_id, timer_node_t * p_node, uint32_t timeout_initial, uint32_t timeout_periodic, void * p_context) { uint8_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->p_node = p_node; 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); timer_list_handler_sched(); return NRF_SUCCESS; }
/**@brief Function for scheduling a Timer Stop operation. * * @param[in] timer_id Id of timer to stop. * @param[in] op_type Type of stop operation * * @return NRF_SUCCESS on successful scheduling a timer stop operation. NRF_ERROR_NO_MEM when there * is no memory left to schedule the timer stop operation. */ static uint32_t timer_stop_op_schedule(timer_node_t * p_node, timer_user_op_type_t op_type) { uint8_t last_index; uint32_t err_code = NRF_SUCCESS; CRITICAL_REGION_ENTER(); timer_user_op_t * p_user_op = user_op_alloc(&last_index); if (p_user_op == NULL) { err_code = NRF_ERROR_NO_MEM; } else { p_user_op->op_type = op_type; p_user_op->p_node = p_node; user_op_enque(last_index); } CRITICAL_REGION_EXIT(); if (err_code == NRF_SUCCESS) { timer_list_handler_sched(); } return err_code; }
static uint32_t timer_start_op_schedule(timer_node_t * p_node, uint32_t timeout_initial, uint32_t timeout_periodic, void * p_context) { uint8_t last_index; uint32_t err_code = NRF_SUCCESS; CRITICAL_REGION_ENTER(); timer_user_op_t * p_user_op = user_op_alloc(&last_index); if (p_user_op == NULL) { err_code = NRF_ERROR_NO_MEM; } else { p_user_op->op_type = TIMER_USER_OP_TYPE_START; p_user_op->p_node = p_node; 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(last_index); } CRITICAL_REGION_EXIT(); if (err_code == NRF_SUCCESS) { timer_list_handler_sched(); } return err_code; }
/**@brief Function for scheduling a Timer Stop All operation. * * @param[in] user_id Id of user calling this function. */ static uint32_t timer_stop_all_op_schedule(timer_user_id_t user_id) { timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id]); 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; timer_list_handler_sched(); return NRF_SUCCESS; }
/**@brief Function for scheduling a Timer Stop All operation. * * @param[in] user_id Id of user calling this function. */ static uint32_t timer_stop_all_op_schedule(timer_user_id_t user_id) { uint8_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->p_node = NULL; user_op_enque(&mp_users[user_id], last_index); timer_list_handler_sched(); return NRF_SUCCESS; }
/**@brief Function for checking for expired timers. */ static void timer_timeouts_check(void) { // Handle expired of timer if (mp_timer_id_head != NULL) { timer_node_t * p_timer; timer_node_t * p_previous_timer; uint32_t ticks_elapsed; uint32_t ticks_expired; // 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. p_timer = mp_timer_id_head; // Expire all timers within ticks_elapsed and collect ticks_expired. while (p_timer != NULL) { // Do nothing if timer did not expire. if (ticks_elapsed < p_timer->ticks_to_expire) { break; } // 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. p_previous_timer = p_timer; p_timer = p_timer->next; // Execute Task. timeout_handler_exec(p_previous_timer); } // Prepare to queue the ticks expired in the m_ticks_elapsed queue. if (m_ticks_elapsed_q_read_ind == m_ticks_elapsed_q_write_ind) { // The read index of the queue is equal to the write index. This means the new // value of ticks_expired should be stored at a new location in the m_ticks_elapsed // queue (which is implemented as a double buffer). // Check if there will be a queue overflow. if (++m_ticks_elapsed_q_write_ind == CONTEXT_QUEUE_SIZE_MAX) { // There will be a queue overflow. Hence the write index should point to the start // of the queue. m_ticks_elapsed_q_write_ind = 0; } } // Queue the ticks expired. m_ticks_elapsed[m_ticks_elapsed_q_write_ind] = ticks_expired; timer_list_handler_sched(); } }
/**@brief Function for checking for expired timers. */ static void timer_timeouts_check(void) { // Handle expired of timer if (m_timer_id_head != TIMER_NULL) { uint32_t ticks_expired; uint8_t ticks_elapsed_last; // Initialize actual elapsed ticks being consumed to 0 ticks_expired = 0; // Queue the ticks elapsed (to make the value context safe) ticks_elapsed_last = m_ticks_elapsed_last + 1; if (ticks_elapsed_last == CONTEXT_QUEUE_SIZE_MAX) { ticks_elapsed_last = 0; } if (ticks_elapsed_last != m_ticks_elapsed_first) { app_timer_id_t timer_id; uint32_t ticks_elapsed; // 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 timer_id = m_timer_id_head; // 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 p_timer = &mp_nodes[timer_id]; // Do nothing if timer did not expire if (ticks_elapsed < p_timer->ticks_to_expire) { break; } // 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 timer_id = p_timer->next; // Execute Task timeout_handler_exec(p_timer); } } // Queue the elapsed value m_ticks_elapsed[m_ticks_elapsed_last] = ticks_expired; m_ticks_elapsed_last = ticks_elapsed_last; timer_list_handler_sched(); } }