diff --git a/Lib/PCF85063/PCF85063.c b/Lib/PCF85063/PCF85063.c new file mode 100644 index 0000000..00cc650 --- /dev/null +++ b/Lib/PCF85063/PCF85063.c @@ -0,0 +1,212 @@ +/***************************************************************************** +* | File : PCF85063.c +* | Author : Waveshare team +* | Function : PCF85063 driver +* | Info : +*---------------- +* | This version: V1.0 +* | Date : 2024-02-02 +* | Info : Basic version +* +******************************************************************************/ +#include "PCF85063.h" + +datetime_t datetime= {0}; + +static uint8_t decToBcd(int val); +static int bcdToDec(uint8_t val); + +const unsigned char MonthStr[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov","Dec"}; +/****************************************************************************** +function: PCF85063 initialized +parameter: + +Info:Initiate Normal Mode, RTC Run, NO reset, No correction , 24hr format, Internal load capacitane 12.5pf +******************************************************************************/ +void PCF85063_Init() +{ + uint8_t Value = RTC_CTRL_1_DEFAULT|RTC_CTRL_1_CAP_SEL; + + ESP_ERROR_CHECK(I2C_Write(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1)); + + // datetime_t Now_datetime= {0}; + // Now_datetime.year = 2024; + // Now_datetime.month = 9; + // Now_datetime.day = 20; + // Now_datetime.dotw = 5; + // Now_datetime.hour = 9; + // Now_datetime.minute = 50; + // Now_datetime.second = 0; + // PCF85063_Set_All(Now_datetime); +} + +void PCF85063_Loop(void) +{ + PCF85063_Read_Time(&datetime); +} +/****************************************************************************** +function: Reset PCF85063 +parameter: +Info: +******************************************************************************/ +void PCF85063_Reset() +{ + uint8_t Value = RTC_CTRL_1_DEFAULT|RTC_CTRL_1_CAP_SEL|RTC_CTRL_1_SR; + ESP_ERROR_CHECK(I2C_Write(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1)); +} + +/****************************************************************************** +function: Set Time +parameter: +Info: +******************************************************************************/ +void PCF85063_Set_Time(datetime_t time) +{ + uint8_t buf[3] = {decToBcd(time.second), + decToBcd(time.minute), + decToBcd(time.hour)}; + ESP_ERROR_CHECK(I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, 3)); +} + +/****************************************************************************** +function: Set Date +parameter: +Info: +******************************************************************************/ +void PCF85063_Set_Date(datetime_t date) +{ + uint8_t buf[4] = {decToBcd(date.day), + decToBcd(date.dotw), + decToBcd(date.month), + decToBcd(date.year - YEAR_OFFSET)}; + ESP_ERROR_CHECK(I2C_Write(PCF85063_ADDRESS, RTC_DAY_ADDR, buf, 4)); +} + +/****************************************************************************** +function: Set Time And Date +parameter: +Info: +******************************************************************************/ +void PCF85063_Set_All(datetime_t time) +{ + 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_ERROR_CHECK(I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, 7)); +} + +/****************************************************************************** +function: Read Time And Date +parameter: +Info: +******************************************************************************/ +void PCF85063_Read_Time(datetime_t *time) +{ + uint8_t buf[7] = {0}; + ESP_ERROR_CHECK(I2C_Read(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, 7)); + 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; +} + +/****************************************************************************** +function: Enable Alarm and Clear Alarm flag +parameter: +Info: +******************************************************************************/ +void PCF85063_Enable_Alarm() +{ + uint8_t Value = RTC_CTRL_2_DEFAULT | RTC_CTRL_2_AIE; + Value &= ~RTC_CTRL_2_AF; + ESP_ERROR_CHECK(I2C_Write(PCF85063_ADDRESS, RTC_CTRL_2_ADDR, &Value, 1)); +} + +/****************************************************************************** +function: Get Alarm flay +parameter: +Info: +******************************************************************************/ +uint8_t PCF85063_Get_Alarm_Flag() +{ + uint8_t Value = 0; + ESP_ERROR_CHECK(I2C_Read(PCF85063_ADDRESS, RTC_CTRL_2_ADDR, &Value, 1)); + //printf("Value = 0x%x",Value); + Value &= RTC_CTRL_2_AF | RTC_CTRL_2_AIE; + return Value; +} + +/****************************************************************************** +function: Set Alarm +parameter: +Info: +******************************************************************************/ +void PCF85063_Set_Alarm(datetime_t time) +{ + + 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_ERROR_CHECK(I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ALARM, buf, 6)); +} + +/****************************************************************************** +function: +parameter: +Info: +******************************************************************************/ +void PCF85063_Read_Alarm(datetime_t *time) +{ + uint8_t bufss[6] = {0}; + ESP_ERROR_CHECK(I2C_Read(PCF85063_ADDRESS, RTC_SECOND_ALARM, bufss, 6)); + time->second = bcdToDec(bufss[0] & 0x7F); + time->minute = bcdToDec(bufss[1] & 0x7F); + time->hour = bcdToDec(bufss[2] & 0x3F); + time->day = bcdToDec(bufss[3] & 0x3F); + time->dotw = bcdToDec(bufss[4] & 0x07); +} + + +/****************************************************************************** +function: Convert normal decimal numbers to binary coded decimal +parameter: +Info: +******************************************************************************/ +static uint8_t decToBcd(int val) +{ + return (uint8_t)((val / 10 * 16) + (val % 10)); +} + +/****************************************************************************** +function: Convert binary coded decimal to normal decimal numbers +parameter: +Info: +******************************************************************************/ +static int bcdToDec(uint8_t val) +{ + return (int)((val / 16 * 10) + (val % 16)); +} + +/****************************************************************************** +function: +parameter: +Info: +******************************************************************************/ +void datetime_to_str(char *datetime_str,datetime_t time) +{ + sprintf(datetime_str, " %d.%d.%d %d %d:%d:%d ", time.year, time.month, + time.day, time.dotw, time.hour, time.minute, time.second); +} \ No newline at end of file diff --git a/Lib/PCF85063/PCF85063.h b/Lib/PCF85063/PCF85063.h new file mode 100644 index 0000000..2ccb083 --- /dev/null +++ b/Lib/PCF85063/PCF85063.h @@ -0,0 +1,102 @@ +#pragma once + +#include "I2C_Driver.h" + + +//PCF85063_ADDRESS +#define PCF85063_ADDRESS (0x51) +// +#define YEAR_OFFSET (1970) +// registar overview - crtl & status reg +#define RTC_CTRL_1_ADDR (0x00) +#define RTC_CTRL_2_ADDR (0x01) +#define RTC_OFFSET_ADDR (0x02) +#define RTC_RAM_by_ADDR (0x03) +// registar overview - time & data reg +#define RTC_SECOND_ADDR (0x04) +#define RTC_MINUTE_ADDR (0x05) +#define RTC_HOUR_ADDR (0x06) +#define RTC_DAY_ADDR (0x07) +#define RTC_WDAY_ADDR (0x08) +#define RTC_MONTH_ADDR (0x09) +#define RTC_YEAR_ADDR (0x0A) // years 0-99; calculate real year = 1970 + RCC reg year +// registar overview - alarm reg +#define RTC_SECOND_ALARM (0x0B) +#define RTC_MINUTE_ALARM (0x0C) +#define RTC_HOUR_ALARM (0x0D) +#define RTC_DAY_ALARM (0x0E) +#define RTC_WDAY_ALARM (0x0F) +// registar overview - timer reg +#define RTC_TIMER_VAL (0x10) +#define RTC_TIMER_MODE (0x11) + +//RTC_CTRL_1 registar +#define RTC_CTRL_1_EXT_TEST (0x80) +#define RTC_CTRL_1_STOP (0x20) //0-RTC clock runs 1- RTC clock is stopped +#define RTC_CTRL_1_SR (0X10) //0-no software reset 1-initiate software rese +#define RTC_CTRL_1_CIE (0X04) //0-no correction interrupt generated 1-interrupt pulses are generated at every correction cycle +#define RTC_CTRL_1_12_24 (0X02) //0-24H 1-12H +#define RTC_CTRL_1_CAP_SEL (0X01) //0-7PF 1-12.5PF + +//RTC_CTRL_2 registar +#define RTC_CTRL_2_AIE (0X80) //alarm interrupt 0-disalbe 1-enable +#define RTC_CTRL_2_AF (0X40) //alarm flag 0-inactive/cleared 1-active/unchanged +#define RTC_CTRL_2_MI (0X20) //minute interrupt 0-disalbe 1-enable +#define RTC_CTRL_2_HMI (0X10) //half minute interrupt +#define RTC_CTRL_2_TF (0X08) + +// +#define RTC_OFFSET_MODE (0X80) + +// +#define RTC_TIMER_MODE_TE (0X04) //timer enable 0-disalbe 1-enable +#define RTC_TIMER_MODE_TIE (0X02) //timer interrupt enable 0-disalbe 1-enable +#define RTC_TIMER_MODE_TI_TP (0X01) //timer interrupt mode 0-interrupt follows timer flag 1-interrupt generates a pulse + +// format +#define RTC_ALARM (0x80) // set AEN_x registers +#define RTC_CTRL_1_DEFAULT (0x00) +#define RTC_CTRL_2_DEFAULT (0x00) + +#define RTC_TIMER_FLAG (0x08) + +typedef struct { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t dotw; + uint8_t hour; + uint8_t minute; + uint8_t second; +}datetime_t; + + +extern datetime_t datetime; + +void PCF85063_Init(void); +void PCF85063_Loop(void); +void PCF85063_Reset(void); + +void PCF85063_Set_Time(datetime_t time); +void PCF85063_Set_Date(datetime_t date); +void PCF85063_Set_All(datetime_t time); + +void PCF85063_Read_Time(datetime_t *time); + + +void PCF85063_Enable_Alarm(void); +uint8_t PCF85063_Get_Alarm_Flag(); +void PCF85063_Set_Alarm(datetime_t time); +void PCF85063_Read_Alarm(datetime_t *time); + +void datetime_to_str(char *datetime_str,datetime_t time); + + +// weekday format +// 0 - sunday +// 1 - monday +// 2 - tuesday +// 3 - wednesday +// 4 - thursday +// 5 - friday +// 6 - saturday \ No newline at end of file