⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isl1208.c

📁 这是isl1208实时时钟 RTC wince驱动程序
💻 C
字号:
//************************************************************************
//                                                                      
// Filename: ISL1208.c
//                                                                      
// Copyright(c) Cirrus Logic Corporation 2004, All Rights Reserved                       
//
// Author: YUJIANG.ZHENG@CIRRUS.BEIJING
//
// TODOTODOTODO: Replace all while{} with timeout function.
//
//************************************************************************
#ifdef REAL_RTC

#include <Windows.h>
#include <Winbase.h>
#include <hwdefs.h>
#include <haluser.h>
#include <nkintr.h>
#include "ISL1208.h"

#define TIME_TEST  0
#define TIME_ERROR	1

static volatile GPIOG * const gpio_g       = (GPIOG *)(GPIO_BASE + 0x0038);

#define PERIOD_US_100HZ             10
//QQQQQQQQQQQQ #define DELAY_US                    (PERIOD_US_100HZ/2)
#define DELAY_US                    1

static void gen_ack(int not_ack);
static int wait_ack(void);

extern void DelayInuSec(unsigned long uS);

/*
 *  Write the registers of ISL1208, 
 */
int write_ISL1208(int address,const char* pdata, int nbytes)
{
    int i,j;
    //
    //  Wait for bus not busy.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =0;
    while( !(gpio_g->PGDR.Value & 0x3) ){}

    //
    //  Start Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 0;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    //
    //  Send ISL1208 Slave Address For Write.
    //
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);
    for(i=0;i<8;i++)
    {
        gpio_g->PGDR.Field.EEDATA = ((WRITE_ADDRESS>>(7-i))&0x01);
        gpio_g->PGDR.Field.EECLK = 1;
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
        DelayInuSec(DELAY_US);
    }
    if(! wait_ack ()) {
		RETAILMSG(TIME_ERROR,(TEXT("ISL1208 write failed 1111\r\n")));
		goto w_failed;
	}

    gpio_g->PGDDR.Field.EEDATA =1;

    //
    //  Set The Register Pointer.
    //
    for(i=0;i<8;i++)
    {
        gpio_g->PGDR.Field.EEDATA = ((address>>(7-i))&0x01);
        gpio_g->PGDR.Field.EECLK = 1;
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
        DelayInuSec(DELAY_US);
    }
    if(! wait_ack ()) {
		RETAILMSG(TIME_ERROR,(TEXT("ISL1208 write failed 2222\r\n")));
		goto w_failed;
	}
	if (!nbytes )
		return 0;

    gpio_g->PGDDR.Field.EEDATA =1;

    //
    //  Write Bytes To ISL1208.
    //

    j=0;
    while(nbytes--)
    {
        for(i=0;i<8;i++)
        {
            gpio_g->PGDR.Field.EEDATA = ((pdata[j]>>(7-i))&0x01);
            gpio_g->PGDR.Field.EECLK = 1;
            DelayInuSec(DELAY_US);
            gpio_g->PGDR.Field.EECLK = 0;
            DelayInuSec(DELAY_US);
        }
        if(! wait_ack ()) goto w_failed;

        gpio_g->PGDDR.Field.EEDATA =1;
        j++;
    }
        DelayInuSec(DELAY_US);

    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
	//Braden added the following two lines for testing.
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDR.Field.EECLK =1;

    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

        DelayInuSec(DELAY_US);

	RETAILMSG(TIME_TEST,(TEXT("ISL1208 write OK\r\n")));
    return 0;

w_failed:

    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    return -1;
}

/*
 *  Read the registers of ISL1208, 
 */

int read_ISL1208(int address,char* pdata, int nbytes)
{

    int i,j;
    char udata;

    //
    //  Set regsitor pointer.
    //
    if( write_ISL1208(address, (char*)0, 0) <0){
		RETAILMSG(TIME_ERROR,(TEXT("ISL1208 read failed 1111\r\n")));
		return -1;
	}

    //
    //  Wait for bus not busy.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =0;
    while( !(gpio_g->PGDR.Value & 0x3) ){}

    //
    //  Start Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 0;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    
    //
    //  Send ISL1208 Slave Address For Read.
    //
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);
    for(i=0;i<8;i++)
    {
        gpio_g->PGDR.Field.EEDATA = ((READ_ADDRESS>>(7-i))&0x01);
        gpio_g->PGDR.Field.EECLK = 1;
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
        DelayInuSec(DELAY_US);
    }
    if(! wait_ack ()) {
		RETAILMSG(TIME_ERROR,(TEXT("ISL1208 read failed 2222\r\n")));
		goto r_failed;
	}
    //
    //  Read Bytes From ISL1208.
    //
    gpio_g->PGDDR.Field.EEDATA =0;
    j=0;
    while(nbytes--)
    {
        for(i=0;i<8;i++)
        {
            gpio_g->PGDR.Field.EECLK = 1;
            DelayInuSec(DELAY_US);
            gpio_g->PGDR.Field.EECLK = 0;
            udata =(udata<<1) | gpio_g->PGDR.Field.EEDATA;
            DelayInuSec(DELAY_US);
        }
        pdata[j] = udata;
        if(nbytes==0)
            gen_ack(1);
        else
            gen_ack(0);
        j++;

		DelayInuSec(DELAY_US); //delay here,otherwise it can't read more than 2 bytes.
    }

	DelayInuSec(DELAY_US);
    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;

	//Braden added the following two lines for testing.
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDR.Field.EECLK =1;

    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

	RETAILMSG(TIME_TEST,(TEXT("ISL1208 read OK\r\n")));
    return 0;
r_failed:

    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    return -1;
}

/*
 *  When sending data to ISL1208, 
 *  ISL1208 will generate an ack for every received byte.
 */
int wait_ack(void)
{
    int n;
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =0;

    if(gpio_g->PGDR.Field.EECLK !=0)
    {
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
    }
    DelayInuSec(DELAY_US);
    gpio_g->PGDR.Field.EECLK = 1;
    n=gpio_g->PGDR.Field.EEDATA;
    DelayInuSec(DELAY_US);
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);

    return  n ? 0:1;
}

/*
 *  When receiving data from ISL1208, 
 *  The host should generate an ack for every received byte.
 */
void gen_ack(int not_ack)
{
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =1;

    if(gpio_g->PGDR.Field.EECLK !=0)
    {
        gpio_g->PGDR.Field.EECLK = 0;
    }
    gpio_g->PGDR.Field.EEDATA = not_ack;
    gpio_g->PGDR.Field.EECLK = 1;
    DelayInuSec(DELAY_US);
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);
    gpio_g->PGDDR.Field.EEDATA =0;
}



int init_ISL1208(void )
{
	char buffer[8]={5};
	char status;
	BOOL bRTCValid;

	if( read_ISL1208( REG1208_STATUS ,&status, 1 ) < 0 ){

		RETAILMSG(TIME_ERROR,(TEXT("Test ISL1208, failed to read\r\n")));
		return -1;
	}
	RETAILMSG(TIME_ERROR,(TEXT("RTC status %x\r\n"),status));

	if( status & 0x1 )
	{
		bRTCValid=0;

	}else{
		bRTCValid=1;
	}

	if( !(status&STATUS_WRTC ) ){

		status=STATUS_WRTC |STATUS_ARST;

		if( write_ISL1208(REG1208_STATUS,&status, 1)< 0 ){

			RETAILMSG(TIME_ERROR,(TEXT("Init RTC failed\r\n")));
			bRTCValid=-1;
		}
    }
    return bRTCValid;
}

__inline BYTE GETBCDDATA(BYTE data )  {

	return  ( (data>>4)&0xF) *10 + ( (data)&0xF);
 }
__inline BYTE SETBCDDATA( WORD data )  {
	
	return  ((data/10)<<4) | (data %10 );
}


BOOL ISL1208SetRealTime(LPSYSTEMTIME ptime)
{
	BOOL bRet=FALSE;

	RETAILMSG(TIME_ERROR,(TEXT("SetRealTime %d/%d/%d\r\n")
		,ptime->wYear
		,ptime->wMonth
		,ptime->wDay));

	if( ptime->wYear >=2000 ){

		char buffer[7];

		buffer[REG1208_SECOND]=(char)SETBCDDATA(ptime->wSecond);
		buffer[REG1208_MIN]=(char) SETBCDDATA(ptime->wMinute);
		buffer[REG1208_HOUR]=(char)SETBCDDATA(ptime->wHour) | 0x80; //set 24h.
		buffer[REG1208_DAY]=(char) SETBCDDATA(ptime->wDay);
		buffer[REG1208_MONTH]=(char)SETBCDDATA(ptime->wMonth);
		buffer[REG1208_YEAR]=(char)SETBCDDATA(ptime->wYear-2000);

		buffer[REG1208_WEEK]=(char)SETBCDDATA(ptime->wDayOfWeek);
		if( write_ISL1208(0,buffer, 7)>= 0 ){

			RETAILMSG(TIME_ERROR,(TEXT("SetRealTime OK\r\n")));
			bRet=TRUE;
		}
	}else
		RETAILMSG(TIME_ERROR,(TEXT("SetRealTime Year invalid\r\n")));

	//ISL1208GetRealTime(  ptime );
	return bRet;
}


BOOL ISL1208GetRealTime( LPSYSTEMTIME  ptime )
{
	unsigned char buffer[7]={0};
	BOOL bRet=TRUE;

	if( read_ISL1208(0,(char*)buffer, 7) < 0 ){

		bRet=FALSE;
	}
/*	{
		int i;

		RETAILMSG(TIME_ERROR,(TEXT("Time is\r\n")));

		for(i=0; i< 7;i++ ){

			RETAILMSG(TIME_ERROR,(TEXT(" %x --- (%d) \r\n"),(BYTE)buffer[i], i ));
		}
	} 
*/
	ptime->wSecond=GETBCDDATA(buffer[REG1208_SECOND]);
	ptime->wMinute=GETBCDDATA(buffer[REG1208_MIN]);
	ptime->wHour=GETBCDDATA(buffer[REG1208_HOUR]& 0x3F);
	ptime->wDay=GETBCDDATA(buffer[REG1208_DAY]);
	ptime->wMonth=GETBCDDATA(buffer[REG1208_MONTH]);
	ptime->wYear=GETBCDDATA(buffer[REG1208_YEAR])+2000;
	ptime->wDayOfWeek=GETBCDDATA(buffer[REG1208_WEEK]);

	RETAILMSG(1,(TEXT("Time orig %d/%d/%d  %d:%d:%d\r\n")
		,ptime->wYear
		,ptime->wMonth
		,ptime->wDay
		,ptime->wHour
		,ptime->wMinute
		,ptime->wSecond
		,ptime->wDayOfWeek
		));

	return bRet;
}


static BOOL IsTimeValid(LPSYSTEMTIME ptime)
{
  if ( (ptime->wMonth<=0) || (ptime->wMonth>12) ) return FALSE;

  if ( (ptime->wDay<=0) || (ptime->wDay>32) ) return FALSE;

  if ( (ptime->wHour<0) || (ptime->wHour>24) ) return FALSE;
  
  if ( (ptime->wMinute<0) || (ptime->wMinute>60) ) return FALSE;

  if ( (ptime->wSecond<0) || (ptime->wSecond>60) ) return FALSE;

  return TRUE;
}

BOOL InitializeISL1208(LPSYSTEMTIME ptime)
{
	BOOL bRet=TRUE;
	int islStatus;
	int cnt;

	islStatus=init_ISL1208(  );
	if( islStatus < 0 )
		return FALSE;

	if( islStatus ==1 ){

		//QQQQQQQQQQQQQQQ
		for (cnt=1; cnt<=10; cnt++)
        {
           bRet=ISL1208GetRealTime( ptime );
 		   //Check if this is a valid time. If yes, break the for loop.
           if ( (bRet==TRUE) && (IsTimeValid(ptime)==TRUE) ) break;
			 
		   //If it is not a valid time, read RTC again.
	       RETAILMSG(1,(TEXT("Called ISL1208GetRealTime() the %dth time. \r\n"),cnt));
		}

	}else{
		bRet=ISL1208SetRealTime( ptime );
	}

	return bRet;
}


#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -