/**********************************************************************/
/*                                                                    */
/* File name: uip_kernel_time.c                                       */
/*                                                                    */
/* Since:     2007-02-25                                              */
/*                                                                    */
/* Version:   uip Kernel v1.09                                        */
/*            Copyright (C) 2006..2018 Wang Baojin.                   */
/*                                                                    */
/* Author:    Designed by Wang Baojin(王保进)                         */
/*                                                                    */
/*                                                                    */
/* Purpose:   Support uip kernel timing/alarm management              */
/*                                                                    */
/* Distribution: This file is part of uip kernel.                     */
/*            uip Kernel is free software, you can redistribute it    */
/*            and/or modify it under the terms of the GNU General     */
/*            Public License as published by the Free Software        */
/*            Foundation either version 2, or (at your option)        */
/*            any later version.                                      */
/*                                                                    */
/*            uip Kernel is distributed in the hope that it will be   */
/*            useful, but WITHOUT ANY WARRANTY without even the       */
/*            implied warranty of MERCHANTABILITY or FITNESS FOR A    */
/*            PuipICULAR PURPOSE.  See the GNU General Public         */
/*            License for more details.                               */
/*                                                                    */
/*            You should have received a copy of the GNU General      */
/*            Public License along with gpsim see the file            */
/*            COPYING.txt. If not, write to the Free Software         */
/*            Foundation, 59 Temple Place - Suite 330,                */
/*            Boston, MA 02111-1307, USA.                             */
/*                                                                    */
/*          > A special exception to the GPL can be applied should    */
/*            you wish to distribute a combined work that includes    */
/*            uip Kernel, without being obliged to provide the        */
/*            source code for any proprietary components.             */
/*                                                                    */
/* History:                                                           */
/*   2007/02/25  [WBJ] Create this file.                              */
/*                                                                    */
/**********************************************************************/

#include "uip_kernel_api.h"

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    UIP_GetAlarmBase                                     1.09       */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    The system service UIP_GetAlarmBase reads the alarm base        */
/*    characteristics. The return value <Info> is a structure         */
/*    in which the information of data type AlarmBaseType is stored.  */ 
/*                                                                    */ 
/*  Note:                                                             */
/*    Any events not set in the event mask remain unchanged.          */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    AlarmID                     Reference to alarm                  */
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    Info                        Reference to structure with         */
/*                                constants of the alarm base         */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    E_OK                        No error                            */ 
/*    E_OS_ID                     Alarm <AlarmID> is invalid          */
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    ISR, Task,  Several hook routines                               */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*    BCC1, BCC2, ECC1, ECC2                                          */ 
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/ 
StatusType UIP_GetAlarmBase(AlarmType AlarmID, AlarmBaseRefType Info)
{
    uipAlarmPtr        alarmPtr;
    
    if (AlarmID > uipAlarmNumber)
    {
        return (E_OS_ID);
    }  
  
    alarmPtr = (uipAlarmPtr)(&uipACBArray[AlarmID]);
    
    Info = (AlarmBaseRefType)(&((alarmPtr -> uipCounterPtr) -> uipCtrBase));
    
    return (E_OK);
} /* end */

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    UIP_GetAlarm                                        1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    The system service returns the relative value in ticks before   */
/*    the alarm<AlarmID> expires.                                     */ 
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    It is up to the application to decide whether for example a     */
/*    UIP_CancelAlarm may still be useful.                            */
/*    If <AlarmID> is not in use, <Tick> is not defined.              */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    AlarmID                    Reference to an alarm                */ 
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    Tick                       Relative value in ticks before       */
/*                               the alarm <AlarmID> expires.         */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    E_OK                        No error                            */ 
/*    E_OS_NOFUNC                 Alarm <AlarmID> is not used         */ 
/*    E_OS_ID                     Alarm <AlarmID> is invalid          */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    ISR, Task,  Several hook routines                               */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*    BCC1, BCC2, ECC1, ECC2                                          */ 
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/ 
StatusType UIP_GetAlarm(AlarmType AlarmID, TickRefType Tick)
{
    uip_INTERRUPT_STATE_SAVED;
    uipAlarmPtr        alarmPtr;
          
    if (AlarmID > uipAlarmNumber)
    {
        return (E_OS_ID);
    }  
    
    alarmPtr = (uipAlarmPtr)(&uipACBArray[AlarmID]);

    /* Enter critical area */
    uip_KERNEL_DISABLE_INTS;
    
    if ((alarmPtr -> uipAlarmState) == uip_ALARM_OFF)
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
  	    return (E_OS_NOFUNC);
    } 
  
    /* Get tick value of AlarmID */
    if ((alarmPtr -> uipAlarmValue) >= ((alarmPtr -> uipCounterPtr) -> uipCtrValue))
    {
    	*Tick = (alarmPtr -> uipAlarmValue) - 
                ((alarmPtr -> uipCounterPtr) -> uipCtrValue);
    }
    else
    {
    	*Tick = (alarmPtr -> uipAlarmValue) + 
    	        ((((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue) - 
    	                                ((alarmPtr -> uipCounterPtr) -> uipCtrValue));
    } 
    /* Leave cirtical area */
    uip_KERNEL_RESTORE_INTS;        

    /* No error */
    return (E_OK);
} /* end */

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    UIP_SetRelAlarm                                     1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    The system service occupies the alarm <AlarmID> element.        */
/*    After <increment> ticks have elapsed, the task assigned         */
/*    to the alarm <AlarmID> is activated or the assigned event       */
/*    (only for extended tasks) is set or the alarm-callback          */
/*    routine is called.                                              */ 
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    The behaviour of <increment> equal to 0 is up to the            */
/*    implementation.                                                 */
/*    If the relative value <increment> is very small, the alarm      */
/*    may expire, and the task may become ready or the alarm-callback */
/*    may be called before the system service returns to the user.    */
/*    If <cycle> is unequal zero, the alarm element is logged on      */
/*    again immediately after expiry with the relative value <cycle>. */
/*    The alarm <AlarmID> must not already be in use.                 */
/*    To change values of alarms already in use the alarm shall be    */
/*    cancelled first.                                                */
/*    If the alarm is already in use, this call will be ignored and   */
/*    the error E_OS_STATE is returned.                               */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    AlarmID                     Reference to the alarm              */
/*                                elementincrement                    */
/*    increment                   Relative value in ticks             */
/*    cycle                       Cycle value in case of cyclic alarm */
/*                                In case of single alarms,           */
/*                                cycle shall be zero.                */ 
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    E_OK                        No error                            */ 
/*    E_OS_ID                     Task <TaskID> is invalid            */
/*    E_OS_STATE                  Alarm <AlarmID> is already in use   */ 
/*    E_OS_VALUE                  Value of <increment> outside of the */
/*                                admissible limits (lower than zero  */
/*                                or greater than maxallowedvalue)    */ 
/*                                Value of <cycle> unequal to 0 and   */
/*                                outside of the admissible counter   */
/*                                limits (less than mincycle or       */
/*                                greater than maxallowedvalue)       */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    ISR, Non preemptable task, Preemptable task                     */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*    BCC1, BCC2, ECC1, ECC2; Events only ECC1, ECC2                  */ 
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/ 
StatusType UIP_SetRelAlarm(AlarmType AlarmID, TickType increment, TickType cycle)
{
    uip_INTERRUPT_STATE_SAVED;
    uipAlarmPtr        alarmPtr;
          
    /* Check to see if AlarmID is valid(not larger than uipAlarmNumber */
    if (AlarmID > uipAlarmNumber)
    {
        return (E_OS_ID);
    }  
    
    alarmPtr = (uipAlarmPtr)(&uipACBArray[AlarmID]);

    /* Enter critical area */
    uip_KERNEL_DISABLE_INTS;

    /* Check to see if alarm is in ON state */    
    if ((alarmPtr -> uipAlarmState) == uip_ALARM_ON)
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
  	    return (E_OS_STATE);
    } 

    /* Check to see if increment is valid (not larger than maxAllowedValue) */    
    if (increment > (((alarmPtr -> uipCounterPtr) 
                                  -> uipCtrBase) -> maxAllowedValue))
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
        return (E_OS_VALUE);
    }
    
    /* Check to see if cycle is valid */    
    if ((cycle!=0) && ((cycle < ((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> minCycle) || 
                  (cycle > ((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue)))
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
        return (E_OS_VALUE);
    }
  
    if (increment > ((((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue) 
                                  - ((alarmPtr -> uipCounterPtr) -> uipCtrValue)))
    {
        alarmPtr -> uipAlarmValue = increment - 
                            ((((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue) - 
                            ((alarmPtr -> uipCounterPtr) -> uipCtrValue)+1);                                  
    }                                           
    else
    {
        alarmPtr -> uipAlarmValue = ((alarmPtr -> uipCounterPtr) -> uipCtrValue) + increment;
    }
    
    alarmPtr -> uipCycle = cycle;

    alarmPtr -> uipAlarmState = uip_ALARM_ON;
    
    /* Leave cirtical area */
    uip_KERNEL_RESTORE_INTS;

    return (E_OK);
} /* end */

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    UIP_SetAbsAlarm                                     1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    The system service occupies the alarm <AlarmID> element.        */
/*    When <start> ticks are reached, the task assigned to the alarm  */
/*    <AlarmID> is activated or the assigned event (only for extended */
/*    tasks) is set or the alarm-callback routine is called.          */
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    If the absolute value <start> is very close to the current      */
/*    counter value, the alarm may expire, and the task may become    */
/*    ready or the alarm-callback may be called before the system     */
/*    service returns to the user.                                    */
/*    If the absolute value <start> already was reached before the    */
/*    system call, the alarm shall only expire when the absolute      */
/*    value <start> is reached again, i.e. after the next overrun of  */
/*    the counter.                                                    */
/*    If <cycle> is unequal zero, the alarm element is logged on      */
/*    again immediately after expiry with the relative value <cycle>. */
/*    The alarm <AlarmID> shall not already be in use.                */
/*    To change values of alarms already in use the alarm shall be    */
/*    cancelled first.                                                */
/*    If the alarm is already in use, this call will be ignored       */
/*    and the error E_OS_STATE is returned.                           */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    AlarmID                     Reference to the alarm              */
/*                                elementincrement                    */
/*    start                       Absolute value in ticks             */
/*    cycle                       Cycle value in case of cyclic alarm */
/*                                In case of single alarms,           */
/*                                cycle shall be zero.                */ 
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    E_OK                        No error                            */ 
/*    E_OS_ACCESS                 Call not from extended task.        */ 
/*    E_OS_CALLEVEL               Call at interrupt level.            */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    ISR, Non preemptable task, Preemptable task                     */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*    BCC1, BCC2, ECC1, ECC2; Events only ECC1, ECC2                  */ 
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/ 
StatusType UIP_SetAbsAlarm(AlarmType AlarmID, TickType start, TickType cycle)
{
    uip_INTERRUPT_STATE_SAVED;
    uipAlarmPtr        alarmPtr;
              
    /* Check to see if AlarmID is valid(not larger than uipAlarmNumber */
    if (AlarmID > uipAlarmNumber)
    {
        return (E_OS_ID);
    }  
    
    alarmPtr = (uipAlarmPtr)(&uipACBArray[AlarmID]);

    /* Enter critical area */
    uip_KERNEL_DISABLE_INTS;

    /* Check to see if alarm is in ON state */    
    if ((alarmPtr -> uipAlarmState) == uip_ALARM_ON)
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
  	    return (E_OS_STATE);
    } 
  
    /* Check to see if increment is valid (not larger than maxAllowedValue) */    
    if (start > (((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue))
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
        return (E_OS_VALUE);
    }
  
    /* Check to see if cycle is valid */    
    if ((cycle != 0) && ((cycle < ((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> minCycle) 
         || (cycle > ((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue)))
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
        return (E_OS_VALUE);
    }
  
    alarmPtr -> uipAlarmValue = start;

    alarmPtr -> uipCycle = cycle;

    alarmPtr -> uipAlarmState = uip_ALARM_ON;
    
    /* Leave cirtical area */
    uip_KERNEL_RESTORE_INTS;

    return (E_OK);
} /* end */

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    UIP_CancelAlarm                                     1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    The system service cancels the alarm <AlarmID>.                 */ 
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    AlarmID                     Reference to the alarm              */
/*                                elementincrement                    */
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    E_OK                        No error                            */ 
/*    E_OS_NOFUNC                 Alarm <AlarmID> is not used         */ 
/*    E_OS_ID                     Alarm <AlarmID> is invalid          */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    ISR, Non preemptable task, Preemptable task                     */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*    ECC1, ECC2                                                      */ 
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/
StatusType UIP_CancelAlarm(AlarmType AlarmID)
{
    uip_INTERRUPT_STATE_SAVED;
    uipAlarmPtr        alarmPtr;
              
    /* Check to see if AlarmID is valid(not larger than uipAlarmNumber */
    if (AlarmID > uipAlarmNumber)
    {
        return (E_OS_ID);
    }  
    
    alarmPtr = (uipAlarmPtr)(&uipACBArray[AlarmID]);

    /* Enter critical area */
    uip_KERNEL_DISABLE_INTS;

    if ((alarmPtr -> uipAlarmState) == uip_ALARM_OFF)
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
  	    return (E_OS_NOFUNC);
    } 
  
    alarmPtr -> uipAlarmState = uip_ALARM_OFF;
    
    /* Leave cirtical area */
    uip_KERNEL_RESTORE_INTS;

    return (E_OK);
} /* end */

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    uipSystemCounterHandler                             1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    System counter(system timer)'s tick handler                     */ 
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    None                                                            */
/*                                                                    */
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    uipAlarmHandler()                                               */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    System timer's ISR                                              */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/
VOID uipSystemCounterHandler(VOID)
{
    UIP_UINT           alarm_index;  
    uipAlarmPtr        alarmPtr;
              
    if(uipSystemCounter.uipCtrValue < (uipSystemCounter.uipCtrBase)->maxAllowedValue)
    {
        uipSystemCounter.uipCtrValue++;
    }
    else 
    {
        uipSystemCounter.uipCtrValue = 0;
    }
    
    for (alarm_index = 0; alarm_index < uipAlarmNumber; alarm_index++)
    {
        alarmPtr = (uipAlarmPtr)(&uipACBArray[alarm_index]);

        if (alarmPtr -> uipAlarmState == uip_ALARM_ON)
        {  
            /* 改变 uipCtrValue 的计数方式，循环递增 */
            /* Change the counting way of uipCtrValue to cycle increasing */
            if((alarmPtr -> uipCounterPtr) -> uipCtrValue < ((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue)
            {
                (alarmPtr -> uipCounterPtr) -> uipCtrValue++;
            }
            else
            {
                (alarmPtr -> uipCounterPtr) -> uipCtrValue = 0;
            }
            /* Check to see if alarm is expired */
            if ((alarmPtr -> uipCounterPtr) -> uipCtrValue == alarmPtr -> uipAlarmValue)
            {
                /* 不归零，因为 uipAlarmValue 一直在递增 */
                /*  not reset to zero, because uipAlarmValue is increasing all the time */
				uipAlarmHandler(alarm_index);
            }
        }/* end of if (Alarm_list[alarm_index].State == uip_ALARM_ON) */
    }/* end of for (alarm_index = 0; alarm_index < uipAlarmNumber**; alarm_index++) */
} /* end */

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    uipAlarmHandler                                     1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    AlarmID's handler                                               */ 
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    UIP_SetEvent, UIP_ActivateTask, Alarm's callback function       */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    uipSystemCounterHandler()                                       */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/
VOID uipAlarmHandler(UIP_UINT alarm_index)
{
    uipAlarmPtr        alarmPtr;

    alarmPtr = (uipAlarmPtr)(&uipACBArray[alarm_index]);

    /* Check to see alarm's cycle value is 0 */
    /* If it is, set alarm's state is off */
    if (alarmPtr -> uipCycle == 0)
    {
        alarmPtr -> uipAlarmState = uip_ALARM_OFF;    	
    }
    /* If it is not, reset alarm's expiring value */
    else
    {
        if ((alarmPtr -> uipCycle) > ((((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue) - 
                                     ((alarmPtr -> uipCounterPtr) -> uipCtrValue)))
        {
            alarmPtr -> uipAlarmValue = (alarmPtr -> uipCycle) - 
                                     ((((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue) - 
                                     ((alarmPtr -> uipCounterPtr) -> uipCtrValue) + 1);                                      
        }  
                                                 
        else
        {
            alarmPtr -> uipAlarmValue = ((alarmPtr -> uipCounterPtr) -> uipCtrValue) + (alarmPtr -> uipCycle);
        }
    }
    
    /* If needed, execute call back function of alarm */    
    if (alarmPtr -> uipCallBack != 0)
    {
        alarmPtr -> uipCallBack();	
    }

    /* If needed, set event */    
    if (alarmPtr -> uipEvent != 0)
    {
        UIP_SetEvent(alarmPtr -> uipAlarmActTaskID, alarmPtr -> uipEvent);
    }
    
    /* If needed, activate task */    
    else if (alarmPtr -> uipAlarmActTaskID != uipIdleTaskID)
    {
        UIP_ActivateTask(alarmPtr -> uipAlarmActTaskID);
    }
} /* end */

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    uipGeneralCounterHandler                            1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    General counter's tick handler                                  */ 
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    AlarmID                    Reference to an alarm                */ 
/*                                                                    */
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    uipAlarmHandler()                                               */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    General counter's ISR                                           */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/
VOID uipGeneralCounterHandler(AlarmType AlarmID)
{    
    uipAlarmPtr        alarmPtr;

    alarmPtr = (uipAlarmPtr)(&uipACBArray[AlarmID]);

    /* 改变 uipCtrValue 的计数方式，循环递增 */
    /* Change the counting way of uipCtrValue to cycle increasing */
    if((alarmPtr -> uipCounterPtr) -> uipCtrValue < ((alarmPtr -> uipCounterPtr) -> uipCtrBase) -> maxAllowedValue)
    {
        (alarmPtr -> uipCounterPtr) -> uipCtrValue++;
    }
    else
    {
        (alarmPtr -> uipCounterPtr) -> uipCtrValue = 0;
    }

    if ((AlarmID <= uipAlarmNumber) && ((alarmPtr -> uipAlarmState) == uip_ALARM_ON))
    {  
        /* Check to see if alarm is expired */
        if ((alarmPtr -> uipCounterPtr) -> uipCtrValue == alarmPtr -> uipAlarmValue)
        {
            /* 不归零，因为uipAlarmValue一直在递增 */
            /*  not reset to zero, because uipAlarmValue is increasing all the time */
			uipAlarmHandler(AlarmID);
        }
    }/* end of if (Alarm_list[alarm_index].State == uip_ALARM_ON) */
}

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    uipGetCtrCurrentValue                               1.09        */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    Get counter's current value                                     */ 
/*                                                                    */ 
/*  Note:                                                             */
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    AlarmID                    Reference to an alarm                */ 
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    Tick                       Counter's current value in ticks     */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    ISR, Task,  Several hook routines                               */ 
/*                                                                    */ 
/*  Conformance:                                                      */
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2007.02.25            Initial Version 1.0    */ 
/*                                                                    */ 
/**********************************************************************/
StatusType uipGetCtrCurrentValue(AlarmType AlarmID, TickRefType Tick)
{
    uip_INTERRUPT_STATE_SAVED;
    uipAlarmPtr        alarmPtr;

    if (AlarmID > uipAlarmNumber)
    {
        return (E_OS_ID);
    }  
    
    alarmPtr = (uipAlarmPtr)(&uipACBArray[AlarmID]);

    /* Enter critical area */
    uip_KERNEL_DISABLE_INTS;

    if ((alarmPtr -> uipAlarmState) == uip_ALARM_OFF)
    {
        /* Leave cirtical area */
        uip_KERNEL_RESTORE_INTS;
        
  	    return (E_OS_NOFUNC);
    } 

    *Tick = (alarmPtr -> uipCounterPtr) -> uipCtrValue;

    /* Leave cirtical area */
    uip_KERNEL_RESTORE_INTS;        

    /* No error */
    return (E_OK);
} /* end */

/***************************************************************************************/
/*                           End of File : uip_kernel_time.c                           */
/***************************************************************************************/
