Muzi Works R1 Neo support#2007
Conversation
Support for R1 Neo hardware. New variant and baseboard class. * Known issues: - power management is not currently supported - power off via long button press is not implemented Add support for Epson Seiko RX8130CE I2C Real-time clock.
| 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; |
There was a problem hiding this comment.
The RX8130CE WEEK register uses a bitmap format (bit 0 = Sun, bit 1 = Mon, ..., bit 6 = Sat), not BCD. For example Wednesday (tm_wday=3) should be 0x08 (bit 3), but bin2bcd(3) gives 0x03 (bits 0+1 = Sun+Mon). The ArtronShop library has the same bug - opened a fix upstream: ArtronShop/ArtronShop_RX8130CE#1
| buf[4] = bin2bcd(t->tm_wday) & 0x07; | |
| buf[4] = (1 << t->tm_wday) & 0x7F; |
| 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); |
There was a problem hiding this comment.
Same bitmap issue as setTime() — the WEEK register is a bitmap, not BCD. This needs to find which bit is set and convert it back to an index. See ArtronShop/ArtronShop_RX8130CE#1
| t->tm_wday = bcd2bin(buff[3] & 0x07); | |
| // WEEK register is a bitmap (bit 0=Sun, bit 1=Mon, ..., bit 6=Sat) | |
| uint8_t wday_bits = buff[3] & 0x7F; | |
| t->tm_wday = 0; | |
| while (wday_bits >>= 1) t->tm_wday++; |
| if (i2c_probe(wire, RX8130CE_ADDRESS)) { | ||
| MESH_DEBUG_PRINTLN("RX8130CE: Found"); | ||
| rtc_8130.begin(&wire); | ||
| rtc_8130_success = true; | ||
| MESH_DEBUG_PRINTLN("RX8130CE: Initialized"); | ||
| } |
There was a problem hiding this comment.
Nit: begin() return value is ignored. Unlikely to fail since i2c_probe() already confirmed the device is present, but worth checking defensively to match the pattern of the other RTCs above.
| if (i2c_probe(wire, RX8130CE_ADDRESS)) { | |
| MESH_DEBUG_PRINTLN("RX8130CE: Found"); | |
| rtc_8130.begin(&wire); | |
| rtc_8130_success = true; | |
| MESH_DEBUG_PRINTLN("RX8130CE: Initialized"); | |
| } | |
| if (i2c_probe(wire, RX8130CE_ADDRESS)) { | |
| MESH_DEBUG_PRINTLN("RX8130CE: Found"); | |
| rtc_8130_success = rtc_8130.begin(&wire); | |
| if (rtc_8130_success) { | |
| MESH_DEBUG_PRINTLN("RX8130CE: Initialized"); | |
| } | |
| } |
| if (!i2c_dev->begin()) { | ||
| return false; | ||
| } | ||
|
|
There was a problem hiding this comment.
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
| if (!i2c_dev->begin()) { | |
| return false; | |
| } | |
| if (!i2c_dev->begin()) { | |
| return false; | |
| } | |
| // Dummy read per init flowchart (page 55) | |
| read_register(0x1D); | |
| // Check VLF flag (bit 1 of Flag Register 0x1D) — indicates data loss | |
| uint8_t flags = read_register(0x1D); | |
| if (flags & 0x02) { | |
| // VLF set: clock data unreliable after power loss, clear flag | |
| write_register(0x1D, flags & ~0x02); | |
| } | |
| #define PIN_VBAT_READ (31) // P0.31 (39) ADC_VBAT | ||
| #define PIN_BAT_CHG (34) // P1.02 (26) BAT_CHG_STATUS | ||
|
|
||
| #define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000) |
There was a problem hiding this comment.
The Meshtastic variant uses an ADC multiplier of 1.667, which was calibrated by simon-muzi via a 15-hour discharge test (Meshtastic commit f4e260e0f). Accounting for nRF52's 3.6V default AREF that works out to 3.6 * 1.667 * 1000 = 6001.2. The current formula gives ~6159 which is about 2.6% off. Could you verify with a multimeter to confirm which value is closer?
| #define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000) | |
| #define ADC_MULTIPLIER (3.6 * 1.667 * 1000) |
|
|
||
|
|
||
| bool RTC_RX8130CE::stop(bool stop) { | ||
| write_register(0x1E, stop ? 0x040 : 0x00); |
There was a problem hiding this comment.
| write_register(0x1E, stop ? 0x040 : 0x00); | |
| write_register(0x1E, stop ? 0x40 : 0x00); |
| for (int i = 1; i <= len + 1; i++) { | ||
| buf[i] = value[i - 1]; | ||
| } |
There was a problem hiding this comment.
| for (int i = 1; i <= len + 1; i++) { | |
| buf[i] = value[i - 1]; | |
| } | |
| for (int i = 1; i <= len; i++) { | |
| buf[i] = value[i - 1]; | |
| } |
| #define PIN_QSPI_SCK (3) // P0.03 (29) BUZZER | ||
| #define PIN_QSPI_CS (26) // P0.26 (34) USER_BUTTON | ||
| #define PIN_QSPI_IO0 (30) // P0.30 (33) MCU_SIGNAL | ||
| #define PIN_QSPI_IO1 (29) // P0.29 (32) SOFT_SHUTDOWN | ||
| #define PIN_QSPI_IO2 (28) // P0.28 (31) BLU_LED_RAK | ||
| #define PIN_QSPI_IO3 (2) // P0.02 (30) GPS_PPS |
There was a problem hiding this comment.
MeshCore convention is PIN_GPS_TX = GPS module's TX output = MCU receives, so PIN_SERIAL1_RX should map to PIN_GPS_TX (and vice versa). Every other nRF52 variant does it that way.
Also, the PIN_QSPI_* block and EXTERNAL_FLASH_* defines should be removed — the R1 Neo has no QSPI flash, and those defines alias active GPIOs (buzzer, user button, soft shutdown, LED, GPS PPS). If the BSP ever initializes the QSPI peripheral it would reconfigure those pins.
| #define PIN_QSPI_SCK (3) // P0.03 (29) BUZZER | |
| #define PIN_QSPI_CS (26) // P0.26 (34) USER_BUTTON | |
| #define PIN_QSPI_IO0 (30) // P0.30 (33) MCU_SIGNAL | |
| #define PIN_QSPI_IO1 (29) // P0.29 (32) SOFT_SHUTDOWN | |
| #define PIN_QSPI_IO2 (28) // P0.28 (31) BLU_LED_RAK | |
| #define PIN_QSPI_IO3 (2) // P0.02 (30) GPS_PPS | |
| #define PIN_SERIAL1_RX (PIN_GPS_TX) // MCU receives <- GPS transmits | |
| #define PIN_SERIAL1_TX (PIN_GPS_RX) // MCU transmits -> GPS receives |
|
Where are we at with this? Waiting for more feedback? Thanks again! Can't wait! |
|
Hello. Wondering what needs to be done to merge this? I'm excited to get the r1 neo on meshcore. |
|
Just waiting for it to be merged at this point. Hopefully @ripplebiz or someone can give it a once over and push it through.
… On Mar 31, 2026, at 4:41 AM, mem101296 ***@***.***> wrote:
mem101296 left a comment (meshcore-dev/MeshCore#2007)
Hello. Wondering what needs to be done to merge this? I'm excited to get the r1 neo on meshcore.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Co-authored-by: Wessel <wessel@weebl.me>
Co-authored-by: Wessel <wessel@weebl.me>
| if (i2c_probe(wire, RX8130CE_ADDRESS)) { | ||
| MESH_DEBUG_PRINTLN("RX8130CE: Found"); | ||
| rtc_8130.begin(&wire); | ||
| rtc_8130_success = true; | ||
| MESH_DEBUG_PRINTLN("RX8130CE: Initialized"); | ||
| } |
| #define BATTERY_SAMPLES 8 | ||
|
|
||
| uint16_t getBattMilliVolts() override { | ||
| MESH_DEBUG_PRINTLN("R1Neo: Sampling battery"); |
There was a problem hiding this comment.
probably don't need this debug line
Hey @khudson, thanks for the PR. Sorry for being so slow at reviewing it. Have been working on lots of other things at once. Originally when I looked at it, I saw a bunch of review comments from @weebl2000 that had gone unanswered. Was waiting to see any movement on those. Most of the changes are variant specific, except for the RTC clock stuff, so if there's any issues it should only affect the new variant. I added some minor comments, that would be good to resolve, but will merge now anyway so things can move forward :) Note: I also merged in a couple of minor changes related to the Thanks for contributing! |
|
Thanks - I had mainly just gotten frustrated at the pushy, AI-generated code review and my inability to test these commits before merge. I had asked weebl2000 to submit PRs to my branch directly, without conflicts, so I could test them locally and that hadn't been done. A lot of the review points to code paths that aren't even in use, so it's not particularly important to address them now before the code gets merged.Thanks - I look forward to seeing this live in the next release!On Apr 1, 2026, at 4:35 AM, Liam Cottle ***@***.***> wrote:liamcottle left a comment (meshcore-dev/MeshCore#2007)
Just waiting for it to be merged at this point. Hopefully @ripplebiz or someone can give it a once over and push it through.
Hey @khudson, thanks for the PR. Sorry for being so slow at reviewing it. Have been working on lots of other things at once. Originally when I looked at it, I saw a bunch of review comments from @weebl2000 that had gone unanswered.
Was waiting to see any movement on those. Most of the changes are variant specific, except for the RTC clock stuff, so if there's any issues it should only affect the new variant.
I added some minor comments, that would be good to resolve, but will merge now anyway so things can move forward :)
Thanks for contributing!
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Resolves #1275.
Adds support for Muzi Works R1 Neo device.
Adds new RTC: Epson Seiko RX8130CE.
All features on the board currently work with the exception of software shutdown. Workaround: Hold the button for 8 seconds to put the unit into DFU mode with the USB cable disconnected. The device will shut down.