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);

 

 

 

actionbytestotal
start point command1 byte1
coordinate x2 bytes3
coordinate y2 bytes5
end point command1 byte6
coordinate x2 bytes8
coordinate y2 bytes10
write data command1 byte11
write the pixel colour2 bytes13

 

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.

 

The Series
0 - Buffers and Parallel Data Lines
1a - Buffers and DMA
1b - SPI without Buffers
2 - SPI with Buffers
3a - SPI with DMA
3b - SPI with DMA works
4a - SPI Master with DMA and Parallel Data Lines
Hercules microcontrollers, DMA and Memory Cache