CoOS Demonstrator adapted to mbed Hardware.

Dependencies:   mbed

Revision:
0:57690853989a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/timer.c	Fri Dec 03 19:45:30 2010 +0000
@@ -0,0 +1,447 @@
+/**
+ *******************************************************************************
+ * @file       timer.c
+ * @version    V1.1.3    
+ * @date       2010.04.26
+ * @brief      timer management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+/*---------------------------- Variable Define -------------------------------*/
+#if CFG_TMR_EN > 0
+
+TmrCtrl    TmrTbl[CFG_MAX_TMR]= {{0}};/*!< Table which save timer control block.*/
+P_TmrCtrl  TmrList     = 0;      /*!< The header of the TmrCtrl list.      */
+U32        TmrIDVessel = 0;         /*!< Timer ID container.                  */
+
+
+/**
+ *******************************************************************************
+ * @brief      Insert a timer into the timer list	   
+ * @param[in]  tmrID    Specify timer ID which insertted.		 
+ * @param[out] None  
+ * @retval     E_INVALID_ID  Timer ID passed was invalid,insert fail.
+ * @retval     E_OK          Insert successful.			 
+ *
+ * @par Description
+ * @details    This function is called to insert a timer into the timer list.  
+ *******************************************************************************
+ */
+static void InsertTmrList(OS_TCID tmrID)
+{
+    P_TmrCtrl pTmr;
+    S32 deltaTicks;
+    U32 tmrCnt;
+    tmrCnt = TmrTbl[tmrID].tmrCnt;      /* Get timer time                     */
+    
+    if(tmrCnt == 0)                     /* Is timer time==0?                  */
+    {
+        return;                         /* Do nothing,return                  */
+    }
+    
+    OsSchedLock();                      /* Lock schedule                      */
+    if(TmrList == 0)                 /* Is no item in timer list?          */
+    {
+        TmrList = &TmrTbl[tmrID];       /* Yes,set this as first item         */
+    }
+    else                  /* No,find correct place ,and insert inserted timer */
+    {								    
+      	pTmr       = TmrList; 
+      	deltaTicks = tmrCnt;            /* Get timer tick                     */
+      	
+      	/* find correct place */
+      	while(pTmr != 0)
+      	{				    
+            deltaTicks -= pTmr->tmrCnt; /* Get ticks with previous item       */
+            if(deltaTicks < 0)          /* Is delta ticks<0?                  */  
+            {	
+                /* Yes,get correct place */
+                if(pTmr->tmrPrev!= 0)/* Is head item of timer list?        */
+                {	
+                    /* No,insert into */
+                    pTmr->tmrPrev->tmrNext = &TmrTbl[tmrID]; 
+                    TmrTbl[tmrID].tmrPrev  = pTmr->tmrPrev;
+                    TmrTbl[tmrID].tmrNext  = pTmr;
+                    pTmr->tmrPrev          = &TmrTbl[tmrID];
+                }
+                else                    /* Yes,set task as first item         */ 	
+                {
+                    TmrTbl[tmrID].tmrNext = TmrList;
+                    TmrList->tmrPrev      = &TmrTbl[tmrID];
+                    TmrList               = &TmrTbl[tmrID];
+                }
+                TmrTbl[tmrID].tmrCnt            = TmrTbl[tmrID].tmrNext->tmrCnt+deltaTicks;
+                TmrTbl[tmrID].tmrNext->tmrCnt  -= TmrTbl[tmrID].tmrCnt; 
+                break;	
+            }
+            /* Is last item in list? */									
+            else if((deltaTicks >= 0) && (pTmr->tmrNext == 0))
+            {	
+                /* Yes,insert into */
+                TmrTbl[tmrID].tmrPrev = pTmr;
+                pTmr->tmrNext         = &TmrTbl[tmrID];	
+                TmrTbl[tmrID].tmrCnt  = deltaTicks;
+                break;	
+            }
+            pTmr = pTmr->tmrNext;       /* Get the next item in timer list    */	
+      	}
+    }
+    OsSchedUnlock();                    /* Unlock schedule                    */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Remove a timer from the timer list	  
+ * @param[in]  tmrID    Specify ID for a timer which removed form timer list.	 
+ * @param[out] None 
+ * @retval     None
+ *
+ * @par Description
+ * @details    This function is called to remove a timer from the timer list. 
+ *******************************************************************************
+ */
+static void RemoveTmrList(OS_TCID tmrID)
+{
+    P_TmrCtrl pTmr;
+    
+    pTmr = &TmrTbl[tmrID];
+    
+    OsSchedLock();                      /* Lock schedule                      */
+    
+    /* Is there only one item in timer list?                                  */
+    if((pTmr->tmrPrev == 0) && (pTmr->tmrNext == 0))
+    {		
+        TmrList = 0;                 /* Yes,set timer list as 0         */ 	
+    }
+    else if(pTmr->tmrPrev == 0)      /* Is the first item in timer list?   */
+    {   /* Yes,remove timer from list,and reset timer list                    */
+        TmrList  = pTmr->tmrNext;
+        TmrList->tmrPrev = 0;
+        pTmr->tmrNext->tmrCnt += pTmr->tmrCnt;
+        pTmr->tmrNext    = 0;  
+    }
+    else if(pTmr->tmrNext == 0)      /* Is the last item in timer list?    */
+    {
+        /* Yes,remove timer form list */
+        pTmr->tmrPrev->tmrNext = 0;	
+        pTmr->tmrPrev = 0;
+    }
+    else                                /* No, remove timer from list         */
+    {
+        pTmr->tmrPrev->tmrNext  =  pTmr->tmrNext;
+        pTmr->tmrNext->tmrPrev  =  pTmr->tmrPrev;
+        pTmr->tmrNext->tmrCnt  += pTmr->tmrCnt;
+        pTmr->tmrNext = 0;
+        pTmr->tmrPrev = 0;
+    }
+    OsSchedUnlock();                    /* Unlock schedule                    */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a timer	   
+ * @param[in]  tmrType     Specify timer's type.		 
+ * @param[in]  tmrCnt      Specify timer initial counter value.  
+ * @param[in]  tmrReload   Specify timer reload value.
+ * @param[in]  func        Specify timer callback function entry.
+ * @param[out] None
+ * @retval     E_CREATE_FAIL   Create timer fail.
+ * @retval     others          Create timer successful.			 
+ *
+ * @par Description
+ * @details    This function is called to create a timer.
+ *******************************************************************************
+ */
+OS_TCID CoCreateTmr(U8 tmrType, U32 tmrCnt, U32 tmrReload, vFUNCPtr func)
+{
+    U8 i;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if((tmrType != TMR_TYPE_ONE_SHOT) && (tmrType != TMR_TYPE_PERIODIC))
+    {
+        return E_CREATE_FAIL;	
+    }
+    if(func == 0)
+    {
+        return E_CREATE_FAIL;
+    }
+#endif
+    OsSchedLock();                        /* Lock schedule                    */
+    for(i = 0; i < CFG_MAX_TMR; i++)
+    {
+        if((TmrIDVessel & (1 << i)) == 0) /* Is free timer ID?                */
+        {
+            TmrIDVessel |= (1<<i);        /* Yes,assign ID to this timer      */
+            OsSchedUnlock();              /* Unlock schedule                  */
+            TmrTbl[i].tmrID     = i;      /* Initialize timer as user set     */
+            TmrTbl[i].tmrType   = tmrType;	
+            TmrTbl[i].tmrState  = TMR_STATE_STOPPED;
+            TmrTbl[i].tmrCnt    = tmrCnt;
+            TmrTbl[i].tmrReload	= tmrReload;
+            TmrTbl[i].tmrCallBack = func;
+            TmrTbl[i].tmrPrev   = 0;
+            TmrTbl[i].tmrNext   = 0;
+            return i;                     /* Return timer ID                  */
+        }
+    }
+    OsSchedUnlock();                      /* Unlock schedule                  */
+    return E_CREATE_FAIL;                 /* Error return                     */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Start counter	 
+ * @param[in]  tmrID    Specify a timer which startted.		 
+ * @param[out] None 
+ * @retval     E_INVALID_ID  The timer id passed was invalid,can't start timer	
+ * @retval     E_OK          Insert a timer to timer list and start it successful. 
+ *
+ * @par Description
+ * @details    This function is called to make a timer start countering. 
+ *******************************************************************************
+ */
+StatusType CoStartTmr(OS_TCID tmrID)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if( (TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING)   /* Is timer running?    */
+    {
+        return E_OK;                              /* Yes,do nothing,return OK */
+    }
+    
+    /* No,set timer status as TMR_STATE_RUNNING */
+    TmrTbl[tmrID].tmrState = TMR_STATE_RUNNING; 
+    InsertTmrList(tmrID);               /* Insert this timer into timer list  */
+    return E_OK;                        /* Return OK                          */
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Stop countering for a spcify timer	  
+ * @param[in]  tmrID    Specify a timer which stopped.	 
+ * @param[out] None  	 
+ * @retval     E_INVALID_ID  The timer id passed was invalid, stop failure.
+ * @retval     E_OK          Stop a timer countering successful.
+ *
+ * @par Description
+ * @details    This function is called to stop a timer from counting. 
+ *******************************************************************************
+ */
+StatusType CoStopTmr(OS_TCID tmrID)
+{	
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if((TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    
+    
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_STOPPED)/* Does timer stop running?*/
+    {
+        return E_OK;                    /* Yes,do nothing,return OK           */
+    }
+    RemoveTmrList(tmrID);             /* No,remove this timer from timer list */
+    
+    /* Set timer status as TMR_STATE_STOPPED  */
+    TmrTbl[tmrID].tmrState = TMR_STATE_STOPPED;	
+    return E_OK;                        /* Return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete a timer	 
+ * @param[in]  tmrID     Specify a timer which deleted.		 
+ * @param[out] None   
+ * @retval     E_INVALID_ID  The timer id passed was invalid,deleted failure.	
+ * @retval     E_OK          Delete a timer successful.
+ *
+ * @par Description
+ * @details    This function is called to delete a timer which created before.	
+ *******************************************************************************
+ */
+StatusType CoDelTmr(OS_TCID tmrID)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if( (TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+	
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING) /* Is timer running?      */
+    {
+        RemoveTmrList(tmrID);         /* Yes,remove this timer from timer list*/
+    }
+    TmrIDVessel &=~(1<<tmrID);        /* Release resource that this timer hold*/
+    return E_OK;                      /* Return OK                            */
+}
+
+ 
+/**
+ *******************************************************************************
+ * @brief      Get current counter of specify timer	 
+ * @param[in]  tmrID          Specify timer by ID.		 
+ * @param[out] E_INVALID_ID   Invalid ID was passed and get counter failure.	  
+ * @param[out] E_OK           Get current counter successful.	 
+ * @retval     Current counter of a timer which specify by id.			 
+ *
+ * @par Description
+ * @details    This function is called to obtain current counter of specify timer.
+ *******************************************************************************
+ */
+U32 CoGetCurTmrCnt(OS_TCID tmrID,StatusType* perr)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        *perr = E_INVALID_ID;
+        return 0;
+    }
+    if((TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        *perr = E_INVALID_ID;
+        return 0;
+    }
+#endif
+    *perr = E_OK;
+    return TmrTbl[tmrID].tmrCnt;        /* Return timer counter               */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Setting for a specify timer	  		   	
+ * @param[in]  tmrID       Specify timer by ID.
+ * @param[in]  tmrCnt      Specify timer counter which need to be set.
+ * @param[in]  tmrReload   Specify timer reload value which need to be set.		 
+ * @param[out] None  
+ * @retval     E_INVALID_ID  The ID passed was invalid,set fail.
+ * @retval     E_OK          Set timer counter successful.				 
+ *
+ * @par Description
+ * @details    This function is called to set timer counter and reload value.
+ *******************************************************************************
+ */
+StatusType CoSetTmrCnt(OS_TCID tmrID,U32 tmrCnt,U32 tmrReload)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if( (TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    TmrTbl[tmrID].tmrCnt    = tmrCnt; /* Reset timer counter and reload value */
+    TmrTbl[tmrID].tmrReload = tmrReload;
+    								
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING)   /* Is timer running?    */
+    {
+        RemoveTmrList(tmrID);           /* Yes,reorder timer in timer list    */
+        InsertTmrList(tmrID);	
+    }
+    return E_OK;                        /* Return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Timer counter dispose	   
+ * @param[in]  None 	 
+ * @param[out] None	 
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is called to dispose timer counter.
+ *******************************************************************************
+ */
+void TmrDispose(void)
+{
+    P_TmrCtrl	pTmr;
+    
+    pTmr = TmrList;                     /* Get first item of timer list       */
+    while((pTmr != 0) && (pTmr->tmrCnt == 0) )
+    {	
+        if(pTmr->tmrType == TMR_TYPE_ONE_SHOT)    /* Is a One-shot timer?     */
+        {
+            /* Yes,remove this timer from timer list                          */
+            RemoveTmrList(pTmr->tmrID);
+            
+            /* Set timer status as TMR_STATE_STOPPED                          */
+            pTmr->tmrState = TMR_STATE_STOPPED;
+            (pTmr->tmrCallBack)();          /* Call timer callback function   */
+        }
+        else if(pTmr->tmrType == TMR_TYPE_PERIODIC)   /* Is a periodic timer? */
+        {
+            /* Yes,remove this timer from timer list                          */
+            RemoveTmrList(pTmr->tmrID); 
+            pTmr->tmrCnt = pTmr->tmrReload;   /* Reset timer tick             */
+            InsertTmrList(pTmr->tmrID);       /* Insert timer into timer list */
+            (pTmr->tmrCallBack)();            /* Call timer callback function */
+        }
+        pTmr = TmrList;	                      /* Get first item of timer list */
+    }
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Timer counter dispose in ISR	   
+ * @param[in]  None 	 
+ * @param[out] None	 
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is called to dispose timer counter.
+ *******************************************************************************
+ */
+void isr_TmrDispose(void)
+{
+    if(OSSchedLock > 1)                 /* Is schedule lock?                  */
+    {
+        IsrReq = TRUE;
+        TimerReq  = TRUE;               /* Yes,set timer request true         */
+    }
+    else
+    {
+        TmrDispose();                   /* No,call handler                    */
+    }
+}	 
+
+#endif