diff --git a/drivers/pcf85063a/pcf85063a.cpp b/drivers/pcf85063a/pcf85063a.cpp index 7e4599c0..e922e7bf 100644 --- a/drivers/pcf85063a/pcf85063a.cpp +++ b/drivers/pcf85063a/pcf85063a.cpp @@ -34,26 +34,25 @@ namespace pimoroni { } } - // set the speed of (or turn off) the clock output - void PCF85063A::set_clock_output(ClockOut co) { - uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); - bits = (bits & ~0x07) | uint8_t(co); - i2c->reg_write_uint8( - address, Registers::CONTROL_2, bits); + // i2c helper methods + i2c_inst_t* PCF85063A::get_i2c() const { + return i2c->get_i2c(); } - void PCF85063A::set_datetime(datetime_t *t) { - static uint8_t data[7] = { - bcd_encode((uint)t->sec), - bcd_encode((uint)t->min), - bcd_encode((uint)t->hour), - bcd_encode((uint)t->day), - bcd_encode((uint)t->dotw), - bcd_encode((uint)t->month), - bcd_encode((uint)t->year - 2000) // offset year - }; + int PCF85063A::get_address() const { + return address; + } - i2c->write_bytes(address, Registers::SECONDS, data, 7); + int PCF85063A::get_sda() const { + return i2c->get_sda(); + } + + int PCF85063A::get_scl() const { + return i2c->get_scl(); + } + + int PCF85063A::get_int() const { + return interrupt; } datetime_t PCF85063A::get_datetime() { @@ -74,30 +73,26 @@ namespace pimoroni { return dt; } - void PCF85063A::enable_alarm_interrupt(bool enable) { - uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); - bits = enable ? (bits | 0x80) : (bits & ~0x80); - bits |= 0x40; // ensure alarm flag isn't reset - i2c->reg_write_uint8(address, Registers::CONTROL_2, bits); - } + void PCF85063A::set_datetime(datetime_t *t) { + static uint8_t data[7] = { + bcd_encode((uint)t->sec), + bcd_encode((uint)t->min), + bcd_encode((uint)t->hour), + bcd_encode((uint)t->day), + bcd_encode((uint)t->dotw), + bcd_encode((uint)t->month), + bcd_encode((uint)t->year - 2000) // offset year + }; - void PCF85063A::clear_alarm_flag() { - uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); - bits &= ~0x40; - i2c->reg_write_uint8(address, Registers::CONTROL_2, bits); - } - - bool PCF85063A::read_alarm_flag() { - uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); - return bits & 0x40; + i2c->write_bytes(address, Registers::SECONDS, data, 7); } void PCF85063A::set_alarm(int second, int minute, int hour, int day) { uint8_t alarm[5] = { - uint8_t(second != -1 ? bcd_encode(second) : 0x80), - uint8_t(minute != -1 ? bcd_encode(minute) : 0x80), - uint8_t(hour != -1 ? bcd_encode( hour) : 0x80), - uint8_t(day != -1 ? bcd_encode( day) : 0x80), + uint8_t(second != PARAM_UNUSED ? bcd_encode(second) : 0x80), + uint8_t(minute != PARAM_UNUSED ? bcd_encode(minute) : 0x80), + uint8_t(hour != PARAM_UNUSED ? bcd_encode( hour) : 0x80), + uint8_t(day != PARAM_UNUSED ? bcd_encode( day) : 0x80), uint8_t(0x80) }; @@ -108,9 +103,9 @@ namespace pimoroni { int second, int minute, int hour, DayOfWeek dotw) { uint8_t alarm[5] = { - uint8_t(second != -1 ? bcd_encode(second) : 0x80), - uint8_t(minute != -1 ? bcd_encode(minute) : 0x80), - uint8_t(hour != -1 ? bcd_encode( hour) : 0x80), + uint8_t(second != PARAM_UNUSED ? bcd_encode(second) : 0x80), + uint8_t(minute != PARAM_UNUSED ? bcd_encode(minute) : 0x80), + uint8_t(hour != PARAM_UNUSED ? bcd_encode( hour) : 0x80), uint8_t(0x80), uint8_t(dotw != DayOfWeek::NONE ? bcd_encode( dotw) : 0x80) }; @@ -118,34 +113,46 @@ namespace pimoroni { i2c->write_bytes(address, Registers::SECOND_ALARM, alarm, 5); } + void PCF85063A::enable_alarm_interrupt(bool enable) { + uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); + bits = enable ? (bits | 0x80) : (bits & ~0x80); + bits |= 0x40; // ensure alarm flag isn't reset + i2c->reg_write_uint8(address, Registers::CONTROL_2, bits); + } + + bool PCF85063A::read_alarm_flag() { + uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); + return bits & 0x40; + } + + void PCF85063A::clear_alarm_flag() { + uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); + bits &= ~0x40; + i2c->reg_write_uint8(address, Registers::CONTROL_2, bits); + } + void PCF85063A::unset_alarm() { uint8_t dummy[5] = {0}; i2c->write_bytes(address, Registers::SECOND_ALARM, dummy, 5); } - void PCF85063A::enable_timer_interrupt(bool enable, bool flag_only) { - uint8_t bits = i2c->reg_read_uint8(address, Registers::TIMER_MODE); - bits = (bits & ~0x03) | (enable ? 0x02 : 0x00) | (flag_only ? 0x01 : 0x00); - i2c->reg_write_uint8(address, Registers::TIMER_MODE, bits); - } - - void PCF85063A::unset_timer() { - uint8_t bits = i2c->reg_read_uint8(address, Registers::TIMER_MODE); - bits &= ~0x04; - i2c->reg_write_uint8(address, Registers::TIMER_MODE, bits); - } - void PCF85063A::set_timer(uint8_t ticks, TimerTickPeriod ttp) { uint8_t bits = i2c->reg_read_uint8(address, Registers::TIMER_MODE); uint8_t timer[2] = { ticks, - uint8_t((bits & ~0x18) | ttp | 0x04) // mask out current ttp and set new + enable + uint8_t((bits & ~0x18) | (ttp << 3) | 0x04) // mask out current ttp and set new + enable }; i2c->write_bytes(address, Registers::TIMER_VALUE, timer, 2); } + void PCF85063A::enable_timer_interrupt(bool enable, bool flag_only) { + uint8_t bits = i2c->reg_read_uint8(address, Registers::TIMER_MODE); + bits = (bits & ~0x03) | (enable ? 0x02 : 0x00) | (flag_only ? 0x01 : 0x00); + i2c->reg_write_uint8(address, Registers::TIMER_MODE, bits); + } + bool PCF85063A::read_timer_flag() { uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); return bits & 0x08; @@ -157,25 +164,18 @@ namespace pimoroni { i2c->reg_write_uint8(address, Registers::CONTROL_2, bits); } - // i2c helper methods - i2c_inst_t* PCF85063A::get_i2c() const { - return i2c->get_i2c(); + void PCF85063A::unset_timer() { + uint8_t bits = i2c->reg_read_uint8(address, Registers::TIMER_MODE); + bits &= ~0x04; + i2c->reg_write_uint8(address, Registers::TIMER_MODE, bits); } - int PCF85063A::get_address() const { - return address; - } - - int PCF85063A::get_sda() const { - return i2c->get_sda(); - } - - int PCF85063A::get_scl() const { - return i2c->get_sda(); - } - - int PCF85063A::get_int() const { - return interrupt; + // set the speed of (or turn off) the clock output + void PCF85063A::set_clock_output(ClockOut co) { + uint8_t bits = i2c->reg_read_uint8(address, Registers::CONTROL_2); + bits = (bits & ~0x07) | uint8_t(co); + i2c->reg_write_uint8( + address, Registers::CONTROL_2, bits); } } \ No newline at end of file diff --git a/drivers/pcf85063a/pcf85063a.hpp b/drivers/pcf85063a/pcf85063a.hpp index 5dd45c9c..bd12c211 100644 --- a/drivers/pcf85063a/pcf85063a.hpp +++ b/drivers/pcf85063a/pcf85063a.hpp @@ -14,7 +14,13 @@ namespace pimoroni { //-------------------------------------------------- public: static const uint DEFAULT_I2C_ADDRESS = 0x51; + static const int PARAM_UNUSED = -1; + + //-------------------------------------------------- + // Enums + //-------------------------------------------------- + public: enum ClockOut : uint8_t { CLOCK_OUT_32768HZ = 0, CLOCK_OUT_16384HZ = 1, @@ -34,26 +40,17 @@ namespace pimoroni { THURSDAY = 4, FRIDAY = 5, SATURDAY = 6, - NONE = -1 + NONE = PARAM_UNUSED }; enum TimerTickPeriod : int8_t { - TIMER_TICK_4096HZ = 0b00 << 3, - TIMER_TICK_64HZ = 0b01 << 3, - TIMER_TICK_1HZ = 0b10 << 3, - TIMER_TICK_1_OVER_60HZ = 0b11 << 3 + TIMER_TICK_4096HZ = 0b00, + TIMER_TICK_64HZ = 0b01, + TIMER_TICK_1HZ = 0b10, + TIMER_TICK_1_OVER_60HZ = 0b11 }; - //-------------------------------------------------- - // Variables - //-------------------------------------------------- private: - I2C *i2c; - - // interface pins with our standard defaults where appropriate - uint address = DEFAULT_I2C_ADDRESS; - uint interrupt = PIN_UNUSED; - enum Registers : uint8_t { CONTROL_1 = 0x00, CONTROL_2 = 0x01, @@ -76,6 +73,18 @@ namespace pimoroni { TIMER_MODE = 0x11 }; + + //-------------------------------------------------- + // Variables + //-------------------------------------------------- + private: + I2C *i2c; + + // Interface pins with our standard defaults where appropriate + uint address = DEFAULT_I2C_ADDRESS; + uint interrupt = PIN_UNUSED; + + //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- @@ -92,38 +101,38 @@ namespace pimoroni { void init(); void reset(); - // set and get the date and time - // uses datetime_t from pico sdk (hardware/rtc) for compatibility - void set_datetime(datetime_t *t); - datetime_t get_datetime(); - - // alarm manipulation methods - void enable_alarm_interrupt(bool enable); - void clear_alarm_flag(); - bool read_alarm_flag(); - void unset_alarm(); - void set_alarm(int second = -1, int minute = -1, int hour = -1, int day = -1); - void set_weekday_alarm(int second = -1, int minute = -1, int hour = -1, - DayOfWeek dotw = DayOfWeek::NONE); - - // timer manipulation methods - void enable_timer_interrupt(bool enable, bool flag_only = false); - void unset_timer(); - void set_timer(uint8_t ticks, - TimerTickPeriod ttp = TimerTickPeriod::TIMER_TICK_1HZ); - bool read_timer_flag(); - void clear_timer_flag(); - - // clock output - void set_clock_output(ClockOut co); - - // i2c instance details access methods + // I2C instance details access methods i2c_inst_t* get_i2c() const; int get_address() const; int get_sda() const; int get_scl() const; int get_int() const; + // Set and get the date and time + // Uses datetime_t from pico sdk (hardware/rtc) for compatibility + datetime_t get_datetime(); + void set_datetime(datetime_t *t); + + // Alarm manipulation methods + void set_alarm(int second = PARAM_UNUSED, int minute = PARAM_UNUSED, + int hour = PARAM_UNUSED, int day = PARAM_UNUSED); + void set_weekday_alarm(int second = PARAM_UNUSED, int minute = PARAM_UNUSED, + int hour = PARAM_UNUSED, DayOfWeek dotw = DayOfWeek::NONE); + void enable_alarm_interrupt(bool enable); + bool read_alarm_flag(); + void clear_alarm_flag(); + void unset_alarm(); + + // Timer manipulation methods + void set_timer(uint8_t ticks, + TimerTickPeriod ttp = TimerTickPeriod::TIMER_TICK_1HZ); + void enable_timer_interrupt(bool enable, bool flag_only = false); + bool read_timer_flag(); + void clear_timer_flag(); + void unset_timer(); + + // Clock output + void set_clock_output(ClockOut co); }; } \ No newline at end of file