OSAL_Timers.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. /**************************************************************************************************
  2. Filename: OSAL_Timers.c
  3. Revised: $Date: 2009-02-24 11:20:27 -0800 (Tue, 24 Feb 2009) $
  4. Revision: $Revision: 19256 $
  5. Description: OSAL Timer definition and manipulation functions.
  6. Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /*********************************************************************
  34. * INCLUDES
  35. */
  36. #include "comdef.h"
  37. #include "OnBoard.h"
  38. #include "OSAL.h"
  39. #include "OSAL_Timers.h"
  40. #include "hal_timer.h"
  41. /*********************************************************************
  42. * MACROS
  43. */
  44. /*********************************************************************
  45. * CONSTANTS
  46. */
  47. /*********************************************************************
  48. * TYPEDEFS
  49. */
  50. typedef struct
  51. {
  52. void *next;
  53. uint16 timeout;
  54. uint16 event_flag;
  55. uint8 task_id;
  56. } osalTimerRec_t;
  57. /*********************************************************************
  58. * GLOBAL VARIABLES
  59. */
  60. osalTimerRec_t *timerHead;
  61. /*********************************************************************
  62. * EXTERNAL VARIABLES
  63. */
  64. /*********************************************************************
  65. * EXTERNAL FUNCTIONS
  66. */
  67. /*********************************************************************
  68. * LOCAL VARIABLES
  69. */
  70. // Milliseconds since last reboot
  71. static uint32 osal_systemClock;
  72. /*********************************************************************
  73. * LOCAL FUNCTION PROTOTYPES
  74. */
  75. osalTimerRec_t *osalAddTimer( uint8 task_id, uint16 event_flag, uint16 timeout );
  76. osalTimerRec_t *osalFindTimer( uint8 task_id, uint16 event_flag );
  77. void osalDeleteTimer( osalTimerRec_t *rmTimer );
  78. /*********************************************************************
  79. * FUNCTIONS
  80. *********************************************************************/
  81. /*********************************************************************
  82. * @fn osalTimerInit
  83. *
  84. * @brief Initialization for the OSAL Timer System.
  85. *
  86. * @param none
  87. *
  88. * @return
  89. */
  90. void osalTimerInit( void )
  91. {
  92. osal_systemClock = 0;
  93. }
  94. /*********************************************************************
  95. * @fn osalAddTimer
  96. *
  97. * @brief Add a timer to the timer list.
  98. * Ints must be disabled.
  99. *
  100. * @param task_id
  101. * @param event_flag
  102. * @param timeout
  103. *
  104. * @return osalTimerRec_t * - pointer to newly created timer
  105. */
  106. osalTimerRec_t * osalAddTimer( uint8 task_id, uint16 event_flag, uint16 timeout )
  107. {
  108. osalTimerRec_t *newTimer;
  109. osalTimerRec_t *srchTimer;
  110. // Look for an existing timer first
  111. newTimer = osalFindTimer( task_id, event_flag );
  112. if ( newTimer )
  113. {
  114. // Timer is found - update it.
  115. newTimer->timeout = timeout;
  116. return ( newTimer );
  117. }
  118. else
  119. {
  120. // New Timer
  121. newTimer = osal_mem_alloc( sizeof( osalTimerRec_t ) );
  122. if ( newTimer )
  123. {
  124. // Fill in new timer
  125. newTimer->task_id = task_id;
  126. newTimer->event_flag = event_flag;
  127. newTimer->timeout = timeout;
  128. newTimer->next = (void *)NULL;
  129. // Does the timer list already exist
  130. if ( timerHead == NULL )
  131. {
  132. // Start task list
  133. timerHead = newTimer;
  134. }
  135. else
  136. {
  137. // Add it to the end of the timer list
  138. srchTimer = timerHead;
  139. // Stop at the last record
  140. while ( srchTimer->next )
  141. srchTimer = srchTimer->next;
  142. // Add to the list
  143. srchTimer->next = newTimer;
  144. }
  145. return ( newTimer );
  146. }
  147. else
  148. return ( (osalTimerRec_t *)NULL );
  149. }
  150. }
  151. /*********************************************************************
  152. * @fn osalFindTimer
  153. *
  154. * @brief Find a timer in a timer list.
  155. * Ints must be disabled.
  156. *
  157. * @param task_id
  158. * @param event_flag
  159. *
  160. * @return osalTimerRec_t *
  161. */
  162. osalTimerRec_t *osalFindTimer( uint8 task_id, uint16 event_flag )
  163. {
  164. osalTimerRec_t *srchTimer;
  165. // Head of the timer list
  166. srchTimer = timerHead;
  167. // Stop when found or at the end
  168. while ( srchTimer )
  169. {
  170. if ( srchTimer->event_flag == event_flag &&
  171. srchTimer->task_id == task_id )
  172. break;
  173. // Not this one, check another
  174. srchTimer = srchTimer->next;
  175. }
  176. return ( srchTimer );
  177. }
  178. /*********************************************************************
  179. * @fn osalDeleteTimer
  180. *
  181. * @brief Delete a timer from a timer list.
  182. *
  183. * @param table
  184. * @param rmTimer
  185. *
  186. * @return none
  187. */
  188. void osalDeleteTimer( osalTimerRec_t *rmTimer )
  189. {
  190. // Does the timer list really exist
  191. if ( rmTimer )
  192. {
  193. // Clear the event flag and osalTimerUpdate() will delete
  194. // the timer from the list.
  195. rmTimer->event_flag = 0;
  196. }
  197. }
  198. /*********************************************************************
  199. * @fn osal_start_timerEx
  200. *
  201. * @brief
  202. *
  203. * This function is called to start a timer to expire in n mSecs.
  204. * When the timer expires, the calling task will get the specified event.
  205. *
  206. * @param uint8 taskID - task id to set timer for
  207. * @param uint16 event_id - event to be notified with
  208. * @param UNINT16 timeout_value - in milliseconds.
  209. *
  210. * @return SUCCESS, or NO_TIMER_AVAIL.
  211. */
  212. uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value )
  213. {
  214. halIntState_t intState;
  215. osalTimerRec_t *newTimer;
  216. HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
  217. // Add timer
  218. newTimer = osalAddTimer( taskID, event_id, timeout_value );
  219. HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
  220. return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );
  221. }
  222. /*********************************************************************
  223. * @fn osal_stop_timerEx
  224. *
  225. * @brief
  226. *
  227. * This function is called to stop a timer that has already been started.
  228. * If ZSUCCESS, the function will cancel the timer and prevent the event
  229. * associated with the timer from being set for the calling task.
  230. *
  231. * @param uint8 task_id - task id of timer to stop
  232. * @param uint16 event_id - identifier of the timer that is to be stopped
  233. *
  234. * @return SUCCESS or INVALID_EVENT_ID
  235. */
  236. uint8 osal_stop_timerEx( uint8 task_id, uint16 event_id )
  237. {
  238. halIntState_t intState;
  239. osalTimerRec_t *foundTimer;
  240. HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
  241. // Find the timer to stop
  242. foundTimer = osalFindTimer( task_id, event_id );
  243. if ( foundTimer )
  244. {
  245. osalDeleteTimer( foundTimer );
  246. }
  247. HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
  248. return ( (foundTimer != NULL) ? SUCCESS : INVALID_EVENT_ID );
  249. }
  250. /*********************************************************************
  251. * @fn osal_get_timeoutEx
  252. *
  253. * @brief
  254. *
  255. * @param uint8 task_id - task id of timer to check
  256. * @param uint16 event_id - identifier of timer to be checked
  257. *
  258. * @return Return the timer's tick count if found, zero otherwise.
  259. */
  260. uint16 osal_get_timeoutEx( uint8 task_id, uint16 event_id )
  261. {
  262. halIntState_t intState;
  263. uint16 rtrn = 0;
  264. osalTimerRec_t *tmr;
  265. HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
  266. tmr = osalFindTimer( task_id, event_id );
  267. if ( tmr )
  268. {
  269. rtrn = tmr->timeout;
  270. }
  271. HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
  272. return rtrn;
  273. }
  274. /*********************************************************************
  275. * @fn osal_timer_num_active
  276. *
  277. * @brief
  278. *
  279. * This function counts the number of active timers.
  280. *
  281. * @return uint8 - number of timers
  282. */
  283. uint8 osal_timer_num_active( void )
  284. {
  285. halIntState_t intState;
  286. uint8 num_timers = 0;
  287. osalTimerRec_t *srchTimer;
  288. HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
  289. // Head of the timer list
  290. srchTimer = timerHead;
  291. // Count timers in the list
  292. while ( srchTimer != NULL )
  293. {
  294. num_timers++;
  295. srchTimer = srchTimer->next;
  296. }
  297. HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
  298. return num_timers;
  299. }
  300. /*********************************************************************
  301. * @fn osalTimerUpdate
  302. *
  303. * @brief Update the timer structures for a timer tick.
  304. *
  305. * @param none
  306. *
  307. * @return none
  308. *********************************************************************/
  309. void osalTimerUpdate( uint16 updateTime )
  310. {
  311. halIntState_t intState;
  312. osalTimerRec_t *srchTimer;
  313. osalTimerRec_t *prevTimer;
  314. HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
  315. // Update the system time
  316. osal_systemClock += updateTime;
  317. HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
  318. // Look for open timer slot
  319. if ( timerHead != NULL )
  320. {
  321. // Add it to the end of the timer list
  322. srchTimer = timerHead;
  323. prevTimer = (void *)NULL;
  324. // Look for open timer slot
  325. while ( srchTimer )
  326. {
  327. osalTimerRec_t *freeTimer = NULL;
  328. HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
  329. if (srchTimer->timeout <= updateTime)
  330. {
  331. srchTimer->timeout = 0;
  332. }
  333. else
  334. {
  335. srchTimer->timeout = srchTimer->timeout - updateTime;
  336. }
  337. // When timeout or delete (event_flag == 0)
  338. if ( srchTimer->timeout == 0 || srchTimer->event_flag == 0 )
  339. {
  340. // Take out of list
  341. if ( prevTimer == NULL )
  342. timerHead = srchTimer->next;
  343. else
  344. prevTimer->next = srchTimer->next;
  345. // Setup to free memory
  346. freeTimer = srchTimer;
  347. // Next
  348. srchTimer = srchTimer->next;
  349. }
  350. else
  351. {
  352. // Get next
  353. prevTimer = srchTimer;
  354. srchTimer = srchTimer->next;
  355. }
  356. HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
  357. if ( freeTimer )
  358. {
  359. if ( freeTimer->timeout == 0 )
  360. {
  361. osal_set_event( freeTimer->task_id, freeTimer->event_flag );
  362. }
  363. osal_mem_free( freeTimer );
  364. }
  365. }
  366. }
  367. }
  368. #ifdef POWER_SAVING
  369. /*********************************************************************
  370. * @fn osal_adjust_timers
  371. *
  372. * @brief Update the timer structures for elapsed ticks.
  373. *
  374. * @param none
  375. *
  376. * @return none
  377. *********************************************************************/
  378. void osal_adjust_timers( void )
  379. {
  380. uint16 eTime;
  381. if ( timerHead != NULL )
  382. {
  383. // Compute elapsed time (msec)
  384. eTime = TimerElapsed() / TICK_COUNT;
  385. if ( eTime )
  386. osalTimerUpdate( eTime );
  387. }
  388. }
  389. /*********************************************************************
  390. * @fn osal_next_timeout
  391. *
  392. * @brief
  393. *
  394. * Search timer table to return the lowest timeout value. If the
  395. * timer list is empty, then the returned timeout will be zero.
  396. *
  397. * @param none
  398. *
  399. * @return none
  400. *********************************************************************/
  401. uint16 osal_next_timeout( void )
  402. {
  403. uint16 nextTimeout;
  404. osalTimerRec_t *srchTimer;
  405. if ( timerHead != NULL )
  406. {
  407. // Head of the timer list
  408. srchTimer = timerHead;
  409. nextTimeout = OSAL_TIMERS_MAX_TIMEOUT;
  410. // Look for the next timeout timer
  411. while ( srchTimer != NULL )
  412. {
  413. if (srchTimer->timeout < nextTimeout)
  414. {
  415. nextTimeout = srchTimer->timeout;
  416. }
  417. // Check next timer
  418. srchTimer = srchTimer->next;
  419. }
  420. }
  421. else
  422. {
  423. // No timers
  424. nextTimeout = 0;
  425. }
  426. return ( nextTimeout );
  427. }
  428. #endif // POWER_SAVING
  429. /*********************************************************************
  430. * @fn osal_GetSystemClock()
  431. *
  432. * @brief Read the local system clock.
  433. *
  434. * @param none
  435. *
  436. * @return local clock in milliseconds
  437. */
  438. uint32 osal_GetSystemClock( void )
  439. {
  440. return ( osal_systemClock );
  441. }
  442. /*********************************************************************
  443. *********************************************************************/