#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/i2c.h"
#include "esp_log.h"
//BEGIN RTC CODE
//rtc variables
uint8_t second, minute, hour, dayOfWeek, dayOfMonth, month, year;
//end rtc variables
#define RTC_TAG "RTC"
esp_err_t rtc_Init(gpio_num_t sda, gpio_num_t scl, i2c_port_t p)
{
int i2c_master_port = p;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = sda,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = scl,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 100000,
.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL
};
esp_err_t err;
err = i2c_param_config(i2c_master_port, &conf);
if(err != ESP_OK){ ESP_LOGE(RTC_TAG, "%s", "I2C PARAM CONFIG ERR!"); return err;}
err = i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0);
if(err != ESP_OK){ ESP_LOGE(RTC_TAG, "%s", "I2C DRIVER INSTALL ERR!"); return err;}
return err;
}
uint8_t decToBcd(uint8_t val) {
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to decimal numbers
uint8_t bcdToDec(uint8_t val) {
return ( (val / 16 * 10) + (val % 16) );
}
// Set the time
esp_err_t rtc_setTime(i2c_port_t p, uint16_t addr, uint8_t second, uint8_t minute, uint8_t hour, uint8_t wday, uint8_t mday, uint8_t mon, uint8_t year) {
// sets time and date data to DS3231
uint8_t size = 8;
uint8_t data_write[] = {
0, // set next input to start at the seconds register
decToBcd(second), // set seconds
decToBcd(minute), // set minute
decToBcd(hour), // set hour
decToBcd(wday), // set set day of week
decToBcd(mday), // set date
decToBcd(mon), // set month
decToBcd(year) // set year
};
esp_err_t err = i2c_master_write_to_device(p, addr, data_write, size, 0);
if(err != ESP_OK){ ESP_LOGE(RTC_TAG, "%s", "I2C SET TIME ERR!"); return err;}
return err;
}
//Refresh/Read the time
esp_err_t rtc_readTime(i2c_port_t p, uint16_t addr) {
uint8_t size = 7;
uint8_t data_read[] = {0,0,0,0,0,0,0};
uint8_t start_address[] = {0}; // set DS3231 register pointer to 00h
// request seven bytes of data from DS3231 starting from register 00h
esp_err_t err = i2c_master_write_read_device(p, addr, start_address, 1, data_read, size, 0);
if (err != ESP_OK) { ESP_LOGE(RTC_TAG, "%s", "I2C READ TIME ERR!"); return err; }
second = bcdToDec(data_read[0]);
minute = bcdToDec(data_read[1]);
hour = bcdToDec(data_read[2]);
dayOfWeek = bcdToDec(data_read[3]);
dayOfMonth = bcdToDec(data_read[4]);
month = bcdToDec(data_read[5]);
year = bcdToDec(data_read[6]);
//leap year correction (if year is > 2100)
#define LEAP_YEAR(Y) ( !(((Y))%4) && ( (((Y))%100) || !(((Y))%400) ) )
if(LEAP_YEAR(year) == 0 && dayOfMonth == 29 && month == 2){
rtc_setTime(p, addr, second, minute, hour, dayOfWeek, 1, 3, year);
}
if(year == 0){
rtc_setTime(p, addr, second, minute, hour, dayOfWeek, dayOfMonth, month, 2100);
}
return err;
}
//END RTC CODE
#define I2C_PORT I2C_NUM_0
#define SDA_PIN 21
#define SCL_PIN 22
#define I2C_SLAVE_ADDR 0x68
#define TAG "ESP32"
void app_main() {
rtc_Init(SDA_PIN, SCL_PIN, I2C_PORT);
//rtc_setTime(I2C_PORT,I2C_SLAVE_ADDR,0,0,0,1,1,1,10);
while(1) {
vTaskDelay(pdMS_TO_TICKS(1000));
rtc_readTime(I2C_PORT,I2C_SLAVE_ADDR);
printf("%u-%02d-%02dT%02d:%02d:%02dZ\n", 2000+year,month,dayOfMonth,hour,minute,second);
ESP_LOGI(TAG, "%u-%02d-%02dT%02d:%02d:%02dZ\n", 2000+year,month,dayOfMonth,hour,minute,second);
}
}