1 /* 2 * Copyright 2018-2021 NXP 3 * All rights reserved. 4 * 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #ifndef __TIMERS_MANAGER_H__ 10 #define __TIMERS_MANAGER_H__ 11 12 #ifndef SDK_COMPONENT_DEPENDENCY_FSL_COMMON 13 #define SDK_COMPONENT_DEPENDENCY_FSL_COMMON (1U) 14 #endif 15 #if (defined(SDK_COMPONENT_DEPENDENCY_FSL_COMMON) && (SDK_COMPONENT_DEPENDENCY_FSL_COMMON > 0U)) 16 #include "fsl_common.h" 17 #else 18 #endif 19 20 #if (defined(COMMON_TASK_ENABLE) && (COMMON_TASK_ENABLE == 0U)) 21 #include "fsl_component_common_task.h" 22 #endif /* COMMON_TASK_ENABLE */ 23 /*! 24 * @addtogroup Timer_Manager 25 * @{ 26 */ 27 28 /*! 29 * @brief The timer manager component 30 * 31 * The timer manager is built based on the timer adapter component provided by the NXP 32 * MCUXpresso SDK. It could provide bellow features: 33 * shall support SingleShot,repeater,one minute timer,one second timer and low power mode 34 * shall support timer open ,close, start and stop operation, and support callback function install 35 * And provide 1ms accuracy timers 36 * 37 * The timer manager would be used with different HW timer modules like FTM, PIT, LPTMR. 38 * But at the same time, only one HW timer module could be used. On different platforms,different 39 * HW timer module would be used. For the platforms which have multiple HW timer modules, 40 * one HW timer module would be selected as the default, but it is easy to change the default 41 * HW timer module to another. Just two steps to switch the HW timer module: 42 * 1.Remove the default HW timer module source file from the project 43 * 2.Add the expected HW timer module source file to the project. 44 * For example, in platform FRDM-K64F, there are two HW timer modules available, FTM and PIT. 45 * FTM is used as the default HW timer, so ftm_adapter.c and timer.h is included in the project by 46 * default.If PIT is expected to be used as the HW timer, ftm_adapter.c need to be removed from the 47 * project and pit_adapter.c should be included in the project 48 */ 49 /***************************************************************************** 50 ****************************************************************************** 51 * Public macros 52 ****************************************************************************** 53 *****************************************************************************/ 54 /* 55 * @brief Configures the common task enable.If set to 1, then timer will use common task and consume less ram/flash 56 * size. 57 */ 58 #ifndef TM_COMMON_TASK_ENABLE 59 #define TM_COMMON_TASK_ENABLE (0) 60 #if (defined(COMMON_TASK_ENABLE) && (COMMON_TASK_ENABLE == 0U)) 61 #undef TM_COMMON_TASK_ENABLE 62 #define TM_COMMON_TASK_ENABLE (0U) 63 #endif 64 #endif 65 /* 66 * @brief Configures the timer task stack size. 67 */ 68 #ifndef TM_TASK_STACK_SIZE 69 #define TM_TASK_STACK_SIZE (1024U) 70 #endif 71 72 /* 73 * @brief Configures the timer task priority. 74 */ 75 #ifndef TM_TASK_PRIORITY 76 #define TM_TASK_PRIORITY (1U) 77 #endif 78 79 /* 80 * @brief Enable/Disable Low Power Timer 81 * VALID RANGE: TRUE/FALSE 82 */ 83 #ifndef TM_ENABLE_LOW_POWER_TIMER 84 #define TM_ENABLE_LOW_POWER_TIMER (0) 85 #endif 86 /* 87 * @brief Enable/Disable TimeStamp 88 * VALID RANGE: TRUE/FALSE 89 */ 90 #ifndef TM_ENABLE_TIME_STAMP 91 #define TM_ENABLE_TIME_STAMP (0) 92 #endif 93 94 /*! @brief Definition of timer manager handle size. */ 95 #define TIMER_HANDLE_SIZE (32U) 96 97 /*! 98 * @brief Defines the timer manager handle 99 * 100 * This macro is used to define a 4 byte aligned timer manager handle. 101 * Then use "(eeprom_handle_t)name" to get the timer manager handle. 102 * 103 * The macro should be global and could be optional. You could also define timer manager handle by yourself. 104 * 105 * This is an example, 106 * @code 107 * TIMER_MANAGER_HANDLE_DEFINE(timerManagerHandle); 108 * @endcode 109 * 110 * @param name The name string of the timer manager handle. 111 */ 112 #define TIMER_MANAGER_HANDLE_DEFINE(name) uint32_t name[(TIMER_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)] 113 114 /***************************************************************************** 115 ****************************************************************************** 116 * Public type definitions 117 ****************************************************************************** 118 *****************************************************************************/ 119 /**@brief Timer status. */ 120 #if (defined(SDK_COMPONENT_DEPENDENCY_FSL_COMMON) && (SDK_COMPONENT_DEPENDENCY_FSL_COMMON > 0U)) 121 typedef enum _timer_status 122 { 123 kStatus_TimerSuccess = kStatus_Success, /*!< Success */ 124 kStatus_TimerInvalidId = MAKE_STATUS(kStatusGroup_TIMERMANAGER, 1), /*!< Invalid Id */ 125 kStatus_TimerNotSupport = MAKE_STATUS(kStatusGroup_TIMERMANAGER, 2), /*!< Not Support */ 126 kStatus_TimerOutOfRange = MAKE_STATUS(kStatusGroup_TIMERMANAGER, 3), /*!< Out Of Range */ 127 kStatus_TimerError = MAKE_STATUS(kStatusGroup_TIMERMANAGER, 4), /*!< Fail */ 128 } timer_status_t; 129 #else 130 typedef enum _timer_status 131 { 132 kStatus_TimerSuccess = 0, /*!< Success */ 133 kStatus_TimerInvalidId = 1, /*!< Invalid Id */ 134 kStatus_TimerNotSupport = 2, /*!< Not Support */ 135 kStatus_TimerOutOfRange = 3, /*!< Out Of Range */ 136 kStatus_TimerError = 4, /*!< Fail */ 137 } timer_status_t; 138 139 #endif 140 141 /**@brief Timer modes. */ 142 typedef enum _timer_mode 143 { 144 kTimerModeSingleShot = 0x01U, /**< The timer will expire only once. */ 145 kTimerModeIntervalTimer = 0x02U, /**< The timer will restart each time it expires. */ 146 kTimerModeSetMinuteTimer = 0x04U, /**< The timer will one minute timer. */ 147 kTimerModeSetSecondTimer = 0x08U, /**< The timer will one second timer. */ 148 kTimerModeLowPowerTimer = 0x10U, /**< The timer will low power mode timer. */ 149 kTimerModeSetMicrosTimer = 0x20U, /**< The timer will low power mode timer with microsecond unit. */ 150 } timer_mode_t; 151 152 /**@brief Timer config. */ 153 typedef struct _timer_config 154 { 155 uint32_t srcClock_Hz; /**< The timer source clock frequency. */ 156 uint8_t instance; /*!< Hardware timer module instance, for example: if you want use FTM0,then the instance 157 is configured to 0, if you want use FTM2 hardware timer, then configure the instance 158 to 2, detail information please refer to the SOC corresponding RM. Invalid instance 159 value will cause initialization failure. */ 160 161 uint8_t clockSrcSelect; /*!< Select clock source. It is timer clock select, if the lptmr does not 162 to use the default clock source*/ 163 164 #if (defined(TM_ENABLE_TIME_STAMP) && (TM_ENABLE_TIME_STAMP > 0U)) 165 uint32_t timeStampSrcClock_Hz; /**< The timer stamp source clock frequency. */ 166 uint8_t timeStampInstance; /**< Hardware timer module instance. This instance for time stamp */ 167 168 uint8_t timeStampClockSrcSelect; /*!< Select clock source. It is timer clock select, if the lptmr 169 does not to use the default clock source*/ 170 171 #endif 172 } timer_config_t; 173 174 /* 175 * @brief Timer handle 176 */ 177 typedef void *timer_handle_t; 178 179 /* 180 * @brief Timer callback fiction 181 */ 182 typedef void (*timer_callback_t)(void *param); 183 184 /* 185 * \brief Converts the macro argument from seconds to microseconds 186 */ 187 #define TmSecondsToMicroseconds(n) ((uint64_t)((n)*1000000UL)) 188 189 /* 190 * \brief Converts the macro argument from seconds to milliseconds 191 */ 192 #define TmSecondsToMilliseconds(n) ((uint32_t)((n)*1000UL)) 193 194 /* 195 * \brief Converts the macro argument from microseconds to seconds 196 */ 197 #define TmMicrosecondsToSeconds(n) (((n) + 500000U) / 1000000U) 198 /***************************************************************************** 199 ****************************************************************************** 200 * Public memory declarations 201 ****************************************************************************** 202 *****************************************************************************/ 203 204 /***************************************************************************** 205 ****************************************************************************** 206 * Public prototypes 207 ****************************************************************************** 208 *****************************************************************************/ 209 210 #if defined(__cplusplus) 211 extern "C" { 212 #endif /* _cplusplus */ 213 214 /*! 215 * @brief Initializes timer manager module with the user configuration structure. 216 * 217 * For Initializes timer manager, 218 * @code 219 * timer_config_t timerConfig; 220 * timerConfig.instance = 0; 221 * timerConfig.srcClock_Hz = BOARD_GetTimerSrcClock(); 222 * TM_Init(&timerConfig); 223 * @endcode 224 * 225 * @param timerConfig Pointer to user-defined timer configuration structure. 226 * @retval kStatus_TimerSuccess Timer manager initialization succeed. 227 * @retval kStatus_TimerError An error occurred. 228 */ 229 timer_status_t TM_Init(timer_config_t *timerConfig); 230 231 /*! 232 * @brief Deinitialize timer manager module. 233 * 234 */ 235 void TM_Deinit(void); 236 237 /*! 238 * @brief Power up timer manager module. 239 * 240 */ 241 void TM_ExitLowpower(void); 242 243 /*! 244 * @brief Power down timer manager module. 245 * 246 */ 247 void TM_EnterLowpower(void); 248 249 /*! 250 * @brief Programs a timer needed for RTOS tickless low power period 251 * 252 * Starts a timer and sync all timer manager ressources before programming HW 253 * timer module. Everything is done by bypassing the timer manager task as this 254 * function is usually called under masked interrupts (no context switch). 255 * 256 * @param timerHandle the handle of the timer 257 * @param timerTimeout The timer timeout in microseconds unit 258 * 259 */ 260 void TM_EnterTickless(timer_handle_t timerHandle, uint64_t timerTimeout); 261 262 /*! 263 * @brief Resyncs timer manager ressources after tickless low power period 264 * 265 * Makes sure to stop the tickless timer and resync all existing timers. 266 * Everything is done by bypassing the timer manager task as this 267 * function is usually called under masked interrupts (no context switch). 268 * 269 * @param timerHandle the handle of the timer 270 * 271 */ 272 void TM_ExitTickless(timer_handle_t timerHandle); 273 274 /*! 275 * @brief Open a timer with user handle. 276 * 277 * @param timerHandle Pointer to a memory space of size #TIMER_HANDLE_SIZE allocated by the caller. 278 * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. 279 * You can define the handle in the following two ways: 280 * #TIMER_MANAGER_HANDLE_DEFINE(timerHandle); 281 * or 282 * uint32_t timerHandle[((TIMER_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; 283 * @retval kStatus_TimerSuccess Timer open succeed. 284 * @retval kStatus_TimerError An error occurred. 285 */ 286 timer_status_t TM_Open(timer_handle_t timerHandle); 287 288 /*! 289 * @brief Close a timer with user handle. 290 * 291 * @param timerHandle the handle of the timer 292 * 293 * @retval kStatus_TimerSuccess Timer close succeed. 294 * @retval kStatus_TimerError An error occurred. 295 */ 296 timer_status_t TM_Close(timer_handle_t timerHandle); 297 298 /*! 299 * @brief Install a specified timer callback 300 * 301 * @note Application need call the function to install specified timer callback before start a timer . 302 * 303 * @param timerHandle the handle of the timer 304 * @param callback callback function 305 * @param callbackParam parameter to callback function 306 * 307 * @retval kStatus_TimerSuccess Timer install callback succeed. 308 * 309 */ 310 timer_status_t TM_InstallCallback(timer_handle_t timerHandle, timer_callback_t callback, void *callbackParam); 311 312 /*! 313 * @brief Start a specified timer 314 * 315 * TM_Start() starts a specified timer that was previously opened using the TM_Open() API function. 316 * The function is a non-blocking API, the funciton will return at once. And the callback function that was previously 317 * installed by using the TM_InstallCallback() API function will be called if timer is expired. 318 * 319 * @param timerHandle the handle of the timer 320 * @param timerType The mode of the timer, for example: kTimerModeSingleShot for the timer will expire 321 * only once, kTimerModeIntervalTimer, the timer will restart each time it expires. 322 * If low power mode is used at the same time. It should be set like this: kTimerModeSingleShot | 323 * kTimerModeLowPowerTimer. kTimerModeSetMicosTimer is microsecond unit, and please note the timer 324 * Manager can't make sure the high resolution accuracy than 1ms with kTimerModeSetMicosTimer 325 * support, for example if timer manager use 32K OSC timer as clock source, actually the precision 326 * of timer is about 31us. 327 * @param timerTimeout The timer timeout in milliseconds unit for kTimerModeSingleShot, kTimerModeIntervalTimer 328 * and kTimerModeLowPowerTimer,if kTimerModeSetMinuteTimer timeout for minutes unit, if 329 * kTimerModeSetSecondTimer the timeout for seconds unit. the timeout is in microseconds if 330 * kTimerModeSetMicrosTimer is used. 331 * 332 * @retval kStatus_TimerSuccess Timer start succeed. 333 * @retval kStatus_TimerError An error occurred. 334 */ 335 timer_status_t TM_Start(timer_handle_t timerHandle, uint8_t timerType, uint32_t timerTimeout); 336 337 /*! 338 * @brief Stop a specified timer 339 * 340 * @param timerHandle the handle of the timer 341 * 342 * @retval kStatus_TimerSuccess Timer stop succeed. 343 * @retval kStatus_TimerError An error occurred. 344 */ 345 timer_status_t TM_Stop(timer_handle_t timerHandle); 346 347 /*! 348 * @brief Check if a specified timer is active 349 * 350 * @param timerHandle the handle of the timer 351 * 352 * @retval return 1 if timer is active, return 0 if timer is not active. 353 */ 354 uint8_t TM_IsTimerActive(timer_handle_t timerHandle); 355 356 /*! 357 * @brief Check if a specified timer is ready 358 * 359 * @param timerHandle the handle of the timer 360 * 361 * @retval return 1 if timer is ready, return 0 if timer is not ready. 362 */ 363 uint8_t TM_IsTimerReady(timer_handle_t timerHandle); 364 365 /*! 366 * @brief Returns the remaining time until timeout 367 * 368 * @param timerHandle the handle of the timer 369 * 370 * @retval remaining time in microseconds until first timer timeouts. 371 */ 372 uint32_t TM_GetRemainingTime(timer_handle_t timerHandle); 373 374 /*! 375 * @brief Get the first expire time of timer 376 * 377 * @param timerType The mode of the timer, for example: kTimerModeSingleShot for the timer will expire 378 * only once, kTimerModeIntervalTimer, the timer will restart each time it expires. 379 * 380 * @retval return the first expire time of all timer. 381 */ 382 uint32_t TM_GetFirstExpireTime(uint8_t timerType); 383 384 /*! 385 * @brief Returns the handle of the timer of the first allocated timer that has the 386 * specified parameter. 387 * 388 * @param param specified parameter of timer 389 * 390 * @retval return the handle of the timer if success. 391 */ 392 timer_handle_t TM_GetFirstTimerWithParam(void *param); 393 394 /*! 395 * @brief Check if all timers except the LP timers are OFF 396 * 397 * 398 * @retval return 1 there are no active non-low power timers, 0 otherwise. 399 */ 400 uint8_t TM_AreAllTimersOff(void); 401 402 /*! 403 * @brief Returns not counted time before system entering in sleep, This function is called 404 * by Low Power module. 405 * 406 * @retval return microseconds that wasn't counted before entering in sleep. 407 */ 408 uint32_t TM_NotCountedTimeBeforeSleep(void); 409 410 /*! 411 * @brief Sync low power timer in sleep mode, This function is called by Low Power module; 412 * 413 * @param sleepDurationTmrUs sleep duration in microseconds unit 414 * 415 */ 416 void TM_SyncLpmTimers(uint32_t sleepDurationTmrUs); 417 418 /*! 419 * @brief Make timer task ready after wakeup from lowpower mode, This function is called 420 * by Low Power module; 421 * 422 */ 423 void TM_MakeTimerTaskReady(void); 424 425 /*! 426 * @brief Get a time-stamp value 427 * 428 */ 429 uint64_t TM_GetTimestamp(void); 430 431 #if defined(__cplusplus) 432 } 433 #endif 434 /*! @}*/ 435 #endif /* #ifndef __TIMERS_MANAGER_H__ */ 436