You've already forked TEF6686_ESP32
add support for hardware rtc, not sure if this version won't crash
This commit is contained in:
429
lib/RX8010SJ/RX8010SJ.cpp
Normal file
429
lib/RX8010SJ/RX8010SJ.cpp
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user