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 #endif 139 140 /**@brief Timer modes. */ 141 #define kTimerModeSingleShot 0x01U /**< The timer will expire only once. */ 142 #define kTimerModeIntervalTimer 0x02U /**< The timer will restart each time it expires. */ 143 #define kTimerModeSetMinuteTimer 0x04U /**< The timer will one minute timer. */ 144 #define kTimerModeSetSecondTimer 0x08U /**< The timer will one second timer. */ 145 #define kTimerModeLowPowerTimer 0x10U /**< The timer will low power mode timer. */ 146 #define kTimerModeSetMicrosTimer 0x20U /**< The timer will low power mode timer with microsecond unit. */ 147 148 /**@brief Timer config. */ 149 typedef struct _timer_config 150 { 151 uint32_t srcClock_Hz; /**< The timer source clock frequency. */ 152 uint8_t instance; /*!< Hardware timer module instance, for example: if you want use FTM0,then the instance 153 is configured to 0, if you want use FTM2 hardware timer, then configure the instance 154 to 2, detail information please refer to the SOC corresponding RM. Invalid instance 155 value will cause initialization failure. */ 156 157 uint8_t clockSrcSelect; /*!< Select clock source. It is timer clock select, if the lptmr does not 158 to use the default clock source*/ 159 160 #if (defined(TM_ENABLE_TIME_STAMP) && (TM_ENABLE_TIME_STAMP > 0U)) 161 uint32_t timeStampSrcClock_Hz; /**< The timer stamp source clock frequency. */ 162 uint8_t timeStampInstance; /**< Hardware timer module instance. This instance for time stamp */ 163 164 uint8_t timeStampClockSrcSelect; /*!< Select clock source. It is timer clock select, if the lptmr 165 does not to use the default clock source*/ 166 167 #endif 168 } timer_config_t; 169 170 /* 171 * @brief Timer handle 172 */ 173 typedef void *timer_handle_t; 174 175 /* 176 * @brief Timer callback fiction 177 */ 178 typedef void (*timer_callback_t)(void *param); 179 180 /* 181 * \brief Converts the macro argument from seconds to microseconds 182 */ 183 #define TmSecondsToMicroseconds(n) ((uint64_t)((n)*1000000UL)) 184 185 /* 186 * \brief Converts the macro argument from seconds to milliseconds 187 */ 188 #define TmSecondsToMilliseconds(n) ((uint32_t)((n)*1000UL)) 189 190 /* 191 * \brief Converts the macro argument from microseconds to seconds 192 */ 193 #define TmMicrosecondsToSeconds(n) (((n) + 500000U) / 1000000U) 194 /***************************************************************************** 195 ****************************************************************************** 196 * Public memory declarations 197 ****************************************************************************** 198 *****************************************************************************/ 199 200 /***************************************************************************** 201 ****************************************************************************** 202 * Public prototypes 203 ****************************************************************************** 204 *****************************************************************************/ 205 206 #if defined(__cplusplus) 207 extern "C" { 208 #endif /* _cplusplus */ 209 210 /*! 211 * @brief Initializes timer manager module with the user configuration structure. 212 * 213 * For Initializes timer manager, 214 * @code 215 * timer_config_t timerConfig; 216 * timerConfig.instance = 0; 217 * timerConfig.srcClock_Hz = BOARD_GetTimerSrcClock(); 218 * TM_Init(&timerConfig); 219 * @endcode 220 * 221 * @param timerConfig Pointer to user-defined timer configuration structure. 222 * @retval kStatus_TimerSuccess Timer manager initialization succeed. 223 * @retval kStatus_TimerError An error occurred. 224 */ 225 timer_status_t TM_Init(timer_config_t *timerConfig); 226 227 /*! 228 * @brief Deinitialize timer manager module. 229 * 230 */ 231 void TM_Deinit(void); 232 233 /*! 234 * @brief Power up timer manager module. 235 * 236 */ 237 void TM_ExitLowpower(void); 238 239 /*! 240 * @brief Power down timer manager module. 241 * 242 */ 243 void TM_EnterLowpower(void); 244 245 /*! 246 * @brief Programs a timer needed for RTOS tickless low power period 247 * 248 * Starts a timer and sync all timer manager ressources before programming HW 249 * timer module. Everything is done by bypassing the timer manager task as this 250 * function is usually called under masked interrupts (no context switch). 251 * 252 * @param timerHandle the handle of the timer 253 * @param timerTimeout The timer timeout in microseconds unit 254 * 255 */ 256 void TM_EnterTickless(timer_handle_t timerHandle, uint64_t timerTimeout); 257 258 /*! 259 * @brief Resyncs timer manager ressources after tickless low power period 260 * 261 * Makes sure to stop the tickless timer and resync all existing timers. 262 * Everything is done by bypassing the timer manager task as this 263 * function is usually called under masked interrupts (no context switch). 264 * 265 * @param timerHandle the handle of the timer 266 * 267 */ 268 void TM_ExitTickless(timer_handle_t timerHandle); 269 270 /*! 271 * @brief Open a timer with user handle. 272 * 273 * @param timerHandle Pointer to a memory space of size #TIMER_HANDLE_SIZE allocated by the caller. 274 * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. 275 * You can define the handle in the following two ways: 276 * #TIMER_MANAGER_HANDLE_DEFINE(timerHandle); 277 * or 278 * uint32_t timerHandle[((TIMER_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; 279 * @retval kStatus_TimerSuccess Timer open succeed. 280 * @retval kStatus_TimerError An error occurred. 281 */ 282 timer_status_t TM_Open(timer_handle_t timerHandle); 283 284 /*! 285 * @brief Close a timer with user handle. 286 * 287 * @param timerHandle the handle of the timer 288 * 289 * @retval kStatus_TimerSuccess Timer close succeed. 290 * @retval kStatus_TimerError An error occurred. 291 */ 292 timer_status_t TM_Close(timer_handle_t timerHandle); 293 294 /*! 295 * @brief Install a specified timer callback 296 * 297 * @note Application need call the function to install specified timer callback before start a timer . 298 * 299 * @param timerHandle the handle of the timer 300 * @param callback callback function 301 * @param callbackParam parameter to callback function 302 * 303 * @retval kStatus_TimerSuccess Timer install callback succeed. 304 * 305 */ 306 timer_status_t TM_InstallCallback(timer_handle_t timerHandle, timer_callback_t callback, void *callbackParam); 307 308 /*! 309 * @brief Start a specified timer 310 * 311 * TM_Start() starts a specified timer that was previously opened using the TM_Open() API function. 312 * The function is a non-blocking API, the funciton will return at once. And the callback function that was previously 313 * installed by using the TM_InstallCallback() API function will be called if timer is expired. 314 * 315 * @param timerHandle the handle of the timer 316 * @param timerType The mode of the timer, for example: kTimerModeSingleShot for the timer will expire 317 * only once, kTimerModeIntervalTimer, the timer will restart each time it expires. 318 * If low power mode is used at the same time. It should be set like this: kTimerModeSingleShot | 319 * kTimerModeLowPowerTimer. kTimerModeSetMicosTimer is microsecond unit, and please note the timer 320 * Manager can't make sure the high resolution accuracy than 1ms with kTimerModeSetMicosTimer 321 * support, for example if timer manager use 32K OSC timer as clock source, actually the precision 322 * of timer is about 31us. 323 * @param timerTimeout The timer timeout in milliseconds unit for kTimerModeSingleShot, kTimerModeIntervalTimer 324 * and kTimerModeLowPowerTimer,if kTimerModeSetMinuteTimer timeout for minutes unit, if 325 * kTimerModeSetSecondTimer the timeout for seconds unit. the timeout is in microseconds if 326 * kTimerModeSetMicrosTimer is used. 327 * 328 * @retval kStatus_TimerSuccess Timer start succeed. 329 * @retval kStatus_TimerError An error occurred. 330 */ 331 timer_status_t TM_Start(timer_handle_t timerHandle, uint8_t timerType, uint32_t timerTimeout); 332 333 /*! 334 * @brief Stop a specified timer 335 * 336 * @param timerHandle the handle of the timer 337 * 338 * @retval kStatus_TimerSuccess Timer stop succeed. 339 * @retval kStatus_TimerError An error occurred. 340 */ 341 timer_status_t TM_Stop(timer_handle_t timerHandle); 342 343 /*! 344 * @brief Check if a specified timer is active 345 * 346 * @param timerHandle the handle of the timer 347 * 348 * @retval return 1 if timer is active, return 0 if timer is not active. 349 */ 350 uint8_t TM_IsTimerActive(timer_handle_t timerHandle); 351 352 /*! 353 * @brief Check if a specified timer is ready 354 * 355 * @param timerHandle the handle of the timer 356 * 357 * @retval return 1 if timer is ready, return 0 if timer is not ready. 358 */ 359 uint8_t TM_IsTimerReady(timer_handle_t timerHandle); 360 361 /*! 362 * @brief Returns the remaining time until timeout 363 * 364 * @param timerHandle the handle of the timer 365 * 366 * @retval remaining time in microseconds until first timer timeouts. 367 */ 368 uint32_t TM_GetRemainingTime(timer_handle_t timerHandle); 369 370 /*! 371 * @brief Get the first expire time of timer 372 * 373 * @param timerType The mode of the timer, for example: kTimerModeSingleShot for the timer will expire 374 * only once, kTimerModeIntervalTimer, the timer will restart each time it expires. 375 * 376 * @retval return the first expire time of all timer. 377 */ 378 uint32_t TM_GetFirstExpireTime(uint8_t timerType); 379 380 /*! 381 * @brief Returns the handle of the timer of the first allocated timer that has the 382 * specified parameter. 383 * 384 * @param param specified parameter of timer 385 * 386 * @retval return the handle of the timer if success. 387 */ 388 timer_handle_t TM_GetFirstTimerWithParam(void *param); 389 390 /*! 391 * @brief Check if all timers except the LP timers are OFF 392 * 393 * 394 * @retval return 1 there are no active non-low power timers, 0 otherwise. 395 */ 396 uint8_t TM_AreAllTimersOff(void); 397 398 /*! 399 * @brief Returns not counted time before system entering in sleep, This function is called 400 * by Low Power module. 401 * 402 * @retval return microseconds that wasn't counted before entering in sleep. 403 */ 404 uint32_t TM_NotCountedTimeBeforeSleep(void); 405 406 /*! 407 * @brief Sync low power timer in sleep mode, This function is called by Low Power module; 408 * 409 * @param sleepDurationTmrUs sleep duration in microseconds unit 410 * 411 */ 412 void TM_SyncLpmTimers(uint32_t sleepDurationTmrUs); 413 414 /*! 415 * @brief Make timer task ready after wakeup from lowpower mode, This function is called 416 * by Low Power module; 417 * 418 */ 419 void TM_MakeTimerTaskReady(void); 420 421 /*! 422 * @brief Get a time-stamp value 423 * 424 */ 425 uint64_t TM_GetTimestamp(void); 426 427 #if defined(__cplusplus) 428 } 429 #endif 430 /*! @}*/ 431 #endif /* #ifndef __TIMERS_MANAGER_H__ */ 432