The past month has been spent refactoring the STM32 code. I had initially implemented the panel on top of the Arduino framework as this offers very rapid development… to a point. There were significant issues that needed resolution, e.g. the WS2812 LED driver was running in userspace (ab)using the SPI driver. This was interrupted by I2C messages resulting in signal corruption and weird LED behaviour.
I started to reimplement using HAL (which worked) but have a problem with HAL. It relies on custom code that is created by CubeMX IDE for each project. CubeMX does not (easily) run on arm64 Linux. So I moved to libopencm3 which is a light wrapper for bare metal register access. This has been slow going due to the documentation being sparse and example code being processor specific which makes it difficult to locate and invariably in need of modification. It also doesn’t help that libopencm3 implements the same functions in different ways for different processors which is kind of the opposite to what you expect from a framework.
I think I am on the other side of the learning curve, mostly understanding the framework and the STM32. I have WS2812 driver working, using DMA to massively reduce the CPU load.
I am considering moving back to using STM32F103 (from STM32F072). The features of the F072 that make it attractive are not actually being used and the F103 has more RAM and is available on the Bluepill development board (of which I have several) allowing ad-hoc design and testing before committing to PCB fabrication.
I am also considering moving from I2C bus to CAN. It provides many advantages including being more robust in electrically hostile environments (like on stage with lighting, etc ), supports faster bitrate and may reduce the quantity of connectors required. The data footprint is higher but I think the net difference of data throughput will be negligible. Panels will be able to initiate messages which may reduce the polling requirement and allows this same bus to be used for panel detection, removing the 1-wire detection bus and probably the reset signal. The ribbon bus could be reduced to 6 pins which makes it easier to build smaller panels. CAN does require an extra transceiver chip and the F103 is a bit more expensive but I think it can still be done within budget and offers significant advantage. I can always revisit the chip selection if I need to economise later.
I would probably interface the Pi with a STM32 in the Brain via I2C (or a custom interface if throughput is a problem). That STM32 would talk to the rest of the system via the CAN which is implemented in hardware on the STM32 but would require a software driver if driven directly by the RPi.
I am also working on a firmware update mechanism. I had intended to use the STM32F072’s bootloader feature to update firmware via I2C (not available in STM32F103) but it wasn’t viable (requiring control of each panels’ boot pin) so I am back to a previous idea of writing a custom bootloader that will allow firmware update via CAN, and runtime code selection based on firmware version (or some other rule). It reduces the available flash memory a lot. We need equal partitions for 2 versions of the runtime code (current and next/previous) to allow rollback of failed update plus a partition for the bootloader. I think this is fine but will choose a larger flash option, e.g. 128KB.
I haven’t taken my foot off the pedal and am still working hard on this project but the tangible changes are not yet material. I had hoped to order some more panels by now but these changes will render the existing design (and hence panels) useless (incompatible) so let’s get this bit right before moving on. (The old I2C panels may find their way into a Zynthian build…)