Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
DS1338 RTC driver |
Posted: Sat Apr 11, 2020 7:59 am |
|
|
Code: |
//////////////////////////////////////////////////////////////////////////
//// DS1338.C ////
//// Driver for Real Time Clock ////
//// ////
//// rtc_init() Call after power up////
//// ////
//// rtc_set_datetime(day,mth,year,dow,hour,min) Set the date/time ////
//// ////
//// rtc_get_date(day,mth,year,dow) Get the date ////
//// ////
//// rtc_get_time(hr,min,sec) Get the time ////
//// ////
//// rtc_write_nvr(address,data) Write to NVR ////
//// ////
//// data = rtc_read_nvr(address) Read from NVR ////
//// ////
//// get_bcd(data) Convert data to BCD ////
//// ////
//// rm_bcd(data) Convert data to int ////
//// ////
#define DSADDR 0xD0
#define DSRDADDR 0xD1
#define DS1338_SEC 0
#define DS1338_MIN 1
#define DS1338_HR 2
#define DS1338_DAY 3
#define DS1338_DATE 4
#define DS1338_MONTH 5
#define DS1338_YR 6
#define DS1338_CONTROL 7
unsigned int8 read_DS1338(unsigned int8 address)
{
unsigned int8 result;
i2c_start(I2CBUS);
i2c_write(I2CBUS, DSADDR);
i2c_write(I2CBUS, address);
i2c_start(I2CBUS);
i2c_write(I2CBUS, DSRDADDR);
result = i2c_read(I2CBUS, 0);
i2c_stop(I2CBUS);
return(result);
}
void write_DS1338(unsigned int8 address, unsigned int8 data)
{
i2c_start(I2CBUS);
i2c_write(I2CBUS, DSADDR);
i2c_write(I2CBUS, address);
i2c_write(I2CBUS, data);
i2c_stop(I2CBUS);
}
void rtc_init()
{
unsigned int8 data;
data = read_DS1338(DS1338_SEC);
//if (bit_test(data,7)==0) //test if chip was alive
// rtc_live=TRUE;
data &= 0x7F;
i2c_start(I2CBUS);
i2c_write(I2CBUS, DSADDR);
i2c_write(I2CBUS, DS1338_SEC);
i2c_write(I2CBUS, data);
i2c_start(I2CBUS);
i2c_write(I2CBUS, DSADDR);
i2c_write(I2CBUS, DS1338_CONTROL);
i2c_write(I2CBUS, 0x10); //0x90 should give 1Hz 0xB0 does not reset OSC stopped flag
i2c_stop(I2CBUS);
}
unsigned int8 get_bcd(unsigned int8 data)
{
unsigned int8 nibh;
unsigned int8 nibl;
nibh=data/10;
nibl=data-(nibh*10);
return((nibh<<4)|nibl);
}
unsigned int8 rm_bcd(unsigned int8 data)
{
unsigned int8 i;
i=data;
data=(i>>4)*10;
data=data+(i&0x0F);
return data;
}
void rtc_set_datetime(unsigned int8 day, unsigned int8 mth, unsigned int8 year, unsigned int8 dow, unsigned int8 hr, unsigned int8 min)
{
i2c_start(I2CBUS);
i2c_write(I2CBUS, DSADDR);
i2c_write(I2CBUS, DS1338_SEC);
i2c_write(I2CBUS, 0x00);
i2c_write(I2CBUS, get_bcd(min));
i2c_write(I2CBUS, get_bcd(hr));
i2c_write(I2CBUS, get_bcd(dow));
i2c_write(I2CBUS, get_bcd(day));
i2c_write(I2CBUS, get_bcd(mth));
i2c_write(I2CBUS, get_bcd(year));
i2c_stop();
}
void rtc_get_date(unsigned int8 &date, unsigned int8 &mth, unsigned int8 &year, unsigned int8 &dow)
{
date = rm_bcd(read_DS1338(DS1338_DATE));
mth = rm_bcd(read_DS1338(DS1338_MONTH));
year = rm_bcd(read_DS1338(DS1338_YR));
dow = rm_bcd(read_DS1338(DS1338_DAY));
}
void rtc_get_time(unsigned int8 &hr, unsigned int8 &min, unsigned int8 &sec)
{
hr = rm_bcd(read_DS1338(DS1338_HR));
min = rm_bcd(read_DS1338(DS1338_MIN));
sec = rm_bcd(read_DS1338(DS1338_SEC));
}
void rtc_write_nvr(unsigned int8 address, unsigned int8 data)
{
write_DS1338(address, data);
}
unsigned int8 rtc_read_nvr(unsigned int8 address)
{
return(read_DS1338(address));
}
|
Driver for the DS1338 RTC module. Just a slight 'tweak' of the other
drivers for the Maxim RTC's |
|