We know SPI as a 4*-wire protocol. But it doesn't have to be. I'm checking high speed SPI data transfer with buffers, DMA and parallel data lines.
Let's analyse what the SPI cost is of my naive implementation, where I paint pixel by pixel. |
SPI Traffic for a Single Pixel
Painting a single pixel on the LCD requires 8 SPI calls. In total we move 15 bytes.
The majority is spent on setting a draw window of 1 x 1 pixel. The paint command by itself just takes 2 bytes.
Code snippet
_writeCommand(HX8353E_CASET); _writeData16(x0); _writeData16(x1); _writeCommand(HX8353E_RASET); _writeData16(y0); _writeData16(y1); _writeCommand(HX8353E_RAMWR); _writeData16(colour);
action | bytes | total |
---|---|---|
start point command | 1 byte | 1 |
coordinate x | 2 bytes | 3 |
coordinate y | 2 bytes | 5 |
end point command | 1 byte | 6 |
coordinate x | 2 bytes | 8 |
coordinate y | 2 bytes | 10 |
write data command | 1 byte | 11 |
write the pixel colour | 2 bytes | 13 |
The analyser trace looks like this:
And the protocol analyser tells us:
Almost 20 µS for a pixel. My SPI clock runs at 27.5 Mbits per second.
13 bytes per pixel is 1664 bytes for one line of 128 pixels.
2.6 ms per line (20µs x 128). 328 ms for the whole 128 x 128 bitmap.
A Slightly Less Naive Approach
Let's try a first speed bump by setting the window to one line in stead of one pixel, and then push the data after that.
Unbuffered still. We are looping through the line and send a pixel at a time over SPI.
But we only send the positioning and windowing bytes (11 of the 13) only once per line.
A saving of 1397 bytes per single line.
Code snippet:
void setBitmapInOneThrow(bitmap_t *bmp) { uint32_t xx, yy; for (yy = 0; yy < bmp->height; yy++) { _setWindow(0, yy, bmp->width, yy ); loadBitmapInDMABuffer(bmp, yy); for (xx = 0; xx < bmp->width; xx++) { _writeData16(TXDATA[xx]); } } }
We still spend the same time for these activities as in the previous implementation.
16 µS to get the LCD screen initialises. For a whole line now.
Beaming the full line of data, 128 x 2 bytes, took us 360 µS
The total time to draw a line decreased from 2.6 ms per line to 376 µS.
In the next blog, we'll try to bring the 360 µS pixel data transmit further down by using buffered SPI.
Top Comments