www.pudn.com > vxworks0108.rar > watchdog.c


#include "type.h"
#include "watchdog.h"
#include "sysLibExt.h"
#include "vg4.h"

/*
 * timeout table. Indexed with W_SEL1 and W_SEL0 value. Return corresponding
 * timeout value in milliseconds.
 */
static UINT32 wd_to_table[] = {
    296,    /* W_SEL_1_0 = 00 */
    593,    /* W_SEL_1_0 = 01, default after reset */
   1186,    /* W_SEL_1_0 = 10 */
   2373,    /* W_SEL_1_0 = 11 */
};

static int boardRevision = -1;  /* -1: unknown, 1: rev 1.x, 2: rev 2.x */

/*******************************************************************************
*
* watchdogStart - start the watchdog timer
*
* This routine starts the watchdog timer. The extended register set must be 
* unlocked before accessing the watchdog register.
*
* RETURNS: N/A
*
* SEE ALSO: watchdogStop(), watchdogRetrigger()
*/

void watchdogStart 
   (
      void
   )
{
    UINT8   chBuf;
    int     lockKey;

    /* unlock extended regs */
    lockKey = sysUnlockExtRegSet();

    /* start the watchdog timer */
    chBuf = sysInByte (WATCHDOG_BASEADRESS);
    sysOutByte (WATCHDOG_BASEADRESS, (chBuf | WD_ON));

    /* lock extended regs again */
    sysLockExtRegSet(lockKey);
}



/*******************************************************************************
*
* watchdogStop - stop the watchdog timer
*
*
* This routine stops the watchdog timer. The extended register set must be 
* unlocked before accessing the watchdog register.
*
* RETURNS: N/A
*
* SEE ALSO: watchdogStart(), watchdogRetrigger()
*/

void watchdogStop 
   (
      void
   )
{
    UINT8   chBuf;
    int     lockKey;

    /* unlock extended regs */
    lockKey = sysUnlockExtRegSet();

    /* stop the watchdog timer */
    chBuf = sysInByte (WATCHDOG_BASEADRESS);
    sysOutByte (WATCHDOG_BASEADRESS, (chBuf&(~WD_ON)));

    /* lock extended regs again */
    sysLockExtRegSet(lockKey);
}



/*******************************************************************************
*
* watchdogRetrigger - retrigger the watchdog timer
*
* This routine retriggers the watchdog timer. The extended register set must be 
* unlocked before accessing the watchdog register.
*
* RETURNS: N/A
*
* SEE ALSO: watchdogStart(), watchdogStop()
*/

void watchdogRetrigger 
   (
   void
   )
{
    UINT8   dummy;
    int     lockKey;

    /* unlock extended regs */
    lockKey = sysUnlockExtRegSet();

    /* reading the watchdog control register retriggers the timer */
    dummy = sysInByte (WATCHDOG_BASEADRESS);

    /* lock extended regs again */
    sysLockExtRegSet(lockKey);
}



/*******************************************************************************
*
* watchdogReadBootStatus - get last reset condition
*
* This routine reads the boot status of the watchdog timer. If the last system
* reset has been caused by the watchdog, this is stored in the watchdog control
* register (bit 2). The extended register set must be unlocked before accessing 
* the watchdog register.
*
* RETURNS: 
*   RESET_BY_WD, if the last board reset has been caused by the watchdog
*   RESET_NORMAL, otherwise
*
* SEE ALSO: watchdogStart()
*/

int watchdogReadBootStatus 
   (
      void
   )
{
    int     retVal,
            lockKey;

    /* unlock extended regs */
    lockKey = sysUnlockExtRegSet();

    if ( sysInByte (WATCHDOG_BASEADRESS) & WD_RES )
        retVal = RESET_BY_WD;
    else
        retVal = RESET_NORMAL;

    /* lock extended regs again */
    sysLockExtRegSet(lockKey);

    return (retVal);
}


/*******************************************************************************
*
* watchdogClearBootStatus - reset the "last system reset by Watchdog" flag
*
*
* SEE ALSO: watchdogStart()
*/

void watchdogClearBootStatus 
   (
      void
   )
{
    int     lockKey;

    /* unlock extended regs */
    lockKey = sysUnlockExtRegSet();

    sysOutByte (WATCHDOG_BASEADRESS, WD_RES);

    /* lock extended regs again */
    sysLockExtRegSet(lockKey);
}

/*******************************************************************************
*
* watchdogTimeoutGet - get current timeout value in ms
*
* RETURNS: timeout value in milliseconds
*
* NOTE: works only on VG4 rev > 1.x
*       On VG4 rev 1.x there is no WCLKSEL. In the register at the same offset
*       (0x0162) only bit 0 is valid, but unused (VPP on/off, default 0).
*
* SEE ALSO: watchdogTimeoutSet()
*/

UINT32  watchdogTimeoutGet(void)
{
    int     lockKey;
    UINT8   wclksel;
    static int firstread = 1;

    /* unlock extended regs */
    lockKey = sysUnlockExtRegSet();

    /* read WD Clock Select register */
    wclksel = sysInByte (WATCHDOG_BASEADRESS+2);

    /* lock extended regs again */
    sysLockExtRegSet(lockKey);

    if (firstread) {
        if ((wclksel & 0x03) == 0) {
            boardRevision = 1;  /* rev. 1.x */
        } else {
            boardRevision = 2;  /* rev. 2.x */
        }
        firstread = 0;
    }

    if (boardRevision == 1) {
        return 593;
    }
    return wd_to_table[wclksel & 0x03];
}

/*******************************************************************************
*
* watchdogTimeoutSet - set timeout value
*
* Set the watchdog timeout period to given value. Value is one of:
* WD_TO_296MS, WD_TO_593MS, WD_TO_1186MS, WD_TO_373MS. See also watchdog.h.
*
* RETURNS: ERROR upon invalid timeoutIdx, OK otherwise.
*
* NOTE: works only on VG4 rev > 1.x
*       On VG4 rev 1.x there is no WCLKSEL. In the register at the same offset
*       (0x0162) only bit 0 is valid, but unused (VPP on/off, default 0).
*
* SEE ALSO: watchdogTimeoutGet()
*/

STATUS watchdogTimeoutSet(int timeoutIdx)
{
    int     lockKey;
    UINT8   wclksel;

    if (boardRevision == -1) {  /* unknown */
        (void) watchdogTimeoutGet();    /* sets boardRevision */
    }
    if (boardRevision == 1) {  /* rev 1.x */
        if (timeoutIdx != WD_TO_593MS) {
            return ERROR;
        }
        return OK;
    }

    wclksel = timeoutIdx & 0x03;
    /* unlock extended regs */
    lockKey = sysUnlockExtRegSet();

    /* write WD Clock Select register */
    sysOutByte (WATCHDOG_BASEADRESS+2, wclksel);

    /* lock extended regs again */
    sysLockExtRegSet(lockKey);

    return OK;
}