Merge pull request #2007 from khudson/r1neo
Some checks are pending
PR Build Check / build (Heltec_v3_companion_radio_ble) (push) Waiting to run
PR Build Check / build (Heltec_v3_repeater) (push) Waiting to run
PR Build Check / build (Heltec_v3_room_server) (push) Waiting to run
PR Build Check / build (LilyGo_Tlora_C6_repeater_) (push) Waiting to run
PR Build Check / build (PicoW_repeater) (push) Waiting to run
PR Build Check / build (RAK_4631_companion_radio_ble) (push) Waiting to run
PR Build Check / build (RAK_4631_repeater) (push) Waiting to run
PR Build Check / build (RAK_4631_room_server) (push) Waiting to run
PR Build Check / build (wio-e5-mini_repeater) (push) Waiting to run

Muzi Works R1 Neo support
This commit is contained in:
Liam Cottle 2026-04-02 00:36:44 +13:00 committed by GitHub
commit b934daa990
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 858 additions and 5 deletions

View file

@ -1,6 +1,7 @@
#include "AutoDiscoverRTCClock.h"
#include "RTClib.h"
#include <Melopero_RV3028.h>
#include "RTC_RX8130CE.h"
static RTC_DS3231 rtc_3231;
static bool ds3231_success = false;
@ -11,9 +12,13 @@ static bool rv3028_success = false;
static RTC_PCF8563 rtc_8563;
static bool rtc_8563_success = false;
static RTC_RX8130CE rtc_8130;
static bool rtc_8130_success = false;
#define DS3231_ADDRESS 0x68
#define RV3028_ADDRESS 0x52
#define PCF8563_ADDRESS 0x51
#define RX8130CE_ADDRESS 0x32
bool AutoDiscoverRTCClock::i2c_probe(TwoWire& wire, uint8_t addr) {
wire.beginTransmission(addr);
@ -25,22 +30,32 @@ void AutoDiscoverRTCClock::begin(TwoWire& wire) {
if (i2c_probe(wire, DS3231_ADDRESS)) {
ds3231_success = rtc_3231.begin(&wire);
}
if (i2c_probe(wire, RV3028_ADDRESS)) {
rtc_rv3028.initI2C(wire);
rtc_rv3028.writeToRegister(0x35, 0x00);
rtc_rv3028.writeToRegister(0x37, 0xB4); // Direct Switching Mode (DSM): when VDD < VBACKUP, switchover occurs from VDD to VBACKUP
rtc_rv3028.set24HourMode(); // Set the device to use the 24hour format (default) instead of the 12 hour format
rtc_rv3028.writeToRegister(0x35, 0x00);
rtc_rv3028.writeToRegister(0x37, 0xB4); // Direct Switching Mode (DSM): when VDD < VBACKUP, switchover occurs from VDD to VBACKUP
rtc_rv3028.set24HourMode(); // Set the device to use the 24hour format (default) instead of the 12 hour format
rv3028_success = true;
}
if(i2c_probe(wire,PCF8563_ADDRESS)){
if (i2c_probe(wire, PCF8563_ADDRESS)) {
rtc_8563_success = rtc_8563.begin(&wire);
}
if (i2c_probe(wire, RX8130CE_ADDRESS)) {
MESH_DEBUG_PRINTLN("RX8130CE: Found");
rtc_8130.begin(&wire);
rtc_8130_success = true;
MESH_DEBUG_PRINTLN("RX8130CE: Initialized");
}
}
uint32_t AutoDiscoverRTCClock::getCurrentTime() {
if (ds3231_success) {
return rtc_3231.now().unixtime();
}
if (rv3028_success) {
return DateTime(
rtc_rv3028.getYear(),
@ -51,9 +66,16 @@ uint32_t AutoDiscoverRTCClock::getCurrentTime() {
rtc_rv3028.getSecond()
).unixtime();
}
if(rtc_8563_success){
if (rtc_8563_success) {
return rtc_8563.now().unixtime();
}
if (rtc_8130_success) {
MESH_DEBUG_PRINTLN("RX8130CE: Reading time");
return rtc_8130.now().unixtime();
}
return _fallback->getCurrentTime();
}
@ -66,6 +88,9 @@ void AutoDiscoverRTCClock::setCurrentTime(uint32_t time) {
rtc_rv3028.setTime(dt.year(), dt.month(), weekday, dt.day(), dt.hour(), dt.minute(), dt.second());
} else if (rtc_8563_success) {
rtc_8563.adjust(DateTime(time));
} else if (rtc_8130_success) {
MESH_DEBUG_PRINTLN("RX8130CE: Setting time");
rtc_8130.adjust(DateTime(time));
} else {
_fallback->setCurrentTime(time);
}

View file

@ -0,0 +1,197 @@
#include "RTC_RX8130CE.h"
#include "RTClib.h"
bool RTC_RX8130CE::stop(bool stop) {
write_register(0x1E, stop ? 0x040 : 0x00);
return true;
}
bool RTC_RX8130CE::begin(TwoWire *wire) {
if (i2c_dev) {
delete i2c_dev;
}
i2c_dev = new Adafruit_I2CDevice(this->_addr, wire);
if (!i2c_dev->begin()) {
return false;
}
/*
* Digital offset register:
* [7] DET: 0 -> disabled
* [6:0] L7-L1: 0 -> no offset
*/
write_register(0x30, 0x00);
/*
* Extension Register register:
* [7:6] FSEL: 0 -> 0
* [5] USEL: 0 -> 0
* [4] TE: 0 ->
* [3] WADA: 0 -> 0
* [2-0] TSEL: 0 -> 0
*/
write_register(0x1C, 0x00);
/*
* Flag Register register:
* [7] VBLF: 0 -> 0
* [6] 0: 0 ->
* [5] UF: 0 ->
* [4] TF: 0 ->
* [3] AF: 0 -> 0
* [2] RSF: 0 -> 0
* [1] VLF: 0 -> 0
* [0] VBFF: 0 -> 0
*/
write_register(0x1D, 0x00);
/*
* Control Register0 register:
* [7] TEST: 0 -> 0
* [6] STOP: 0 ->
* [5] UIE: 0 ->
* [4] TIE: 0 ->
* [3] AIE: 0 -> 0
* [2] TSTP: 0 -> 0
* [1] TBKON: 0 -> 0
* [0] TBKE: 0 -> 0
*/
write_register(0x1E, 0x00);
/*
* Control Register1 register:
* [7-6] SMPTSEL: 0 -> 0
* [5] CHGEN: 0 ->
* [4] INIEN: 0 ->
* [3] 0: 0 ->
* [2] RSVSEL: 0 -> 0
* [1-0] BFVSEL: 0 -> 0
*/
write_register(0x1F, 0x00);
this->stop(false); // clear STOP bit
/*
* Function register:
* [7] 100TH: 0 -> disabled
* [6:5] Periodic interrupt: 0 -> no periodic interrupt
* [4] RTCM: 0 -> real-time clock mode
* [3] STOPM: 0 -> RTC stop is controlled by STOP bit only
* [2:0] Clock output frequency: 000 (Default value)
*/
write_register(0x28, 0x00);
// Battery switch register
write_register(0x26, 0x00); // enable battery switch feature
return true;
}
bool RTC_RX8130CE::setTime(struct tm *t) {
uint8_t buf[8];
buf[0] = 0x10;
buf[1] = bin2bcd(t->tm_sec) & 0x7F;
buf[2] = bin2bcd(t->tm_min) & 0x7F;
buf[3] = bin2bcd(t->tm_hour) & 0x3F;
buf[4] = bin2bcd(t->tm_wday) & 0x07;
buf[5] = bin2bcd(t->tm_mday) & 0x3F;
buf[6] = bin2bcd(t->tm_mon + 1) & 0x1F;
buf[7] = bin2bcd((t->tm_year - 100));
this->stop(true);
i2c_dev->write(buf, sizeof(buf));
this->stop(false);
return true;
}
void RTC_RX8130CE::adjust(DateTime dt) {
struct tm *atv;
time_t utime;
utime = (time_t)dt.unixtime();
atv = gmtime(&utime);
this->setTime(atv);
}
DateTime RTC_RX8130CE::now() {
struct tm atv;
this->getTime(&atv);
return DateTime((uint32_t)mktime(&atv));
}
uint32_t RTC_RX8130CE::unixtime() {
struct tm atv;
this->getTime(&atv);
return (uint32_t)mktime(&atv);
}
bool RTC_RX8130CE::getTime(struct tm *t) {
uint8_t buff[7];
buff[0] = 0x10;
i2c_dev->write_then_read(buff, 1, buff, 7);
t->tm_sec = bcd2bin(buff[0] & 0x7F);
t->tm_min = bcd2bin(buff[1] & 0x7F);
t->tm_hour = bcd2bin(buff[2] & 0x3F);
t->tm_wday = bcd2bin(buff[3] & 0x07);
t->tm_mday = bcd2bin(buff[4] & 0x3F);
t->tm_mon = bcd2bin(buff[5] & 0x1F) - 1;
t->tm_year = bcd2bin(buff[6]) + 100;
return true;
}
bool RTC_RX8130CE::writeRAM(uint8_t address, uint8_t value) {
return this->writeRAM(address, &value, 1);
}
size_t RTC_RX8130CE::writeRAM(uint8_t address, uint8_t *value, size_t len) {
uint8_t buf[len + 1];
if (address > 3) {
return 0;
}
if ((address + len) > 3) {
len = 3 - address;
}
buf[0] = 0x20 + address;
for (int i = 1; i <= len + 1; i++) {
buf[i] = value[i - 1];
}
i2c_dev->write(buf, len + 1);
return len;
}
bool RTC_RX8130CE::readRAM(uint8_t address, uint8_t *value, size_t len) {
uint8_t real_address = 0x20 + address;
if (address > 3) { // Oversize of 64-bytes RAM
return false;
}
if ((address + len) > 3) { // Data size over RAM size
len = 3 - address;
}
i2c_dev->write_then_read(&real_address, 1, value, len);
return true;
}
uint8_t RTC_RX8130CE::readRAM(uint8_t address) {
uint8_t value = 0xFF;
this->readRAM(address, &value, 1);
return value;
}

View file

@ -0,0 +1,33 @@
#ifndef __RTC_RX8130CE_H__
#define __RTC_RX8130CE_H__
#include <Arduino.h>
#include <Wire.h>
#include <time.h>
#include "RTClib.h"
class RTC_RX8130CE : RTC_I2C {
private:
const uint8_t _addr = 0x32;
bool stop(bool stop);
protected:
public:
bool begin(TwoWire *wire);
bool setTime(struct tm *t);
bool getTime(struct tm *t);
void adjust(DateTime t);
DateTime now();
uint32_t unixtime();
bool writeRAM(uint8_t address, uint8_t value);
size_t writeRAM(uint8_t address, uint8_t *value, size_t len);
bool readRAM(uint8_t address, uint8_t *value, size_t len);
uint8_t readRAM(uint8_t address);
};
#endif