Changes for C6670 support from Hao
[keystone-rtos/ibl.git] / src / driver / timer / timer.c
1 /**
2  *   @file  timer.c
3  *
4  *   @brief   
5  *      The file implements the TIMER module. 
6  *
7  *  \par
8  *  NOTE:
9  *      (C) Copyright 2008, Texas Instruments, Inc.
10  * 
11  *  Redistribution and use in source and binary forms, with or without 
12  *  modification, are permitted provided that the following conditions 
13  *  are met:
14  *
15  *    Redistributions of source code must retain the above copyright 
16  *    notice, this list of conditions and the following disclaimer.
17  *
18  *    Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the 
20  *    documentation and/or other materials provided with the   
21  *    distribution.
22  *
23  *    Neither the name of Texas Instruments Incorporated nor the names of
24  *    its contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
28  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
29  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
31  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
32  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
33  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
36  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
37  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  *  \par
40 */
41  #include "types.h"
42  #include "iblloc.h"
43  #include "timer.h"
44  #include "devtimer.h"
45  #include "iblcfg.h"
46  #include "timer_osal.h"
47  #include <string.h>
50 /**********************************************************************
51  *************************** LOCAL Structures *************************
52  **********************************************************************/
54 /**
55  * @brief 
56  *  The structure describes the Timer blocks.
57  *
58  * @details
59  *  Each timer in the system is associated with a timer
60  *  block.  
61  */
62 typedef struct TIMER_BLOCK
63 {
64     /**
65      * @brief  Expiration Routine which is called once the timer
66      * expires.
67      */
68     void        (*expiry)(void);
70     /**
71      * @brief  This is the original expiration time in milli-seconds.
72      */
73     Uint32      org_timeout;
75     /**
76      * @brief  This is the expiration time in milli-seconds. This is
77      * decremented by the timer module.
78      */
79     Uint32      timeout;
80 }TIMER_BLOCK;
82 /**
83  * @brief 
84  *  The structure describes the Timer Master Control Block.
85  *
86  * @details
87  *  The structure contains information about the Timer Master Control
88  *  block which stores information about the Timer Module.
89  */
90 typedef struct TIMER_MCB
91 {
92     /**
93      * @brief  This keeps track of all timers which can exist in the
94      * System.
95      */
96     TIMER_BLOCK   timer[MAX_TIMER_BLOCKS];
98     /**
99      * @brief  This is the number of active timers in the system.
100      */
101     Uint32        num_active_timers;
102 }TIMER_MCB;
104 /**********************************************************************
105  *************************** GLOBAL Variables *************************
106  **********************************************************************/
108 /**
109  * @brief   This global variable keeps track of all the timer which are
110  * currently active in the system.
111  */
112 TIMER_MCB   timermcb;
114 /**********************************************************************
115  *************************** TIMER Functions **************************
116  **********************************************************************/
118 /**
119  *  @b Description
120  *  @n  
121  *      The function initializes the Timer module.
122  *
123  *  @retval
124  *      Not Applicable.
125  */
126 void timer_init (void)
128     /* Initialize the Timer Master Control Block. */
129     timerMemset (&timermcb, 0, sizeof(TIMER_MCB));
130     return;
133 /**
134  *  @b Description
135  *  @n  
136  *      The function creates a timer.
137  *
138  *  @param[in]  timeout
139  *      This is the timeout specified in milli-seconds after which the timer
140  *      will expire.
141  *  @param[in]  expiry
142  *      Expiration routine which is called to indicate that the timer block
143  *      has expired.
144  *
145  *  @retval
146  *      Success  -  Handle to the timer block
147  *  @retval
148  *      Error    -  <0
149  */
150 Int32 timer_add (Uint32 timeout, void (*expiry)(void))
152     Uint16  index;
154     /* Basic Validations: Ensure parameters passed are valid. */
155     if ((timeout == 0) || (expiry == NULL))
156         return -1;
158     /* Cycle through and find a free timer block. */
159     for (index = 0; index < MAX_TIMER_BLOCKS; index++)
160     {
161         /* Free timers can be identified using the expiry routine. NULL indicates
162          * that the timer block is free. */
163         if (timermcb.timer[index].expiry == NULL)
164         {
165             /* Found a free slot. Is this the first timer being created? */
166             if (timermcb.num_active_timers == 0)
167             {
168                 /* YES. We need to start the device timer. */
169                 if (dev_create_timer() < 0)
170                 {
171                     /* Device layer timer creation failed. We will not be able
172                      * to get the timers operational without this API. So we 
173                      * might as well fail also. */
174                     return -1;
175                 }
176             }
178             /* Populate the timer block structure. */
179             timermcb.timer[index].expiry      = expiry;
180             timermcb.timer[index].timeout     = timeout;
181             timermcb.timer[index].org_timeout = timeout;
183             /* Increment the number of timers in the system */
184             timermcb.num_active_timers++;
186             /* Return the handle to the timer block. */
187             return index;
188         }
189     }
191     /* Control comes here indicating that there were no free timer slots. */
192     return -1;
195 /**
196  *  @b Description
197  *  @n  
198  *      The function deletes a timer which was previously created.
199  *
200  *  @param[in]  handle
201  *      This is the handle to the timer block to be deleted.
202  *
203  *  @retval
204  *      Not Applicable.
205  */
206 void timer_delete (Int32 handle)
208     /* Basic Validations: Ensure paramter is valid. */
209     if ((handle < 0) || (handle > MAX_TIMER_BLOCKS))
210         return;
212     /* Make sure there is at least one timer which is active; */
213     if (timermcb.num_active_timers > 0)
214     {
215         /* Simply reset the memory contents */
216         timerMemset ((void *)&timermcb.timer[handle], 0, sizeof(TIMER_BLOCK));
218         /* Decrement the number of active timers in the system */
219         timermcb.num_active_timers--;
221         /* Check if there are any active timers in the system? */
222         if (timermcb.num_active_timers == 0)
223         {
224             /* No more active timers; we can delete the timer in the device layer. */
225             dev_delete_timer ();
226         }
227     }
228     return;
231 /**
232  *  @b Description
233  *  @n  
234  *      The function runs the timer scheduler. This API is required to be 
235  *      called by the boot modules and this in turn will decrement the various
236  *      timer registered in the system and will call the appropriate
237  *      expiration routines. If the boot modules fail to call this API then 
238  *      the timers will never expire.
239  *
240  *  @retval
241  *      Not Applicable.
242  */
243 void timer_run (void)
245     Uint16  index;
247     /* Check if there are any active timers in the System or not? 
248      * If none are present; then we dont need to run the scheduler. */
249     if (timermcb.num_active_timers == 0)
250         return;
252     /* Check if the device timer has expired or not? 
253      *  If the timer has not expired there is no management to be done. */
254     if (dev_check_timer() == FALSE)
255         return;
257     /* Cycle through all the timer blocks and update them. */
258     for (index = 0; index < MAX_TIMER_BLOCKS; index++)
259     {
260         /* Is this an active timer? */
261         if (timermcb.timer[index].expiry != NULL)
262         {
263             /* YES. Decrement the timeout. */
264             timermcb.timer[index].timeout = timermcb.timer[index].timeout - 100;
266             /* Has the timer expired? */
267             if (timermcb.timer[index].timeout == 0)
268             {
269                 /* Reset the timeouts */
270                 timermcb.timer[index].timeout = timermcb.timer[index].org_timeout;
272                 /* Call the expiration routine. */   
273                 timermcb.timer[index].expiry();
274             }
276         }
277     }
278     return;