Skip to content

Commit

Permalink
Add PCF timer example
Browse files Browse the repository at this point in the history
  • Loading branch information
goertzel committed Jul 23, 2019
1 parent 2deadff commit 9106293
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 2 deletions.
92 changes: 92 additions & 0 deletions OPEnS_RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,98 @@ void PCF8523::stop_32768_clkout() {
write_reg(PCF8523_TMR_CLKOUT_CTRL , tmp);
}

void PCF8523::setTimer1(eTIMER_TIMEBASE timebase, uint8_t value)
{
uint8_t tmp;

// Set the timebase
write_reg(PCF8523_TMR_A_FREQ_CTRL , timebase);

// Set the value
write_reg(PCF8523_TMR_A_REG , value);

// Clear any Timer A flags
tmp = read_reg(PCF8523_CONTROL_2);

tmp &= ~_BV(PCF8523_CONTROL_2_CTAF_BIT); // Clear the Timer A flag
tmp |= _BV(PCF8523_CONTROL_2_CTAIE_BIT); // Enable Timer A interrupt

write_reg(PCF8523_CONTROL_2 , tmp);

// Set Timer A as Countdown and Enable
tmp = read_reg(PCF8523_TMR_CLKOUT_CTRL);

tmp |= _BV(PCF8523_TMR_CLKOUT_CTRL_TAM_BIT); // /INT line is pulsed
tmp |= 0x02; // Set as a Countdown Timer and Enable

write_reg(PCF8523_TMR_CLKOUT_CTRL , tmp);

}
void PCF8523::ackTimer1(void)
{
uint8_t tmp;

// Clear any Timer A flags
tmp = read_reg(PCF8523_CONTROL_2);

tmp &= ~_BV(PCF8523_CONTROL_2_CTAF_BIT); // Clear the Timer A flag

write_reg(PCF8523_CONTROL_2 , tmp);

return;
}
uint8_t PCF8523::getTimer1(void)
{
return read_reg(PCF8523_TMR_A_REG);
}
void PCF8523::setTimer2(eTIMER_TIMEBASE timebase,uint8_t value)
{
uint8_t tmp;

// Set the timebase
write_reg(PCF8523_TMR_B_FREQ_CTRL , timebase);

// Set the value
write_reg(PCF8523_TMR_B_REG , value);

// Clear any Timer B flags
tmp = read_reg(PCF8523_CONTROL_2);

tmp &= ~_BV(PCF8523_CONTROL_2_CTBF_BIT); // Clear the Timer B flag
tmp |= _BV(PCF8523_CONTROL_2_CTBIE_BIT); // Enable Timer B interrupt

write_reg(PCF8523_CONTROL_2 , tmp);

// Set Timer A as Countdown and Enable
tmp = read_reg(PCF8523_TMR_CLKOUT_CTRL);

tmp |= _BV(PCF8523_TMR_CLKOUT_CTRL_TBM_BIT); // /INT line is pulsed
tmp |= 0x01; // Enable

write_reg(PCF8523_TMR_CLKOUT_CTRL , tmp);


}
void PCF8523::ackTimer2(void)
{
uint8_t tmp;

// Clear any Timer B flags
tmp = read_reg(PCF8523_CONTROL_2);

tmp &= ~_BV(PCF8523_CONTROL_2_CTBF_BIT); // Clear the Timer A flag

write_reg(PCF8523_CONTROL_2 , tmp);

return;
}
uint8_t PCF8523::getTimer2(void)
{
return read_reg(PCF8523_TMR_B_REG);
}



////////////////////////////////////////////////////////////////////////////////
// RTC_DS1307 implementation

Expand Down
23 changes: 21 additions & 2 deletions OPEnS_RTC.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ class TimeSpan;
#define PCF8523_YEAR_1H_BIT 3
#define PCF8523_YEAR_1H_LENGTH 4


#define PCF8523_TMR_CLKOUT_CTRL_TAM_BIT 7
#define PCF8523_TMR_CLKOUT_CTRL_TBM_BIT 6
#define PCF8523_TMR_CLKOUT_CTRL_TBC_BIT 0

//End PCF8523 defines

#define DS1307_ADDRESS 0x68
Expand Down Expand Up @@ -186,6 +191,13 @@ class TimeSpan {

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 };

typedef enum {
eTB_4KHZ = 0,
eTB_64HZ,
eTB_SECOND,
eTB_MINUTE,
eTB_HOUR
} eTIMER_TIMEBASE;

class PCF8523{

Expand All @@ -201,19 +213,26 @@ class PCF8523{
void write_reg(uint8_t address, uint8_t* buf, uint8_t size);
void set_alarm(uint8_t day_alarm, uint8_t hour_alarm,uint8_t minute_alarm ) ;
void set_alarm(uint8_t hour_alarm,uint8_t minute_alarm );
void set_alarm(uint8_t minute_alarm );
void get_alarm(uint8_t* buf);
void reset();
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);

// Periodic Timers
void setTimer1(eTIMER_TIMEBASE timebase, uint8_t value);
void ackTimer1(void);
uint8_t getTimer1(void);
void setTimer2(eTIMER_TIMEBASE timebase,uint8_t value);
void ackTimer2(void);
uint8_t getTimer2(void);

};

enum Ds1307SqwPinMode { OFF = 0x00, ON = 0x80, SquareWave1HZ = 0x10, SquareWave4kHz = 0x11, SquareWave8kHz = 0x12, SquareWave32kHz = 0x13 };
Expand Down
76 changes: 76 additions & 0 deletions examples/PCF8523_Timer/PCF8523_Timer.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@

// The PCF8523 alarm only supports down to minute resolution, no seconds


#include <OPEnS_RTC.h>

#define ALARM_PIN 6


// Instance of DS3231 RTC
PCF8523 PCF;

volatile bool alarmFlag = false;
volatile int count = 0;
void alarmISR() {
// PCF.ackTimer1();
count++;
alarmFlag = true;
}


void print_DateTime(DateTime time);



// ======= SETUP ======
void setup()
{
pinMode(ALARM_PIN, INPUT_PULLUP); // Pull up resistors required for Active-Low interrupts
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);

Serial.begin(115200);
while (!Serial); // Won't start anything until serial is open, comment this line out if powering from battery

PCF.begin();
PCF.adjust(DateTime(__DATE__, __TIME__));

PCF.setTimer1(eTB_SECOND, 5);

attachInterrupt( digitalPinToInterrupt(ALARM_PIN), alarmISR, FALLING );

digitalWrite(LED_BUILTIN, LOW);
Serial.println("Setup Complete");
}


// ======= LOOP ======
void loop()
{
if (alarmFlag) {
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("Timer triggered, resetting alarm");

delay(2000);

digitalWrite(LED_BUILTIN, LOW);
alarmFlag = false;
}
Serial.print("Count: "); Serial.println(count);
print_DateTime(PCF.now());

delay(1000);
}


// Print an RTC time
void print_DateTime(DateTime time)
{
Serial.print(time.year()); Serial.print('/');
Serial.print(time.month()); Serial.print('/');
Serial.print(time.day()); Serial.print(' ');
Serial.print(time.hour()); Serial.print(':');
Serial.print(time.minute());Serial.print(':');
Serial.println(time.second());
}

0 comments on commit 9106293

Please sign in to comment.