mirror of
https://github.com/Lurkars/esp-ena.git
synced 2026-05-08 20:10:37 +02:00
componeent structure, preparation for component branch
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"ds3231.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
rtc
|
||||
i2c-main
|
||||
)
|
||||
@@ -0,0 +1,120 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rtc.h"
|
||||
#include "i2c-main.h"
|
||||
|
||||
#include "ds3231.h"
|
||||
|
||||
uint8_t ds3231_dec2bcd(uint8_t value)
|
||||
{
|
||||
return ((value / 10 * 16) + (value % 10));
|
||||
}
|
||||
|
||||
uint8_t ds3231_bcd2dec(uint8_t value)
|
||||
{
|
||||
return ((value / 16 * 10) + (value % 16));
|
||||
}
|
||||
|
||||
void rtc_get_time(struct tm *time)
|
||||
{
|
||||
if (!i2c_is_initialized())
|
||||
{
|
||||
i2c_main_init();
|
||||
}
|
||||
uint8_t data[7];
|
||||
|
||||
i2c_cmd_handle_t cmd;
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (DS3231_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, DS3231_TIME, true);
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (DS3231_ADDRESS << 1) | I2C_MASTER_READ, true);
|
||||
i2c_master_read(cmd, data, 7, I2C_MASTER_LAST_NACK);
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
|
||||
time->tm_sec = ds3231_bcd2dec(data[0]);
|
||||
time->tm_min = ds3231_bcd2dec(data[1]);
|
||||
if (data[2] & DS3231_12_HOUR_FLAG)
|
||||
{
|
||||
time->tm_hour = ds3231_bcd2dec(data[2] & DS3231_12_HOUR_MASK) - 1;
|
||||
if (data[2] & DS3231_PM_HOUR_FLAG)
|
||||
{
|
||||
time->tm_hour += 12;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
time->tm_hour = ds3231_bcd2dec(data[2]);
|
||||
}
|
||||
time->tm_wday = ds3231_bcd2dec(data[3]) - 1;
|
||||
time->tm_mday = ds3231_bcd2dec(data[4]);
|
||||
time->tm_mon = ds3231_bcd2dec(data[5] & DS3231_MONTH_MASK) - 1;
|
||||
uint8_t century = (data[5] & DS3231_CENTURY_FLAG) >> 7;
|
||||
if (century)
|
||||
{
|
||||
time->tm_year = ds3231_bcd2dec(data[6]) + 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
time->tm_year = ds3231_bcd2dec(data[6]);
|
||||
}
|
||||
time->tm_isdst = 0;
|
||||
}
|
||||
|
||||
void rtc_set_time(struct tm *time)
|
||||
{
|
||||
if (!i2c_is_initialized())
|
||||
{
|
||||
i2c_main_init();
|
||||
}
|
||||
uint8_t data[7] = {0};
|
||||
data[0] = ds3231_dec2bcd(time->tm_sec);
|
||||
data[1] = ds3231_dec2bcd(time->tm_min);
|
||||
data[2] = ds3231_dec2bcd(time->tm_hour); // write 24h format
|
||||
data[3] = ds3231_dec2bcd(time->tm_wday + 1);
|
||||
data[4] = ds3231_dec2bcd(time->tm_mday);
|
||||
uint8_t century = 0;
|
||||
if (time->tm_year > 100)
|
||||
{
|
||||
century = DS3231_CENTURY_FLAG;
|
||||
data[6] = ds3231_dec2bcd(time->tm_year - 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
data[6] = ds3231_dec2bcd(time->tm_year);
|
||||
}
|
||||
|
||||
data[5] = ds3231_dec2bcd(time->tm_mon + 1) + century;
|
||||
|
||||
i2c_cmd_handle_t cmd;
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (DS3231_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, DS3231_TIME, true);
|
||||
i2c_master_write(cmd, data, 7, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief I2C driver for DS3231 Real Time Clock
|
||||
*
|
||||
*/
|
||||
#ifndef _ds3231_H_
|
||||
#define _ds3231_H_
|
||||
|
||||
#include <time.h>
|
||||
|
||||
// I2C address
|
||||
#define DS3231_ADDRESS 0x68
|
||||
|
||||
// I2C registers
|
||||
#define DS3231_TIME 0x00
|
||||
#define DS3231_SECONDS 0x00
|
||||
#define DS3231_MINUTES 0x01
|
||||
#define DS3231_HOURS 0x02
|
||||
#define DS3231_DAY 0x03
|
||||
#define DS3231_DATE 0x04
|
||||
#define DS3231_MONTH 0x05
|
||||
#define DS3231_YEAR 0x06
|
||||
#define DS3231_ALARM1_SECONDS 0x07
|
||||
#define DS3231_ALARM1_MINUTES 0x08
|
||||
#define DS3231_ALARM1_HOURS 0x09
|
||||
#define DS3231_ALARM1_DATE 0x0A
|
||||
#define DS3231_ALARM2_MINUTES 0x0B
|
||||
#define DS3231_ALARM2_HOURS 0x0C
|
||||
#define DS3231_ALARM2_DATE 0x0D
|
||||
#define DS3231_CONTROL 0x0E
|
||||
#define DS3231_STATUS 0x0F
|
||||
#define DS3231_AGING_OFFSET 0x10
|
||||
#define DS3231_MSB_TEMP 0x11
|
||||
#define DS3231_LSB_TEMP 0x12
|
||||
|
||||
// control registers
|
||||
#define DS3231_CONTROL_A1IE 0x01
|
||||
#define DS3231_CONTROL_A2IE 0x02
|
||||
#define DS3231_CONTROL_INTCN 0x04
|
||||
#define DS3231_CONTROL_RS1 0x08
|
||||
#define DS3231_CONTROL_RS2 0x10
|
||||
#define DS3231_CONTROL_CONV 0x20
|
||||
#define DS3231_CONTROL_BBSQW 0x40
|
||||
#define DS3231_CONTROL_EOSC 0x80
|
||||
|
||||
// status registers
|
||||
#define DS3231_STATUSL_A1F 0x01
|
||||
#define DS3231_STATUSL_A2F 0x02
|
||||
#define DS3231_STATUSL_BSY 0x04
|
||||
#define DS3231_STATUSL_EN32KHZ 0x08
|
||||
#define DS3231_STATUSL_OSF 0x80
|
||||
|
||||
// flags
|
||||
#define DS3231_CENTURY_FLAG 0x80
|
||||
#define DS3231_12_HOUR_FLAG 0x40
|
||||
#define DS3231_PM_HOUR_FLAG 0x20
|
||||
#define DS3231_12_HOUR_MASK 0x1F
|
||||
#define DS3231_MONTH_MASK 0x1F
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user