ESPHome 2026.10.0
Loading...
Searching...
No Matches
rx8025t.cpp
Go to the documentation of this file.
1#include "rx8025t.h"
2#include "esphome/core/log.h"
3
4// Datasheet:
5// - https://support.epson.biz/td/api/doc_check.php?dl=app_RX8025T
6
7namespace esphome::rx8025t {
8
9static constexpr uint8_t RX8025T_REG_SEC = 0x00;
10static constexpr uint8_t RX8025T_REG_FLAG = 0x0E;
11static constexpr uint8_t RX8025T_FLAG_VDET = 0x01;
12static constexpr uint8_t RX8025T_FLAG_VLF = 0x02;
13
14static const char *const TAG = "rx8025t";
15
16constexpr uint8_t bcd2dec(uint8_t val) { return (val >> 4) * 10 + (val & 0x0f); }
17constexpr uint8_t dec2bcd(uint8_t val) { return ((val / 10) << 4) + (val % 10); }
18
20 uint8_t flags;
21 if (!this->read_flags_(&flags)) {
22 this->mark_failed();
23 return;
24 }
25
26 if (flags & RX8025T_FLAG_VLF) {
27 ESP_LOGW(TAG, "VLF flag is set - Loss of oscillator detected. Time may be invalid.");
28 }
29}
30
32
34 ESP_LOGCONFIG(TAG, "RX8025T:");
35 LOG_I2C_DEVICE(this);
36 if (this->is_failed()) {
37 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
38 }
40}
41
43 if (!this->read_byte(RX8025T_REG_FLAG, flags)) {
44 ESP_LOGE(TAG, "Can't read flag register.");
45 this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
46 return false;
47 }
48 return true;
49}
50
52 uint8_t flags;
53 if (!this->read_flags_(&flags)) {
54 return;
55 }
56
57 uint8_t date[7];
58 if (!this->read_bytes(RX8025T_REG_SEC, date, sizeof(date))) {
59 ESP_LOGE(TAG, "Can't read I2C data.");
60 this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
61 return;
62 }
64
65 if (flags & RX8025T_FLAG_VLF) {
66 ESP_LOGW(TAG, "VLF flag is set - time data may be invalid, not syncing to system clock.");
67 return;
68 }
69
70 ESPTime rtc_time{
71 .second = bcd2dec(date[0] & 0x7f),
72 .minute = bcd2dec(date[1] & 0x7f),
73 .hour = bcd2dec(date[2] & 0x3f),
74 .day_of_week = static_cast<uint8_t>((date[3] & 0x7f) ? __builtin_ctz(date[3] & 0x7f) + 1 : 1),
75 .day_of_month = bcd2dec(date[4] & 0x3f),
76 .day_of_year = 1,
77 .month = bcd2dec(date[5] & 0x1f),
78 .year = static_cast<uint16_t>(bcd2dec(date[6]) + 2000),
79 .is_dst = false,
80 .timestamp = 0,
81 };
82 rtc_time.recalc_timestamp_utc(false);
83 if (!rtc_time.is_valid(/*check_day_of_week=*/true, /*check_day_of_year=*/false)) {
84 ESP_LOGE(TAG, "Invalid RTC time, not syncing to system clock.");
85 return;
86 }
87 ESP_LOGD(TAG, "Read UTC time: %04d-%02d-%02d %02d:%02d:%02d VDET:%s", rtc_time.year, rtc_time.month,
88 rtc_time.day_of_month, rtc_time.hour, rtc_time.minute, rtc_time.second, ONOFF(flags & RX8025T_FLAG_VDET));
89 this->synchronize_epoch_(rtc_time.timestamp);
90}
91
93 auto now = this->utcnow();
94 if (!now.is_valid()) {
95 ESP_LOGE(TAG, "Invalid system time, not syncing to RTC.");
96 return;
97 }
98
99 uint8_t buff[7];
100 buff[0] = dec2bcd(now.second);
101 buff[1] = dec2bcd(now.minute);
102 buff[2] = dec2bcd(now.hour);
103 buff[3] = 1 << (now.day_of_week - 1);
104 buff[4] = dec2bcd(now.day_of_month);
105 buff[5] = dec2bcd(now.month);
106 buff[6] = dec2bcd(now.year % 100);
107 if (!this->write_bytes(RX8025T_REG_SEC, buff, sizeof(buff))) {
108 ESP_LOGE(TAG, "Can't write I2C data.");
109 this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
110 return;
111 }
112 ESP_LOGD(TAG, "Wrote UTC time: %04d-%02d-%02d %02d:%02d:%02d", now.year, now.month, now.day_of_month, now.hour,
114
115 // Clear VLF and VDET flags via read-modify-write of flag register
116 uint8_t flags;
117 if (!this->read_flags_(&flags)) {
118 return;
119 }
120 flags &= ~(RX8025T_FLAG_VLF | RX8025T_FLAG_VDET);
121 if (!this->write_byte(RX8025T_REG_FLAG, flags)) {
122 this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
123 return;
124 }
125 this->status_clear_warning();
126}
127
128} // namespace esphome::rx8025t
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:272
void status_clear_warning()
Definition component.h:289
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:265
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:240
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len) const
Definition i2c.h:251
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition i2c.h:217
bool read_flags_(uint8_t *flags)
Definition rx8025t.cpp:42
ESPTime now()
Get the time in the currently defined timezone.
ESPTime utcnow()
Get the time without any time zone or DST corrections.
void synchronize_epoch_(uint32_t epoch)
Report a unix epoch as current time.
uint16_t flags
mopeka_std_values val[3]
constexpr uint8_t bcd2dec(uint8_t val)
Definition rx8025t.cpp:16
constexpr uint8_t dec2bcd(uint8_t val)
Definition rx8025t.cpp:17
A more user-friendly version of struct tm from time.h.
Definition time.h:23
uint8_t minute
minutes after the hour [0-59]
Definition time.h:32
void recalc_timestamp_utc(bool use_day_of_year=true)
Recalculate the timestamp field from the other fields of this ESPTime instance (must be UTC).
Definition time.cpp:280
uint8_t second
seconds after the minute [0-60]
Definition time.h:30
uint8_t hour
hours since midnight [0-23]
Definition time.h:34
bool is_valid(bool check_day_of_week=true, bool check_day_of_year=true) const
Check if this ESPTime is valid (year >= 2019 and the requested fields are in range).
Definition time.h:82
uint8_t day_of_month
day of the month [1-31]
Definition time.h:38
uint16_t year
year
Definition time.h:44
uint8_t month
month; january=1 [1-12]
Definition time.h:42
uint8_t day_of_week
day of the week; sunday=1 [1-7]
Definition time.h:36
uint16_t timestamp
Definition tt21100.cpp:2