In our previous post, Vlaya and I said that when a full rotation completion triggers an interrupt simultaneously with a flash interrupt, the order in which the HAL API IRQ Handler checks and handles each source of the interruption (both share the same IRQ line to the processor, and they set flags that the IRQ Handler must inspect to determine what happened) made it so that the rotation was handled first, delaying the flash handling.
To solve this, we decided to check the flags for the flash directly in the rotation callback, and trigger the flash before handling the rotation completion if they were set.
But it turns out that the reason all these delays were noticeable in the first place was because we forgot to remove debug prints from the IRQs. Without them, the delays becomes so small as to be unnoticeable again. Oops ?
So after all there’s no need to check the flags ourselves and we can just let the HAL IRQ Handler handle everything it its own order.
In order to take as little time as possible to send the SPI “FLASH” frame, we used the Low Level API Drivers generated by STM32CubeMX instead of the Hardware Abstraction Layer. That way, sending the frame is reduced to writing two bytes to a memory-mapped register, and enabling the SPI and other configurations can be done beforehand, which the HAL API doesn’t provide for.
That also means we’ll have to also handle the other, less time sensitive SPI transmissions manually via the Low Level Driver, except if we find a way to mix both APIs.
We measured the SPI jitter with our python script (after exporting the data from the Saleae software), and here are the results for the three SPI buses we use:
- Maximum SPI3 latency : 10.94000µs
- Minimum SPI3 latency : 5.9599µs
- Maximum SPI3 jitter: 4.98000µs
- Maximum SPI4 latency : 10.92000µs
- Minimum SPI4 latency : 5.80000µs
- Maximum SPI4 jitter: 5.11999µs
- Maximum SPI6 latency : 11.08000µs
- Minimum SPI6 latency : 5.98000µs
- Maximum SPI6 jitter: 5.09999µs
The latency evoked here is the amount of time elapsed between the timer triggering and the SPI “FLASH” frame being sent on the SPi bus. We didn’t measure the latency between each SPI, but the maximum and minimum latency measured ensures the latency between each SPI is at most 5µs, which is more than small enough for us: it represents a 0.05 degree angle when the Phyllo spins at 30 RPS.
Now we need to integrate this with our image generation code, and send the color configurations for each LED in between the flashes.
Stay tuned 🙂