Skip to content

generalize: generalize for use with multiple I2C interfaces #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
239 changes: 125 additions & 114 deletions PCF85063A.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,92 +2,103 @@


// INIT
PCF85063A::PCF85063A(void)
PCF85063A::PCF85063A(TwoWire *_Wire_Interface = &Wire)
{
Wire.begin();
Wire_Interface = _Wire_Interface;
}

// PUBLIC
void PCF85063A::setTime(uint8_t hour, uint8_t minute, uint8_t second)
bool
PCF85063A::exist (void)
{
Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_SECOND_ADDR);
Wire.write(decToBcd( second) );
Wire.write(decToBcd( minute) );
Wire.write(decToBcd( hour) );
Wire.endTransmission();
bool RetVal;

Wire_Interface->beginTransmission(PCF85063A_ADDR);
RetVal = (Wire_Interface->endTransmission() == 0);

return RetVal;
}

void PCF85063A::setTime(uint8_t hour, uint8_t minute, uint8_t second)
{
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_SECOND_ADDR);
Wire_Interface->write(decToBcd( second) );
Wire_Interface->write(decToBcd( minute) );
Wire_Interface->write(decToBcd( hour) );
Wire_Interface->endTransmission();
}

void PCF85063A::setDate(uint8_t weekday, uint8_t day, uint8_t month, uint8_t yr)
{
year = yr - 1970; // convert to RTC year format 0-99

Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_DAY_ADDR);
Wire.write( decToBcd(day) );
Wire.write( decToBcd(weekday) );
Wire.write( decToBcd(month) );
Wire.write( decToBcd(year) );
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_DAY_ADDR);
Wire_Interface->write( decToBcd(day) );
Wire_Interface->write( decToBcd(weekday) );
Wire_Interface->write( decToBcd(month) );
Wire_Interface->write( decToBcd(year) );
Wire_Interface->endTransmission();
}

void PCF85063A::readTime()
void PCF85063A::readTime()
{
Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_SECOND_ADDR); // datasheet 8.4.
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_SECOND_ADDR); // datasheet 8.4.
Wire_Interface->endTransmission();

Wire.requestFrom(I2C_ADDR, 7);
Wire_Interface->requestFrom(PCF85063A_ADDR, 7);

while( Wire.available() )
while( Wire_Interface->available() )
{
second = bcdToDec( Wire.read() & 0x7F ); // ignore bit 7
minute = bcdToDec( Wire.read() & 0x7F );
hour = bcdToDec( Wire.read() & 0x3F ); // ignore bits 7 & 6
day = bcdToDec( Wire.read() & 0x3F );
weekday = bcdToDec( Wire.read() & 0x07); // ignore bits 7,6,5,4 & 3
month = bcdToDec( Wire.read() & 0x1F); // ignore bits 7,6 & 5
year = bcdToDec( Wire.read()) + 1970;
second = bcdToDec( Wire_Interface->read() & 0x7F ); // ignore bit 7
minute = bcdToDec( Wire_Interface->read() & 0x7F );
hour = bcdToDec( Wire_Interface->read() & 0x3F ); // ignore bits 7 & 6
day = bcdToDec( Wire_Interface->read() & 0x3F );
weekday = bcdToDec( Wire_Interface->read() & 0x07); // ignore bits 7,6,5,4 & 3
month = bcdToDec( Wire_Interface->read() & 0x1F); // ignore bits 7,6 & 5
year = bcdToDec( Wire_Interface->read()) + 1970;
}
}

uint8_t PCF85063A::getSecond()
uint8_t PCF85063A::getSecond()
{
readTime();
return second;
}

uint8_t PCF85063A::getMinute()
uint8_t PCF85063A::getMinute()
{
readTime();
return minute;
}

uint8_t PCF85063A::getHour()
uint8_t PCF85063A::getHour()
{
readTime();
return hour;
}

uint8_t PCF85063A::getDay()
uint8_t PCF85063A::getDay()
{
readTime();
return day;
}

uint8_t PCF85063A::getWeekday()
uint8_t PCF85063A::getWeekday()
{
readTime();
return weekday;
}

uint8_t PCF85063A::getMonth()
uint8_t PCF85063A::getMonth()
{
readTime();
return month;
}

uint16_t PCF85063A::getYear()
uint16_t PCF85063A::getYear()
{
readTime();
return year;
Expand All @@ -96,116 +107,116 @@ uint16_t PCF85063A::getYear()
void PCF85063A::enableAlarm() // datasheet 8.5.6.
{
// check Table 2. Control_2
control_2 = RTC_CTRL_2_DEFAULT | RTC_ALARM_AIE; // enable interrupt
control_2 &= ~RTC_ALARM_AF; // clear alarm flag
control_2 = PCF85063A_CTRL_2_DEFAULT | PCF85063A_ALARM_AIE; // enable interrupt
control_2 &= ~PCF85063A_ALARM_AF; // clear alarm flag

Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_CTRL_2);
Wire.write(control_2);
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_CTRL_2);
Wire_Interface->write(control_2);
Wire_Interface->endTransmission();
}

void PCF85063A::setAlarm(uint8_t alarm_second, uint8_t alarm_minute, uint8_t alarm_hour, uint8_t alarm_day, uint8_t alarm_weekday)
{
if (alarm_second <99) { // second
alarm_second = constrain(alarm_second, 0, 59);
alarm_second = decToBcd(alarm_second);
alarm_second &= ~RTC_ALARM;
alarm_second &= ~PCF85063A_ALARM;
} else {
alarm_second = 0x0; alarm_second |= RTC_ALARM;
alarm_second = 0x0; alarm_second |= PCF85063A_ALARM;
}

if (alarm_minute <99) { // minute
alarm_minute = constrain(alarm_minute, 0, 59);
alarm_minute = decToBcd(alarm_minute);
alarm_minute &= ~RTC_ALARM;
alarm_minute &= ~PCF85063A_ALARM;
} else {
alarm_minute = 0x0; alarm_minute |= RTC_ALARM;
alarm_minute = 0x0; alarm_minute |= PCF85063A_ALARM;
}

if (alarm_hour <99) { // hour
alarm_hour = constrain(alarm_hour, 0, 23);
alarm_hour = decToBcd(alarm_hour);
alarm_hour &= ~RTC_ALARM;
alarm_hour &= ~PCF85063A_ALARM;
} else {
alarm_hour = 0x0; alarm_hour |= RTC_ALARM;
alarm_hour = 0x0; alarm_hour |= PCF85063A_ALARM;
}

if (alarm_day <99) { // day
alarm_day = constrain(alarm_day, 1, 31);
alarm_day = decToBcd(alarm_day);
alarm_day &= ~RTC_ALARM;
alarm_day = decToBcd(alarm_day);
alarm_day &= ~PCF85063A_ALARM;
} else {
alarm_day = 0x0; alarm_day |= RTC_ALARM;
alarm_day = 0x0; alarm_day |= PCF85063A_ALARM;
}

if (alarm_weekday <99) { // weekday
alarm_weekday = constrain(alarm_weekday, 0, 6);
alarm_weekday = decToBcd(alarm_weekday);
alarm_weekday &= ~RTC_ALARM;
alarm_weekday &= ~PCF85063A_ALARM;
} else {
alarm_weekday = 0x0; alarm_weekday |= RTC_ALARM;
alarm_weekday = 0x0; alarm_weekday |= PCF85063A_ALARM;
}

enableAlarm();

Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_SECOND_ALARM);
Wire.write(alarm_second);
Wire.write(alarm_minute);
Wire.write(alarm_hour);
Wire.write(alarm_day);
Wire.write(alarm_weekday);
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_SECOND_ALARM);
Wire_Interface->write(alarm_second);
Wire_Interface->write(alarm_minute);
Wire_Interface->write(alarm_hour);
Wire_Interface->write(alarm_day);
Wire_Interface->write(alarm_weekday);
Wire_Interface->endTransmission();
}

void PCF85063A::readAlarm()
void PCF85063A::readAlarm()
{
Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_SECOND_ALARM); // datasheet 8.4.
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_SECOND_ALARM); // datasheet 8.4.
Wire_Interface->endTransmission();

Wire.requestFrom(I2C_ADDR, 5);
Wire_Interface->requestFrom(PCF85063A_ADDR, 5);

while( Wire.available() )
while( Wire_Interface->available() )
{
alarm_second = Wire.read(); // read RTC_SECOND_ALARM register
if( RTC_ALARM & alarm_second) // check is AEN = 1 (second alarm disabled)
alarm_second = Wire_Interface->read(); // read PCF85063A_SECOND_ALARM register
if( PCF85063A_ALARM & alarm_second) // check is AEN = 1 (second alarm disabled)
{
alarm_second = 99; // using 99 as code for no alarm
} else { // else if AEN = 0 (second alarm enabled)
alarm_second = bcdToDec( alarm_second & ~RTC_ALARM); // remove AEN flag and convert to dec number
alarm_second = bcdToDec( alarm_second & ~PCF85063A_ALARM); // remove AEN flag and convert to dec number
}

alarm_minute = Wire.read(); // minute
if( RTC_ALARM & alarm_minute)
alarm_minute = Wire_Interface->read(); // minute
if( PCF85063A_ALARM & alarm_minute)
{
alarm_minute = 99;
} else {
alarm_minute = bcdToDec( alarm_minute & ~RTC_ALARM);
alarm_minute = 99;
} else {
alarm_minute = bcdToDec( alarm_minute & ~PCF85063A_ALARM);
}

alarm_hour = Wire.read(); // hour
if( RTC_ALARM & alarm_hour)
alarm_hour = Wire_Interface->read(); // hour
if( PCF85063A_ALARM & alarm_hour)
{
alarm_hour = 99;
} else {
alarm_hour = 99;
} else {
alarm_hour = bcdToDec( alarm_hour & 0x3F); // remove bits 7 & 6
}

alarm_day = Wire.read(); // day
if( RTC_ALARM & alarm_day)
alarm_day = Wire_Interface->read(); // day
if( PCF85063A_ALARM & alarm_day)
{
alarm_day = 99;
} else {
alarm_day = 99;
} else {
alarm_day = bcdToDec( alarm_day & 0x3F); // remove bits 7 & 6
}

alarm_weekday = Wire.read(); // weekday
if( RTC_ALARM & alarm_weekday)
alarm_weekday = Wire_Interface->read(); // weekday
if( PCF85063A_ALARM & alarm_weekday)
{
alarm_weekday = 99;
} else {
alarm_weekday = 99;
} else {
alarm_weekday = bcdToDec( alarm_weekday & 0x07); // remove bits 7,6,5,4 & 3
}
}
Expand Down Expand Up @@ -246,53 +257,53 @@ void PCF85063A::timerSet(CountdownSrcClock source_clock, uint8_t value, bool int
uint8_t timer_reg[2] = {0};

// disable the countdown timer
Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_TIMER_MODE);
Wire.write(0x18); // default
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_TIMER_MODE);
Wire_Interface->write(0x18); // default
Wire_Interface->endTransmission();

// clear Control_2
Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_CTRL_2);
Wire.write(0x00); // default
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_CTRL_2);
Wire_Interface->write(0x00); // default
Wire_Interface->endTransmission();

// reconfigure timer
timer_reg[1] |= RTC_TIMER_TE; // enable timer
if (int_enable) timer_reg[1] |= RTC_TIMER_TIE; // enable interrupr
if (int_pulse) timer_reg[1] |= RTC_TIMER_TI_TP; // interrupt mode
timer_reg[1] |= PCF85063A_TIMER_TE; // enable timer
if (int_enable) timer_reg[1] |= PCF85063A_TIMER_TIE; // enable interrupr
if (int_pulse) timer_reg[1] |= PCF85063A_TIMER_TI_TP; // interrupt mode
timer_reg[1] |= source_clock << 3; // clock source
//timer_reg[1] = 0b00011111;

timer_reg[0] = value;

// write timer value
Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_TIMER_VAL);
Wire.write(timer_reg[0]);
Wire.write(timer_reg[1]);
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_TIMER_VAL);
Wire_Interface->write(timer_reg[0]);
Wire_Interface->write(timer_reg[1]);
Wire_Interface->endTransmission();
}

bool PCF85063A::checkTimerFlag()
{
uint8_t _crtl_2 = RTC_TIMER_FLAG;
uint8_t _crtl_2 = PCF85063A_TIMER_FLAG;

Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_CTRL_2);
Wire.endTransmission();
Wire.requestFrom(I2C_ADDR, 1);
_crtl_2 &= Wire.read();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_CTRL_2);
Wire_Interface->endTransmission();
Wire_Interface->requestFrom(PCF85063A_ADDR, 1);
_crtl_2 &= Wire_Interface->read();

return _crtl_2;
}

void PCF85063A::reset() // datasheet 8.2.1.3.
{
Wire.beginTransmission(I2C_ADDR);
Wire.write(RTC_CTRL_1);
Wire.write(0x58);
Wire.endTransmission();
Wire_Interface->beginTransmission(PCF85063A_ADDR);
Wire_Interface->write(PCF85063A_CTRL_1);
Wire_Interface->write(0x58);
Wire_Interface->endTransmission();
}


Expand Down
Loading