Skip to content
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

Add some functions to PCF8523 (Alarm) #291

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
158 changes: 157 additions & 1 deletion src/RTC_PCF8523.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,143 @@ bool RTC_PCF8523::initialized(void) {
return (read_register(PCF8523_CONTROL_3) & 0xE0) != 0xE0;
}

/**************************************************************************/
/*!
@brief Set RTC alarm value for a specific register
*/
/**************************************************************************/

void RTC_PCF8523::set_alarm_value_for_register(Pcf8563AlarmRegister the_register,uint8_t the_value) {
//set the value and enable the AEN_X (enabled with 0 value)
switch(the_register){
case PCF8523_ALARM_MINUTE:
write_register(the_register,bin2bcd((the_value%60) & 0x7F));
break;
case PCF8523_ALARM_HOUR:
write_register(the_register,bin2bcd((the_value%24) & 0x7F));
break;
case PCF8523_ALARM_DAY:
write_register(the_register,bin2bcd((the_value%32) & 0x7F));
break;
case PCF8523_ALARM_WEEKDAY:
write_register(the_register,bin2bcd((the_value%8) & 0x7F));
break;
default:
break;
}
}

/**************************************************************************/
/*!
@brief Get RTC alarm value for a specific register
*/
/**************************************************************************/

uint8_t RTC_PCF8523::get_alarm_value_for_register(Pcf8563AlarmRegister the_register) {
//set the value and enable the AEN_X (enabled with 0 value)
switch(the_register){
case PCF8523_ALARM_MINUTE:
return bcd2bin(read_register(the_register));
break;
case PCF8523_ALARM_HOUR:
return bcd2bin(read_register(the_register));
break;
case PCF8523_ALARM_DAY:
return bcd2bin(read_register(the_register));
break;
case PCF8523_ALARM_WEEKDAY:
return bcd2bin(read_register(the_register));
break;
default:
break;
}
return 0xFF;
}

/**************************************************************************/
/*!
@brief RTC Upgrade oscillator capacitor From 7pF to 12.5pF
*/
/**************************************************************************/

void RTC_PCF8523::upgrade_osci_capa_to_12pf5() {
write_register(PCF8523_CONTROL_1,
read_register(PCF8523_CONTROL_1) | (1 << 7));//Enable CAP_SEL

}

/**************************************************************************/
/*!
@brief Enable Alarm based on previous set_alarm_value_for_register call
*/
/**************************************************************************/

void RTC_PCF8523::enable_alarm() {
write_register(PCF8523_CONTROL_1,
read_register(PCF8523_CONTROL_1) | (1 << 1));//Enable AIE

}

/**************************************************************************/
/*!
@brief Check Alarm fired
*/
/**************************************************************************/

bool RTC_PCF8523::is_alarm_fired(void) {
return (read_register(PCF8523_CONTROL_2) && (1 << 3));//Check AF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return (read_register(PCF8523_CONTROL_2) && (1 << 3));//Check AF
return (read_register(PCF8523_CONTROL_2) & (1 << 3));//Check AF

}

/**************************************************************************/
/*!
@brief Clear Alarm
*/
/**************************************************************************/

void RTC_PCF8523::clear_alarm() {
write_register(PCF8523_CONTROL_2,
read_register(PCF8523_CONTROL_2) & ~(1 << 3));//Clear AF
}

/**************************************************************************/
/*!
@brief Disable Alarm
*/
/**************************************************************************/

void RTC_PCF8523::disable_alarm() {
//write_register(PCF8523_CONTROL_1,
// read_register(PCF8523_CONTROL_1) & 0xFD);//Disable AIE
write_register(PCF8523_CONTROL_1,
read_register(PCF8523_CONTROL_1) & ~(1 << 1));//Disable AIE
write_register(PCF8523_ALARM_MINUTE,0x80);
write_register(PCF8523_ALARM_HOUR,0x80);
write_register(PCF8523_ALARM_DAY,0x80);
write_register(PCF8523_ALARM_WEEKDAY,0x80);
}

/**************************************************************************/
/*!
@brief Ask if any Alarm is setup
*/
/**************************************************************************/

bool RTC_PCF8523::is_any_alarm_setup(void) {
if(read_register(PCF8523_CONTROL_1) && (1<<1)){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(read_register(PCF8523_CONTROL_1) && (1<<1)){
if(read_register(PCF8523_CONTROL_1) & (1<<1)){

return true;
}
return false;
}

/**************************************************************************/
/*!
@brief Set RTC battery switch-over mode in register Control_3
*/
/**************************************************************************/
void RTC_PCF8523::set_battery_switch_over(uint8_t battery_switch_over_value) {
write_register(PCF8523_CONTROL_3,battery_switch_over_value);
}

/**************************************************************************/
/*!
@brief Set the date and time, set battery switchover mode
Expand All @@ -67,10 +204,20 @@ void RTC_PCF8523::adjust(const DateTime &dt) {
bin2bcd(0), // skip weekdays
bin2bcd(dt.month()),
bin2bcd(dt.year() - 2000U)};

#ifdef DEBUG_RTCLIB
DEBUG_RTCLIB.printf("I2C_W(0x%02X,0x%02X)\n",3,buffer[1]);
DEBUG_RTCLIB.printf("I2C_W(0x%02X,0x%02X)\n",4,buffer[2]);
DEBUG_RTCLIB.printf("I2C_W(0x%02X,0x%02X)\n",5,buffer[3]);
DEBUG_RTCLIB.printf("I2C_W(0x%02X,0x%02X)\n",6,buffer[4]);
DEBUG_RTCLIB.printf("I2C_W(0x%02X,0x%02X)\n",7,buffer[5]);
DEBUG_RTCLIB.printf("I2C_W(0x%02X,0x%02X)\n",8,buffer[6]);
DEBUG_RTCLIB.printf("I2C_W(0x%02X,0x%02X)\n",9,buffer[7]);
#endif /* DEBUG_RTCLIB */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug statements probably do not belong to this pull request.

i2c_dev->write(buffer, 8);

// set to battery switchover mode
write_register(PCF8523_CONTROL_3, 0x00);
set_battery_switch_over(0x00);
}

/**************************************************************************/
Expand Down Expand Up @@ -110,6 +257,15 @@ void RTC_PCF8523::stop(void) {
read_register(PCF8523_CONTROL_1) | (1 << 5));
}

/**************************************************************************/
/*!
@brief Reset RTC sending 0x58 in register Control_1
*/
/**************************************************************************/
void RTC_PCF8523::reset(void) {
write_register(PCF8523_CONTROL_1,0x58);
}

/**************************************************************************/
/*!
@brief Is the PCF8523 running? Check the STOP bit in register Control_1
Expand Down
6 changes: 6 additions & 0 deletions src/RTClib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
/**************************************************************************/
void RTC_I2C::write_register(uint8_t reg, uint8_t val) {
uint8_t buffer[2] = {reg, val};
#ifdef DEBUG_RTCLIB
Serial.printf("I2C_W(0x%02X,0x%02X)\n",reg,val);
#endif /* DEBUG_RTCLIB */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#ifdef DEBUG_RTCLIB
Serial.printf("I2C_W(0x%02X,0x%02X)\n",reg,val);
#endif /* DEBUG_RTCLIB */

i2c_dev->write(buffer, 2);
}

Expand All @@ -79,6 +82,9 @@ uint8_t RTC_I2C::read_register(uint8_t reg) {
uint8_t buffer[1];
i2c_dev->write(&reg, 1);
i2c_dev->read(buffer, 1);
#ifdef DEBUG_RTCLIB
DEBUG_RTCLIB.printf("I2C_R(0x%02X)=0x%02X\n",reg,buffer[0]);
#endif /* DEBUG_RTCLIB */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#ifdef DEBUG_RTCLIB
DEBUG_RTCLIB.printf("I2C_R(0x%02X)=0x%02X\n",reg,buffer[0]);
#endif /* DEBUG_RTCLIB */

return buffer[0];
}

Expand Down
18 changes: 18 additions & 0 deletions src/RTClib.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ enum Pcf8563SqwPinMode {
PCF8563_SquareWave32kHz = 0x80 /**< 32kHz square wave */
};

/** PCF8563 CLKOUT pin mode settings */
enum Pcf8563AlarmRegister {
PCF8523_ALARM_MINUTE = 0x0A, ///< Minute Alarm register
PCF8523_ALARM_HOUR = 0x0B, ///< Hour Alarm register
PCF8523_ALARM_DAY = 0x0C, ///< Day Alarm register
PCF8523_ALARM_WEEKDAY = 0x0D, ///< WeekDay Alarm register
};

/**************************************************************************/
/*!
@brief Simple general-purpose date/time class (no TZ / DST / leap
Expand Down Expand Up @@ -409,9 +417,19 @@ class RTC_PCF8523 : RTC_I2C {
void adjust(const DateTime &dt);
bool lostPower(void);
bool initialized(void);
bool is_alarm_fired(void);
bool is_any_alarm_setup(void);
DateTime now();
void upgrade_osci_capa_to_12pf5();
void start(void);
void stop(void);
void reset(void);
void set_battery_switch_over(uint8_t battery_switch_over_value);
void set_alarm_value_for_register(Pcf8563AlarmRegister the_register,uint8_t the_value);
uint8_t get_alarm_value_for_register(Pcf8563AlarmRegister the_register);
void enable_alarm();
void clear_alarm();
void disable_alarm();
uint8_t isrunning();
Pcf8523SqwPinMode readSqwPinMode();
void writeSqwPinMode(Pcf8523SqwPinMode mode);
Expand Down