• Picking a Microcontroller

    Nolan Hergert07/12/2025 at 20:35 0 comments

    Working on a portable project like this requires the elegant resolving of a lot of conflicting constraints. Long story short, I bought a few breakout boards of the STM32G03 series, thinking that the ultra-low shutdown current would be useful (<50 nA!), the DMA seemed reasonably fast and well supported, the documentation and app notes were excellent, and that I would need ECC or parity checking on my memory (for robustness). Turns out a lot of those assumptions were wrong!

    This project requires reading from a camera quickly, thresholding that data, and inverting that information for display on the LCD lenses. This involves very deterministic read timing from GPIO for the camera parallel data interface, maybe doing a minimal amount of calculation, storing that data off to SRAM, then reading back from SRAM when needed to do some more algorithm work, then writing out to GPIO again for the LCD interface.

    I wanted to use DMA to do the copying from GPIO to SRAM and vice versa. But, as I found out after much frustration, the GPIO on most Cortex-M0+ chips is not accessible via DMA! Unfortunately, the only reference to this is in the system diagram and an error bit getting set when you do a DMA transfer with GPIO. 

    https://community.st.com/t5/stm32-mcus-products/dma-transfer-error-for-gpio-on-stm32g031/m-p/811559#M280713

    When instead I tried to do the reading of data myself as suggested, the code that I was writing had to do work *and* have precision timing (it can't drift relative to the timer clock I am providing the camera). It is hard to do this, and IMO requires hand-writing it in assembly to make sure the periodicity in when it reads GPIO is aligned to a multiple of the camera pixel clock. While I could in theory extend the back or front porch timings for a row to allow for the CPU to do "reading" work, then do "algorithm" work, both of the camera chips I was using weren't acting as I was expecting in this regard.

    It feels a lot easier to have a system where the concerns are decoupled. DMA is periodically reading from GPIO into a SRAM buffer "A" and is triggered by a timer periodically. If it's delayed a few <internal> clock cycles, no big deal, as long as it starts the process at a periodic time. Meanwhile the CPU is operating on the previous row (SRAM buffer "B") and has no concerns about the periodicity of when exactly it executes reads/writes and I can keep that work in a higher level of abstraction and readability. As long as it completes on time (within the row time), it's good. There's some bus contention issues that I hope won't be a problem, we'll see. 

    Another reason to use the STM32 chips was the generous ECC correction and parity checking on flash and SRAM, respectively. When I looked at CH32V* chips, I noticed they neglected adding these hardware features (but still kept things like two watchdog timers or hardware CRC). It turns out that bit flipping shouldn't occur that often in practice (at least terrestrially), so if you can periodically (once per day?) checksum your data and if you have a backup to recover from, you should be good...? 

    And on shutdown current...I'm not sure about this one yet. While it is preferable to be able to leave the device out and not worry about leakage, 500nA is probably fine?