Hacker News new | ask | show | jobs
by elipsitz 1048 days ago
I had a project where I needed predictable timing for I/O (reading a microprocessor’s bus at 1 MHz), and the ESP32 I was using just couldn’t do it reliably. Despite having a tight loop on a dedicated core with interrupts disabled, a loop iteration would sometimes take longer than a microsecond, causing it to miss some I/O. I was able to do it much more reliably with RP2040’s PIO.

For another project, the ESP32 family unfortunately doesn’t have a model that has both Bluetooth Classic (only the original ESP32 does) and USB host/device modes (only ESP32-S2 and ESP32-S3 do), so I’m thinking I’ll use the RP2040 as the main processor, with USB, and an ESP32 coprocessor. I really would rather just use a single ESP32, but that isn’t looking like an option here.

1 comments

> I had a project where I needed predictable timing for I/O (reading a microprocessor’s bus at 1 MHz), and the ESP32 I was using just couldn’t do it reliably. Despite having a tight loop on a dedicated core with interrupts disabled, a loop iteration would sometimes take longer than a microsecond, causing it to miss some I/O. I was able to do it much more reliably with RP2040’s PIO.

You should either:

* have a timer triggering interrupt that reads the data

* have a timer triggering DMA from the input port (if it was whole 8/16 bit) directly to memory

* trigger an interrupt with microprocessor's clock bus and read it directly.

Technically the 2nd one should have zero jitter (aside from clock itself).

Busy loop is the worst case on a microprocessor running RTOS to do the other stuff.

I’ve tested it. Interrupt to pin latency on ESP32 is more than 1 us so none of those solutions work if you need it to respond in <1 us.
Depends what poster above did. If they are just monitoring something at constant rate "just" low jitter" is enough.

No idea if ESP32 DMA engine can do it but common trick to get either constant rate input or output was just setting DMA engine to copy data from/to IO port to/from memory at constant rate.

I remember someone using it to drive some ridiculus number of RGB LEDs by basically using DMA to bitbang multiple chains of them at once

But yeah, using a simpler MCU as basically IO co-processor is usually simpler. I wish there was some kind of low pin bus that allowed to say directly map a part of memory to the chip on other side, akin to what RDMA does.

I wrote about what I was doing here: https://eli.lipsitz.net/posts/internet-connected-pinball/#mo...

I needed to detect writes to a bus that could happen at 1MHz, which involved reading the state of the bus multiple times per microsecond (based on the timing of the various signals). The jitter in the worst case was multiple microseconds (causing missed accesses), no matter what I tried.

I wasn’t able to use DMA on the ESP32 to help— perhaps it could have if I had tried to massage the problem a little bit more though.