Skip to content

Commit

Permalink
Fix PCF alarms add example
Browse files Browse the repository at this point in the history
  • Loading branch information
goertzel committed Jul 22, 2019
1 parent a253448 commit 2deadff
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 85 deletions.
221 changes: 148 additions & 73 deletions OPEnS_RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,23 +358,98 @@ void PCF8523::write_reg(uint8_t address, uint8_t data) {
void PCF8523::set_alarm(uint8_t day_alarm, uint8_t hour_alarm,uint8_t minute_alarm ) {
WIRE.beginTransmission(PCF8523_ADDRESS);
WIRE._I2C_WRITE(0x0A);
WIRE._I2C_WRITE(bin2bcd(minute_alarm));
WIRE._I2C_WRITE(bin2bcd(hour_alarm));
WIRE._I2C_WRITE(bin2bcd(day_alarm));
WIRE._I2C_WRITE(0);
// Enable Minute
WIRE._I2C_WRITE(bin2bcd(minute_alarm) & ~0x80 );
// Enable Hour
WIRE._I2C_WRITE(bin2bcd(hour_alarm) & ~0x80 );
// Enable Day
WIRE._I2C_WRITE(bin2bcd(day_alarm) & ~0x80);
WIRE._I2C_WRITE(0x80); // Disable WeekDay
WIRE.endTransmission();
}

void PCF8523::set_alarm(uint8_t hour_alarm,uint8_t minute_alarm ) {
WIRE.beginTransmission(PCF8523_ADDRESS);
WIRE._I2C_WRITE(0x0A);
WIRE._I2C_WRITE(bin2bcd(minute_alarm));
WIRE._I2C_WRITE(bin2bcd(hour_alarm));
WIRE._I2C_WRITE(bin2bcd(0));
WIRE._I2C_WRITE(0);
// Enable Minute
WIRE._I2C_WRITE(bin2bcd(minute_alarm) & ~0x80 );
// Enable Hour
WIRE._I2C_WRITE(bin2bcd(hour_alarm) & ~0x80 );
WIRE._I2C_WRITE(0x80); // Disable Day
WIRE._I2C_WRITE(0x80); // Disable WeekDay
WIRE.endTransmission();
}

// = = = = = = = =
void PCF8523::set_alarm(uint8_t minute_alarm ) {
WIRE.beginTransmission(PCF8523_ADDRESS);
WIRE._I2C_WRITE(0x0A);
// Enable Minute
WIRE._I2C_WRITE(bin2bcd(minute_alarm) & ~0x80 );
WIRE._I2C_WRITE(0x80); // Disable Hour
WIRE._I2C_WRITE(0x80); // Disable Day
WIRE._I2C_WRITE(0x80); // Disable WeekDay
WIRE.endTransmission();
}

void PCF8523::enable_alarm(bool enable)
{
uint8_t tmp;

tmp = read_reg(PCF8523_CONTROL_1);
if(enable){
// Disable Clockout & other Timers
write_reg(PCF8523_TMR_CLKOUT_CTRL , 0x38);

// Clear any existing flags
ack_alarm();
// Enable the AIE bit
tmp |= _BV(PCF8523_CONTROL_1_AIE_BIT);

}
else {
tmp &= ~_BV(PCF8523_CONTROL_1_AIE_BIT); // Disable the AIE bit
}
write_reg(PCF8523_CONTROL_1 , tmp);

}

void PCF8523::ack_alarm(void)
{
uint8_t tmp;
tmp = read_reg(PCF8523_CONTROL_2);

tmp &= ~_BV(PCF8523_CONTROL_2_AF_BIT); // Clear the AF bit

write_reg(PCF8523_CONTROL_2 , tmp);
return;
}


Pcf8523SqwPinMode PCF8523::readSqwPinMode() {
int mode;

Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
Wire.endTransmission();

Wire.requestFrom((uint8_t)PCF8523_ADDRESS, (uint8_t)1);
mode = Wire._I2C_READ();

mode >>= 3;
mode &= 0x7;
return static_cast<Pcf8523SqwPinMode>(mode);
}

void PCF8523::writeSqwPinMode(Pcf8523SqwPinMode mode) {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
Wire._I2C_WRITE(mode << 3);
Wire.endTransmission();
}

// = = = = = = = =

// Example: PCF8523.get_alarm(a);
// Returns a[0] = alarm minutes, a[1] = alarm hour, a[2] = alarm day
void PCF8523::get_alarm(uint8_t* buf) {
Expand Down Expand Up @@ -410,7 +485,7 @@ void PCF8523::start_counter_1(uint8_t value){
// Example: PCF8523.reset();
// Reset the PCF8523
void PCF8523::reset(){
write_reg(PCF8523_CONTROL_1, 0x58);
write_reg(PCF8523_CONTROL_1, 0x58);
}

uint8_t PCF8523::clear_rtc_interrupt_flags() {
Expand All @@ -421,9 +496,9 @@ uint8_t PCF8523::clear_rtc_interrupt_flags() {

// Stop the default 32.768KHz CLKOUT signal on INT1.
void PCF8523::stop_32768_clkout() {
uint8_t tmp = (read_reg (PCF8523_TMR_CLKOUT_CTRL))|RTC_CLKOUT_DISABLED;
uint8_t tmp = (read_reg (PCF8523_TMR_CLKOUT_CTRL))|RTC_CLKOUT_DISABLED;

write_reg(PCF8523_TMR_CLKOUT_CTRL , tmp);
write_reg(PCF8523_TMR_CLKOUT_CTRL , tmp);
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -547,78 +622,78 @@ DateTime RTC_Millis::now() {
////////////////////////////////////////////////////////////////////////////////
// RTC_PCF8563 implementation

boolean RTC_PCF8523::begin(void) {
Wire.begin();
return true;
}

boolean RTC_PCF8523::initialized(void) {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)PCF8523_CONTROL_3);
Wire.endTransmission();
// boolean RTC_PCF8523::begin(void) {
// Wire.begin();
// return true;
// }

Wire.requestFrom(PCF8523_ADDRESS, 1);
uint8_t ss = Wire._I2C_READ();
return ((ss & 0xE0) != 0xE0);
}
// boolean RTC_PCF8523::initialized(void) {
// Wire.beginTransmission(PCF8523_ADDRESS);
// Wire._I2C_WRITE((byte)PCF8523_CONTROL_3);
// Wire.endTransmission();

void RTC_PCF8523::adjust(const DateTime& dt) {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)3); // start at location 3
Wire._I2C_WRITE(bin2bcd(dt.second()));
Wire._I2C_WRITE(bin2bcd(dt.minute()));
Wire._I2C_WRITE(bin2bcd(dt.hour()));
Wire._I2C_WRITE(bin2bcd(dt.day()));
Wire._I2C_WRITE(bin2bcd(0)); // skip weekdays
Wire._I2C_WRITE(bin2bcd(dt.month()));
Wire._I2C_WRITE(bin2bcd(dt.year() - 2000));
Wire.endTransmission();

// set to battery switchover mode
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)PCF8523_CONTROL_3);
Wire._I2C_WRITE((byte)0x00);
Wire.endTransmission();
}
// Wire.requestFrom(PCF8523_ADDRESS, 1);
// uint8_t ss = Wire._I2C_READ();
// return ((ss & 0xE0) != 0xE0);
// }

DateTime RTC_PCF8523::now() {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)3);
Wire.endTransmission();
// void RTC_PCF8523::adjust(const DateTime& dt) {
// Wire.beginTransmission(PCF8523_ADDRESS);
// Wire._I2C_WRITE((byte)3); // start at location 3
// Wire._I2C_WRITE(bin2bcd(dt.second()));
// Wire._I2C_WRITE(bin2bcd(dt.minute()));
// Wire._I2C_WRITE(bin2bcd(dt.hour()));
// Wire._I2C_WRITE(bin2bcd(dt.day()));
// Wire._I2C_WRITE(bin2bcd(0)); // skip weekdays
// Wire._I2C_WRITE(bin2bcd(dt.month()));
// Wire._I2C_WRITE(bin2bcd(dt.year() - 2000));
// Wire.endTransmission();

// // set to battery switchover mode
// Wire.beginTransmission(PCF8523_ADDRESS);
// Wire._I2C_WRITE((byte)PCF8523_CONTROL_3);
// Wire._I2C_WRITE((byte)0x00);
// Wire.endTransmission();
// }

Wire.requestFrom(PCF8523_ADDRESS, 7);
uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F);
uint8_t mm = bcd2bin(Wire._I2C_READ());
uint8_t hh = bcd2bin(Wire._I2C_READ());
uint8_t d = bcd2bin(Wire._I2C_READ());
Wire._I2C_READ(); // skip 'weekdays'
uint8_t m = bcd2bin(Wire._I2C_READ());
uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000;
// DateTime RTC_PCF8523::now() {
// Wire.beginTransmission(PCF8523_ADDRESS);
// Wire._I2C_WRITE((byte)3);
// Wire.endTransmission();

// Wire.requestFrom(PCF8523_ADDRESS, 7);
// uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F);
// uint8_t mm = bcd2bin(Wire._I2C_READ());
// uint8_t hh = bcd2bin(Wire._I2C_READ());
// uint8_t d = bcd2bin(Wire._I2C_READ());
// Wire._I2C_READ(); // skip 'weekdays'
// uint8_t m = bcd2bin(Wire._I2C_READ());
// uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000;

return DateTime (y, m, d, hh, mm, ss);
}
// return DateTime (y, m, d, hh, mm, ss);
// }

Pcf8523SqwPinMode RTC_PCF8523::readSqwPinMode() {
int mode;
// Pcf8523SqwPinMode RTC_PCF8523::readSqwPinMode() {
// int mode;

Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
Wire.endTransmission();
// Wire.beginTransmission(PCF8523_ADDRESS);
// Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
// Wire.endTransmission();

Wire.requestFrom((uint8_t)PCF8523_ADDRESS, (uint8_t)1);
mode = Wire._I2C_READ();
// Wire.requestFrom((uint8_t)PCF8523_ADDRESS, (uint8_t)1);
// mode = Wire._I2C_READ();

mode >>= 3;
mode &= 0x7;
return static_cast<Pcf8523SqwPinMode>(mode);
}
// mode >>= 3;
// mode &= 0x7;
// return static_cast<Pcf8523SqwPinMode>(mode);
// }

void RTC_PCF8523::writeSqwPinMode(Pcf8523SqwPinMode mode) {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
Wire._I2C_WRITE(mode << 3);
Wire.endTransmission();
}
// void RTC_PCF8523::writeSqwPinMode(Pcf8523SqwPinMode mode) {
// Wire.beginTransmission(PCF8523_ADDRESS);
// Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
// Wire._I2C_WRITE(mode << 3);
// Wire.endTransmission();
// }

////////////////////////////////////////////////////////////////////////////////
// RTC_DS3231 implementation
Expand Down
38 changes: 26 additions & 12 deletions OPEnS_RTC.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class TimeSpan;
// with M0 (was not in original RTClibExtended.h):
#define _BV(bit) (1 << (bit))

// #define EI_NOTEXTERNAL
// #include <EnableInterrupt.h>


//Begin PCF8523 definitions
Expand Down Expand Up @@ -181,6 +183,10 @@ class TimeSpan {
int32_t _seconds;
};


enum Pcf8523SqwPinMode { PCF8523_OFF = 7, PCF8523_SquareWave1HZ = 6, PCF8523_SquareWave32HZ = 5, PCF8523_SquareWave1kHz = 4, PCF8523_SquareWave4kHz = 3, PCF8523_SquareWave8kHz = 2, PCF8523_SquareWave16kHz = 1, PCF8523_SquareWave32kHz = 0 };


class PCF8523{

public:
Expand All @@ -200,6 +206,14 @@ class PCF8523{
uint8_t clear_rtc_interrupt_flags();
void stop_32768_clkout();
void start_counter_1(uint8_t value);

//
void set_alarm(uint8_t minute_alarm );
void enable_alarm(bool enable);
void ack_alarm(void);
Pcf8523SqwPinMode readSqwPinMode();
void writeSqwPinMode(Pcf8523SqwPinMode mode);

};

enum Ds1307SqwPinMode { OFF = 0x00, ON = 0x80, SquareWave1HZ = 0x10, SquareWave4kHz = 0x11, SquareWave8kHz = 0x12, SquareWave32kHz = 0x13 };
Expand Down Expand Up @@ -259,18 +273,18 @@ class RTC_DS3231 {
};

// RTC based on the PCF8523 chip connected via I2C and the Wire library
enum Pcf8523SqwPinMode { PCF8523_OFF = 7, PCF8523_SquareWave1HZ = 6, PCF8523_SquareWave32HZ = 5, PCF8523_SquareWave1kHz = 4, PCF8523_SquareWave4kHz = 3, PCF8523_SquareWave8kHz = 2, PCF8523_SquareWave16kHz = 1, PCF8523_SquareWave32kHz = 0 };

class RTC_PCF8523 {
public:
boolean begin(void);
void adjust(const DateTime& dt);
boolean initialized(void);
static DateTime now();

Pcf8523SqwPinMode readSqwPinMode();
void writeSqwPinMode(Pcf8523SqwPinMode mode);
};
// enum Pcf8523SqwPinMode { PCF8523_OFF = 7, PCF8523_SquareWave1HZ = 6, PCF8523_SquareWave32HZ = 5, PCF8523_SquareWave1kHz = 4, PCF8523_SquareWave4kHz = 3, PCF8523_SquareWave8kHz = 2, PCF8523_SquareWave16kHz = 1, PCF8523_SquareWave32kHz = 0 };

// class RTC_PCF8523 {
// public:
// boolean begin(void);
// void adjust(const DateTime& dt);
// boolean initialized(void);
// static DateTime now();

// Pcf8523SqwPinMode readSqwPinMode();
// void writeSqwPinMode(Pcf8523SqwPinMode mode);
// };

// RTC using the internal millis() clock, has to be initialized before use
// NOTE: this clock won't be correct once the millis() timer rolls over (>49d?)
Expand Down
Loading

0 comments on commit 2deadff

Please sign in to comment.