📄 ds1337.c
字号:
//************************************************************************
//
// Filename: DS1337.c
//
// Copyright(c) Cirrus Logic Corporation 2004, All Rights Reserved
//
// Author: YUJIANG.ZHENG@CIRRUS.BEIJING
//
// TODOTODOTODO: Replace all while{} with timeout function.
//
//************************************************************************
#include "ds1337.h"
unsigned long ds1337_bias=0;
unsigned long ds1337_current_sec=0;
static volatile GPIOG * const gpio_g = (GPIOG *)(GPIO_BASE + 0x0038);
#define PERIOD_US_100HZ 10
#define DELAY_US (PERIOD_US_100HZ/2)
void gen_ack(int not_ack);
int wait_ack(void);
/*
* Delay Function.
*/
void DelayInuSec(unsigned long uS)
{
unsigned long passed, startTime;
startTime= *TIM_DEBUGVALUELOW;
passed=0;
while ( passed < uS)
{
passed = (*TIM_DEBUGVALUELOW - startTime);
}
}
/*
* Write the registers of DS1337,
*/
int write_ds1337(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 DS1337 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 ()) 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 ()) goto w_failed;
gpio_g->PGDDR.Field.EEDATA =1;
//
// Write Bytes To DS1337.
//
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++;
}
//
// 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 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 DS1337,
*/
int read_ds1337(int address,char* pdata, int nbytes)
{
int i,j;
char udata;
//
// Set regsitor pointer.
//
if( write_ds1337(address, (void*)0, 0) <0) 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 DS1337 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 ()) goto r_failed;
//
// Read Bytes From DS1337.
//
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++;
}
//
// 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 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 ds1337,
* DS1337 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 ds1337,
* 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 gettime_from_ds1337(PSYSTEMTIME ptime)
{
int n;
char buffer[16]={0};
SYSTEMTIME m_time;
unsigned long msec;
n = read_ds1337(0,buffer,7);
m_time.wHour= (((buffer[2]&0x10) >>4)*10) + (buffer[2] & 0xf);
m_time.wMinute= (((buffer[1]&0x70) >>4)*10) + (buffer[1] & 0xf);
m_time.wSecond= (((buffer[0]&0x70) >>4)*10) + (buffer[0] & 0xf);
msec = m_time.wHour * 3600 + m_time.wMinute * 60 + m_time.wSecond;
msec -= ds1337_current_sec;
msec += ds1337_bias;
ptime->wYear = 0;
ptime->wMonth = 0;
ptime->wDayOfWeek =0;
ptime->wDay =0;
ptime->wHour= msec / 3600;
ptime->wMinute= ( msec % 3600 ) /60;
ptime->wSecond= msec % 60 ;
ptime->wMilliseconds= 0;
// ptime->wYear = ((buffer[6]>>4)*10) + (buffer[6] & 0xf);
// ptime->wMonth = (((buffer[5]&0x10) >>4)*10) + (buffer[5] & 0xf);
// ptime->wDayOfWeek =buffer[3] & 0x7;
// ptime->wDay =(((buffer[4]&0x30) >>4)*10) + (buffer[4] & 0xf);
// ptime->wHour= (((buffer[2]&0x10) >>4)*10) + (buffer[2] & 0xf);
// ptime->wMinute= (((buffer[1]&0x70) >>4)*10) + (buffer[1] & 0xf);
// ptime->wSecond= (((buffer[0]&0x70) >>4)*10) + (buffer[0] & 0xf);
// ptime->wMilliseconds=0;
return n;
}
int init_ds1337(PSYSTEMTIME ptime)
{
int n;
char buffer[16]={0};
SYSTEMTIME m_time;
ds1337_bias = ptime->wHour * 3600 + ptime->wMinute * 60 + ptime->wSecond;
//
// Enable 1Hz Square-Wave Output.
//
write_ds1337(0x0E, buffer, 1);
n = read_ds1337(0,buffer,7);
m_time.wHour= (((buffer[2]&0x10) >>4)*10) + (buffer[2] & 0xf);
m_time.wMinute= (((buffer[1]&0x70) >>4)*10) + (buffer[1] & 0xf);
m_time.wSecond= (((buffer[0]&0x70) >>4)*10) + (buffer[0] & 0xf);
ds1337_current_sec = m_time.wHour * 3600 + m_time.wMinute * 60 + m_time.wSecond;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -