SPI Write Limitation

Hi All,

I’ve been working with some adafruit DotStar LED strands, driving them with the RIO’s onboard SPI (using Java). I have them working, but to do so required I chunk the data to send into 128-byte sections, and call the spi.write() multiple times (once per section). This was done because the maximum return value I ever saw spi.write() give was 128.

I’m not horribly experienced with SPI - is this an implicit limitation of SPI in general? Or of the libraries and hardware we’re using for FRC? Perhaps also I forgot to set up some buffer properly. Has anyone else seen this?

EDIT: Here’s the code in question
DotStarsLEDStrip.java (6.33 KB)

DotStarsLEDStrip.java (6.33 KB)

DotStarsLEDStrip.java (6.33 KB)

It looks like the limitation is in wpilib, rather then the roboRIO.

Seems like it. The bit of research I’ve done on this seems to indicate SPI is implemented on the FPGA, which I assume means any buffers are of fixed length. What those lengths are, however, I’m not really sure…

Yes, it’s a hardware limitation. Per the Zynq documentation [1], the SPI read and write FIFOs are 128 bytes deep. This matches the behavior you’re seeing. Conceptually, functionality could be added to wpilib to do the outer loop for longer writes, but I think this case is rare enough (and there’s multiple ways to do it, e.g. use interrupts to determine when to continue filling the FIFO, or periodically check), that it’s better left to the user code to implement.

[1] http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf, section 17.2.4.

We are trying to control the AdaFruit DotStars through the SPI bus, too, except we are using LabVIEW. Which ports on the roboRIO did you guys connect the dotstar to?

Actually, we ended up using both at one point. We started by using the dedicated 10-pin port on the top, then we switched to the port that’s on the custom expansion port in the middle.

I’m not familiar with sending bytes in labview. However, I know in java it was just a single initialization parameter to say which SPI port to use. Everything else was the same.

Also as indicated in this thread, we did have to chunk the send data into 128-length bytes to get it to work nicely.