More progress: I now have a Python program, running on the RPi to send data to the PIC32 Frame Driver. It was about 500 lines of new C code, plus 100-odd lines of Python, but I can now dynamically update frames.
It projected this little thing onto my notebook.
As predicted, the communications protocol was tricky. I wrote a 4 page document to describe it. The main complication is that the PIC32+MP Harmony approach to the SPI chip select (aka CS, aka Slave Select aka SS) line doesn't conveniently allow it to be used to define the end of packet, which makes handling variable-sized packets difficult.
As a result, the protocol I ended up with has fixed size command packets, and one of the commands says 'hey! there's data coming and it has length N'. The PIC32 then goes into a special mode where it waits for exactly that much data.
Here's the state diagram from the PIC32's point of view:
Also, inspired by Ben Eater's recent video about CRCs, I use 16 bit CRCs on all requests and responses. I used pycrc to both calculate CRCs in Python and to generate the C code for the PIC32. The PIC32 actually has built in facilities for CRC calculation, but I'm not clear on how to use it in conjunction with the MP Harmony SPI drivers.
Speaking of MP Harmony, I now have a whole rant about MP Harmony which I might polish up and publish.
The Frame Driver is now Almost Finished Enough that I could start building the clock daemon that will run on the Raspberry Pi. However, I think my next task will be to integrate the new, 505nm 50mW laser that is due to be delivered mid-next week.