-
Notifications
You must be signed in to change notification settings - Fork 639
Muzi Works R1 Neo support #2007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,197 @@ | ||||||||||||||||||||||||||||||||||||
| #include "RTC_RX8130CE.h" | ||||||||||||||||||||||||||||||||||||
| #include "RTClib.h" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| bool RTC_RX8130CE::stop(bool stop) { | ||||||||||||||||||||||||||||||||||||
| write_register(0x1E, stop ? 0x040 : 0x00); | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
| 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; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
Comment on lines
+16
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per the RX8130CE datasheet init flowchart (fig. 42, page 55), after a power loss the VLF flag (bit 1 of Flag Register 0x1D) indicates clock data may be unreliable. A dummy read followed by a VLF check should happen before the register configuration. See also ArtronShop/ArtronShop_RX8130CE#1
Suggested change
|
||||||||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||||||||
| * 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; | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The RX8130CE WEEK register uses a bitmap format (bit 0 = Sun, bit 1 = Mon, ..., bit 6 = Sat), not BCD. For example Wednesday (
Suggested change
|
||||||||||||||||||||||||||||||||||||
| 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); | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same bitmap issue as
Suggested change
|
||||||||||||||||||||||||||||||||||||
| 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) { | ||||||||||||||||||||||||||||||||||||
khudson marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
| 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]; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+169
to
+171
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||||||||||
khudson marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
| 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; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| #include <Arduino.h> | ||
| #include <Wire.h> | ||
|
|
||
| #include "R1NeoBoard.h" | ||
|
|
||
| #ifdef NRF52_POWER_MANAGEMENT | ||
| // Static configuration for power management | ||
| // Values set in variant.h defines | ||
| const PowerMgtConfig power_config = { | ||
| .lpcomp_ain_channel = PWRMGT_LPCOMP_AIN, | ||
| .lpcomp_refsel = PWRMGT_LPCOMP_REFSEL, | ||
| .voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK | ||
| }; | ||
|
|
||
| void R1NeoBoard::initiateShutdown(uint8_t reason) { | ||
| // Disable LoRa module power before shutdown | ||
| MESH_DEBUG_PRINTLN("R1Neo: shutting down"); | ||
| digitalWrite(SX126X_POWER_EN, LOW); | ||
khudson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (reason == SHUTDOWN_REASON_LOW_VOLTAGE || | ||
| reason == SHUTDOWN_REASON_BOOT_PROTECT) { | ||
| configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel); | ||
| } | ||
|
|
||
| enterSystemOff(reason); | ||
| } | ||
| #endif // NRF52_POWER_MANAGEMENT | ||
|
|
||
| void R1NeoBoard::begin() { | ||
| // R1 Neo peculiarity: tell DCDC converter to stay powered. | ||
| // Must be done as soon as practical during boot. | ||
|
|
||
| pinMode(PIN_DCDC_EN_MCU_HOLD, OUTPUT); | ||
| digitalWrite(PIN_DCDC_EN_MCU_HOLD, HIGH); | ||
|
|
||
| // R1 Neo peculiarity: Tell I/O Controller device is on | ||
| // Enables passthrough of buttons and LEDs | ||
|
|
||
| pinMode(PIN_SOFT_SHUTDOWN, OUTPUT); | ||
| digitalWrite(PIN_SOFT_SHUTDOWN, HIGH); | ||
|
|
||
| NRF52BoardDCDC::begin(); | ||
|
|
||
| // button is active high and passed through from I/O controller | ||
| pinMode(PIN_USER_BTN, INPUT); | ||
|
|
||
| pinMode(PIN_BUZZER, OUTPUT); | ||
| digitalWrite(PIN_BUZZER, LOW); | ||
|
|
||
| // battery pins | ||
| pinMode(PIN_BAT_CHG, INPUT); | ||
| pinMode(PIN_VBAT_READ, INPUT); | ||
|
|
||
| Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL); | ||
|
|
||
| Wire.begin(); | ||
|
|
||
| pinMode(SX126X_POWER_EN, OUTPUT); | ||
| #ifdef NRF52_POWER_MANAGEMENT | ||
| // Boot voltage protection check (may not return if voltage too low) | ||
| // We need to call this after we configure SX126X_POWER_EN as output but before we pull high | ||
| checkBootVoltage(&power_config); | ||
| #endif | ||
| digitalWrite(SX126X_POWER_EN, HIGH); | ||
| delay(10); // give sx1262 some time to power up | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
begin()return value is ignored. Unlikely to fail sincei2c_probe()already confirmed the device is present, but worth checking defensively to match the pattern of the other RTCs above.