SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
time/pcf8563/SensorPCF8563.hpp
Go to the documentation of this file.
1
31#pragma once
32
33#include "../../SensorBuildOpt.h"
34#if !SENSORLIB_EXCLUDE_PCF8563
35
36#include "../../platform/comm/I2CDeviceNoHal.hpp"
37#include "../SensorRTC.h"
38
43static const uint8_t PCF8563_SLAVE_ADDRESS = 0x51;
44
50{
51public:
55
66
70 SensorPCF8563() = default;
71
77 ~SensorPCF8563() = default;
78
79#if defined(ARDUINO)
88 bool begin(TwoWire &wire, int sda = -1, int scl = -1)
89 {
90 return I2CDeviceNoHal::begin(wire, PCF8563_SLAVE_ADDRESS, sda, scl);
91 }
92#elif defined(ESP_PLATFORM)
93
94#if defined(SENSORLIB_USE_I2C_LEGACY)
103 bool begin(i2c_port_t port_num, int sda = -1, int scl = -1)
104 {
105 return I2CDeviceNoHal::begin(port_num, PCF8563_SLAVE_ADDRESS, sda, scl);
106 }
107#else
114 bool begin(i2c_master_bus_handle_t handle)
115 {
116 return I2CDeviceNoHal::begin(handle, PCF8563_SLAVE_ADDRESS);
117 }
118#endif // SENSORLIB_USE_I2C_LEGACY
119#endif // ESP_PLATFORM
120
128 {
129 return I2CDeviceNoHal::begin(callback, PCF8563_SLAVE_ADDRESS);
130 }
131
139 void setDateTime(RTC_DateTime datetime) override
140 {
141 uint8_t buffer[7];
142 buffer[0] = DEC2BCD(datetime.getSecond()) & 0x7F;
143 buffer[1] = DEC2BCD(datetime.getMinute());
144 buffer[2] = DEC2BCD(datetime.getHour());
145 buffer[3] = DEC2BCD(datetime.getDay());
146 buffer[4] = getDayOfWeek(datetime.getDay(), datetime.getMonth(), datetime.getYear());
147 buffer[5] = DEC2BCD(datetime.getMonth());
148 buffer[6] = DEC2BCD(datetime.getYear() % 100);
149
150 // Set century bit according to year.
151 if ((2000 % datetime.getYear()) == 2000) {
152 buffer[5] &= 0x7F;
153 } else {
154 buffer[5] |= 0x80;
155 }
156 writeRegBuff(SEC_REG, buffer, 7);
157 }
158
167 {
168 uint8_t buffer[7];
169 readRegBuff(SEC_REG, buffer, 7);
170 uint8_t second = BCD2DEC(buffer[0] & 0x7F);
171 uint8_t minute = BCD2DEC(buffer[1] & 0x7F);
172 uint8_t hour = BCD2DEC(buffer[2] & 0x3F);
173 uint8_t day = BCD2DEC(buffer[3] & 0x3F);
174 uint8_t week = BCD2DEC(buffer[4] & 0x07);
175 uint8_t month = BCD2DEC(buffer[5] & 0x1F);
176 uint16_t year = BCD2DEC(buffer[6]);
177
178 // Century: 0 = 1900, 1 = 2000.
179 year += (buffer[5] & CENTURY_MASK) ? 1900 : 2000;
180 return RTC_DateTime(year, month, day, hour, minute, second, week);
181 }
182
192 {
193 return getRegBit(SEC_REG, 7) == 0;
194 }
195
205 {
206 uint8_t buffer[4];
207 readRegBuff(ALRM_MIN_REG, buffer, 4);
208 buffer[0] = BCD2DEC(buffer[0] & 0x80); // minute
209 buffer[1] = BCD2DEC(buffer[1] & 0x40); // hour
210 buffer[2] = BCD2DEC(buffer[2] & 0x40); // day
211 buffer[3] = BCD2DEC(buffer[3] & 0x08); // weekday
212 // RTC_Alarm(uint8_t hour, uint8_t minute, uint8_t second, uint8_t day, uint8_t week)
213 return RTC_Alarm(buffer[1], buffer[0], 0, buffer[2], buffer[3]);
214 }
215
220 {
222 }
223
228 {
230 }
231
236 {
238 }
239
245 {
246 return getRegBit(STAT2_REG, 3);
247 }
248
253 void setAlarm(RTC_Alarm alarm)
254 {
255 setAlarm(alarm.getHour(), alarm.getMinute(), alarm.getDay(), alarm.getWeek());
256 }
257
268 void setAlarm(uint8_t hour, uint8_t minute, uint8_t day, uint8_t week)
269 {
270 uint8_t buffer[4] = {0};
271
272 RTC_DateTime datetime = getDateTime();
273
274 uint8_t daysInMonth = getDaysInMonth(datetime.getMonth(), datetime.getYear());
275
276 if (minute != NO_ALARM) {
277 if (minute > 59) {
278 minute = 59;
279 }
280 buffer[0] = DEC2BCD(minute);
281 buffer[0] &= ~ALARM_ENABLE;
282 } else {
283 buffer[0] = ALARM_ENABLE;
284 }
285
286 if (hour != NO_ALARM) {
287 if (hour > 23) {
288 hour = 23;
289 }
290 buffer[1] = DEC2BCD(hour);
291 buffer[1] &= ~ALARM_ENABLE;
292 } else {
293 buffer[1] = ALARM_ENABLE;
294 }
295 if (day != NO_ALARM) {
296 buffer[2] = DEC2BCD(((day) < (1) ? (1) : ((day) > (daysInMonth) ? (daysInMonth) : (day))));
297 buffer[2] &= ~ALARM_ENABLE;
298 } else {
299 buffer[2] = ALARM_ENABLE;
300 }
301 if (week != NO_ALARM) {
302 if (week > 6) {
303 week = 6;
304 }
305 buffer[3] = DEC2BCD(week);
306 buffer[3] &= ~ALARM_ENABLE;
307 } else {
308 buffer[3] = ALARM_ENABLE;
309 }
310 writeRegBuff(ALRM_MIN_REG, buffer, 4);
311 }
312
317 void setAlarmByMinutes(uint8_t minute)
318 {
320 }
321
326 void setAlarmByDays(uint8_t day)
327 {
329 }
330
335 void setAlarmByHours(uint8_t hour)
336 {
338 }
339
344 void setAlarmByWeekDay(uint8_t week)
345 {
347 }
348
358 {
359 uint8_t buffer[2];
360 buffer[0] = readReg(STAT2_REG);
361 buffer[1] = readReg(TIMER1_REG);
362 if (buffer[0] & TIMER_TIE) {
363 return buffer[1] & TIMER_TE ? true : false;
364 }
365 return false;
366 }
367
373 {
374 return getRegBit(STAT2_REG, 2);
375 }
376
381 {
383 }
384
389 {
391 }
392
399 void setCountdownTimer(uint8_t val, uint8_t freq)
400 {
401 uint8_t buffer[3];
402 buffer[1] = readReg(TIMER1_REG);
403 buffer[1] |= (freq & TIMER_TD10);
404 buffer[2] = val;
405 writeReg(TIMER1_REG, buffer[1]);
406 writeReg(TIMER2_REG, buffer[2]);
407 }
408
413 {
414 uint8_t val;
415 val = readReg(STAT2_REG);
416 val &= ~(TIMER_TF | TIMER_TIE);
417 val |= ALARM_AF;
418 writeReg(STAT2_REG, val);
419 writeReg(TIMER1_REG, (uint8_t)0x00);
420 }
421
427 {
428 if (freq == CLK_DISABLE) {
429 clrRegBit(SQW_REG, 7);
430 } else {
431 writeReg(SQW_REG, freq | CLK_ENABLE);
432 }
433 }
434
439 const char *getChipName() override
440 {
441 return "PCF8563";
442 }
443
447 void reset() override
448 {
449 }
450
451private:
459 bool initImpl(uint8_t param) override
460 {
461 // Check device is online.
462 int ret = readReg(SEC_REG);
463 if (ret < 0) {
464 return false;
465 }
466 if (BCD2DEC(ret & 0x7F) > 59) {
467 return false;
468 }
469 return true;
470 }
471
472protected:
473 // Register addresses
474 static constexpr uint8_t STAT1_REG = 0x00;
475 static constexpr uint8_t STAT2_REG = 0x01;
476 static constexpr uint8_t SEC_REG = 0x02;
477 static constexpr uint8_t MIN_REG = 0x03;
478 static constexpr uint8_t HR_REG = 0x04;
479 static constexpr uint8_t DAY_REG = 0x05;
480 static constexpr uint8_t WEEKDAY_REG = 0x06;
481 static constexpr uint8_t MONTH_REG = 0x07;
482 static constexpr uint8_t YEAR_REG = 0x08;
483 static constexpr uint8_t ALRM_MIN_REG = 0x09;
484 static constexpr uint8_t SQW_REG = 0x0D;
485 static constexpr uint8_t TIMER1_REG = 0x0E;
486 static constexpr uint8_t TIMER2_REG = 0x0F;
487
488 // Mask values
489 static constexpr uint8_t VOL_LOW_MASK = 0x80;
490 static constexpr uint8_t MINUTES_MASK = 0x7F;
491 static constexpr uint8_t HOUR_MASK = 0x3F;
492 static constexpr uint8_t WEEKDAY_MASK = 0x07;
493 static constexpr uint8_t CENTURY_MASK = 0x80;
494 static constexpr uint8_t DAY_MASK = 0x3F;
495 static constexpr uint8_t MONTH_MASK = 0x1F;
496 static constexpr uint8_t TIMER_CTL_MASK = 0x03;
497
498 // Alarm and Timer flags
499 static constexpr uint8_t ALARM_AF = 0x08;
500 static constexpr uint8_t TIMER_TF = 0x04;
501 static constexpr uint8_t ALARM_AIE = 0x02;
502 static constexpr uint8_t TIMER_TIE = 0x01;
503 static constexpr uint8_t TIMER_TE = 0x80;
504 static constexpr uint8_t TIMER_TD10 = 0x03;
505
506 // Other constants
507 static constexpr uint8_t NO_ALARM = 0xFF;
508 static constexpr uint8_t ALARM_ENABLE = 0x80;
509 static constexpr uint8_t CLK_ENABLE = 0x80;
510};
511
512#endif
bool begin(SensorCommCustom::CustomCallback callback, uint8_t addr)
Initialize the sensor using custom callback interface.
uint8_t getDay() const
Definition SensorRTC.h:199
uint8_t getMinute() const
Definition SensorRTC.h:201
uint8_t getHour() const
Definition SensorRTC.h:200
uint8_t getWeek() const
Definition SensorRTC.h:203
uint8_t getMinute() const
Definition SensorRTC.h:149
uint8_t getMonth() const
Definition SensorRTC.h:146
uint8_t getDay() const
Definition SensorRTC.h:147
uint16_t getYear() const
Definition SensorRTC.h:145
uint8_t getHour() const
Definition SensorRTC.h:148
uint8_t getSecond() const
Definition SensorRTC.h:150
bool(*)(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite) CustomCallback
bool clrRegBit(uint8_t reg, uint8_t bit)
bool getRegBit(uint8_t reg, uint8_t bit)
int readReg(uint8_t reg) const
int writeRegBuff(uint8_t reg, uint8_t *buf, size_t len)
int writeReg(uint8_t reg, uint8_t val)
int readRegBuff(uint8_t reg, uint8_t *buf, size_t len) const
bool setRegBit(uint8_t reg, uint8_t bit)
Driver for the PCF8563 real-time clock (RTC) over I2C.
SensorPCF8563()=default
Construct a PCF8563 driver instance.
ClockHz
Clock output frequencies for the CLKOUT pin.
@ CLK_32768HZ
32.768 kHz output
@ CLK_1024HZ
1.024 kHz output
void resetAlarm()
Clear the alarm flag.
RTC_Alarm getAlarm()
Read the currently configured alarm settings.
void clearCountdownTimer()
Clear and disable the countdown timer.
void disableAlarm()
Disable the alarm interrupt.
static constexpr uint8_t ALRM_MIN_REG
static constexpr uint8_t TIMER_TIE
static constexpr uint8_t HR_REG
static constexpr uint8_t NO_ALARM
static constexpr uint8_t HOUR_MASK
static constexpr uint8_t CENTURY_MASK
void setDateTime(RTC_DateTime datetime) override
Set the RTC date/time.
void setAlarmByMinutes(uint8_t minute)
Convenience API to set an alarm that matches only minutes.
void setClockOutput(ClockHz freq)
Configure the clock output (CLKOUT) pin.
static constexpr uint8_t MONTH_REG
static constexpr uint8_t STAT1_REG
static constexpr uint8_t SQW_REG
static constexpr uint8_t MIN_REG
void setAlarmByDays(uint8_t day)
Convenience API to set an alarm that matches only day-of-month.
static constexpr uint8_t TIMER_CTL_MASK
void setAlarmByHours(uint8_t hour)
Convenience API to set an alarm that matches only hours.
void setCountdownTimer(uint8_t val, uint8_t freq)
Configure countdown timer.
bool isCountdownTimerActive()
Check whether the countdown timer flag is active.
static constexpr uint8_t ALARM_AIE
static constexpr uint8_t STAT2_REG
void enableAlarm()
Enable the alarm interrupt.
static constexpr uint8_t MINUTES_MASK
static constexpr uint8_t WEEKDAY_REG
bool isCountdownTimerEnable()
Check whether the countdown timer is enabled.
static constexpr uint8_t ALARM_ENABLE
void setAlarm(uint8_t hour, uint8_t minute, uint8_t day, uint8_t week)
Set the alarm configuration.
static constexpr uint8_t TIMER_TF
static constexpr uint8_t SEC_REG
static constexpr uint8_t DAY_MASK
static constexpr uint8_t WEEKDAY_MASK
void enableCountdownTimer()
Enable the countdown timer interrupt.
static constexpr uint8_t TIMER_TD10
static constexpr uint8_t TIMER_TE
static constexpr uint8_t DAY_REG
bool begin(SensorCommCustom::CustomCallback callback)
Initialize the device using a user-provided transport callback.
const char * getChipName() override
Get the chip name string.
static constexpr uint8_t TIMER2_REG
static constexpr uint8_t VOL_LOW_MASK
static constexpr uint8_t CLK_ENABLE
static constexpr uint8_t ALARM_AF
RTC_DateTime getDateTime() override
Get the current RTC date/time.
bool isClockIntegrityGuaranteed()
Check whether the clock integrity is guaranteed.
void setAlarmByWeekDay(uint8_t week)
Convenience API to set an alarm that matches only weekday.
static constexpr uint8_t TIMER1_REG
~SensorPCF8563()=default
Destructor.
void disableCountdownTimer()
Disable the countdown timer interrupt.
static constexpr uint8_t MONTH_MASK
bool isAlarmActive()
Check whether the alarm flag is active.
void setAlarm(RTC_Alarm alarm)
Set the alarm configuration.
static constexpr uint8_t YEAR_REG
void reset() override
Reset the RTC.
uint32_t getDayOfWeek(uint32_t day, uint32_t month, uint32_t year)
Calculate the day of the week for a given date using Zeller's congruence.
Definition SensorRTC.h:483
virtual void setDateTime(RTC_DateTime datetime)=0
Set the date and time of the RTC using an RTC_DateTime object.
static uint8_t BCD2DEC(uint8_t val)
Convert a Binary Coded Decimal (BCD) number to a decimal number.
Definition SensorRTC.h:657
uint8_t getDaysInMonth(uint8_t month, uint16_t year)
Get the number of days in a given month of a specific year, considering leap years.
Definition SensorRTC.h:552
virtual RTC_DateTime getDateTime()=0
Get the current date and time from the RTC.
static uint8_t DEC2BCD(uint8_t val)
Convert a decimal number to a Binary Coded Decimal (BCD) number.
Definition SensorRTC.h:667