mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 10:46:31 +00:00
RV3028 RTC Chip support (#23672)
* Update xdrv_56_rtc_chips.ino Added support for RV3028 RTC * Update I2CDEVICES.md RV3028 RTC Support * Update my_user_config.h
This commit is contained in:
parent
6c699e9b95
commit
d3e2bb6906
@ -131,5 +131,6 @@ Index | Define | Driver | Device | Address(es) | Bus2 | Descrip
|
||||
91 | USE_MS5837 | xsns_116 | MS5837 | 0x76 | | Pressure and temperature sensor
|
||||
92 | USE_PCF85063 | xdrv_56 | PCF85063 | 0x51 | | PCF85063 Real time clock
|
||||
93 | USE_AS33772S | xdrv_119 | AS33772S | 0x52 | Yes | AS33772S USB PD Sink Controller
|
||||
94 | USE_RV3028 | xdrv_56 | RV3028 | 0x52 | Yes | RV-3028-C7 RTC Controller
|
||||
|
||||
NOTE: Bus2 supported on ESP32 only.
|
||||
|
@ -791,6 +791,7 @@
|
||||
// #define USE_AP33772S // [I2cDriver93] Enable AP33772S USB PD Sink Controller (I2C addresses 0x52) (+3k1 code)
|
||||
|
||||
// #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
|
||||
// #define USE_RV3028 // [I2cDriver94] Enable RV3028 RTC chip support (I2C address 0x52)
|
||||
// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC - used by Ulanzi TC001 (I2C address 0x68) (+1k2 code)
|
||||
// #define DS3231_ENABLE_TEMP // In DS3231 driver, enable the internal temperature sensor
|
||||
// #define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - used by M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2.5k code)
|
||||
|
@ -11,6 +11,9 @@
|
||||
/*********************************************************************************************\
|
||||
* RTC chip support
|
||||
*
|
||||
* #define USE_RV3028
|
||||
* RV-3028-C7 at I2C address 0x52
|
||||
* Used in MSB Master G1
|
||||
* #define USE_DS3231
|
||||
* DS1307 and DS3231 at I2C address 0x68
|
||||
* Used by Ulanzi TC001
|
||||
@ -44,6 +47,137 @@ struct {
|
||||
char name[10];
|
||||
} RtcChip;
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* RV-3028-C7 RTC Controller
|
||||
*
|
||||
* I2C Address: 0x52
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef USE_RV3028
|
||||
|
||||
#define XI2C_94 94 // See I2CDEVICES.md
|
||||
|
||||
#define RV3028_ADDR 0x52 // I2C address of RV-3028-C7
|
||||
|
||||
// RV-3028-C7 Register Addresses
|
||||
#define RV3028_SECONDS 0x00
|
||||
#define RV3028_MINUTES 0x01
|
||||
#define RV3028_HOURS 0x02
|
||||
#define RV3028_WEEKDAY 0x03
|
||||
#define RV3028_DATE 0x04
|
||||
#define RV3028_MONTH 0x05
|
||||
#define RV3028_YEAR 0x06
|
||||
#define RV3028_STATUS 0x0E
|
||||
#define RV3028_CONTROL1 0x0F
|
||||
#define RV3028_CONTROL2 0x10
|
||||
|
||||
// Status register bits
|
||||
#define RV3028_PORF 0 // Power-on Reset flag (bit 0 in STATUS register)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Init register to activate BSM from VBACKUP (Direct Switching Mode)
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
void RV3028_EnableDSM(void) {
|
||||
uint8_t current_eeprom;
|
||||
|
||||
I2cWrite8(RtcChip.address, 0x25, 0x37, RtcChip.bus); // EEADDR = 0x37
|
||||
I2cWrite8(RtcChip.address, 0x27, 0x22, RtcChip.bus); // EECMD = 0x22 (EEPROM Read)
|
||||
delay(3);
|
||||
|
||||
current_eeprom = I2cRead8(RtcChip.address, 0x26, RtcChip.bus); // EEDATA actual data
|
||||
|
||||
if (current_eeprom != 0x14) {
|
||||
I2cWrite8(RtcChip.address, 0x25, 0x37, RtcChip.bus); // EEADDR = 0x37
|
||||
I2cWrite8(RtcChip.address, 0x26, 0x14, RtcChip.bus); // EEDATA = 0x14 (FEDE=1, BSM=01 DSM mode)
|
||||
I2cWrite8(RtcChip.address, 0x27, 0x21, RtcChip.bus); // EECMD = 0x21 (EEPROM Write)
|
||||
delay(25);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("RV3028: EEPROM 0x37 updated to DSM mode."));
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("RV3028: EEPROM 0x37 already set to DSM mode."));
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Read time from RV-3028-C7 and return the epoch time (seconds since 1-1-1970 00:00)
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
uint32_t RV3028ReadTime(void) {
|
||||
|
||||
uint8_t status = I2cRead8(RtcChip.address, RV3028_STATUS, RtcChip.bus);
|
||||
|
||||
// Skontroluj PORF bit (bit 0 registra STATUS)
|
||||
if (status & _BV(RV3028_PORF)) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("RV3028: PORF detected, RTC time invalid"));
|
||||
return 0; // Invalid RTC time data
|
||||
}
|
||||
|
||||
|
||||
TIME_T tm;
|
||||
tm.second = Bcd2Dec(I2cRead8(RtcChip.address, RV3028_SECONDS, RtcChip.bus) & 0x7F);
|
||||
tm.minute = Bcd2Dec(I2cRead8(RtcChip.address, RV3028_MINUTES, RtcChip.bus) & 0x7F);
|
||||
tm.hour = Bcd2Dec(I2cRead8(RtcChip.address, RV3028_HOURS, RtcChip.bus) & 0x3F); // 24h mode (12_24 bit = 0)
|
||||
tm.day_of_week = I2cRead8(RtcChip.address, RV3028_WEEKDAY, RtcChip.bus) & 0x07; // 0..6 (3-bit weekday counter)
|
||||
tm.day_of_month = Bcd2Dec(I2cRead8(RtcChip.address, RV3028_DATE, RtcChip.bus) & 0x3F);
|
||||
tm.month = Bcd2Dec(I2cRead8(RtcChip.address, RV3028_MONTH, RtcChip.bus) & 0x1F);
|
||||
uint8_t year = Bcd2Dec(I2cRead8(RtcChip.address, RV3028_YEAR, RtcChip.bus));
|
||||
// RV-3028-C7 holds year 00-99 (representing 2000-2099).
|
||||
// MakeTime requires tm.year as years since 1970.
|
||||
tm.year = year + 30; // (e.g., 23 -> 53 for year 2023)
|
||||
return MakeTime(tm);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Set RV-3028-C7 time using the given epoch time (seconds since 1-1-1970 00:00)
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
void RV3028SetTime(uint32_t epoch_time) {
|
||||
TIME_T tm;
|
||||
BreakTime(epoch_time, tm);
|
||||
I2cWrite8(RtcChip.address, RV3028_SECONDS, Dec2Bcd(tm.second), RtcChip.bus);
|
||||
I2cWrite8(RtcChip.address, RV3028_MINUTES, Dec2Bcd(tm.minute), RtcChip.bus);
|
||||
I2cWrite8(RtcChip.address, RV3028_HOURS, Dec2Bcd(tm.hour), RtcChip.bus);
|
||||
I2cWrite8(RtcChip.address, RV3028_WEEKDAY, tm.day_of_week, RtcChip.bus);
|
||||
I2cWrite8(RtcChip.address, RV3028_DATE, Dec2Bcd(tm.day_of_month), RtcChip.bus);
|
||||
I2cWrite8(RtcChip.address, RV3028_MONTH, Dec2Bcd(tm.month), RtcChip.bus);
|
||||
// Convert years since 1970 to RTC register value (00..99)
|
||||
uint8_t true_year = (tm.year < 30) ? (tm.year + 70) : (tm.year - 30);
|
||||
I2cWrite8(RtcChip.address, RV3028_YEAR, Dec2Bcd(true_year), RtcChip.bus);
|
||||
// Clear the power-on reset flag (PORF) in the status register
|
||||
uint8_t status = I2cRead8(RtcChip.address, RV3028_STATUS, RtcChip.bus);
|
||||
I2cWrite8(RtcChip.address, RV3028_STATUS, status & ~_BV(RV3028_PORF), RtcChip.bus);
|
||||
|
||||
// Enable LSM mode (VBACKUP)
|
||||
RV3028_EnableDSM();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Detection
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
void RV3028Detected(void) {
|
||||
if (!RtcChip.detected && I2cEnabled(XI2C_94)) {
|
||||
RtcChip.address = RV3028_ADDR;
|
||||
for (RtcChip.bus = 0; RtcChip.bus < 2; RtcChip.bus++) {
|
||||
if (!I2cSetDevice(RtcChip.address, RtcChip.bus)) continue;
|
||||
if (I2cValidRead(RtcChip.address, RV3028_STATUS, 1, RtcChip.bus)) {
|
||||
uint8_t status = I2cRead8(RtcChip.address, RV3028_STATUS, RtcChip.bus);
|
||||
if (status & _BV(RV3028_PORF)) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("RV3028: PORF detected at init, RTC time invalid"));
|
||||
}
|
||||
RtcChip.detected = 1;
|
||||
strcpy_P(RtcChip.name, PSTR("RV3028"));
|
||||
RtcChip.ReadTime = &RV3028ReadTime;
|
||||
RtcChip.SetTime = &RV3028SetTime;
|
||||
RtcChip.mem_size = 2; // RAM 2 byte
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // USE_RV3028
|
||||
|
||||
/*********************************************************************************************\
|
||||
* DS1307 and DS3231
|
||||
*
|
||||
@ -188,7 +322,7 @@ void DS3231Detected(void) {
|
||||
#endif // USE_DS3231
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* PCF85063 support
|
||||
*
|
||||
@ -596,6 +730,9 @@ void RtcChipDetect(void) {
|
||||
RtcChip.detected = 0;
|
||||
RtcChip.bus = 0;
|
||||
|
||||
#ifdef USE_RV3028
|
||||
RV3028Detected();
|
||||
#endif // USE_RV3028
|
||||
#ifdef USE_DS3231
|
||||
DS3231Detected();
|
||||
#endif // USE_DS3231
|
||||
|
Loading…
x
Reference in New Issue
Block a user