leotimer.c 5.81 KB
/*
 *  F i l e N a m e  :  l e o t i m e r . c
 *
 ****************************************************************************
 *                   (C) Copyright ALPS Electric Co., Ltd. 1995-1996
 ****************************************************************************
 *  Version
 *
 *  ver     Date
 *  ----  --------
 *  1.02  '97-01-10  Change sense code name to LEO_SENSE_ILLEGAL_TIMER_VALUE.
 *  1.01  '96-12-24  Add invalid value check.Support hex value.
 *  1.00  '96-11-17  Initial revision .
 ****************************************************************************
*/
#include "os.h"

#include <ultra64.h>
#include "leodefine.h"
#include "leodrive.h"
#include "leomacro.h"
#include "leoappli.h"

/*************************************/
/* PROTOTYPE                         */
/*************************************/
void leoReadTimer(void);
void leoSetTimer(void);

/*************************************/
/* EXTERNALY DEFINED FUNCTION        */
/*************************************/

/*************************************/
/* EXTERNAL RAM                      */
/*************************************/
extern OSMesg      LEOcur_command;
extern OSPiHandle *LEOPiInfo;

/*************************************/
/*  MACROS                           */
/*************************************/
#define  timer_cmd         ((LEOCmdReadTimer *)LEOcur_command)
#define  bcd_to_hex(bcd)   (bcd - (bcd>>4)*6)

/*==========================================================================
* Function : leoReadTimer
*--------------------------------------------------------------------------
* Description : EXECUTE READ_TIMER COMMAND
*--------------------------------------------------------------------------
* IN    : LEOcur_command
* OUT   : *LEOcur_command
* ARG   : non
* RET   : non
*==========================================================================
*/
void leoReadTimer(void)
{
    u8 *rdparam;
    u8 data[4];
    u8 sense_code;

    /* Read timer minute. */
    if (sense_code = leoSend_asic_cmd_w(ASIC_READ_TIMER_MINUTE, 0))
        goto rd_timer_err2;
    leoGet_leo_asic_data((u32*)&data[0]);
    timer_cmd->minute = data[0];  /* minute */
    timer_cmd->second = data[1];  /* second */
    if (sense_code = leoSend_asic_cmd_w(ASIC_READ_TIMER_DATE, 0))
        goto rd_timer_err1;
    leoGet_leo_asic_data((u32*)&data[0]);
    timer_cmd->day  = data[0];    /* day */
    timer_cmd->hour = data[1];    /* hour */
    if (sense_code = leoSend_asic_cmd_w(ASIC_READ_TIMER_YEAR, 0))
        goto rd_timer_err1;
    leoGet_leo_asic_data((u32*)&data[0]);
    timer_cmd->year  = data[0];   /* year  */
    timer_cmd->month = data[1];   /* month */
    /* Check RTC failure */
    if (timer_cmd->minute & 0x80)
    {
        sense_code = LEO_SENSE_REAL_TIME_CLOCK_FAILURE;
rd_timer_err1:
        timer_cmd->minute &= ~0x80;
    }
#ifdef _ERRCHK
    else
        sense_code = timer_cmd->header.reserve1;
#endif

    if (sense_code)
    {
rd_timer_err2:
        timer_cmd->header.sense  = sense_code;
        timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
        return;
    }
    timer_cmd->header.status = LEO_STATUS_GOOD;
}

/*=========================================================================
* Function : leoSetTimer
*--------------------------------------------------------------------------
* Description : EXECUTE SET_TIMER COMMAND
*--------------------------------------------------------------------------
* IN    : LEOcur_command
* OUT   : *LEOcur_command
* ARG   : non
* RET   : non
*==========================================================================
*/
const static u8 ymdupper[6] = { 99, 12, 31, 23, 59, 59};
const static u8 dayupper[13]= {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
void leoSetTimer(void)
{
    LEOCmdReadTimer rd_timer;
    u8   *p_tmp;
    u32  year,month;
    u32  temp;
    u32  ymd;
    u8   result;

    /* Check parameter */
    p_tmp = (u8*)&timer_cmd->year;
    for (ymd = 0; ymd<6; ymd++)
    {
        temp = *p_tmp;
        if ((temp & 0x0f)>0x09)
            goto cmd_invalid_param;
        temp = bcd_to_hex(temp);
        /* check parameter */
        switch (ymd)
        {
            case 2:  /* day */
                if (temp > dayupper[month])
                {
                    if ( (temp != 29) || (year & 3) )
                        goto cmd_invalid_param;
                }
            case 1:  /* month */
                if (temp == 0)
                    goto cmd_invalid_param;
            default:
                if (temp > ymdupper[ymd])
                {
                    goto cmd_invalid_param;
                }
        }
        year  = month;
        month = temp;
        p_tmp++;
    }
    /* Set timer */
    if (   (result = leoSend_asic_cmd_w(ASIC_SET_TIMER_YEAR,  *(u32 *)&timer_cmd->year) )
        || (result = leoSend_asic_cmd_w(ASIC_SET_TIMER_DATE,  *(u32 *)&timer_cmd->day) )
#ifdef _ERRCHK
        || (result = timer_cmd->header.reserve1 )
#endif
        || (result = leoSend_asic_cmd_w(ASIC_SET_TIMER_MINUTE,*(u32 *)&timer_cmd->minute) ) )
    {
        goto cmd_err_end;
    }
    /* read RTC to check */
    p_tmp = (void*)LEOcur_command;
    rd_timer.header.command = LEO_COMMAND_READ_TIMER;
#ifdef _ERRCHK
    rd_timer.header.reserve1 = 0;
#endif
    LEOcur_command = &rd_timer;
    leoReadTimer();
    LEOcur_command = (void*)p_tmp;
    if (rd_timer.header.status == LEO_STATUS_CHECK_CONDITION)
    {
        result = rd_timer.header.sense;
        goto cmd_err_end;
    }
    /* compare RTC value */
    if ( ( (*(u32*)&timer_cmd->year) != (*(u32*)&rd_timer.year) )
      || ( (*(u32*)&timer_cmd->day ) != (*(u32*)&rd_timer.day ) ) )
    {
cmd_invalid_param:
        result =  LEO_SENSE_ILLEGAL_TIMER_VALUE;
cmd_err_end:
        timer_cmd->header.sense  = result;
        timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
        return;
    }
    timer_cmd->header.status = LEO_STATUS_GOOD;
}