leotimer.c 8.01 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"

typedef struct
{
  u8	year;
  u8	month;
  u8	day;
  u8	hour;
  u8 	minute;
  u8	second;

} __LOCTime;


/*************************************/
/* PROTOTYPE                         */
/*************************************/
void leoReadTimer(void);
void leoSetTimer(void);
static u8 __locReadTimer(__LOCTime *time);
static u8 __locSetTimer(__LOCTime *time);

/*************************************/
/* EXTERNALY DEFINED FUNCTION        */
/*************************************/
extern u8 leoSend_asic_cmd_w_nochkDiskChange(u32 asic_cmd, u32 asic_data);

/*************************************/
/* 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;
    __LOCTime		time;

    sense_code = __locReadTimer(&time);
#ifdef _ERRCHK
    sense_code = timer_cmd->header.reserve1;
#endif

    timer_cmd->year = time.year;
    timer_cmd->month = time.month;
    timer_cmd->day = time.day;
    timer_cmd->hour = time.hour;
    timer_cmd->minute = time.minute;
    timer_cmd->second = time.second;

    if (sense_code)
    {
      timer_cmd->header.sense  = sense_code;
      timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
      return;
    }
    
    /*
     * もし正常に時刻が読めた場合、timer_cmd->year (西暦の下2桁)から
     * timer_cmd->reserve13 (上2桁)を作る。
     * 法則は	   下2桁が 96 以上 -> 上2桁は 19
     *		            95 以下 ->          20
     */
    if ( (u32)timer_cmd->year >= 0x96 )
    {
      timer_cmd->reserve13 = 0x19;

    } else 	/* 下2桁が 95 以下 */
    {
      timer_cmd->reserve13 = 0x20;
      
    }

    timer_cmd->header.status = LEO_STATUS_GOOD;

} /* leoReadTimer() */

/*=========================================================================
* 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;
    __LOCTime	time;

    /* Check parameter */
    p_tmp = (u8*)&timer_cmd->year;
    for (ymd = 0; ymd<6; ymd++)
    {
        temp = *p_tmp;
        if ((temp & 0x0f)>0x09)
	{
	  timer_cmd->header.sense  = LEO_SENSE_ILLEGAL_TIMER_VALUE;
	  timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
	  return;
	}
	
        temp = bcd_to_hex(temp);
        /* check parameter */
        switch (ymd)
        {
            case 2:  /* day */
                if (temp > dayupper[month])
                {
                    if ( (temp != 29) || (year & 3) )
		    {
		      timer_cmd->header.sense  = LEO_SENSE_ILLEGAL_TIMER_VALUE;
		      timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
		      return;
		    }
                }
            case 1:  /* month */
                if (temp == 0)
		{
		  timer_cmd->header.sense  = LEO_SENSE_ILLEGAL_TIMER_VALUE;
		  timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
		  return;
		}
            default:
                if (temp > ymdupper[ymd])
		{
		  timer_cmd->header.sense  = LEO_SENSE_ILLEGAL_TIMER_VALUE;
		  timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
		  return;
		}
        }
        year  = month;
        month = temp;
        p_tmp++;
    }

    time.year   = timer_cmd->year;
    time.month  = timer_cmd->month;
    time.day    = timer_cmd->day;
    time.hour   = timer_cmd->hour;
    time.minute = timer_cmd->minute;
    time.second = timer_cmd->second;

    result = __locSetTimer(&time);
    if (result)
    {
      timer_cmd->header.sense  = result;
      timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
      return;
    }

    result = __locReadTimer(&time);
    if (result)
    {
      timer_cmd->header.sense  = result;
      timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
      return;
    }

    /* compare RTC value */
    if ( ( time.year != timer_cmd->year ) || ( time.month != timer_cmd->month )
      || ( time.day != timer_cmd->day ) || ( time.hour != timer_cmd->hour )
      || ( time.minute != timer_cmd->minute ) || ( time.second != timer_cmd->second ) )
    {
        timer_cmd->header.sense  = LEO_SENSE_ILLEGAL_TIMER_VALUE;
        timer_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
        return;
    }

    timer_cmd->header.status = LEO_STATUS_GOOD;

} /* leoSetTimer() */


static u8 __locReadTimer(__LOCTime *time)
{
    u32		data;
    u8 		sense_code;

    /* Read timer minute. */
    if (sense_code = leoSend_asic_cmd_w_nochkDiskChange(ASIC_READ_TIMER_MINUTE, 0))
    {
      return sense_code;
    }
    leoGet_leo_asic_data(&data);
    time->minute = (data & 0xff000000) >> 24;  /* minute */
    time->second = (data & 0x00ff0000) >> 16;  /* second */

    if (sense_code = leoSend_asic_cmd_w_nochkDiskChange(ASIC_READ_TIMER_DATE, 0))
    {
      time->minute &= ~0x80;
      return sense_code;
    }
    leoGet_leo_asic_data(&data);
    time->day  = (data & 0xff000000) >> 24;    /* day */
    time->hour = (data & 0x00ff0000) >> 16;    /* hour */

    if (sense_code = leoSend_asic_cmd_w_nochkDiskChange(ASIC_READ_TIMER_YEAR, 0))
    {
      time->minute &= ~0x80;
      return sense_code;
    }
    leoGet_leo_asic_data(&data);
    time->year  = (data & 0xff000000) >> 24;   /* year  */
    time->month = (data & 0x00ff0000) >> 16;   /* month */

    /* Check RTC failure */
    if (time->minute & 0x80)
    {
      time->minute &= ~0x80;
      return (u8)LEO_SENSE_REAL_TIME_CLOCK_FAILURE;
    }

    return (u8)0;

} /* __locReadTimer() */


static u8 __locSetTimer(__LOCTime *time)
{
  u32	YearMonthX10000h;
  u32	DayHourX10000h;
  u32	MinuteSecondX10000h;
  u8	result;

  YearMonthX10000h = 	( (time->year) << 24 )   + ( (time->month) << 16 );
  DayHourX10000h = 	( (time->day) << 24 )    + ( (time->hour) << 16 );
  MinuteSecondX10000h = ( (time->minute) << 24 ) + ( (time->second) << 16 );
  
  /* Set timer */
  if (   (result = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_TIMER_YEAR,  YearMonthX10000h) )
      || (result = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_TIMER_DATE,  DayHourX10000h) )
#ifdef _ERRCHK
      || (result = timer_cmd->header.reserve1 )
#endif
      || (result = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_TIMER_MINUTE, MinuteSecondX10000h) ) )
  {
    return result;
  }

  return (u8)0;
  
} /* __locSetTimer() */