Для работы микросхемой часов реального времени DS337 и DS3231/DS3231M (RTC) существует внешний компонент [1, 2].
Компонент создает удобную абстракцию для функций получения/установки времени и управления настройками RTC. Поддерживается также управление функционалом будильников, генерацией прямоугольного сигнала, формирование прерываний и другие функции.
Рис. 1. Подключение модуля DS3231 к плате ESP32.
Для работы с компонентом необходима установленная среда ESP-IDF версии v5.0+. Для начала работы с компонентом в каталоге проекта запустите команду:
Чтобы использовать функции библиотеки, добавьте в код подключение заголовка esp-idf-ds3231.h:
#include"esp-idf-ds3231.h"
Простой пример использования:
#include< stdio.h> #include"esp-idf-ds3231.h"
voidapp_main(void)
{
// Выделение памяти для указателя на дескриптор i2c_master_bus_handle_t:i2c_master_bus_handle_t* bus_handle =
(i2c_master_bus_handle_t*)malloc(sizeof(i2c_master_bus_handle_t));
// Создание структуры конфигурации i2c_master_bus_config_t и присвоение её значений:i2c_master_bus_config_t i2c_mst_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = -1,
.scl_io_num = GPIO_NUM_5,
.sda_io_num = GPIO_NUM_4,
.glitch_ignore_cnt = 7,
// Микросхема DS3231 **требует** наличия внешних pullup-резисторов на всех её выводах I/O. // Замечание: на многих платах DS3231 уже есть эти резисторы.
.flags.enable_internal_pullup = true,
};
i2c_new_master_bus(&i2c_mst_config, bus_handle);
rtc_handle_t* rtc_handle = ds3231_init(bus_handle); time_t now;
char strftime_buf[64];
structtmtimeinfo;
now = ds3231_time_unix_get(rtc_handle);
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
printf("Текущее время, прочитанное из DS3231 RTC: %s\n", strftime_buf);
}
В следующей таблице приведено краткое описание функций библиотеки. Полное описание функций есть заголовочном файле esp-idf-ds3231.h (также см. врезку далее).
Функция
Описание
ds3231_init_full
Инициализирует I2C и модуль DS3231 RTC.
ds3231_init
Инициализация модуля DS3231 RTC с предварительно созданным дескриптором шины.
ds3231_debug_print_data
Функция для тестирования. Она прочитает все регистры и напечатает их данные.
ds3231_get_registers_raw
Запрашивает у DS3231 содержимое всех регистров (00h - 12h) в виде сырых данных.
ds3231_send_byte_raw
Посылает одиночный байт в указанный регистр DS3231.
ds3231_time_minutes_or_seconds_get
Запрашивает у DS3231 содержимое регистров минут или секунд. Работает как с регистрами Time, так и с регистрами Alarm.
ds3231_time_hours_get
Запрашивает у DS3231 содержимое регистра часа. Работает как с регистрами Time, так и с регистрами Alarm.
ds3231_time_day_of_week_get
Запрашивает у DS3231 содержимое регистра дня недели. Работает как с регистрами Time, так и с регистрами Alarm.
ds3231_time_date_get
Запрашивает у DS3231 содержимое дня месяца. Работает как с регистрами Time, так и с регистрами Alarm.
ds3231_time_month_get
Запрашивает у DS3231 содержимое регистра месяца. Работает только на Time.
ds3231_time_year_get
Запрашивает у DS3231 содержимое регистра года. Работает только на Time.
ds3231_aging_offset_get
Запрашивает у DS3231 содержимое регистра смещения старения (Aging Offset).
ds3231_temperature_get
Запрашивает у DS3231 содержимое регистра температуры.
ds3231_control_status_flags_get
Запрашивает у DS3231 содержимое регистров управления (Control) и состояния (Status).
ds3231_time_get
Запрашивает у DS3231 текущее значение времени, возвращенное как struct tm.
ds3231_time_time_t_set
Установит время DS3231, используя значение time_t.
ds3231_time_unix_get
Запрашивает у DS3231 значение текущего времени, возвращаемое как struct tm.
ds3231_time_unix_set
Установит время DS3231, используя значение времени Unix.
ds3231_time_tm_set
Установит время DS3231, используя значение struct tm.
ds3231_alarm_isr_create
Создаст прерывание по сигналу на выводе порта (GPIO Pin interrupt) и соответствующую очередь обработки, а также назначит определяемую пользователем функцию для обработки прерываний, генерируемых сигналом на выводе INT DS3231.
ds3231_alarm_isr_delete
Удаляет alarm isr, ранее созданный вызовом ds3231_alarm_isr_create.
ds3231_alarm1_time_get
Запрашивает у DS3231 установку значения Alarm 1.
ds3231_alarm1_day_of_week_set
Установит значение Alarm 1 для срабатывания на одном и том же дне каждой недели.
ds3231_alarm1_day_of_month_set
Установит значение Alarm 1 для срабатывания на одном и том же дне каждого месяца.
ds3231_alarm1_enable_flag_get
Возвратит двоичное значение, представляющее статус разрешения Alarm 1.
ds3231_alarm1_enable_flag_set
Установит состояние разрешено/запрещено для Alarm 1.
ds3231_alarm1_fired_flag_get
Получит статус срабатывания Alarm 1.
ds3231_alarm1_rate_get
Получит условия срабатывания Alarm 1, как это описано в rtc_alarm_rate_e.
ds3231_alarm1_rate_set
Установит условие срабатывания Alarm 1, как это описано в rtc_alarm_rate_e.
ds3231_alarm1_fired_flag_reset
Сбросит в 0 флаг срабатывания Alarm 1.
ds3231_alarm2_time_get
Запросит у DS3231 установленное значение Alarm 2.
ds3231_alarm2_day_of_week_set
Установит значение Alarm 2, чтобы он срабатывал в один и тот же день недели.
ds3231_alarm2_day_of_month_set
Установит значение Alarm 2, чтобы он срабатывал в один и тот же день каждого месяца.
ds3231_alarm2_enable_flag_get
Вернет двоичное значение, представляющее состояние разрешен/запрещен будильника Alarm 2.
ds3231_alarm2_enable_flag_set
Установит состояние разрешен/запрещен будильника Alarm 2.
ds3231_alarm2_fired_flag_get
Получит статус флага срабатывания Alarm 2.
ds3231_alarm2_rate_set
Установит условие срабатывания Alarm 2, как это описано rtc_alarm_rate_e.
ds3231_alarm2_fired_flag_reset
Сбросит в 0 флаг срабатывания Alarm 2.
ds3231_set_esp_with_rtc
Синхронизирует время ESP32 с временем из DS3231.
ds3231_enable_oscillator_flag_get
Получит статус флага генератора (Oscillator Flag).
ds3231_enable_oscillator_flag_set
Установит статус флага генератора (Oscillator Flag).
ds3231_battery_backed_square_wave_flag_get
Получит статус флага генерации выходного прямоугольного сигнала при работе от батареи (Battery Backed Square Wave Flag).
ds3231_battery_backed_square_wave_flag_set
Установит состояние Battery Backed Square Wave Flag.
ds3231_convert_temp_flag_get
Вернет состояние флага преобразования температуры (Convert Temp Temperature Flag).
ds3231_convert_temp_flag_set
Установит состояние Convert Temperature Flag.
ds3231_square_wave_freq_get
Получит текущее значение (1 .. 4) настройки выхода генерации прямоугольника.
ds3231_square_wave_freq_set
Установит значение перечисления (1 .. 4) для настройки генерируемого прямоугольного сигнала.
ds3231_interrupt_square_wave_control_flag_get
Получит статус Interrupt/Square Wave Flag.
ds3231_interrupt_square_wave_control_flag_set
Установит значение флага управления формированием прямоугольника.
ds3231_get_oscillator_stop_flag
Получит состояние флага остановки генератора (Oscillator Stop Flag).
ds3231_oscillator_stop_flag_reset
Сбросит состояние Oscillator Stop Flag.
ds3231_32kHz_out_enable_flag_get
Получит состояние флага генерации 32 кГц.
ds3231_32kHz_out_enable_flag_set
Установит состояние флага генерации 32 кГц.
ds3231_busy_flag_get
Получит состояние флага занятости (Busy Flag).
ds3231_register_set
Подобная концепция в ds3231_set_registers_raw. Позволяет установить один регистр одним байтом данных.
ds3231_set_registers_raw
Подобная концепция в ds3231_register_set. Позволяет установить несколько идущих друг за другом регистров из массива данных.
ds3231_debug_print_data
Получит все регистры времени, будильника и управления/статуса. Данные выводятся функцией ESP_LOGI.
ds3231_debug_test_set
Получит и установит/сбросит все флаги из регистров управления/статуса. Данные выводятся функцией ESP_LOGI.
/*
* esp-idf-ds3231 component library for the ESP32 family of microcontrollers
* using ESP-IDF v5.0 or later.
* Copyright 224 Jason M. Schwefel
*
* Licensed under the MIT License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/license/MIT
*
* 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.
*/ #pragma once #include< sys/time.h> #include"driver/gpio.h" #include"driver/i2c_master.h"
#ifdef __cplusplus extern"C" { #endif
#define RTC_I2C_TIMEOUT \
1000 /*!< @brief Таймаут команд I2C в мс, по умолчанию 1000. Переопределите при необходимости. \
Для отключения таймаута используйте -1 \
*/
/**
* @brief Перечисление для всех значений регистров DS3231 RTC
*
*/ enumrtc_register_e {
RTC_REGISTER_TIME_SECONDS = 0x00, /*!< Time - регистр секунд */
RTC_REGISTER_TIME_MINUTES = 0x01, /*!< Time - регистр минут */
RTC_REGISTER_TIME_HOURS = 0x02, /*!< Time - регистр часов */
RTC_REGISTER_TIME_DAY = 0x03, /*!< Time - регистр дня недели (Day of Week) */
RTC_REGISTER_TIME_DATE = 0x04, /*!< Time - регистр дня месяца (Day of Month) */
RTC_REGISTER_TIME_MONTH = 0x05, /*!< Time - регистр месяца */
RTC_REGISTER_TIME_YEAR = 0x06, /*!< Time - регистр года */
RTC_REGISTER_ALARM1_SECONDS = 0x07, /*!< Alarm 1 - будильник 1, регистр секунд */
RTC_REGISTER_ALARM1_MINUTES = 0x08, /*!< Alarm 1 - будильник 1, регистр минут */
RTC_REGISTER_ALARM1_HOURS = 0x09, /*!< Alarm 1 - будильник 1, регистр часов */
RTC_REGISTER_ALARM1_DAY_DATE = 0x0A, /*!< Alarm 1 - будильник 1, день даты */
RTC_REGISTER_ALARM2_MINUTES = 0x0B, /*!< Alarm 2 - будильник 2, регистр минут */
RTC_REGISTER_ALARM2_HOURS = 0x0C, /*!< Alarm 2 - будильник 2, регистр часов */
RTC_REGISTER_ALARM2_DAY_DATE = 0x0D, /*!< Alarm 2 - будильник 2, день даты */
RTC_REGISTER_CONTROL = 0x0E, /*!< регистры управления и статуса (Control & Status) */
RTC_REGISTER_CONTROL_UPPER = 0x0E, /*!< верхние регистры управления и статуса (Upper Control & Status) */
RTC_REGISTER_CONTROL_LOWER = 0x0F, /*!< нижние регистры управления и статуса (Lower Control & Status) */
RTC_REGISTER_AGING_OFFSET = 0x10, /*!< регистр учета старения (Aging Offset) */
RTC_REGISTER_TEMPERATURE = 0x11/*!< регистры температуры */
};
/**
* @brief Перечисление для всех дней недели, используемых чипом DS3231.
*
* @note Значения Day of Week, используемые \b DS3231 и структурой \b struct \b tm, отличаются.
* В DS3231 диапазон значений 1 - 7, соответствующих дням от понедельника (Monday)
* до воскресенья (Sunday). В структуре tm значения 0 - 6 соответствуют диапазону
* дней от воскресенья (Sunday) до субботы (Saturday). Функция ds3231_time_get
* учитывает этот факт, а функция ds3231_time_day_of_week_get не учитывает.
*/ enumrtc_day_of_week_e {
RTC_MONDAY = 1,
RTC_TUESDAY = 2,
RTC_WEDNESDAY = 3,
RTC_THURSDAY = 4,
RTC_FRIDAY = 5,
RTC_SATURDAY = 6,
RTC_SUNDAY = 7
};
/**
* @brief Перечисление всех значений дней недели, используемых POSIX-структурой time.
*
* @note The Значения Day of Week, используемые \b DS3231 и структурой \b struct \b tm, отличаются.
* В DS3231 диапазон значений 1 - 7, соответствующих дням от понедельника (Monday)
* до воскресенья (Sunday). В структуре tm значения 0 - 6 соответствуют диапазону
* дней от воскресенья (Sunday) до субботы (Saturday). Функция ds3231_time_get
* учитывает этот факт, а функция ds3231_time_day_of_week_get не учитывает.
*/ enumtm_day_of_week_e {
TM_SUNDAY = 0,
TM_MONDAY = 1,
TM_TUESDAY = 2,
TM_WEDNESDAY = 3,
TM_THURSDAY = 4,
TM_FRIDAY = 5,
TM_SATURDAY = 6
};
/**
* @brief Функционал будильника DS3231, весьма продвинутая.
*/ enumrtc_alarm_rate_e {
RTC_ALARM_MATCH_EVERY_SECOND = 15, /*!< \b Alarm \b 1 \b Only - alarm будет срабатывать каждую секунду. */
RTC_ALARM_MATCH_SECONDS_A1_OR_EVERY_MINUTES_A2 = 14, /*!< \b Alarm \b 1 \b Only - alarm сработает, когда значение секунд
в регистре alarm совпадет со значением секунд DS3231.
\b Alarm \b 2 \b Only - alarm будет срабатывать каждую минуту, когда
значение секунд на DS3231 достигнет 00.*/
RTC_ALARM_MATCH_MINUTES = 12, /*!< alarm будет срабатывать каждый час, когда его минуты (и секунды для Alarm 1) совпадут
с минутами DS3231 (и секундами для Alarm 1) */
RTC_ALARM_MATCH_HOURS = 8, /*!< alarm будет срабатывать каждый день, когда его часы, минуты (и секунды Alarm 1) совпадут
с часами, минутами DS3231 (и секундами для Alarm 1) */
RTC_ALARM_MATCH_DAY_DATE = 0, /*!< alarm будет срабатывать, когда день, когда часы, минуты (и секунды для Alarm 1) совпадут
с днем, часами, минутами DS3231 (и секундами для Alarm 1) */
RTC_ALARM_MATCH_INVALID = -999/*!< */
};
/**
* @brief Перечисление 2 регистров управления и статуса (0Eh и 0Fh) * DS3231. Все флаги активны, если они равны 1.
*/ typedefunionrtc_control_status_t {uint16_t data; /*!< Традиционное представление данных. */struct {unsigned alarm1_enable : 1; /*!< Alarm 1 Enable. */unsigned alarm2_enable : 1; /*!< Alarm 2 Enable. */unsigned interrupt_control : 1; /*!< Управление прерывание / прямоугольный сигнал (Interrupt/Square Wave Control).
Square Wave активно, когда установлено в 1. См. даташит DS3231 для подробностей. */// clang-format offunsigned square_freq : 2; /*!< Регистр управления частой выходного сигнала (2 бита)
| BIT 1 | BIT 0 | OUTPUT FREQ |
| :-----: | :-----: | :---------: |
| 0 | 0 | 1.000khZ |
| 0 | 1 | 1.024KhZ |
| 1 | 0 | 4.096KhZ |
| 1 | 1 | 8.192KhZ | */// clang-format onunsigned convert_temp : 1; /*!< Принудительный запуск преобразования температуры.
Подробности см. в даташите DS3231 */unsigned battery_square : 1; /*!< Генерировать прямоугольник при питании от батареи.
Подробности см. в даташите DS3231 */unsigned enable_oscillator : 1; /*!< Active 0 - когда неактивно, все регистры только для чтения */unsigned alarm1_flag : 1; /*!< Флаг, показывающий срабатывание Alarm 1. Если прерывания разрешены,
то будет сформирован сигнал прерывания. */unsigned alarm2_flag : 1; /*!< Флаг, показывающий срабатывание Alarm 2. Если прерывания разрешены,
то будет сформирован сигнал прерывания. */unsigned busy_flag : 1; /*!< Идет процесс преобразования температуры. */unsigned enable_32kHz_out : 1; /*!< Разрешает вывод прямоугольного сигнала 32.765kHZ. По умолчанию активно
при включенном питании *//** @cond */unsigned unused : 3;
/** @endcond */unsigned oscillator_stop_flag : 1; /*!< Показывает, что генератор остановлен. Подробности см. в даташите DS3231 */
};
} rtc_control_status_t;
/**
* @brief Простой псевдоним для дескриптора i2c_master_dev_handle.
*/ typedefi2c_master_dev_handle_trtc_handle_t;
#pragma pack(pop)
/**
* @brief Инициализирует I2C и модуль DS3231 RTC.
* @param SCL [in] GPIO_NUM_X ножка для тактов I2C.
* @param SDA [in] GPIO_NUM_X ножка для данных I2C.
* @retval rtc_handle_t: Дескриптор, необходимый для последующих операций.
* @retval NULL: Не получилось создать дескриптор. Проверьте вывод serial monitor для сообщения ошибки.
*/ rtc_handle_t* ds3231_init_full(gpio_num_t SCL, gpio_num_t SDA);
/**
* @brief Инициализация модуля DS3231 RTC с информацией I2C.
* @param *bus_handle [in] дескриптор i2c_master_bus_handle_t, ранее созданный вызовом i2c_new_master_bus.
* @retval rtc_handle_t: Дескриптор, необходимый для последующих операций.
* @retval NULL: Не получилось создать дескриптор. Проверьте вывод serial monitor для сообщения ошибки.
*/ rtc_handle_t* ds3231_init(i2c_master_bus_handle_t* bus_handle);
/**
* @brief Это функция для тестирования. Она прочитает все регистры и напечатает их данные
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
*/ voidds3231_debug_print_data(rtc_handle_t* rtc_handle);
/**
* @brief Запрашивает у DS3231 содержимое всех регистров (00h - 12h) в виде сырых данных.
* @note Возвращенное значение должно быть освобождено вызывающим кодом, чтобы не допустить утечки памяти
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b uint8_t* - массив, содержащий данные всех регистров.
*/ uint8_t* ds3231_get_registers_raw(rtc_handle_t* rtc_handle);
/**
* @brief Посылает одиночный байт в указанный регистр DS3231
* @warning Это потенциально опасная команда. ЛЮБЫЕ данные можно послать в ЛЮБОЙ регистр.
* Никакие проверки не выполняются.
* @warning Подключение этой функции сделано, чтобы позволить низкоуровневый доступ, который
* не предоставляют стандартные функции \a set_x и \a get_x.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param rtc_register [in] Записываемый регистр.
* @param rtc_data [in] Записываемые данные.
* @return @b esp_err_t - каскадируется из i2c_master_transmit
* - \b ESP_OK: успех I2C master transmit-receive
* - \b ESP_ERR_INVALID_ARG: недопустимый параметр I2C master transmit.
* - \b ESP_ERR_TIMEOUT: таймаут операции (прошло время, больше чем xfer_timeout_ms)
* из-за занятости шины или аппаратной проблемы.
*/ esp_err_tds3231_send_byte_raw(rtc_handle_t* rtc_handle, enum rtc_register_e rtc_register, uint8_t rtc_data);
/**
* @brief Запрашивает у DS3231 содержимое регистров минут или секунд. Работает как с регистрами Time,
* так и с регистрами Alarm.
* @note У Alarm2 нет регистра секунд.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param rtc_register [in] rtc_register_e регистр минут/секунд для Time, Alarm 1, Alarm 2
* @return \b uint8_t - один байт, представляющий значение минут или секунд в формате Base-10.
* - значения: 0-59
* - формат \b НЕ учитывает високосные секунды (leap seconds)
*/ int8_tds3231_time_minutes_or_seconds_get(rtc_handle_t* rtc_handle, enum rtc_register_e rtc_register);
/**
* @brief Запрашивает у DS3231 содержимое регистра часа. Работает как с регистрами Time,
* так и с регистрами Alarm.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param rtc_register [in] rtc_register_e регистр часов для Time, Alarm 1, Alarm 2
* @return \b uint8_t - один байт, представляющий значение часов, в формате Base-10.
* - значения: 0-23.
* - данные всегда предоставляются в 24-часовом формате.
*/ int8_tds3231_time_hours_get(rtc_handle_t* rtc_handle, enum rtc_register_e rtc_register);
/**
* @brief Запрашивает у DS3231 содержимое регистра дня недели. Работает как с регистрами Time,
* так и с регистрами Alarm.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param rtc_register [in] rtc_register_e регистр дня недели для Time, Alarm 1, Alarm 2
* @return \b uint8_t - один байт, представляющий день недели (Day of Week).
* - значения 1 - 7
* - отсчет дня начинается с понедельника (1 == Monday)
*/ int8_tds3231_time_day_of_week_get(rtc_handle_t* rtc_handle, enum rtc_register_e rtc_register);
/**
* @brief Запрашивает у DS3231 содержимое дня месяца. Работает как с регистрами Time,
* так и с регистрами Alarm.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param rtc_register [in] rtc_register_e регистр дня месяца для Time, Alarm 1, Alarm 2
* @return \b uint8_t - один байт, представляющий день месяца (Day of Month).
* - значения 1 - 31
*/ int8_tds3231_time_date_get(rtc_handle_t* rtc_handle, enum rtc_register_e rtc_register);
/**
* @brief Запрашивает у DS3231 содержимое регистра месяца. Работает только на Time.
* @note Neither Регистра месяца нет ни у Alarm 1, ни у Alarm 2.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b uint8_t - один байт, представляющий месяц.
* - значения 1 - 12
*/ int8_tds3231_time_month_get(rtc_handle_t* rtc_handle);
/**
* @brief Запрашивает у DS3231 содержимое регистра года. Работает только на Time.
* @note Neither Регистра года нет ни у Alarm 1, ни у Alarm 2.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b uint16_t - два байта, представляющие год.
* - значения 1900 - 2099
*/ int16_tds3231_time_year_get(rtc_handle_t* rtc_handle);
/**
* @brief Запрашивает у DS3231 содержимое регистра смещения старения (Aging Offset).
* @note См. даташит DS3231 для специфики Aging Offset
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b int8_t - один байт со знаком, представляющий смещение старения.
*/ int8_tds3231_aging_offset_get(rtc_handle_t* rtc_handle);
/**
* @brief Запрашивает у DS3231 содержимое регистра температуры.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b float - Float, представляющий температуры с шагом 0.25° C.
*/ floatds3231_temperature_get(rtc_handle_t* rtc_handle);
/**
* @brief Запрашивает у DS3231 содержимое регистров управления (Control) и состояния (Status).
* @note См. даташит DS3231 для полного описания всех значений управления и статуса.
* @note Возвращенное значение должно быть освобождено вызывающим кодом, чтобы не было утечки памяти.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b rtc_control_status_t* - Указатель на структуру, содержащую все значения регистра
* управления и статуса.
*/ rtc_control_status_t* ds3231_control_status_flags_get(rtc_handle_t* rtc_handle);
/**
* @brief Запрашивает у DS3231 текущее значение времени, возвращенное как \b struct \b tm.
* @note Возвращенное значение должно быть освобождено вызывающим кодом, чтобы не было утечки памяти.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b struct \b tm* - указатель на структуру tm, заполненную текущим временем.
*/ struct tm* ds3231_time_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит время DS3231, используя значение \b time_t
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param time [in] time_t, которое будет установлено в DS3231
* @return @b esp_err_t - каскадируется из i2c_master_transmit
*/ esp_err_tds3231_time_time_t_set(rtc_handle_t* rtc_handle, time_t time);
/**
* @brief Запрашивает у DS3231 значение текущего времени, возвращаемое как \b struct \b tm.
* @note Хотя семейство ESP32 32-разрядное, time_t имеет разрядность 64 бита и совместимо с Y2038
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b time_t - целочисленное значение без знака, представляющее количество секунд, прошедших от
* момента 1 января 1970, 00:00:00
*/ time_tds3231_time_unix_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит время DS3231, используя значение времени Unix
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param unix_time [in] long, которое установит время в секундах с момента 1 января 1970 @ 00:00:00
* @return @b esp_err_t - каскадируется из i2c_master_transmit
*/ esp_err_tds3231_time_unix_set(rtc_handle_t* rtc_handle, long unix_time);
/**
* @brief Установит время DS3231, используя значение \b struct \b tm
* @note the Значение \b time \b ДОЛЖНО иметь \b ОБА установленные поля недели (tm.tm_wday)
* и дня месяца (tm.tm_mday)
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param time [in] структура tm, поля которой установлены в желаемые значения времени.
* @return @b esp_err_t - каскадируется из i2c_master_transmit
*/ esp_err_tds3231_time_tm_set(rtc_handle_t* rtc_handle, struct tm time);
/**
* @brief Создаст прерывание по сигналу на выводе порта (GPIO Pin interrupt) и соответствующую
* очередь обработки, а также назначит определяемую пользователем функцию для обработки
* прерываний, генерируемых сигналом на выводе INT DS3231.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param INT [in] gpio_num_t ножка GPIO, к которой подключен вывод INT DS3231.
* @param isr [in] gpio_isr_t определяемая пользователем функция, запускаемая событием прерывания.
* @param params [in] void* указатель на параметры, переданные в \b isr,
* @return \b esp_err_t - каскадируется из gpio_isr_handler_add
*/ esp_err_tds3231_alarm_isr_create(rtc_handle_t* rtc_handle, gpio_num_t INT, gpio_isr_t isr, void* params);
/**
* @brief Удаляет alarm isr, ранее созданный вызовом \b ds3231_alarm_isr_create
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param INT [in] gpio_num_t ножка GPIO, к которой подключен вывод INT DS3231.
* @return \b esp_err_t - cascaded from gpio_isr_handler_delete
*/ esp_err_tds3231_alarm_isr_delete(rtc_handle_t* rtc_handle, gpio_num_t INT);
/**
* @brief Запрашивает у DS3231 установку значения Alarm 1.
* @attention Из-за отличий в том, как DS3231 и \b struct \b tm хранят значения дня недели/месяца,
* будет появляться -1 в tm.tm_wday или tm.tm_mday (или в обоих), чтобы показать
недопустимое значение.
* @attention Если \a tm.tm_wday или \a tm.tm_mday имеет значение -1, и в другом регистре значение >= 0,
* то это нормальная ситуация, потому что только день недели или день месяца может быть
* использовано для определенной установки времени будильника.
* @note Возвращенное значение должно быть освобождено вызывающим кодом, чтобы не было утечки памяти.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b struct \b tm* - указатель на структуру tm, заполненную временем Alarm 1.
*/ struct tm* ds3231_alarm1_time_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит значение Alarm 1 для срабатывания на одном и том же дне каждой недели.
* Alarm 1 поддерживает значение секунд, в то время как Alarm 2 секунды не поддерживает.
* В остальном их функционал одинаковый.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param dow [in] enum rtc_day_of_week_e (это передчисление соответствует тому, как DS3231
* представляет день недели).
* @param hour [in] int8_t представляет часы 00 - 23.
* @param minutes [in] int8_t представляет минуты 00 - 59.
* @param seconds [in] int8_t представляет секунды 00 - 59.
* @return @b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm1_day_of_week_set(rtc_handle_t* rtc_handle, enum rtc_day_of_week_e dow,
int8_t hour, int8_t minutes, int8_t seconds);
/**
* @brief Установит значение Alarm 1 для срабатывания на одном и том же дне каждого месяца.
* Alarm 1 поддерживает значение секунд, в то время как Alarm 2 секунды не поддерживает.
* В остальном их функционал одинаковый.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param day [in] int8_t представляет день месяца.
* @note Если день месяца не существует в текущем месяце, например 30 число февраля, то alarm
* не сработает в этом месяце.
* Рекомендуется добавить логику в alarm ISR, чтобы подстроить запись alarm после его срабатывания.
* @param hour [in] int8_t представляет часы 00 - 23.
* @param minutes [in] int8_t представляет минуты 00 - 59.
* @param seconds [in] int8_t представляет секунды 00 - 59.
* @return @b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm1_day_of_month_set(rtc_handle_t* rtc_handle, int8_t day, int8_t hour,
int8_t minutes, int8_t seconds);
/**
* @brief Установит состояние разрешено/запрещено для Alarm 1
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param isEnabled [in] разрешить или запретить Alarm 1
* @return @b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm1_enable_flag_set(rtc_handle_t* rtc_handle, bool isEnabled);
/**
* @brief Получит статус срабатывания Alarm 1. Если сконфигурированы прерывания alarm, то они сработают.
* Этот флаг остается установленным, пока не будет сброшен вручную.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval true - сработал Alarm 1.
* @retval false - Alarm 1 не срабатывал.
*/ boolds3231_alarm1_fired_flag_get(rtc_handle_t* rtc_handle);
/**
* @brief Получит условия срабатывания Alarm 1, как это описано в \b rtc_alarm_rate_e.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b enum \b rtc_alarm_rate_e - значение перечисления, идентифицирующее условие срабатывания
*/ enum rtc_alarm_rate_e ds3231_alarm1_rate_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит условие срабатывания Alarm 1, как это описано в \b rtc_alarm_rate_e.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param alarm_rate [in] значение перечисление, идентифицирующее условие срабатывания.
* @return @b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm1_rate_set(rtc_handle_t* rtc_handle, enum rtc_alarm_rate_e alarm_rate);
/**
* @brief Сбросит в 0 флаг срабатывания Alarm 1.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return @b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm1_fired_flag_reset(rtc_handle_t* rtc_handle);
/**
* @brief Запросит у DS3231 установленное значение Alarm 2.
* @attention Из-за отличий в том, как DS3231 и \b struct \b tm хранят значения дня недели/месяца,
* будет появляться -1 в tm.tm_wday или tm.tm_mday (или в обоих), чтобы показать
* недопустимое значение.
* @attention Если \a tm.tm_wday или \a tm.tm_mday имеет значение -1, и в другом регистре значение >= 0,
* то это нормальная ситуация, потому что только день недели или день месяца может быть
* использовано для определенной установки времени будильника.
* @note Возвращенное значение должно быть освобождено вызывающим кодом, чтобы не было утечки памяти.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b struct \b tm* - указатель на структуру tm, заполененную временем Alarm 2.
*/ struct tm* ds3231_alarm2_time_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит значение Alarm 2, чтобы он срабатывал в один и тот же день недели.
* Alarm 1 поддерживает секунды, а Alarm 2 секунды не поддерживает.
* В остальном их функционал одинаковый.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param dow [in] enum rtc_day_of_week_e (это перечисление соответствует тому, как DS3231
* представляет день недели).
* @param hour [in] int8_t представляет часы 00 - 23.
* @param minutes [in] int8_t представляет минуты 00 - 59.
* @return @b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm2_day_of_week_set(rtc_handle_t* rtc_handle, enum rtc_day_of_week_e dow,
int8_t hour, int8_t minutes);
/**
* @brief Установит значение Alarm 2, чтобы он срабатывал в один и тот же день каждого месяца.
* Alarm 1 поддерживает секунды, а Alarm 2 секунды не поддерживает.
* В остальном их функционал одинаковый.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param day [in] int8_t представляет день месяца.
* @note Если день месяца не существует в текущем месяце, например 30 число февраля,
* то alarm не сработает в этом месяце. Рекомендуется добавить логику в alarm ISR,
* чтобы подстроить запись alarm после его срабатывания.
* @param hour [in] int8_t представляет часы 00 - 23.
* @param minutes [in] int8_t представляет минуты 00 - 59.
* @return @b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm2_day_of_month_set(rtc_handle_t* rtc_handle, int8_t day,
int8_t hour, int8_t minutes);
/**
* @brief Получит статус флага срабатывания Alarm 2. Если сконфигурированы прерывания alarm,
* то они сработают. Этот флаг остается установленным, пока не будет сброшен вручную.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval true - сработал Alarm 2.
* @retval false - Alarm 2 не срабатывал.
*/ boolds3231_alarm2_fired_flag_get(rtc_handle_t* rtc_handle);
/**
* @brief Получит условие срабатывания Alarm 2, как это описано в \b rtc_alarm_rate_e.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b enum \b rtc_alarm_rate_e - значение перечисления, идентифицирующее условие срабатывания
*/ enum rtc_alarm_rate_e ds3231_alarm2_rate_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит условие срабатывания Alarm 2, как это описано \b rtc_alarm_rate_e.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param alarm_rate [in] значение перечисление, идентифицирующее условие срабатывания.
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm2_rate_set(rtc_handle_t* rtc_handle, enum rtc_alarm_rate_e alarm_rate);
/**
* @brief Сбросит в 0 флаг срабатывания Alarm 2.
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_alarm2_fired_flag_reset(rtc_handle_t* rtc_handle);
/**
* @brief Синхронизирует время ESP32 с временем из DS3231
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval 0 успех
* @retval -1 неудача
*/ intds3231_set_esp_with_rtc(rtc_handle_t* rtc_handle);
/**
* @brief Получит статус флага генератора (Oscillartor Flag)
*
* @note Драйвер знает, что аппаратура разрешена при Logic 0, и вернет true для Logic 0
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval true разрешен
* @retval false запрещен
*/ boolds3231_enable_oscillator_flag_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит статус флага генератора (Oscillartor Flag)
*
* @note Драйвер знает, что аппаратура разрешена при Logic 0, и установит Logic 0 для
* \b isEnabled \b = \b true
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param isEnabled [in] разрешить/запретить Oscillator Flag
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_enable_oscillator_flag_set(rtc_handle_t* rtc_handle, bool isEnabled);
/**
* @brief Получит статус флага генерации выходного прямоугольного сигнала при работе
* от батареи (Battery Backed Scquare Wave Flag)
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval true разрешено
* @retval false запрещено
*/ boolds3231_battery_backed_square_wave_flag_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит состояние Batter Backed Square Wave Flag
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param isEnabled [in] разрешить/запретить генерацию прямоугольника при работе от батареи
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_battery_backed_square_wave_flag_set(rtc_handle_t* rtc_handle, bool isEnabled);
/**
* @brief Вернет состояние флага преобразования температуры (Convert Temp Temperature Flag)
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval true разрешено
* @retval false запрещено
*/ boolds3231_convert_temp_flag_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит состояние Convert Temperature Flag
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param isEnabled [in] разрешить/запретить Convert Temperature Flag
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_convert_temp_flag_set(rtc_handle_t* rtc_handle, bool isEnabled);
/**
* @brief Получит текущее значение (1 .. 4) настройки выхода генерации прямогольника
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return значение перечисления rtc_square_wave_freq_e (соответствует частоте прямоугольного сигнала)
*/ enum rtc_square_wave_freq_e ds3231_square_wave_freq_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит значение перечисления (1 .. 4) для настройки генерируемого прямоугольного сигнала
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param frequency [in] rtc_square_wave_freq_e желаемая выходная частота (один из 4 вариантов).
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_square_wave_freq_set(rtc_handle_t* rtc_handle, enum rtc_square_wave_freq_e frequency);
/**
* @brief Сбросит состояние Ocsillator Stop Flag
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_oscillator_stop_flag_reset(rtc_handle_t* rtc_handle);
/**
* @brief Получит состояние флага генерации 32kHz
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval true разрешено
* @retval false запрещено
*/ boolds3231_32kHz_out_enable_flag_get(rtc_handle_t* rtc_handle);
/**
* @brief Установит состояние флага генерации 32kHz
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param isEnabled [in] разрешить/запретить 32kHz
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_32kHz_out_enable_flag_set(rtc_handle_t* rtc_handle, bool isEnabled);
/**
* @brief Получит состояние флага занятости (Busy Flag)
*
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @retval true DS3231 занята
* @retval false DS3231 не занята
*/ boolds3231_busy_flag_get(rtc_handle_t* rtc_handle);
/**
* @brief Подобная концепция в ds3231_set_registers_raw. Позволяет установить один регистр
* одним байтом данных.
* @warning Это потенциально опасная команда, поскольку никаких защитных проверок данных
* не проводится. Эта функция предоставляется для того, чтобы обеспечить низкоуровневый
* доступ, который не предоставляется другими функциями.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param rtc_register [in] enum rtc_register_e записываемый регистр
* @param bit_pattern [in] uint8_t записываемое значение
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_register_set(rtc_handle_t* rtc_handle, enum rtc_register_e rtc_register,
uint8_t bit_pattern);
/**
* @brief Подобная концепция в ds3231_register_set. Позволяет установить несколько идущих
* друг за другом регистров из массива данных.
*
* @warning Это потенциально опасная команда, поскольку никаких защитных проверок данных
* не проводится. Эта функция предоставляется для того, чтобы обеспечить низкоуровневый
* доступ, который не предоставляется другими функциями.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
* @param rtc_data [in] uint8_t массив данных, записываемых в регистры (регистры).
* @param count [in] size_t количество элементов в rtc_data
* @return \b esp_err_t - каскадируется из i2c_master_transmit.
*/ esp_err_tds3231_set_registers_raw(rtc_handle_t* rtc_handle, uint8_t* rtc_data, size_t count);
/**
* @brief Получит все регистры времени, будильника и управления/статуса. Данные выводятся
* функцией ESP_LOGI.
* @note Это хороший способ проверить, какие данные установлены в DS3231.
* @note Если уровень отладки (debug level) в VERBOSE, то напечатается список каждого
* регистра и его значения в форматах hex и binary.
*/ voidds3231_debug_print_data(rtc_handle_t* rtc_handle);
/**
* @brief Получит и установит/сбросит все флаги из регистров управления/статуса. Данные выводятся
* функцией ESP_LOGI
* @warning Эта функция должна использоваться только для отладки/тестирования DS3231.
* Существующие настройки будут перезаписаны.
* @param rtc_handle [in] rtc_handle_t* дескриптор, возвращенный из ds3231_init.
*/ voidds3231_debug_test_set(rtc_handle_t* rtc_handle);