📄 isl1208.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 + -