Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
app_timer.h
00001 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 /** @file 00014 * 00015 * @defgroup app_timer Application Timer 00016 * @{ 00017 * @ingroup app_common 00018 * 00019 * @brief Application timer functionality. 00020 * 00021 * @details It enables the application to create multiple timer instances based on the RTC1 00022 * peripheral. Checking for timeouts and invokation of user timeout handlers is performed 00023 * in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0). 00024 * Both interrupt handlers are running in APP_LOW priority level. 00025 * 00026 * @note When calling app_timer_start() or app_timer_stop(), the timer operation is just queued, 00027 * and the software interrupt is triggered. The actual timer start/stop operation is 00028 * executed by the SWI0 interrupt handler. Since the SWI0 interrupt is running in APP_LOW, 00029 * if the application code calling the timer function is running in APP_LOW or APP_HIGH, 00030 * the timer operation will not be performed until the application handler has returned. 00031 * This will be the case e.g. when stopping a timer from a timeout handler when not using 00032 * the scheduler. 00033 * 00034 * @details Use the USE_SCHEDULER parameter of the APP_TIMER_INIT() macro to select if the 00035 * @ref app_scheduler is to be used or not. 00036 * 00037 * @note Even if the scheduler is not used, app_timer.h will include app_scheduler.h, so when 00038 * compiling, app_scheduler.h must be available in one of the compiler include paths. 00039 */ 00040 00041 #ifndef APP_TIMER_H__ 00042 #define APP_TIMER_H__ 00043 00044 #include <stdint.h> 00045 #include <stdbool.h> 00046 #include <stdio.h> 00047 #include "nordic_global.h" 00048 #include "app_error.h " 00049 #include "app_util.h " 00050 #include "app_scheduler.h " 00051 #include "compiler_abstraction.h" 00052 00053 #define APP_TIMER_SCHED_EVT_SIZE sizeof(app_timer_event_t) /**< Size of button events being passed through the scheduler (is to be used for computing the maximum size of scheduler events). */ 00054 #define APP_TIMER_CLOCK_FREQ 32768 /**< Clock frequency of the RTC timer used to implement the app timer module. */ 00055 #define APP_TIMER_MIN_TIMEOUT_TICKS 5 /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */ 00056 00057 #define APP_TIMER_NODE_SIZE 40 /**< Size of app_timer.timer_node_t (only for use inside APP_TIMER_BUF_SIZE()). */ 00058 #define APP_TIMER_USER_OP_SIZE 24 /**< Size of app_timer.timer_user_op_t (only for use inside APP_TIMER_BUF_SIZE()). */ 00059 #define APP_TIMER_USER_SIZE 8 /**< Size of app_timer.timer_user_t (only for use inside APP_TIMER_BUF_SIZE()). */ 00060 #define APP_TIMER_INT_LEVELS 3 /**< Number of interrupt levels from where timer operations may be initiated (only for use inside APP_TIMER_BUF_SIZE()). */ 00061 00062 /**@brief Compute number of bytes required to hold the application timer data structures. 00063 * 00064 * @param[in] MAX_TIMERS Maximum number of timers that can be created at any given time. 00065 * @param[in] OP_QUEUE_SIZE Size of queues holding timer operations that are pending execution. 00066 * NOTE: Due to the queue implementation, this size must be one more 00067 * than the size that is actually needed. 00068 * 00069 * @return Required application timer buffer size (in bytes). 00070 */ 00071 #define APP_TIMER_BUF_SIZE(MAX_TIMERS, OP_QUEUE_SIZE) \ 00072 ( \ 00073 ((MAX_TIMERS) * APP_TIMER_NODE_SIZE) \ 00074 + \ 00075 ( \ 00076 APP_TIMER_INT_LEVELS \ 00077 * \ 00078 (APP_TIMER_USER_SIZE + ((OP_QUEUE_SIZE) + 1) * APP_TIMER_USER_OP_SIZE) \ 00079 ) \ 00080 ) 00081 00082 /**@brief Convert milliseconds to timer ticks. 00083 * 00084 * @note This macro uses 64 bit integer arithmetic, but as long as the macro parameters are 00085 * constants (i.e. defines), the computation will be done by the preprocessor. 00086 * 00087 * @param[in] MS Milliseconds. 00088 * @param[in] PRESCALER Value of the RTC1 PRESCALER register (must be the same value that was 00089 * passed to APP_TIMER_INIT()). 00090 * 00091 * @note When using this macro, it is the responsibility of the developer to ensure that the 00092 * values provided as input result in an output value that is supported by the 00093 * @ref app_timer_start function. For example, when the ticks for 1 ms is needed, the 00094 * maximum possible value of PRESCALER must be 6, when @ref APP_TIMER_CLOCK_FREQ is 32768. 00095 * This will result in a ticks value as 5. Any higher value for PRESCALER will result in a 00096 * ticks value that is not supported by this module. 00097 * 00098 * @return Number of timer ticks. 00099 */ 00100 #define APP_TIMER_TICKS(MS, PRESCALER)\ 00101 ((uint32_t)ROUNDED_DIV((MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, ((PRESCALER) + 1) * 1000)) 00102 00103 /**@brief Timer id type. */ 00104 typedef uint32_t app_timer_id_t; 00105 00106 /**@brief Application timeout handler type. */ 00107 typedef void (*app_timer_timeout_handler_t)(void * p_context); 00108 00109 /**@brief Type of function for passing events from the timer module to the scheduler. */ 00110 typedef uint32_t (*app_timer_evt_schedule_func_t) (app_timer_timeout_handler_t timeout_handler, 00111 void * p_context); 00112 00113 /**@brief Timer modes. */ 00114 typedef enum 00115 { 00116 APP_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */ 00117 APP_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */ 00118 } app_timer_mode_t; 00119 00120 /**@brief Macro for initializing the application timer module. 00121 * 00122 * @details It will handle dimensioning and allocation of the memory buffer required by the timer, 00123 * making sure that the buffer is correctly aligned. It will also connect the timer module 00124 * to the scheduler (if specified). 00125 * 00126 * @param[in] PRESCALER Value of the RTC1 PRESCALER register. This will decide the 00127 * timer tick rate. Set to 0 for no prescaling. 00128 * @param[in] MAX_TIMERS Maximum number of timers that can be created at any given time. 00129 * @param[in] OP_QUEUES_SIZE Size of queues holding timer operations that are pending execution. 00130 * @param[in] USE_SCHEDULER TRUE if the application is using the event scheduler, 00131 * FALSE otherwise. 00132 * 00133 * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it 00134 * several times as long as it is from the same location, e.g. to do a reinitialization). 00135 */ 00136 /*lint -emacro(506, APP_TIMER_INIT) */ /* Suppress "Constant value Boolean */ 00137 #define APP_TIMER_INIT(PRESCALER, MAX_TIMERS, OP_QUEUES_SIZE, USE_SCHEDULER) \ 00138 do \ 00139 { \ 00140 static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE((MAX_TIMERS), \ 00141 (OP_QUEUES_SIZE) + 1), \ 00142 sizeof(uint32_t))]; \ 00143 uint32_t ERR_CODE = app_timer_init((PRESCALER), \ 00144 (MAX_TIMERS), \ 00145 (OP_QUEUES_SIZE) + 1, \ 00146 APP_TIMER_BUF, \ 00147 (USE_SCHEDULER) ? app_timer_evt_schedule : NULL); \ 00148 APP_ERROR_CHECK(ERR_CODE); \ 00149 } while (0) 00150 00151 /**@brief Function for initializing the timer module. 00152 * 00153 * @note Normally initialization should be done using the APP_TIMER_INIT() macro, as that will both 00154 * allocate the buffers needed by the timer module (including aligning the buffers correctly, 00155 * and also take care of connecting the timer module to the scheduler (if specified). 00156 * 00157 * @param[in] prescaler Value of the RTC1 PRESCALER register. Set to 0 for no prescaling. 00158 * @param[in] max_timers Maximum number of timers that can be created at any given time. 00159 * @param[in] op_queues_size Size of queues holding timer operations that are pending 00160 * execution. NOTE: Due to the queue implementation, this size must 00161 * be one more than the size that is actually needed. 00162 * @param[in] p_buffer Pointer to memory buffer for internal use in the app_timer 00163 * module. The size of the buffer can be computed using the 00164 * APP_TIMER_BUF_SIZE() macro. The buffer must be aligned to a 00165 * 4 byte boundary. 00166 * @param[in] evt_schedule_func Function for passing timeout events to the scheduler. Point to 00167 * app_timer_evt_schedule() to connect to the scheduler. Set to NULL 00168 * to make the timer module call the timeout handler directly from 00169 * the timer interrupt handler. 00170 * 00171 * @retval NRF_SUCCESS Successful initialization. 00172 * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte 00173 * boundary or NULL). 00174 */ 00175 uint32_t app_timer_init(uint32_t prescaler, 00176 uint8_t max_timers, 00177 uint8_t op_queues_size, 00178 void * p_buffer, 00179 app_timer_evt_schedule_func_t evt_schedule_func); 00180 00181 /**@brief Function for creating a timer instance. 00182 * 00183 * @param[out] p_timer_id Id of the newly created timer. 00184 * @param[in] mode Timer mode. 00185 * @param[in] timeout_handler Function to be executed when the timer expires. 00186 * 00187 * @retval NRF_SUCCESS Timer was successfully created. 00188 * @retval NRF_ERROR_INVALID_PARAM Invalid parameter. 00189 * @retval NRF_ERROR_INVALID_STATE Application timer module has not been initialized. 00190 * @retval NRF_ERROR_NO_MEM Maximum number of timers has already been reached. 00191 * 00192 * @note This function does the timer allocation in the caller's context. It is also not protected 00193 * by a critical region. Therefore care must be taken not to call it from several interrupt 00194 * levels simultaneously. 00195 */ 00196 uint32_t app_timer_create(app_timer_id_t * p_timer_id, 00197 app_timer_mode_t mode, 00198 app_timer_timeout_handler_t timeout_handler); 00199 00200 /**@brief Function for starting a timer. 00201 * 00202 * @param[in] timer_id Id of timer to start. 00203 * @param[in] timeout_ticks Number of ticks (of RTC1, including prescaling) to timeout event 00204 * (minimum 5 ticks). 00205 * @param[in] p_context General purpose pointer. Will be passed to the timeout handler when 00206 * the timer expires. 00207 * 00208 * @retval NRF_SUCCESS Timer was successfully started. 00209 * @retval NRF_ERROR_INVALID_PARAM Invalid parameter. 00210 * @retval NRF_ERROR_INVALID_STATE Application timer module has not been initialized, or timer 00211 * has not been created. 00212 * @retval NRF_ERROR_NO_MEM Timer operations queue was full. 00213 * 00214 * @note The minimum timeout_ticks value is 5. 00215 * @note For multiple active timers, timeouts occurring in close proximity to each other (in the 00216 * range of 1 to 3 ticks) will have a positive jitter of maximum 3 ticks. 00217 * @note When calling this method on a timer which is already running, the second start operation 00218 * will be ignored. 00219 */ 00220 uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context); 00221 00222 /**@brief Function for stopping the specified timer. 00223 * 00224 * @param[in] timer_id Id of timer to stop. 00225 * 00226 * @retval NRF_SUCCESS Timer was successfully stopped. 00227 * @retval NRF_ERROR_INVALID_PARAM Invalid parameter. 00228 * @retval NRF_ERROR_INVALID_STATE Application timer module has not been initialized, or timer 00229 * has not been created. 00230 * @retval NRF_ERROR_NO_MEM Timer operations queue was full. 00231 */ 00232 uint32_t app_timer_stop(app_timer_id_t timer_id); 00233 00234 /**@brief Function for stopping all running timers. 00235 * 00236 * @retval NRF_SUCCESS All timers were successfully stopped. 00237 * @retval NRF_ERROR_INVALID_STATE Application timer module has not been initialized. 00238 * @retval NRF_ERROR_NO_MEM Timer operations queue was full. 00239 */ 00240 uint32_t app_timer_stop_all(void); 00241 00242 /**@brief Function for returning the current value of the RTC1 counter. 00243 * 00244 * @param[out] p_ticks Current value of the RTC1 counter. 00245 * 00246 * @retval NRF_SUCCESS Counter was successfully read. 00247 */ 00248 uint32_t app_timer_cnt_get(uint32_t * p_ticks); 00249 00250 /**@brief Function for computing the difference between two RTC1 counter values. 00251 * 00252 * @param[in] ticks_to Value returned by app_timer_cnt_get(). 00253 * @param[in] ticks_from Value returned by app_timer_cnt_get(). 00254 * @param[out] p_ticks_diff Number of ticks from ticks_from to ticks_to. 00255 * 00256 * @retval NRF_SUCCESS Counter difference was successfully computed. 00257 */ 00258 uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, 00259 uint32_t ticks_from, 00260 uint32_t * p_ticks_diff); 00261 00262 00263 // Type and functions for connecting the timer to the scheduler: 00264 00265 /**@cond NO_DOXYGEN */ 00266 typedef struct 00267 { 00268 app_timer_timeout_handler_t timeout_handler; 00269 void * p_context; 00270 } app_timer_event_t; 00271 00272 static __INLINE void app_timer_evt_get(void * p_event_data, uint16_t event_size) 00273 { 00274 app_timer_event_t * p_timer_event = (app_timer_event_t *)p_event_data; 00275 00276 APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t)); 00277 p_timer_event->timeout_handler(p_timer_event->p_context); 00278 } 00279 00280 static __INLINE uint32_t app_timer_evt_schedule(app_timer_timeout_handler_t timeout_handler, 00281 void * p_context) 00282 { 00283 app_timer_event_t timer_event; 00284 00285 timer_event.timeout_handler = timeout_handler; 00286 timer_event.p_context = p_context; 00287 00288 return app_sched_event_put(&timer_event, sizeof(timer_event), app_timer_evt_get); 00289 } 00290 /**@endcond */ 00291 00292 #endif // APP_TIMER_H__ 00293 00294 /** @} */
Generated on Tue Jul 12 2022 19:00:51 by
