123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566 |
- /**************************************************************************************************
- Filename: OSAL_Timers.c
- Revised: $Date: 2010-09-17 16:25:30 -0700 (Fri, 17 Sep 2010) $
- Revision: $Revision: 23835 $
- Description: OSAL Timer definition and manipulation functions.
- Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved.
- IMPORTANT: Your use of this Software is limited to those specific rights
- granted under the terms of a software license agreement between the user
- who downloaded the software, his/her employer (which must be your employer)
- and Texas Instruments Incorporated (the "License"). You may not use this
- Software unless you agree to abide by the terms of the License. The License
- limits your use, and you acknowledge, that the Software may not be modified,
- copied or distributed unless embedded on a Texas Instruments microcontroller
- or used solely and exclusively in conjunction with a Texas Instruments radio
- frequency transceiver, which is integrated into your product. Other than for
- the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- works of, modify, distribute, perform, display or sell this Software and/or
- its documentation for any purpose.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- Should you have any questions regarding your right to use this Software,
- contact Texas Instruments Incorporated at www.TI.com.
- **************************************************************************************************/
- /*********************************************************************
- * INCLUDES
- */
- #include "comdef.h"
- #include "OnBoard.h"
- #include "OSAL.h"
- #include "OSAL_Timers.h"
- #include "hal_timer.h"
- /*********************************************************************
- * MACROS
- */
- /*********************************************************************
- * CONSTANTS
- */
- /*********************************************************************
- * TYPEDEFS
- */
- typedef struct
- {
- void *next;
- uint16 timeout;
- uint16 event_flag;
- uint8 task_id;
- uint16 reloadTimeout;
- } osalTimerRec_t;
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- osalTimerRec_t *timerHead;
- /*********************************************************************
- * EXTERNAL VARIABLES
- */
- /*********************************************************************
- * EXTERNAL FUNCTIONS
- */
- /*********************************************************************
- * LOCAL VARIABLES
- */
- // Milliseconds since last reboot
- static uint32 osal_systemClock;
- /*********************************************************************
- * LOCAL FUNCTION PROTOTYPES
- */
- osalTimerRec_t *osalAddTimer( uint8 task_id, uint16 event_flag, uint16 timeout );
- osalTimerRec_t *osalFindTimer( uint8 task_id, uint16 event_flag );
- void osalDeleteTimer( osalTimerRec_t *rmTimer );
- /*********************************************************************
- * FUNCTIONS
- *********************************************************************/
- /*********************************************************************
- * @fn osalTimerInit
- *
- * @brief Initialization for the OSAL Timer System.
- *
- * @param none
- *
- * @return
- */
- void osalTimerInit( void )
- {
- osal_systemClock = 0;
- }
- /*********************************************************************
- * @fn osalAddTimer
- *
- * @brief Add a timer to the timer list.
- * Ints must be disabled.
- *
- * @param task_id
- * @param event_flag
- * @param timeout
- *
- * @return osalTimerRec_t * - pointer to newly created timer
- */
- osalTimerRec_t * osalAddTimer( uint8 task_id, uint16 event_flag, uint16 timeout )
- {
- osalTimerRec_t *newTimer;
- osalTimerRec_t *srchTimer;
- // Look for an existing timer first
- newTimer = osalFindTimer( task_id, event_flag );
- if ( newTimer )
- {
- // Timer is found - update it.
- newTimer->timeout = timeout;
- return ( newTimer );
- }
- else
- {
- // New Timer
- newTimer = osal_mem_alloc( sizeof( osalTimerRec_t ) );
- if ( newTimer )
- {
- // Fill in new timer
- newTimer->task_id = task_id;
- newTimer->event_flag = event_flag;
- newTimer->timeout = timeout;
- newTimer->next = (void *)NULL;
- newTimer->reloadTimeout = 0;
- // Does the timer list already exist
- if ( timerHead == NULL )
- {
- // Start task list
- timerHead = newTimer;
- }
- else
- {
- // Add it to the end of the timer list
- srchTimer = timerHead;
- // Stop at the last record
- while ( srchTimer->next )
- srchTimer = srchTimer->next;
- // Add to the list
- srchTimer->next = newTimer;
- }
- return ( newTimer );
- }
- else
- return ( (osalTimerRec_t *)NULL );
- }
- }
- /*********************************************************************
- * @fn osalFindTimer
- *
- * @brief Find a timer in a timer list.
- * Ints must be disabled.
- *
- * @param task_id
- * @param event_flag
- *
- * @return osalTimerRec_t *
- */
- osalTimerRec_t *osalFindTimer( uint8 task_id, uint16 event_flag )
- {
- osalTimerRec_t *srchTimer;
- // Head of the timer list
- srchTimer = timerHead;
- // Stop when found or at the end
- while ( srchTimer )
- {
- if ( srchTimer->event_flag == event_flag &&
- srchTimer->task_id == task_id )
- break;
- // Not this one, check another
- srchTimer = srchTimer->next;
- }
- return ( srchTimer );
- }
- /*********************************************************************
- * @fn osalDeleteTimer
- *
- * @brief Delete a timer from a timer list.
- *
- * @param table
- * @param rmTimer
- *
- * @return none
- */
- void osalDeleteTimer( osalTimerRec_t *rmTimer )
- {
- // Does the timer list really exist
- if ( rmTimer )
- {
- // Clear the event flag and osalTimerUpdate() will delete
- // the timer from the list.
- rmTimer->event_flag = 0;
- }
- }
- /*********************************************************************
- * @fn osal_start_timerEx
- *
- * @brief
- *
- * This function is called to start a timer to expire in n mSecs.
- * When the timer expires, the calling task will get the specified event.
- *
- * @param uint8 taskID - task id to set timer for
- * @param uint16 event_id - event to be notified with
- * @param UNINT16 timeout_value - in milliseconds.
- *
- * @return SUCCESS, or NO_TIMER_AVAIL.
- */
- uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value )
- {
- halIntState_t intState;
- osalTimerRec_t *newTimer;
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
- // Add timer
- newTimer = osalAddTimer( taskID, event_id, timeout_value );
- HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
- return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );
- }
- /*********************************************************************
- * @fn osal_start_reload_timer
- *
- * @brief
- *
- * This function is called to start a timer to expire in n mSecs.
- * When the timer expires, the calling task will get the specified event
- * and the timer will be reloaded with the timeout value.
- *
- * @param uint8 taskID - task id to set timer for
- * @param uint16 event_id - event to be notified with
- * @param UNINT16 timeout_value - in milliseconds.
- *
- * @return SUCCESS, or NO_TIMER_AVAIL.
- */
- uint8 osal_start_reload_timer( uint8 taskID, uint16 event_id, uint16 timeout_value )
- {
- halIntState_t intState;
- osalTimerRec_t *newTimer;
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
- // Add timer
- newTimer = osalAddTimer( taskID, event_id, timeout_value );
- if ( newTimer )
- {
- // Load the reload timeout value
- newTimer->reloadTimeout = timeout_value;
- }
- HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
- return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );
- }
- /*********************************************************************
- * @fn osal_stop_timerEx
- *
- * @brief
- *
- * This function is called to stop a timer that has already been started.
- * If ZSUCCESS, the function will cancel the timer and prevent the event
- * associated with the timer from being set for the calling task.
- *
- * @param uint8 task_id - task id of timer to stop
- * @param uint16 event_id - identifier of the timer that is to be stopped
- *
- * @return SUCCESS or INVALID_EVENT_ID
- */
- uint8 osal_stop_timerEx( uint8 task_id, uint16 event_id )
- {
- halIntState_t intState;
- osalTimerRec_t *foundTimer;
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
- // Find the timer to stop
- foundTimer = osalFindTimer( task_id, event_id );
- if ( foundTimer )
- {
- osalDeleteTimer( foundTimer );
- }
- HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
- return ( (foundTimer != NULL) ? SUCCESS : INVALID_EVENT_ID );
- }
- /*********************************************************************
- * @fn osal_get_timeoutEx
- *
- * @brief
- *
- * @param uint8 task_id - task id of timer to check
- * @param uint16 event_id - identifier of timer to be checked
- *
- * @return Return the timer's tick count if found, zero otherwise.
- */
- uint16 osal_get_timeoutEx( uint8 task_id, uint16 event_id )
- {
- halIntState_t intState;
- uint16 rtrn = 0;
- osalTimerRec_t *tmr;
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
- tmr = osalFindTimer( task_id, event_id );
- if ( tmr )
- {
- rtrn = tmr->timeout;
- }
- HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
- return rtrn;
- }
- /*********************************************************************
- * @fn osal_timer_num_active
- *
- * @brief
- *
- * This function counts the number of active timers.
- *
- * @return uint8 - number of timers
- */
- uint8 osal_timer_num_active( void )
- {
- halIntState_t intState;
- uint8 num_timers = 0;
- osalTimerRec_t *srchTimer;
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
- // Head of the timer list
- srchTimer = timerHead;
- // Count timers in the list
- while ( srchTimer != NULL )
- {
- num_timers++;
- srchTimer = srchTimer->next;
- }
- HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
- return num_timers;
- }
- /*********************************************************************
- * @fn osalTimerUpdate
- *
- * @brief Update the timer structures for a timer tick.
- *
- * @param none
- *
- * @return none
- *********************************************************************/
- void osalTimerUpdate( uint16 updateTime )
- {
- halIntState_t intState;
- osalTimerRec_t *srchTimer;
- osalTimerRec_t *prevTimer;
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
- // Update the system time
- osal_systemClock += updateTime;
- HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
- // Look for open timer slot
- if ( timerHead != NULL )
- {
- // Add it to the end of the timer list
- srchTimer = timerHead;
- prevTimer = (void *)NULL;
- // Look for open timer slot
- while ( srchTimer )
- {
- osalTimerRec_t *freeTimer = NULL;
-
- HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
-
- if (srchTimer->timeout <= updateTime)
- {
- srchTimer->timeout = 0;
- }
- else
- {
- srchTimer->timeout = srchTimer->timeout - updateTime;
- }
-
- // Check for reloading
- if ( (srchTimer->timeout == 0) && (srchTimer->reloadTimeout) && (srchTimer->event_flag) )
- {
- // Notify the task of a timeout
- osal_set_event( srchTimer->task_id, srchTimer->event_flag );
-
- // Reload the timer timeout value
- srchTimer->timeout = srchTimer->reloadTimeout;
- }
-
- // When timeout or delete (event_flag == 0)
- if ( srchTimer->timeout == 0 || srchTimer->event_flag == 0 )
- {
- // Take out of list
- if ( prevTimer == NULL )
- timerHead = srchTimer->next;
- else
- prevTimer->next = srchTimer->next;
- // Setup to free memory
- freeTimer = srchTimer;
- // Next
- srchTimer = srchTimer->next;
- }
- else
- {
- // Get next
- prevTimer = srchTimer;
- srchTimer = srchTimer->next;
- }
-
- HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
-
- if ( freeTimer )
- {
- if ( freeTimer->timeout == 0 )
- {
- osal_set_event( freeTimer->task_id, freeTimer->event_flag );
- }
- osal_mem_free( freeTimer );
- }
- }
- }
- }
- #ifdef POWER_SAVING
- /*********************************************************************
- * @fn osal_adjust_timers
- *
- * @brief Update the timer structures for elapsed ticks.
- *
- * @param none
- *
- * @return none
- *********************************************************************/
- void osal_adjust_timers( void )
- {
- uint16 eTime;
- if ( timerHead != NULL )
- {
- // Compute elapsed time (msec)
- eTime = TimerElapsed() / TICK_COUNT;
- if ( eTime )
- osalTimerUpdate( eTime );
- }
- }
- /*********************************************************************
- * @fn osal_next_timeout
- *
- * @brief
- *
- * Search timer table to return the lowest timeout value. If the
- * timer list is empty, then the returned timeout will be zero.
- *
- * @param none
- *
- * @return none
- *********************************************************************/
- uint16 osal_next_timeout( void )
- {
- uint16 nextTimeout;
- osalTimerRec_t *srchTimer;
- if ( timerHead != NULL )
- {
- // Head of the timer list
- srchTimer = timerHead;
- nextTimeout = OSAL_TIMERS_MAX_TIMEOUT;
- // Look for the next timeout timer
- while ( srchTimer != NULL )
- {
- if (srchTimer->timeout < nextTimeout)
- {
- nextTimeout = srchTimer->timeout;
- }
- // Check next timer
- srchTimer = srchTimer->next;
- }
- }
- else
- {
- // No timers
- nextTimeout = 0;
- }
- return ( nextTimeout );
- }
- #endif // POWER_SAVING
- /*********************************************************************
- * @fn osal_GetSystemClock()
- *
- * @brief Read the local system clock.
- *
- * @param none
- *
- * @return local clock in milliseconds
- */
- uint32 osal_GetSystemClock( void )
- {
- return ( osal_systemClock );
- }
- /*********************************************************************
- *********************************************************************/
|