Spent the weekend getting ESP-Hosted running on an STM32 host, some notes

Oct 19, 2026 Last reply: 1 day ago 5 Replies
Jump to replies (5)

Finally got the wifi coprocessor idea working on my own board. STM32 running Zephyr as the host, an ESP32-C6 module on the other end doing the actual radio work, talking over the SPI bus. The upstream driver in Zephyr mostly just works, though I had to patch a couple of things locally around the handshaking lines before the transfers stopped stalling. Biggest surprise was how much the shared bus matters. I've got an ethernet chip hanging off the same SPI lines, and when both interfaces are alive the throughput drops hard. With one interface shut off during testing, the numbers look decent. Not the headline figure from the readme, but plenty for a home automation node pushing sensor data and handling commands. My advice for anyone trying this: start the bus clock low, get the control flow stable, then crank it up. I chased a phantom bug for two hours that turned out to be signal integrity at the higher clock. Dropping the traces shorter on the next board revision. Next step is getting the power consumption down so it can sleep properly between events.


I ran into almost the same boot problem on my setup, except mine was an ESP32-C3 hanging off an STM32F4. The handshake pins floated while the radio side was still powering up, and transfers would stall right after init until I added pull resistors and a short delay before the first command. Once that was solid I never touched it again, so I'd fix that kind of thing early rather than chase it later at high clock rates.

On the bus sharing, I ended up going a different route and putting the radio on its own serial link instead. I lose some peak speed but the ethernet side never gets starved, and for a node that mostly reports temperature every few seconds the difference doesn't matter day to day.

For the sleep part, what helped me most was letting the host buffer readings and only waking the coprocessor in bursts, plus turning off the radio between transfers instead of leaving it associated the whole time. My current draw dropped a lot once I stopped keeping the link warm out of habit. Also check what your regulator does at light load, mine wasted more idling than the radio itself did asleep.

I took a different route on the transport side. My host board is an STM32L4 running Zephyr, and I put the ESP32 module on its own UART instead of sharing anything with the other peripherals. Slower, no question, but the radio never fights with the display driver for bus time, so I skipped the whole clock speed and trace length headache entirely. The stock setup came up on the first boot and I have not touched it since. For a node that sends a reading every minute or two, the speed difference just doesn't show up in practice.

Still learning my way around Zephyr here so this might be a dumb question, but how do you handle updating the firmware on the coprocessor side? I've got a similar two-chip setup on my bench (Nucleo plus an ESP32 module) and right now I have to clip a programmer onto the module every time I rebuild, which gets old fast. Is there a way to push new firmware over the same SPI link from the host, or do you just live with the programmer? Would love to hear what your workflow looks like before I redo my whole flashing setup.

On the sleep side, one thing that bit me was the module itself refusing to enter its low power state til I checked what was actually holding it awake, which turned out to be a periodic keepalive the host was sending without realizing it. Worth scoping or logging the handshake lines while it should be idle, because something looking asleep on the host side can still be chatty on the wire. Also, if you're measuring current on the bench, don't trust a cheap multimeter at those levels, the averaging lies to you at low duty cycles.

Update: tried the pull resistors plus a delay before the first command, same as the C3 setup mentioned here, and the stalls at init are gone. Sleep is still the stubborn one though. That keepalive point hit close to home, I prolly have something similar. How did you actually track down what was sending it?

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required