/*---------------------------------------------------------------------
        Copyright (C) 1997, 1998 Nintendo.
        
        File            rtcrawwrite.c
        Coded    by     Shigeo Kimura.  Oct 14, 1997.
        Modified by     Koji Mitsunari. Jan 28, 1999.
        Comments        Real Time Clock Library
   
        $Id: rtcrawwrite.c,v 1.1 2004/02/12 20:16:24 tong Exp $
   ---------------------------------------------------------------------*/
/**************************************************************************
 *
 *  $Revision: 1.1 $
 *  $Date: 2004/02/12 20:16:24 $
 *  $Source: 
 *
 **************************************************************************/
#include "osint.h"
#include "controller.h"
#include "siint.h"

#include "rtc.h"
#include "rtcint.h"

static void __osRTCWriteData(u8 address, u8 *buffer);

s32
__osRTCRawWrite(OSMesgQueue *mq, u8 address, u8 *buffer)
{
  s32				ret;
  u8				*ptr;
  __OSRTCReadWriteFormat	rtc_format;

#ifdef _DEBUG
  if ((address > RTC_MAXBLOCKS)|| (__osRTCInitialize == 0)) {
    return((s32)CONT_ERR_INVALID);
  }
#endif /* _DEBUG */
  
  /* Block to get resource token */
  __osSiGetAccess();

  /* Set up request command format for RTC */
  __osRTCWriteData(address, buffer);
  ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam);
  __osContLastCmd = CONT_RTC_WRITE;
 (void)osRecvMesg(mq, (OSMesg *)NULL, OS_MESG_BLOCK);

  /* trigger pifmacro */
  ret = __osSiRawStartDma(OS_READ, &__osEepPifRam);
  ptr = (u8 *)(&__osEepPifRam) + MAXCONTROLLERS; 
  (void)osRecvMesg(mq, (OSMesg *)NULL, OS_MESG_BLOCK);

  rtc_format = *((__OSRTCReadWriteFormat *)ptr);

  ret = (s32)((rtc_format.rxsize & CON_ERR_MASK) >> 4);

  __osSiRelAccess();

  osSetTimer(&__osRtcTimer, OS_USEC_TO_CYCLES(RTC_WAIT), 0, 
	     &__osRtcTimerQ, &__osRtcTimerMsg);
  (void)osRecvMesg(&__osRtcTimerQ, NULL, OS_MESG_BLOCK);

  if (ret == 0){
    bcopy((u8 *)(rtc_format.data), buffer, RTC_BLOCK_SIZE);
    if (rtc_format.status & RTC_STATUS_BDOWN) {
      ret = CONT_ERR_RTC_BDOWN;
    } else if (rtc_format.status & RTC_STATUS_BDOWN) {
      ret = CONT_ERR_RTC_DDOWN;
    } else if (rtc_format.status & RTC_STATUS_BUSY){
      ret = CONT_ERR_RTC_BUSY;
    }
  } else if (ret & (CONT_NO_RESPONSE_ERROR<<4)) {
    ret = CONT_ERR_NO_CONTROLLER;
  } else {
    ret = CONT_ERR_CONTRFAIL;
  }

  __osSiRelAccess();
  return(ret);
}


static void
__osRTCWriteData(u8 address, u8* buffer)
{
  int			i;
  u8			*ptr = (u8 *)(&__osEepPifRam);
  __OSRTCReadWriteFormat rtc_format;

  /* clear pif ram */

  for (i = 0; i < PIFRAMSIZE-1 ; i++) {
    __osEepPifRam.ramarray[i] = 0xff;
  }
  
#ifndef _HW_VERSION_1
  __osEepPifRam.pifstatus = CONT_FORMAT;
#else
  __osEepPifRam.pifstatus = 0;
#endif 

  /* Setup rtc format */

  rtc_format.txsize = 10;
  rtc_format.rxsize = 1;
  rtc_format.cmd = CONT_RTC_WRITE;
  rtc_format.address = address;
  for (i = 0; i < RTC_BLOCK_SIZE ; i++) {
    rtc_format.data[i] = *buffer++;
  }
  for (i = 0; i < MAXCONTROLLERS; i++) {
    *ptr++ = 0;
  }
  *((__OSRTCReadWriteFormat *)ptr) = rtc_format;

#ifndef _HW_VERSION_1
  ptr += sizeof(rtc_format);
  *((u8 *)ptr) = FORMAT_END;
#endif
}
