Completed RTC driver refactoring
This commit is contained in:
@@ -1,257 +1,182 @@
|
|||||||
#include "WS_PCF85063.h"
|
#include "WS_PCF85063.h"
|
||||||
|
#include <ctime>
|
||||||
datetime_t datetime = {0};
|
|
||||||
datetime_t Update_datetime = {0};
|
|
||||||
static uint8_t decToBcd(int val);
|
|
||||||
static int bcdToDec(uint8_t val);
|
|
||||||
|
|
||||||
void Time_printf(void *parameter)
|
|
||||||
{
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
char datetime_str[50];
|
|
||||||
datetime_to_str(datetime_str, datetime);
|
|
||||||
printf("Time:%s\r\n", datetime_str);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
|
||||||
}
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
void PCF85063_Init(void) // PCF85063 initialized
|
|
||||||
{
|
|
||||||
uint8_t Value = RTC_CTRL_1_DEFAULT | RTC_CTRL_1_CAP_SEL;
|
|
||||||
|
|
||||||
I2C_Write(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1);
|
|
||||||
I2C_Read(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1);
|
|
||||||
if (Value & RTC_CTRL_1_STOP)
|
|
||||||
printf("PCF85063 failed to be initialized.state :%d\r\n", Value);
|
|
||||||
else
|
|
||||||
printf("PCF85063 is running,state :%d\r\n", Value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update_datetime.year = 2024;
|
|
||||||
// Update_datetime.month = 9;
|
|
||||||
// Update_datetime.day = 20;
|
|
||||||
// Update_datetime.dotw = 5;
|
|
||||||
// Update_datetime.hour = 9;
|
|
||||||
// Update_datetime.minute = 50;
|
|
||||||
// Update_datetime.second = 0;
|
|
||||||
// PCF85063_Set_All(Update_datetime);
|
|
||||||
xTaskCreatePinnedToCore(
|
|
||||||
PCF85063Task,
|
|
||||||
"PCF85063Task",
|
|
||||||
4096,
|
|
||||||
NULL,
|
|
||||||
3,
|
|
||||||
NULL,
|
|
||||||
0);
|
|
||||||
// xTaskCreatePinnedToCore(
|
|
||||||
// Time_printf,
|
|
||||||
// "Time_printf",
|
|
||||||
// 4096,
|
|
||||||
// NULL,
|
|
||||||
// 3,
|
|
||||||
// NULL,
|
|
||||||
// 0
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCF85063Task(void *parameter)
|
|
||||||
{
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
PCF85063_Read_Time(&datetime);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
|
||||||
}
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCF85063_Reset() // Reset PCF85063
|
|
||||||
{
|
|
||||||
uint8_t Value = RTC_CTRL_1_DEFAULT | RTC_CTRL_1_CAP_SEL | RTC_CTRL_1_SR;
|
|
||||||
esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1);
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Reset failure\r\n");
|
|
||||||
}
|
|
||||||
void PCF85063_Set_Time(datetime_t time) // Set Time
|
|
||||||
{
|
|
||||||
uint8_t buf[3] = {decToBcd(time.second),
|
|
||||||
decToBcd(time.minute),
|
|
||||||
decToBcd(time.hour)};
|
|
||||||
esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, sizeof(buf));
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Time setting failure\r\n");
|
|
||||||
}
|
|
||||||
void PCF85063_Set_Date(datetime_t date) // Set Date
|
|
||||||
{
|
|
||||||
uint8_t buf[4] = {decToBcd(date.day),
|
|
||||||
decToBcd(date.dotw),
|
|
||||||
decToBcd(date.month),
|
|
||||||
decToBcd(date.year - YEAR_OFFSET)};
|
|
||||||
esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_DAY_ADDR, buf, sizeof(buf));
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Date setting failed\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCF85063_Set_All(datetime_t time) // Set Time And Date
|
|
||||||
{
|
|
||||||
uint8_t buf[7] = {decToBcd(time.second),
|
|
||||||
decToBcd(time.minute),
|
|
||||||
decToBcd(time.hour),
|
|
||||||
decToBcd(time.day),
|
|
||||||
decToBcd(time.dotw),
|
|
||||||
decToBcd(time.month),
|
|
||||||
decToBcd(time.year - YEAR_OFFSET)};
|
|
||||||
esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, sizeof(buf));
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Failed to set the date and time\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCF85063_Read_Time(datetime_t *time) // Read Time And Date
|
|
||||||
{
|
|
||||||
uint8_t buf[7] = {0};
|
|
||||||
esp_err_t ret = I2C_Read(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, sizeof(buf));
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Time read failure\r\n");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
time->second = bcdToDec(buf[0] & 0x7F);
|
|
||||||
time->minute = bcdToDec(buf[1] & 0x7F);
|
|
||||||
time->hour = bcdToDec(buf[2] & 0x3F);
|
|
||||||
time->day = bcdToDec(buf[3] & 0x3F);
|
|
||||||
time->dotw = bcdToDec(buf[4] & 0x07);
|
|
||||||
time->month = bcdToDec(buf[5] & 0x1F);
|
|
||||||
time->year = bcdToDec(buf[6]) + YEAR_OFFSET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCF85063_Enable_Alarm() // Enable Alarm and Clear Alarm flag
|
|
||||||
{
|
|
||||||
uint8_t Value = RTC_CTRL_2_DEFAULT | RTC_CTRL_2_AIE;
|
|
||||||
Value &= ~RTC_CTRL_2_AF;
|
|
||||||
esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_CTRL_2_ADDR, &Value, 1);
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Failed to enable Alarm Flag and Clear Alarm Flag \r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t PCF85063_Get_Alarm_Flag() // Get Alarm flag
|
|
||||||
{
|
|
||||||
uint8_t Value = 0;
|
|
||||||
esp_err_t ret = I2C_Read(PCF85063_ADDRESS, RTC_CTRL_2_ADDR, &Value, 1);
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Failed to obtain a warning flag.\r\n");
|
|
||||||
else
|
|
||||||
Value &= RTC_CTRL_2_AF | RTC_CTRL_2_AIE;
|
|
||||||
// printf("Value = 0x%x",Value);
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCF85063_Set_Alarm(datetime_t time) // Set Alarm
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t buf[5] = {
|
|
||||||
decToBcd(time.second) & (~RTC_ALARM),
|
|
||||||
decToBcd(time.minute) & (~RTC_ALARM),
|
|
||||||
decToBcd(time.hour) & (~RTC_ALARM),
|
|
||||||
// decToBcd(time.day)&(~RTC_ALARM),
|
|
||||||
// decToBcd(time.dotw)&(~RTC_ALARM)
|
|
||||||
RTC_ALARM, // disalbe day
|
|
||||||
RTC_ALARM // disalbe weekday
|
|
||||||
};
|
|
||||||
esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ALARM, buf, sizeof(buf));
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Failed to set alarm flag\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCF85063_Read_Alarm(datetime_t *time) // Read Alarm
|
|
||||||
{
|
|
||||||
uint8_t buf[5] = {0};
|
|
||||||
esp_err_t ret = I2C_Read(PCF85063_ADDRESS, RTC_SECOND_ALARM, buf, sizeof(buf));
|
|
||||||
if (ret != ESP_OK)
|
|
||||||
printf("PCF85063 : Failed to read the alarm sign\r\n");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
time->second = bcdToDec(buf[0] & 0x7F);
|
|
||||||
time->minute = bcdToDec(buf[1] & 0x7F);
|
|
||||||
time->hour = bcdToDec(buf[2] & 0x3F);
|
|
||||||
time->day = bcdToDec(buf[3] & 0x3F);
|
|
||||||
time->dotw = bcdToDec(buf[4] & 0x07);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t decToBcd(int val) // Convert normal decimal numbers to binary coded decimal
|
|
||||||
{
|
|
||||||
return (uint8_t)((val / 10 * 16) + (val % 10));
|
|
||||||
}
|
|
||||||
static int bcdToDec(uint8_t val) // Convert binary coded decimal to normal decimal numbers
|
|
||||||
{
|
|
||||||
return (int)((val / 16 * 10) + (val % 16));
|
|
||||||
}
|
|
||||||
void datetime_to_str(char *datetime_str, datetime_t time)
|
|
||||||
{
|
|
||||||
sprintf(datetime_str, " %d.%d.%d %d:%d:%d %s", time.year, time.month,
|
|
||||||
time.day, time.hour, time.minute, time.second, Week[time.dotw]);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace drivers
|
namespace drivers
|
||||||
{
|
{
|
||||||
|
|
||||||
PCF85063::PCF85063(I2C &i2c, const uint8_t address) : m_i2c(i2c), m_address(address)
|
PCF85063::PCF85063(I2C &i2c, const uint8_t address, const uint8_t ctrl1, const uint8_t ctrl2) : m_i2c(i2c), m_address(address)
|
||||||
{
|
{
|
||||||
|
bool success(true);
|
||||||
|
if (ctrl1 == RTC_CTRL_1_DEFAULT)
|
||||||
|
{
|
||||||
|
const uint8_t def_conf1 = RTC_CTRL_1_DEFAULT | RTC_CTRL_1_CAP_SEL; // 12.5pF cap and 24h format
|
||||||
|
success &= m_i2c.write(m_address, RTC_CTRL_1_ADDR, {def_conf1});
|
||||||
|
}
|
||||||
|
if (ctrl2 == RTC_CTRL_2_DEFAULT)
|
||||||
|
{
|
||||||
|
const uint8_t def_conf2 = RTC_CTRL_2_DEFAULT | RTC_CTRL_2_MI; // enable 1 minute interrupt
|
||||||
|
success &= m_i2c.write(m_address, RTC_CTRL_2_ADDR, {def_conf2});
|
||||||
|
}
|
||||||
|
if (!success)
|
||||||
|
log_e("RTC Init Failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::reset(void)
|
const bool PCF85063::reset(void)
|
||||||
{
|
{
|
||||||
|
log_i("RTC Reset Initiated");
|
||||||
|
const uint8_t cfg = RTC_CTRL_1_DEFAULT | RTC_CTRL_1_CAP_SEL | RTC_CTRL_1_SR;
|
||||||
|
if (m_i2c.write(m_address, RTC_CTRL_1_ADDR, {cfg}))
|
||||||
|
return true;
|
||||||
|
log_e("RTC Reset Failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::setTime(datetime_t time)
|
const bool PCF85063::setTime(const datetime_t time)
|
||||||
{
|
{
|
||||||
|
const std::vector<uint8_t> buf = {
|
||||||
|
decToBcd(time.second),
|
||||||
|
decToBcd(time.minute),
|
||||||
|
decToBcd(time.hour)};
|
||||||
|
if (m_i2c.write(m_address, RTC_SECOND_ADDR, buf))
|
||||||
|
return true;
|
||||||
|
log_e("RTC setTime failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::setDate(datetime_t date)
|
const bool PCF85063::setDate(const datetime_t date)
|
||||||
{
|
{
|
||||||
|
const std::vector<uint8_t> buf = {
|
||||||
|
decToBcd(date.day),
|
||||||
|
decToBcd(date.dotw),
|
||||||
|
decToBcd(date.month),
|
||||||
|
decToBcd(date.year - YEAR_OFFSET)};
|
||||||
|
if (m_i2c.write(m_address, RTC_DAY_ADDR, buf))
|
||||||
|
return true;
|
||||||
|
log_e("RTC setDate failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::setDatetime(datetime_t datetime)
|
const bool PCF85063::setDatetime(const datetime_t datetime)
|
||||||
{
|
{
|
||||||
|
return setDate(datetime) && setTime(datetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::readDate(datetime_t &datetime)
|
const bool PCF85063::readDate(datetime_t &datetime)
|
||||||
{
|
{
|
||||||
|
std::vector<uint8_t> buf;
|
||||||
|
if (m_i2c.read(m_address, RTC_DAY_ADDR, 4, buf))
|
||||||
|
{
|
||||||
|
datetime.day = bcdToDec(buf[0] & 0x3F);
|
||||||
|
datetime.dotw = bcdToDec(buf[1] & 0x07);
|
||||||
|
datetime.month = bcdToDec(buf[2] & 0x1F);
|
||||||
|
datetime.year = bcdToDec(buf[3]) + YEAR_OFFSET;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log_e("RTC readDate Failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::readTime(datetime_t &datetime)
|
const bool PCF85063::readTime(datetime_t &datetime)
|
||||||
{
|
{
|
||||||
|
std::vector<uint8_t> buf;
|
||||||
|
if (m_i2c.read(m_address, RTC_SECOND_ADDR, 3, buf))
|
||||||
|
{
|
||||||
|
datetime.second = bcdToDec(buf[0] & 0x7F);
|
||||||
|
datetime.minute = bcdToDec(buf[1] & 0x7F);
|
||||||
|
datetime.hour = bcdToDec(buf[2] & 0x3F);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log_e("RTC readTime Failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::readDatetime(datetime_t &datetime)
|
const bool PCF85063::readDatetime(datetime_t &datetime)
|
||||||
{
|
{
|
||||||
|
return readTime(datetime) && readDate(datetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::enableAlarm(const bool enable)
|
const bool PCF85063::enableAlarm(const bool enable)
|
||||||
{
|
{
|
||||||
|
bool success(true);
|
||||||
|
std::vector<uint8_t> currStatus(1, RTC_CTRL_2_DEFAULT);
|
||||||
|
|
||||||
|
success &= m_i2c.read(m_address, RTC_CTRL_2_ADDR, 1, currStatus);
|
||||||
|
currStatus.at(0) &= ~RTC_CTRL_2_AF; // clear alarm flag
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
currStatus.at(0) |= RTC_CTRL_2_AIE; // enable alarm
|
||||||
|
else
|
||||||
|
currStatus.at(0) &= ~RTC_CTRL_2_AIE; // disable alarm
|
||||||
|
|
||||||
|
if (m_i2c.write(m_address, RTC_CTRL_2_ADDR, currStatus))
|
||||||
|
return true;
|
||||||
|
log_e("RTC enableAlarm failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::setAlarm(datetime_t time)
|
const bool PCF85063::setAlarm(datetime_t time)
|
||||||
{
|
{
|
||||||
|
const std::vector<uint8_t> buf = {
|
||||||
|
(uint8_t)(decToBcd(time.second) & (~RTC_ALARM)),
|
||||||
|
(uint8_t)(decToBcd(time.minute) & (~RTC_ALARM)),
|
||||||
|
(uint8_t)(decToBcd(time.hour) & (~RTC_ALARM)),
|
||||||
|
(uint8_t)(RTC_ALARM), // disalbe day
|
||||||
|
(uint8_t)(RTC_ALARM) // disalbe weekday
|
||||||
|
};
|
||||||
|
if (m_i2c.write(m_address, RTC_SECOND_ALARM, buf))
|
||||||
|
return true;
|
||||||
|
log_e("RTC setAlarm failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::readAlarm(datetime_t &time)
|
const bool PCF85063::readAlarm(datetime_t &time)
|
||||||
{
|
{
|
||||||
|
std::vector<uint8_t> buf;
|
||||||
|
if (m_i2c.read(m_address, RTC_SECOND_ALARM, 5, buf))
|
||||||
|
{
|
||||||
|
time.second = (uint8_t)bcdToDec(buf[0] & 0x7F);
|
||||||
|
time.minute = (uint8_t)bcdToDec(buf[1] & 0x7F);
|
||||||
|
time.hour = (uint8_t)bcdToDec(buf[2] & 0x3F);
|
||||||
|
time.day = (uint8_t)bcdToDec(buf[3] & 0x3F);
|
||||||
|
time.dotw = (uint8_t)bcdToDec(buf[4] & 0x07);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log_e("RTC readAlarm failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool PCF85063::getAlarmFlafs(uint8_t &flags)
|
const bool PCF85063::getAlarmFlag(uint8_t &flags)
|
||||||
{
|
{
|
||||||
|
std::vector<uint8_t> buf;
|
||||||
|
if (m_i2c.read(m_address, RTC_CTRL_2_ADDR, 1, buf))
|
||||||
|
{
|
||||||
|
flags = buf.at(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log_e("RTC readAlarmFlags failure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string PCF85063::datetime2str(datetime_t &time)
|
const std::string PCF85063::datetime2str(datetime_t &datetime)
|
||||||
{
|
{
|
||||||
|
tm dtime;
|
||||||
|
dtime.tm_sec = datetime.second;
|
||||||
|
dtime.tm_min = datetime.minute;
|
||||||
|
dtime.tm_hour = datetime.hour;
|
||||||
|
dtime.tm_wday = datetime.dotw;
|
||||||
|
dtime.tm_mday = datetime.day;
|
||||||
|
dtime.tm_mon = datetime.month;
|
||||||
|
dtime.tm_year = datetime.year - 1900; // time offset in structure according cpp reference
|
||||||
|
return std::string(std::asctime(&dtime));
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t PCF85063::decToBcd(int val)
|
const uint8_t PCF85063::decToBcd(const int val)
|
||||||
{
|
{
|
||||||
|
return (uint8_t)((val / 10 * 16) + (val % 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
const int PCF85063::bcdToDec(uint8_t val)
|
const int PCF85063::bcdToDec(uint8_t val)
|
||||||
{
|
{
|
||||||
|
return (const int)((val / 16 * 10) + (val % 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,27 +112,27 @@ namespace drivers
|
|||||||
} datetime_t;
|
} datetime_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PCF85063(I2C &i2c, const uint8_t address, const uint8_t ctrl1, const uint8_t ctrl2);
|
PCF85063(I2C &i2c, const uint8_t address, const uint8_t ctrl1 = RTC_CTRL_1_DEFAULT, const uint8_t ctrl2 = RTC_CTRL_2_DEFAULT);
|
||||||
|
|
||||||
const bool reset(void);
|
const bool reset(void);
|
||||||
|
|
||||||
const bool setTime(datetime_t time);
|
const bool setTime(const datetime_t time);
|
||||||
const bool setDate(datetime_t date);
|
const bool setDate(const datetime_t date);
|
||||||
const bool setDatetime(datetime_t datetime);
|
const bool setDatetime(const datetime_t datetime);
|
||||||
|
|
||||||
const bool readDate(datetime_t &datetime);
|
const bool readDate(datetime_t &datetime);
|
||||||
const bool readTime(datetime_t &datetime);
|
const bool readTime(datetime_t &datetime);
|
||||||
const bool readDatetime(datetime_t &datetime);
|
const bool readDatetime(datetime_t &datetime);
|
||||||
|
|
||||||
const bool enableAlarm(const bool enable);
|
const bool enableAlarm(const bool enable);
|
||||||
const bool setAlarm(datetime_t time);
|
const bool setAlarm(const datetime_t time);
|
||||||
const bool readAlarm(datetime_t &time);
|
const bool readAlarm(datetime_t &time);
|
||||||
const bool getAlarmFlafs(uint8_t& flags);
|
const bool getAlarmFlag(uint8_t &flags);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string datetime2str(datetime_t &time);
|
const std::string datetime2str(datetime_t &datetime);
|
||||||
const uint8_t decToBcd(int val);
|
const uint8_t decToBcd(const int val);
|
||||||
const int bcdToDec(uint8_t val);
|
const int bcdToDec(const uint8_t val);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user