86 lines
2.8 KiB
C++
86 lines
2.8 KiB
C++
#include "ds1302.h"
|
|
#include "writepin.h"
|
|
|
|
DS1302::DS1302(volatile unsigned char *port, volatile unsigned char *pinReg, volatile unsigned char *ddrReg, const unsigned char pinIO, const unsigned char pinCE, const unsigned char _pinSCLK):
|
|
_port(port), _pinReg(pinReg), _ddrReg(ddrReg), _pinIO(pinIO), _pinCE(pinCE), _pinSCLK(_pinSCLK)
|
|
{
|
|
*_ddrReg |= (1<<_pinCE) | (1<<_pinSCLK) | (1<<_pinIO);
|
|
write(REG_WP, 0x00);
|
|
uint8_t reg = read(REG_SEC);
|
|
write(REG_SEC, reg & ~0b10000000);
|
|
write(REG_WP, 0xFF);
|
|
}
|
|
|
|
void DS1302::write(uint8_t addr, uint8_t value)
|
|
{
|
|
setBit(_ddrReg, _pinIO, true);
|
|
writePin(_port, _pinCE, true);
|
|
for(uint8_t i = 0; i < 8; ++i)
|
|
{
|
|
writePin(_port, _pinSCLK, false);
|
|
writePin(_port, _pinIO, addr & (1<<i));
|
|
writePin(_port, _pinSCLK, true);
|
|
}
|
|
for(uint8_t i = 0; i < 8; ++i)
|
|
{
|
|
writePin(_port, _pinSCLK, false);
|
|
writePin(_port, _pinIO, value & (1<<i));
|
|
writePin(_port, _pinSCLK, true);
|
|
}
|
|
writePin(_port, _pinSCLK, false);
|
|
writePin(_port, _pinCE, false);
|
|
}
|
|
|
|
uint8_t DS1302::read(uint8_t addr)
|
|
{
|
|
setBit(_ddrReg, _pinIO, true);
|
|
writePin(_port, _pinCE, true);
|
|
for(uint8_t i = 0; i < 8; ++i)
|
|
{
|
|
writePin(_port, _pinSCLK, false);
|
|
writePin(_port, _pinIO, (addr | 1) & (1<<i));
|
|
writePin(_port, _pinSCLK, true);
|
|
}
|
|
setBit(_ddrReg, _pinIO, false);
|
|
writePin(_port, _pinSCLK, false);
|
|
uint8_t bits = 0;
|
|
for(uint8_t i = 0; i < 8; ++i)
|
|
{
|
|
writePin(_port, _pinSCLK, true);
|
|
if(readPin(_pinReg, _pinIO)) bits |= (1<<i);
|
|
writePin(_port, _pinSCLK, false);
|
|
}
|
|
writePin(_port, _pinCE, false);
|
|
return bits;
|
|
}
|
|
|
|
DS1302::Timeval DS1302::getTime()
|
|
{
|
|
Timeval time;
|
|
uint8_t reg = read(REG_SEC);
|
|
time.sec = (reg & 0b00001111) + 10*((reg & 0b01110000)>>4);
|
|
reg = read(REG_MIN);
|
|
time.min = (reg & 0b00001111) + 10*((reg & 0b01110000)>>4);
|
|
reg = read(REG_HOUR);
|
|
time.hour = (reg & 0b00001111) + 10*((reg & 0b00110000)>>4);
|
|
reg = read(REG_DAY);
|
|
time.day = (reg & 0b00001111) + 10*((reg & 0b00110000)>>4);
|
|
reg = read(REG_MONTH);
|
|
time.month = (reg & 0b00001111) + 10*((reg & 0b00110000)>>4);
|
|
reg = read(REG_YEAR);
|
|
time.year = (reg & 0b00001111) + 10*((reg & 0b11110000)>>4) + EPOCH;
|
|
return time;
|
|
}
|
|
void DS1302::setTime(const Timeval& in)
|
|
{
|
|
write(REG_WP, 0x00);
|
|
write(REG_SEC, ((in.sec / 10) << 4) | (in.sec % 10) );
|
|
write(REG_MIN, ((in.min / 10) << 4) | (in.min % 10) );
|
|
write(REG_HOUR, ((in.hour / 10) << 4) | (in.hour % 10));
|
|
write(REG_DAY, ((in.day / 10) << 4) | (in.day % 10));
|
|
write(REG_MONTH,((in.month / 10) << 4) | (in.month % 10));
|
|
uint8_t year = in.year - EPOCH;
|
|
write(REG_YEAR,((year / 10) << 4) | (year % 10));
|
|
write(REG_WP, 0xFF);
|
|
}
|