add support for hardware rtc, not sure if this version won't crash

This commit is contained in:
2026-01-11 12:04:40 +01:00
parent 06de03a16d
commit a4346aa4f1
22 changed files with 813 additions and 88 deletions

429
lib/RX8010SJ/RX8010SJ.cpp Normal file
View File

@@ -0,0 +1,429 @@
#include "RX8010SJ.h"
namespace RX8010SJ {
Adapter::Adapter(byte i2cSlaveAddr) {
i2cAddress = i2cSlaveAddr;
}
Adapter::~Adapter() {}
/**
*
* PUBLIC FUNCTIONS
*
*/
/**
* GENERAL
*/
bool Adapter::initAdapter() {
Wire.begin();
delay(40);
return initModule();
}
bool Adapter::initModule() {
byte flagValue = readFromModule(RX8010_FLAG);
byte vlf = getValueFromBinary(flagValue, RX8010_VLF_POS);
// It's 1 when the module had power issues and needs to be reinitialised
if (vlf == 1) {
// The oscillator takes some time stabilise
while (vlf == 1) {
flagValue = setBinary(flagValue, RX8010_VLF_POS, 0);
writeToModule(RX8010_FLAG, vlf);
delay(10);
flagValue = readFromModule(RX8010_FLAG);
vlf = getValueFromBinary(flagValue, RX8010_VLF_POS);
}
resetModule();
return true;
}
return false;
}
void Adapter::resetModule() {
writeToModule(RX8010_RESV17, RX8010_ADDR17_DEF_VAL);
writeToModule(RX8010_RESV30, RX8010_ADDR30_DEF_VAL);
writeToModule(RX8010_RESV31, RX8010_ADDR31_DEF_VAL);
writeToModule(RX8010_IRQ, RX8010_IRQ_DEF_VAL);
writeFlag(RX8010_EXT, RX8010_TE_POS, 0);
writeFlag(RX8010_FLAG, RX8010_VLF_POS, 0);
writeToModule(RX8010_CTRL, RX8010_CTRL_DEF_VAL);
}
void Adapter::toggleGlobalStop(bool stopEnabled) {
writeFlag(RX8010_CTRL, RX8010_STOP_POS, stopEnabled ? 1 : 0);
}
/**
* DATE TIME
*/
DateTime Adapter::readDateTime() {
byte secondBin = readFromModule(RX8010_SEC);
byte minuteBin = readFromModule(RX8010_MIN);
byte hourBin = readFromModule(RX8010_HOUR);
byte dayOfWeekBin = readFromModule(RX8010_WDAY);
byte dayOfMonthBin = readFromModule(RX8010_MDAY);
byte monthBin = readFromModule(RX8010_MONTH);
byte yearBin = readFromModule(RX8010_YEAR);
DateTime dateTime;
dateTime.second = sumValueFromBinary(secondBin, 7);
dateTime.minute =sumValueFromBinary(minuteBin, 7);
dateTime.hour = sumValueFromBinary(hourBin, 6);
dateTime.dayOfWeek = getSingleBit(dayOfWeekBin);
dateTime.dayOfMonth = sumValueFromBinary(dayOfMonthBin, 6);
dateTime.month = sumValueFromBinary(monthBin, 5);
dateTime.year = sumValueFromBinary(yearBin, 8);
return dateTime;
}
void Adapter::writeDateTime(DateTime dateTime) {
byte second = dateTime.second % 10;
byte minute = dateTime.minute % 10;
byte hour = dateTime.hour % 10;
byte dayOfWeek = setBinary(0, dateTime.dayOfWeek, 1);
byte dayOfMonth = dateTime.dayOfMonth % 10;
byte month = dateTime.month % 10;
byte year = dateTime.year % 10;
second = setFortyBinary(second, dateTime.second);
second = setTwentyBinary(second, dateTime.second);
second = setTenBinary(second, dateTime.second);
minute = setFortyBinary(minute, dateTime.minute);
minute = setTwentyBinary(minute, dateTime.minute);
minute = setTenBinary(minute, dateTime.minute);
hour = setTwentyBinary(hour, dateTime.hour);
hour = setTenBinary(hour, dateTime.hour);
dayOfMonth = setTwentyBinary(dayOfMonth, dateTime.dayOfMonth);
dayOfMonth = setTenBinary(dayOfMonth, dateTime.dayOfMonth);
month = setTenBinary(month, dateTime.month);
year = setEightyBinary(year, dateTime.year);
year = setFortyBinary(year, dateTime.year);
year = setTwentyBinary(year, dateTime.year);
year = setTenBinary(year, dateTime.year);
writeToModule(RX8010_SEC, second);
writeToModule(RX8010_MIN, minute);
writeToModule(RX8010_HOUR, hour);
writeToModule(RX8010_WDAY, dayOfWeek);
writeToModule(RX8010_MDAY, dayOfMonth);
writeToModule(RX8010_MONTH, month);
writeToModule(RX8010_YEAR, year);
}
/**
* FCT
*/
void Adapter::setFCTCounter(uint16_t multiplier, byte frequency) {
byte firstHalf = multiplier & 0b11111111;
byte secondHalf = multiplier >> 8;
writeToModule(RX8010_TCOUNT0, firstHalf);
writeToModule(RX8010_TCOUNT1, secondHalf);
writeFlag(RX8010_EXT, RX8010_TSEL0_POS, getValueFromBinary(frequency, RX8010_TSEL0_POS));
writeFlag(RX8010_EXT, RX8010_TSEL1_POS, getValueFromBinary(frequency, RX8010_TSEL1_POS));
writeFlag(RX8010_EXT, RX8010_TSEL2_POS, getValueFromBinary(frequency, RX8010_TSEL2_POS));
}
uint16_t Adapter::getFCTCounter() {
byte firstHalf = readFromModule(RX8010_TCOUNT0);
byte secondHalf = readFromModule(RX8010_TCOUNT1);
return firstHalf + (secondHalf << 8);
}
void Adapter::setFCTOutput(byte pin) {
if (pin > 1) {
writeFlag(RX8010_CTRL, RX8010_TIE_POS, 0);
} else {
writeFlag(RX8010_IRQ, RX8010_TMPIN_POS, pin);
writeFlag(RX8010_CTRL, RX8010_TIE_POS, 1);
}
}
void Adapter::enableFCT() {
writeFlag(RX8010_CTRL, RX8010_TSTP_POS, 0);
writeFlag(RX8010_CTRL, RX8010_TIE_POS, 1);
writeFlag(RX8010_EXT, RX8010_TE_POS, 1);
}
void Adapter::disableFCT() {
writeFlag(RX8010_EXT, RX8010_TE_POS, 0);
writeFlag(RX8010_CTRL, RX8010_TSTP_POS, 1);
}
bool Adapter::checkFCT() {
byte flag = readFromModule(RX8010_FLAG);
bool interrupted = getValueFromBinary(flag, RX8010_TF_POS) == 1;
if (interrupted) {
writeFlag(RX8010_FLAG, RX8010_TF_POS, 0);
}
return interrupted;
}
/**
* ALARM
*/
void Adapter::setAlarm(DateTime time, byte mode) {
byte minute;
byte hour;
if (time.minute == RX8010_ALARM_IGNORE) {
minute = RX8010_AL_DISABLED;
} else {
minute = time.minute % 10;
minute = setFortyBinary(minute, time.minute);
minute = setTwentyBinary(minute, time.minute);
minute = setTenBinary(minute, time.minute);
}
if (time.hour == RX8010_ALARM_IGNORE) {
hour = RX8010_AL_DISABLED;
} else {
hour = time.hour % 10;
hour = setTwentyBinary(hour, time.hour);
hour = setTenBinary(hour, time.hour);
}
writeToModule(RX8010_ALMIN, minute);
writeToModule(RX8010_ALHOUR, hour);
if (mode == RX8010_ALARM_MOD_WEEK) {
writeToModule(RX8010_ALWDAY, time.dayOfWeek == RX8010_ALARM_IGNORE ? RX8010_AL_DISABLED : time.dayOfWeek);
} else {
byte day;
if (time.hour == RX8010_ALARM_IGNORE) {
day = RX8010_AL_DISABLED;
} else {
day = time.dayOfMonth % 10;
day = setTwentyBinary(hour, time.hour);
day = setTenBinary(hour, time.hour);
}
writeToModule(RX8010_ALWDAY, day);
}
writeFlag(RX8010_EXT, RX8010_WADA_POS, mode == RX8010_ALARM_MOD_WEEK ? 0 : 1);
}
void Adapter::enableAlarm() {
writeFlag(RX8010_FLAG, RX8010_AF_POS, 0);
writeFlag(RX8010_CTRL, RX8010_AIE_POS, 1);
}
void Adapter::disableAlarm() {
writeFlag(RX8010_CTRL, RX8010_AIE_POS, 0);
writeFlag(RX8010_FLAG, RX8010_AF_POS, 0);
}
bool Adapter::checkAlarm() {
byte flag = readFromModule(RX8010_FLAG);
bool triggered = getValueFromBinary(flag, RX8010_AF_POS) == 1;
if (triggered) {
writeFlag(RX8010_FLAG, RX8010_AF_POS, 0);
}
return triggered;
}
/**
* TIME UPDATE INTERRUPT
*/
void Adapter::setTUIMode(byte mode) {
writeFlag(RX8010_EXT, RX8010_USEL_POS, mode);
}
void Adapter::enableTUI() {
writeFlag(RX8010_CTRL, RX8010_UIE_POS, 1);
}
void Adapter::disableTUI() {
writeFlag(RX8010_CTRL, RX8010_UIE_POS, 0);
}
bool Adapter::checkTUI() {
byte flag = readFromModule(RX8010_FLAG);
bool interrupted = getValueFromBinary(flag, RX8010_UF_POS) == 1;
if (interrupted) {
writeFlag(RX8010_FLAG, RX8010_UF_POS, 0);
}
return interrupted;
}
/**
* FREQUENCY OUTPUT
*/
void Adapter::enableFOUT(byte frequency, byte pin) {
switch (frequency) {
case 3:
writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 1);
writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 1);
break;
case 2:
writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 0);
writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 1);
break;
case 1:
writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 1);
writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 0);
break;
case 0:
default:
disableFOUT();
return;
}
writeFlag(RX8010_IRQ, RX8010_FOPIN0_POS, pin);
writeFlag(RX8010_IRQ, RX8010_FOPIN1_POS, 0);
}
void Adapter::disableFOUT() {
writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 0);
writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 0);
}
/**
*
* PRIVATE FUNCTIONS
*
*/
byte Adapter::readFromModule(byte address) {
Wire.beginTransmission(i2cAddress);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom((uint8_t)i2cAddress, (uint8_t) 1);
if (Wire.available()) {
return Wire.read();
}
return -1;
}
void Adapter::writeToModule(byte address, byte data) {
Wire.beginTransmission(i2cAddress);
Wire.write(address);
Wire.write(data);
Wire.endTransmission();
}
void Adapter::writeFlag(byte address, byte pos, byte value) {
byte addressValue = readFromModule(address);
addressValue = setBinary(addressValue, pos, value);
writeToModule(address, addressValue);
}
byte Adapter::getSingleBit(byte binary) {
for (byte i = 0; i <= 7; i++) {
if (binary >> i == 1) {
return i;
}
}
return 0;
}
byte Adapter::getValueFromBinary(byte binary, byte pos) {
return getValueFromBinary(binary, pos, 1);
}
byte Adapter::getValueFromBinary(byte binary, byte pos, byte val) {
return ((binary >> pos) & 1) == 1 ? val : 0;
}
byte Adapter::sumValueFromBinary(byte binary, byte length) {
byte sum = 0;
for (byte i = 0; i < length; i++) {
byte value;
if (i < 4 ) {
value = 1 << i;
} else {
value = 10 * (1 << (i - 4));
}
sum += getValueFromBinary(binary, i, value);
}
return sum;
}
byte Adapter::setEightyBinary(byte binary, byte val) {
if (val >= 80) {
return setBinary(binary, 7, 1);
}
return setBinary(binary, 7, 0);
}
byte Adapter::setFortyBinary(byte binary, byte val) {
if (val >= 40 && val < 80) {
return setBinary(binary, 6, 1);
}
return setBinary(binary, 6, 0);
}
byte Adapter::setTwentyBinary(byte binary, byte val) {
if ((val >= 20 && val < 40) ||
(val >= 60 && val < 80)) {
return setBinary(binary, 5, 1);
}
return setBinary(binary, 5, 0);
}
byte Adapter::setTenBinary(byte binary, byte val) {
if ((val >= 10 && val < 20) ||
(val >= 30 && val < 40) ||
(val >= 50 && val < 60) ||
(val >= 70 && val < 80) ||
(val >= 90 && val < 100)) {
return setBinary(binary, 4, 1);
}
return setBinary(binary, 4, 0);
}
byte Adapter::setBinary(byte binary, byte pos, byte flagVal) {
if (flagVal == 1) {
return binary | (1 << pos);
}
return binary & (~(1 << pos));
}
}

152
lib/RX8010SJ/RX8010SJ.h Normal file
View File

@@ -0,0 +1,152 @@
#ifndef RX8010SJ_ADAPTER
#define RX8010SJ_ADAPTER
#include "Arduino.h"
#include "Wire.h"
#define RX8010_FCT_FREQ_4096 0b000
#define RX8010_FCT_FREQ_64 0b001
#define RX8010_FCT_FREQ_1 0b010
#define RX8010_FCT_FREQ_1_60 0b011
#define RX8010_FCT_FREQ_1_3600 0b100
#define RX8010_FCT_OUT_IRQ1 0b01
#define RX8010_FCT_OUT_IRQ2 0b00
#define RX8010_FCT_OUT_OFF 0b10
#define RX8010_ALARM_IGNORE 0b11111111
#define RX8010_ALARM_MOD_MONTH 0b0
#define RX8010_ALARM_MOD_WEEK 0b1
#define RX8010_TUI_MOD_SEC 0b0
#define RX8010_TUI_MOD_MIN 0b1
#define RX8010_FOUT_FREQ_OFF 0b00
#define RX8010_FOUT_FREQ_1 0b01
#define RX8010_FOUT_FREQ_1024 0b10
#define RX8010_FOUT_FREQ_32768 0b11
#define RX8010_FOUT_IRQ1 0b01
#define RX8010_FOUT_IRQ2 0b00
namespace RX8010SJ {
#define RX8010_SEC 0x10
#define RX8010_MIN 0x11
#define RX8010_HOUR 0x12
#define RX8010_WDAY 0x13
#define RX8010_MDAY 0x14
#define RX8010_MONTH 0x15
#define RX8010_YEAR 0x16
#define RX8010_RESV17 0x17
#define RX8010_ALMIN 0x18
#define RX8010_ALHOUR 0x19
#define RX8010_ALWDAY 0x1A
#define RX8010_TCOUNT0 0x1B
#define RX8010_TCOUNT1 0x1C
#define RX8010_EXT 0x1D
#define RX8010_FLAG 0x1E
#define RX8010_CTRL 0x1F
/* 0x20 to 0x2F are user registers */
#define RX8010_RESV30 0x30
#define RX8010_RESV31 0x31
#define RX8010_IRQ 0x32
/* Default values for reseting the module */
#define RX8010_ADDR17_DEF_VAL 0xD8
#define RX8010_ADDR30_DEF_VAL 0x00
#define RX8010_ADDR31_DEF_VAL 0x08
#define RX8010_ADDR31_DEF_VAL 0x08
#define RX8010_IRQ_DEF_VAL 0x04
#define RX8010_CTRL_DEF_VAL 0x04
#define RX8010_VLF_POS 1
#define RX8010_TE_POS 4
#define RX8010_TSEL0_POS 0
#define RX8010_TSEL1_POS 1
#define RX8010_TSEL2_POS 2
#define RX8010_TIE_POS 4
#define RX8010_TMPIN_POS 2
#define RX8010_TF_POS 4
#define RX8010_STOP_POS 6
#define RX8010_TSTP_POS 2
#define RX8010_AIE_POS 3
#define RX8010_WADA_POS 3
#define RX8010_AF_POS 3
#define RX8010_USEL_POS 5
#define RX8010_UF_POS 5
#define RX8010_UIE_POS 5
#define RX8010_FSEL0_POS 6
#define RX8010_FSEL1_POS 7
#define RX8010_FOPIN0_POS 0
#define RX8010_FOPIN1_POS 1
#define RX8010_AL_DISABLED 0b10000000
struct DateTime {
byte second;
byte minute;
byte hour;
byte dayOfWeek; // Has to be set
byte dayOfMonth;
byte month;
byte year; // Two digits
};
class Adapter {
public:
// Constructor/destructor
Adapter(byte i2cSlaveAddr);
virtual ~Adapter();
// Methods
bool initAdapter();
bool initModule();
void resetModule(void);
void toggleGlobalStop(bool stopEnabled);
// Calendar
DateTime readDateTime(void);
void writeDateTime(DateTime dateTime);
// Fixed cycle interrupt
void setFCTCounter(uint16_t multiplier, byte frequency);
uint16_t getFCTCounter();
void setFCTOutput(byte pin);
void enableFCT();
void disableFCT();
bool checkFCT();
// Alarm
void setAlarm(DateTime time, byte mode);
void enableAlarm();
void disableAlarm();
bool checkAlarm();
// Time Update Interrupt
void setTUIMode(byte mode);
void enableTUI();
void disableTUI();
bool checkTUI();
// Frequency output
void enableFOUT(byte frequency, byte pin);
void disableFOUT();
private:
byte i2cAddress;
byte readFromModule(byte address);
void writeToModule(byte address, byte data);
void writeFlag(byte address, byte pos, byte value);
byte getSingleBit(byte binary);
byte getValueFromBinary(byte binary, byte pos);
byte getValueFromBinary(byte binary, byte pos, byte val);
byte sumValueFromBinary(byte binary, byte length);
byte setEightyBinary(byte binary, byte val);
byte setFortyBinary(byte binary, byte val);
byte setTwentyBinary(byte binary, byte val);
byte setTenBinary(byte binary, byte val);
byte setBinary(byte binary, byte pos, byte flagVal);
};
}
#endif

20
lib/RX8010SJ/library.json Normal file
View File

@@ -0,0 +1,20 @@
{
"name": "RX8010SJ",
"version": "1.03",
"repository":
{
"type": "git",
"url": "https://github.com/Wh1teRabbitHU/RX8010SJ"
},
"authors":
[
{
"name": "Wh1teRabbitHU",
"email": "ruszka.tamas@gmail.com",
"maintainer": true
}
],
"frameworks": "arduino",
"platforms": "espressif32",
"headers": "TFT_eSPI.h"
}