FastLED-idf icon indicating copy to clipboard operation
FastLED-idf copied to clipboard

SPI Support

Open Ivorforce opened this issue 4 years ago • 8 comments

Thanks a lot for this port! I'm currently still struggling to get it running with platformio (files aren't being found by default), but meanwhile I wanted to share a quick half-PR with you.

As far as I've seen, so far there is no ESP32 SPI output in FastLED yet.

https://gist.github.com/Ivorforce/adcc7dd68c2b43d8cbb1f58de36a09fe

This gist is a quick dump of my own SPI setup for another project, which is several times faster than bitbanging. I may make this into complete PRs (here and in the original repo) yet, but if someone suddenly feels the urge to include or finalize it, here's a starter. :)

Ivorforce avatar Jun 29 '20 21:06 Ivorforce

Thanks, I'd like to get SPI working, but this looks like it's just an SPI file written for arduino to control LEDs. Any thoughts to integrate it would be helpful, but I don't see how to adapt it to the ESP-IDF hal.

bbulkow avatar Jun 30 '20 02:06 bbulkow

I'm running this on my ESP32, FastLED on Arduino framework. But the code is accessing esp-idf native API only, I believe.

It's a header file that just has to be included somewhere, with some constants being set. The precompiler directives of FastLED coerce this to automatically be used in place of bitbanging if either of the 3 directives on the bottom of the file is matched ( e.g. -D SPI_DATA=13 -D SPI_CLOCK=14).

I haven't looked into what changes you have made to this setup though. But it works analogously to, say, AVRSoftwareSPIOutput, and thus doesn't even have to be specifically referenced by the user.

Ivorforce avatar Jun 30 '20 14:06 Ivorforce

The file that has to be replaced is the clockless_spi file in the platforms/esp/32 directory. If you have a file that works instead of the existing one, writing to the ESP-IDF interface instead of arduino, I'd love to see it.

bbulkow avatar Jul 24 '20 20:07 bbulkow

First, SPI output is supported through bit-banging. Sure it'll be slow, but it saves pins.

@lvorforce , how fast do you need to go?

Second, the SPI hardware support is fairly easy. The Arduino code isn't much help. There's a header file from @ntwallace that shows how to do it on Arduino, this is a pretty simple pattern to follow. I'll rewrite the code for FastLED after I get some LEDs to test with.

There are only two free SPI blocks on most ESP32, and you'll also burn two other pins AFAIK, so it's pin-expensive for a single string.

If you expect to clock more than one or two strings, you have to bit-bang anyway.... is that what you intend?

Knowing the speed you intend to reach helps, please provide. Thanks.

bbulkow avatar Sep 15 '20 18:09 bbulkow

@bbulkow Nice work on this port. BTW, the Arduino implementation of the ESP32 GPIO mux limits speeds to 26Mhz on each SPI bus, I'm assuming in ESP-IDF you have access to the full 80Mhz? The hardware driven SPI in Arduino FastLED I wrote is more efficient in terms of clock cycles than bit banging, but that really only matters when you're running other code with a lot of overhead. As you noted, it's only useful for driving 2 strips anyway, although I think it would probably be possible to use an SPI expander IC and hack it into FastLED for running tons of strips since the writes to each strip are sequential anyway.

@Ivorforce FYI FastLED defaults SPI LED speeds to 12Mhz, because most SPI LED chipsets aren't worth driving at higher rates due to timing issues in the ICs. For example, on a strip of 300 APA102s you will start to get glitching issues if you drive them faster than 12Mhz (and with some strips you may have to drop to 4Mhz or less). The reason why this happens is explained in a great write up by Paul Stoffregen from 2017. Obviously, even 4Mhz is significantly faster than the ~800Khz that WS281x chipsets run at, but you're not gaining much by driving them from hardware.

ntwallace avatar Sep 15 '20 19:09 ntwallace

I have tested the bit-bang APA102 code with the TinyPico (everyone said it would work but it's good to know). Next up is writing a quick shim to the ESP-IDF driver, I have a 128-pixel APA102 strip to test with now.

bbulkow avatar Sep 27 '20 19:09 bbulkow

I read your numbers @ntwallace, but I can only tell you I was able to about 5x my performance (at the least) by using SPI output.

Granted, I require extreme frame rates, so this might not be important to everyone else.

Ivorforce avatar Dec 15 '20 20:12 Ivorforce

Btw.: I've dropped FastLED since I ended up reimplementing all the interfaces anyway for greater framerates, and control over global brightness bits.

In case it's any help with your ongoing efforts: Here's a link to my current running SPI implementation. It's now further removed from FastLED interfaces, but I do still have the FastLED - compatible interface lying here too, which would be powered by an import to this.

Ivorforce avatar Dec 15 '20 20:12 Ivorforce