Zigbee router and Bluetooth Proxy on Sengled G4 #146
Replies: 17 comments
Short answer: on your board the chip is no longer the blocker — but "Zigbee router + Bluetooth proxy" is two different architectures, and only one of them existsIn #108 the answer was no, and the reason was the part: the Lidl's EFR32MG1B has 256 kB flash / 32 kB RAM, below the 512 kB floor Silabs states for DMP. Your G4 carries an EFR32MG13P732F512IM32 — 512 kB flash / 64 kB RAM, which is the first board in this project that clears it. So the question deserved a real answer rather than a repeat of #108, and I went and built the thing. The path that exists: the multiprotocol RCP with a Bluetooth HCI endpointGecko SDK 4.5.0 — the same SDK this project builds every firmware from — ships I built it against your part this afternoon. Measured, not estimated:
So adding Bluetooth + FreeRTOS costs about 105 kB of flash and 20 kB of RAM, which fits on your MG13 with roughly 19 kB of RAM to spare — not generous, but real — and cannot fit on the Lidl part at all. #108's flash floor is now a measurement on this exact SDK rather than a citation. How the Bluetooth would actually reach Home AssistantThis is the half that usually kills the idea, and in our architecture it happens to land right. Home Assistant accepts exactly two kinds of Bluetooth source: a local adapter via BlueZ (D-Bus, BlueZ ≥ 5.43), or a remote proxy speaking the ESPHome or Shelly protocol. There is no "BLE over TCP:8888" in HA — port 8888 is a raw byte pipe to the radio's UART, and nothing in HA knows how to interpret a Silabs radio on the other end. So a BLE stream has to arrive as an HCI adapter. Which is precisely what the SDK provides, down to the service files. CPC endpoint 14 is (There is a second variant, The lucky part is where this runs. Every piece exists. What does not exist is anyone having wired them together on this hardware. What you would be giving up — the honest partIt is not a router. With the RCP architecture the box is a coordinator ( One radio, time-sliced. A Bluetooth proxy wants a high scan duty cycle; a Zigbee coordinator wants its receiver on. DMP arbitrates between them on a single radio, so Zigbee/Thread latency and retries will go up. That is a real cost, not a theoretical one. Your board has no RTS/CTS, and CPC has no software flow control (the reasoning is in #145). Today's G4 RCP link would already run with no flow control at all; a BLE advertisement stream — in a dense apartment building, easily thousands of advertisements per minute — would ride the same UART. That is exactly the traffic pattern that overruns a 16-byte FIFO. And the unknowns stack. Nobody has ever run the plain RCP on a G4, so this would be an unvalidated firmware on an unvalidated path. Worth knowing too: the sample app itself is What I would doIf what you want is Bluetooth coverage in Home Assistant, an ESP32 running ESPHome's But if what you want is to know whether a Series-1 multiprotocol RCP with a Bluetooth HCI endpoint actually works on this hardware — that is a genuinely open question, the firmware builds and fits on your part, the host tooling exists, and you are the only person with the board. If you want to try it, say so and I will wire up a |
The build script, if you want to try itAttached ( cd 2-Zigbee-Radio-Silabs-EFR32/25-RCP-UART-HW
BOARD=sengled-e39-g8c ./build_rcp_blehci.sh # default baud 115200
BOARD=sengled-e39-g8c ./build_rcp_blehci.sh 230400 # if the link proves solidIt follows the same contract as BOARD=sengled-e39-g8c ./flash_efr32.sh --firmware-file \
2-Zigbee-Radio-Silabs-EFR32/25-RCP-UART-HW/firmware/rcp-uart-802154-blehci-115200-none-sengled-e39-g8c.gbl <gateway-ip>I verified both boards before sending it: on your MG13 it builds and links (~231 kB flash, ~44.6 kB RAM), and on the Lidl's MG1B the script refuses the build outright rather than letting you discover the The default baud is 115200 on purpose — it is the SDK sample's own default, and this firmware has never run anywhere, on a link that (on your board) has no flow control and would now also be carrying Bluetooth advertisements. Raise it only once the link proves itself, and keep an eye on Host side, once it is flashed: Whatever happens — including "it does not come up" — post it here. Nobody has run this firmware on any board, so there is no prior art to check your result against, and that makes yours the first. |
|
@jnilo1 Thanks for the building script. My original goal was adding wireless relay ( zigbee router) and BT LE proxy to provide stable mesh network and receive nearby BT broadcast message ( such as BTHome) without involving the host (that running Homeassistant), and deploy multiple of them around house to provide better coverage. Running CPCd on host (especially multiple instances) may not be able to meet my goal consider SiLab multi-protocol app was deprecated in HA due to stability issue. I was wondering if RTL8196 has enough horse power to run cpcd locally to provide such functionality. |
|
Maybe a different question, can RTL8196e run BT proxy (similar to what ESP32 does over wifi)? |
Short answer to both: cpcd is not the bottleneck — the single radio is, and the RTL8196E has no Bluetooth of its ownLet me take your two questions in order, because the second one is the cleaner way to see why the first does not get you where you want. "Can the RTL8196E run cpcd locally?" — it can, and it still would not give you a routercpcd itself is light: it is a serial-to-socket multiplexer, and your G4 has 64 MB of RAM and a 400 MHz core, so running it on the box is not the problem. Nothing here is blocked on horsepower. The problem is what cpcd is connected to at each end. On the Zigbee side, cpcd feeds On the Bluetooth side, cpcd would feed "Can the RTL8196E be a BT proxy, like an ESP32 over WiFi?" — not as it stands, and the ESP32 is instructive about whyThe ESP32 works precisely because of two things the gateway does not have. First, its Bluetooth radio sits on the same chip as its host CPU. The RTL8196E has no Bluetooth of its own; the only BLE-capable radio in your box is the EFR32MG13 — the same multiprotocol part that already runs your Zigbee, with a single 2.4 GHz radio and antenna shared across Zigbee, Thread and BLE. That controller is real rather than theoretical: the To be clear about why that gap is not a small one: an equivalent would mean the EFR32 running a BLE firmware that streams advertisement reports to the host over CPC (the The wall behind both questionsOne EFR32, and three firmwares that never overlap the way you need. The standalone router relays the mesh autonomously but keeps any BLE on-chip — it exposes nothing to the host. The multiprotocol RCP exposes BLE to the host over CPC, but in RCP mode the Zigbee stack lives on the host as a coordinator, so it is not a router. The DMP SoC app is a Zigbee router and a BLE scanner at once, but its scan results are printed to the chip's own CLI and never leave it — there is no host link in those images. "Router + a proxy that reaches HA" is the one intersection none of them occupy, and moving cpcd onto the gateway does not change which firmware the radio runs. And your own observation cuts the same way. The Silicon Labs multiprotocol add-on that HA deprecated for stability is precisely the cpcd + zigbeed + DMP stack you would be leaning on to force this into one box. Avoiding it is not a compromise — it is the architecture HA itself now steers toward. What actually meets the goalSplit it across two single-purpose radios, which is what HA endorses and what stays stable:
That gives you exactly the deployment you described — several units, better coverage, no host in the loop doing the work — without betting it on the one stack HA walked away from, and without a single-box BLE bridge that would be new, unvalidated software on a link that cannot carry the traffic. |
|
Thanks for your detailed explanation and suggestion.
|
Two answers — and your read on the second one is more right than I gave it credit for last roundTaking your points in order. The WiFi objection is fair — but an ESP32 proxy does not require WiFiYou are right that an ESP32 running WiFi adds a 2.4 GHz emitter next to your Zigbee and BLE, and wanting to avoid that is reasonable. But the ESPHome proxy does not need WiFi: ESPHome has an On the DMP idea — the scan output already reaches the gateway's UARTHere your instinct is sound, and better than the way I framed it. I looked at the actual sample. The "key part" — the firmware — is small in one place and unbuilt everywhere elseTwo honest qualifications, because the plumbing being there is not the same as the job being done. First, the small part. As shipped, that handler prints only the sender's address type and its six-byte MAC — it throws the advertisement payload away. BTHome sensor values live in the service-data bytes of that payload ( Second, the parts that are not small. This is a DMP SoC image that has never been built in this project. The DMP floor is 512 KB, so it is G4-only — the Lidl's 256 KB MG1B will not hold it — and even on the MG13 the fit has to be measured, because the sample also carries a full BLE peripheral: an iBeacon, an Eddystone beacon, and a connectable GATT "light" service, none of which a proxy needs and all of which you would want to strip. And the coexistence cost is real and permanent: one radio and one antenna, time-sliced between Zigbee routing and BLE scanning. The sample's own scan setting is a 50% duty cycle — half the airtime to BLE. You would tune that down and trade BLE reception for Zigbee stability, but that tradeoff is inherent to one radio doing two jobs, and it is precisely the shared-radio behavior behind the Silicon Labs multiprotocol stack that Home Assistant deprecated. Your own observation and this design point at the same thing. The daemon is the easy half — but aim it at MQTT, not the ESPHome APIThe daemon you would write on the RTL8196E is the straightforward part, with one steer: do not try to speak "esphome format." The ESPHome native API is protobuf over TCP behind a Noise handshake — a lot of surface to reimplement for no gain here. Since your daemon can decode the BTHome advertisement itself, just publish the decoded values over MQTT; Home Assistant ingests those natively through MQTT discovery, with no BlueZ anywhere in the path. That is a small, well-bounded program, and it is the piece Claude can genuinely help you write. Where I landI am not going to build the DMP firmware. It is a new, unvalidated image, and I would be guessing at both its fit on the MG13 and its coexistence behavior on your one working radio — and unlike the daemon, a bad radio build is the part that can take a satellite off the air. But you are the person who can actually try it: you have the board, you now have the hardware bootloader entry and the 2.4.3 loader from #148 as a recovery path, and the idea is coherent. If you go for it, the three pieces are exactly the two source edits above ( And if you would rather not stake a satellite on an unbuilt image, the lowest-risk build that still matches everything you asked for — wired, no host doing the radio work, several units around the house — is two single-purpose radios per unit: a G4 flashed with plain |
|
@jnilo1 You made a lot of good points. As you said, sharing one radio between zigbee/BLE might not be a good idea. Originally, I thought SiLab may has some secret sauce on RF frontend to enable both protocols concurrently. However, based upon your inputs that it uses TDM, having two separate radios makes more sense to me. I would like run a different idea by you. Since ttyS0 is mainly for initial bring up and console debugging, it is less useful on a product unit, especially ssh is enabled. Do we think it is feasible to have ESP32 device sending BLE information to the hub's ttyS0, then hub converts it ( or maybe ESP32 itself can do the conversion) and sends to a MQTT server? The goal is to reduce number of boxes and share as much as resources as possible ( for example, and a wired esp32 requires another ethernet port) and when ERF32 running in router mode, RTL8196e is pretty much idle all the time. |
|
@jnilo1 Quick update on my progress. Instead of using MQTT for BLE, I was able to prototype Esphome API via UART ( a custom component uart_api was created) using ESP32C3 + CH9121. Next step is to replace CH9121 with RTL8196e ttyS0. Could you please kindly provide your inputs on the followings:
Do you see any other issue using ttyS0? Thanks |
Both questions are a yes — but the list of things that talk on ttyS0 is longer than the two you found, and one of them listens rather than printsFirst on the design, since your last two messages moved it: replacing the CH9121 with the gateway is a better fit than the MQTT converter I suggested, because it asks the RTL8196E to do no protocol work at all. Your 1. What else has output on ttyS0 — and one thing that has inputThe stage-2 bootloader prints, and it also reads. The output half is what you found: The exposure is narrower than it first looks, and it is worth knowing exactly how narrow. Stage-1 Kernel early printk, which Deleting A getty is respawning on it. Everything the init scripts print. Panics and oopses. They follow the console, so they go quiet too, and that is the real cost of this change rather than a detail. 2. Yes,
|
|
@jnilo1 Thanks a lot for your thorough analysis of ttyS0 👍 ! The PCB trace of ttyS1 on G4 is not easily modifiable. I have a different idea and like to run by you. The basic idea is holding ESP32 in reset mode until later S* stage. Here are some details:
Impacts of new proposal:
What do you think? any suggestion is highly appreciated! |
The reset gate is a good idea — it solves the bootloader hazard, but there is still one ttyS0 problem to solveI think the architecture is feasible, and holding the ESP32 in reset is a much better arrangement than leaving its TX connected and active from power-on. It preserves the useful part of ttyS0 during recovery: while the ESP32 is held in reset, a USB-UART adapter can still see the RTL boot messages and send ESC to the loader. There are two corrections I would make before building it, though. 1. Hold the shared reset from the RTL stage-2 loader, not only from
|
|
@jnilo1 Thanks a lot for your detailed reply and insight as usual. For supply voltage concern you bought, my plan was not to tap off 3.3v power supply for ESP32C3, but use 5v supply, and ESP32C3 board itself has a 3.3v regulator. My original plan was this:
Thanks! |
Your unbind/rebind idea can work — the error is the driver/device name, and there is one extra console stepUsing the 5 V rail and the ESP32-C3 board's own regulator removes my concern about loading the gateway's 3.3 V rail. Keep the grounds common and add local decoupling at the ESP32 board, but the power architecture itself is fine. I went through BusyBox init and the 8250 code for both current kernel trees. Your two ideas are possible, with some details that matter. 1.
|
|
@jnilo1 Thanks for the additional info! the not quite match your expectation. Also there is no A different question, if esp32c3 works on G4, do you plan support the build, or it should live in forked repo? Thanks |
|
Thanks — your result explains the mismatch, and my previous sysfs advice was wrong in two ways.
So your For ttyS0 on this board, the physical device and driver can be addressed directly: PLAT_DEV=18002000.serial
PLAT_DRV=/sys/bus/platform/drivers/of_serial
ls -l "$PLAT_DRV"Before changing anything, that directory should contain # Run over SSH, with the ESP32 still held in reset and script I/O already
# redirected away from /dev/console.
echo "$PLAT_DEV" > "$PLAT_DRV/unbind"
echo "$PLAT_DEV" > "$PLAT_DRV/bind"
# Wait until ttyS0 has reappeared, then remove its newly registered
# kernel-console role before the UART bridge opens it.
while [ ! -e /sys/class/tty/ttyS0/console ]; do sleep 1; done
echo 0 > /sys/class/tty/ttyS0/console
cat /sys/class/tty/ttyS0/console # must report NPlease treat this as an experimental recovery-sensitive operation: do it over SSH, keep the ESP32 in reset until the bridge is armed, and be prepared to reboot if rebind or console removal fails. I would first post the output of the read-only On repository support for the ESP32-C3 modification: I do not plan to add or support this integration in the project. It is an interesting way to obtain a wired ESPHome Bluetooth proxy while leaving the EFR32 as a standalone Zigbee router, but it is no longer a firmware option for an otherwise stock G4. It is a hardware modification with several tightly coupled maintenance points: shared reset behaviour in both boot stages, the ttyS0 console handover, conditional getty/inittab handling, two UART bridges, special EFR32 and ESP32 flashing sequences, an ESPHome custom component, and electrical differences between ESP32-C3 boards. Most importantly, I do not have this modified hardware, so I could not reproduce failures or regression-test it across bootloader, rootfs, kernel and ESPHome changes. Adding it to the main support matrix now would imply a level of maintenance and validation that the project cannot provide. If you choose to pursue this modification, its implementation, testing and maintenance would therefore need to remain on your side. I can clarify how the existing RTL8196E firmware behaves, as above, but I cannot take on developing or debugging the complete ESP32-C3 integration. I would therefore treat it as a personal hardware experiment, outside this project's scope. If you choose to build it, please understand that this does not imply a future commitment to incorporate or maintain it in this repository. |
|
@jnilo1 Thanks for the info! The unit immediately panic after issuing Do you have any idea of the root cause? |
Uh oh!
There was an error while loading. Please reload this page.
@jnilo1
Based upon your discussion in #108. It seems that DMP can be enabled on ERF32MG13 (used in Sengled G4). I am wondering if running Zigbee Router + Bluetooth Proxy (listen for Bluetooth Low Energy (BLE) signals and relay them to HA via port 8888) is possible. Do you have any insight? Thanks
All reactions