Skip to content

About SPI optimization

Martin edited this page Jun 14, 2020 · 16 revisions

How it's usually done on every GxEPD model

Independently on the Epaper module, what happens in update() method, is somehow similar.

  • The _wakeup() private method is called. This in some models power on at the beginning (0x04 CMD) and then it sends some LUT tables (usually 4/ 5 between 42 and 44 bytes each as SPI CMD+ DATA)
  • Then the pixel buffer is sent. It's read from the generated GFX _buffer byte by byte and send using IO.data(byte)
  • A command is called that signalizes our display slave that he needs to refresh
  • Refresh takes place and the new pixels are rendered in the epaper

The obvious optimization points

Toggling Chip Select on every byte sent as data is not the best idea. Even if takes nano-seconds to do it, when we are sending a full buffer for a big epaper, this will greatly affect performance. As an example, the Wave12I48 display has 1304*984 pixels. So in total, they are 1.283.136 approx 1 million 283 thousand pixels. Measuring how much times we call data to send this is simple:

160392/8 = 160392 bytes

So we are toggling the Chip Select GPIO 160 thousand times to send our pixel buffer. That calls for some optimization right?

Instead of doing this, we can just use another data function:

EpdSpi::data(const uint8_t *data, int len) {}

And just send a complete line via SPI, toggling CS pin, only once on every Y row. That could be done on single SPI slave displays. But also in Wave12I48 is much more efficient to send the whole line to each of the epaper than it would be to send per byte. Check Wave12I48 stats section to see the optimization gain.

Clone this wiki locally