Looks like this weekend is the time to try and hookup the Neopixels. There have been a bunch of small changes that I ended up making to get things working as efficiently as possible.
So I got a little over zealous in the belief that I had infinite processing power. The SPI bus is running at 2.4 MHz, so each bit is 417 ns. 8 * 417ns = 3.33us. Hmmm, that’s pretty darn fast come to think of it. Assuming 1.5 assembly instructions/clock (RISC based processor with most stuff 1 cycle, but loading, storing, and pushing info onto the stack takes more cycles. Branches are particularly long since the pipeline may need to be flushed), that means the processor has about 53 instructions. In a tight loop the processor was not able to keep the FIFO filled.
The processor is only running at 24MHz (the default), so let’s kick that up to 48MHz which is what the processor can run. That made it so the processor could keep the FIFO full without an issue. The dream of dynamically determining pixel color is probably not possible without hand coding assembly. It is much simpler to allocate the required memory at initialization, and update the RAM on the periodic timer.
Kept thinking about what else could be done. The TX FIFO for the SCB can be changed to 16 bits wide instead of 8 bits wide. This is somewhat annoying since each pixel takes 9 bytes of data, and now pixels must cross a FIFO write boundary. Last optimization is using the TX FIFO level to kick off the processing. If the level is set to 4, there are 5 16 bit pieces of data (4 TX FIFO slots, plus the shift register itself) of interrupt latency that can be tolerated. That is about 33.33us of interrupt latency that can be handled without underflowing the FIFO and not properly updating the chain of Neopixels.
So for 64 Neopixels, the amount of RAM required is (64 * 9) (RAM for holding data sent on SPI bus) + 64 (holds current command for each Neopixel) = 640 bytes. The processor has 8K, so only using half the RAM for this allows about 400 Neopixels per board. Of course, there is no reason that you couldn’t put multiple boards into the machine to support more, but well, that seems ludicrous.
Here is a quick picture of the demo systems setup:
Quick video of the Neopixels working:
There is something weird going on with the first Neopixel. It might be that I got it a little too hot when I soldered the wires to the strip. (I didn’t “tin” the pads before soldering on the leads, which meant I had to use a lot more heat). It could also be a bug in the program, and I should probably send a blank 16 byte word before sending the first bit of data. At this point, it is good enough to hand off.
I’m getting pretty familiar with the processor at this point, so it is getting faster for me to add new features. I really have to work on the next serial commands to interface with the next generation of the boards.