SPI Bus
SPI Bus is a way to transfer data between 2 or more digital circuits. There is typically one master circuit that is in charge of initiating transfers. And then there are one or more slaves on the bus. The BrainPad MicroComputer is always the bus master. A slave can be an accelerometer or a display for example.
When a master talks to a slave, it asserts the salve’s CS (Chip Select) pin. Then the data is exchanged between the two sides. The master will clock the data (usually 8 bit) using the CLK clock pin. The data comes out on the MOSI (Master Out Slave In) pin. At the same time, the data is clocked in on the MISO (Master In Slave Out) pin.
SPI hardware implementation is nothing but two shift registers, one clocking data out and one clocking in.
Some slaves only receives data and do it only needs CLK and MOSI. An example would be a display that would only needs to receive information to show on the screen and it does not send any data back.
When accessing SPI, there is always exchange of a byte between a master and salve, and it is happening simultaneously. It is not possible to only send or only receive. This is shown in the SpiByte() function, which takes a byte and returns a byte.
r = BrainPad.Spi.WriteByte(5); // Exchange 5 with the salve and place the results in variable r
r = BrainPad.Spi.WriteByte(5); # Exchange 5 with the salve and place the results in variable r
To make for a better user experience, the Python and C# API uses SPI streams and give a few options on how to use SPI.
byte[] data = new byte[4];
byte[] incoming = new byte[4];
data[0]= 0x01;
data[1]= 0xff;
data[2]= 0x00;
data[3]= 0x00;
BrainPad.Spi.WriteRead(data,incoming);
// Resulting 4 bytes are placed in incoming array
data = [0] * 4
incoming = [0] * 4
data[0]= 0x01
data[1]= 0xff
data[2]= 0x00
data[3]= 0x00
BrainPad.Spi.WriteRead(data,incoming)
# Resulting 4 bytes are placed in incoming array
The chip select is left optional. Chip select goes low before the transaction and goes high after.
BrainPad.Spi.WriteRead(data,incoming, 2);
BrainPad.Spi.WriteRead(data,incoming, 2)
Display Stream Handling
Since using SPI bus with displays is very common, a special functions were added that converts bitmap data on-the-fly. For example, some displays are 16BPP (16 bits per pixel) but due to memory limitation and transfer speed, the graphics engine can be constructed using 4BPP and then a special stream can converts the data internally then send 16BPP to the display.
byte[] graphics = new byte[128*64/2];
// ...
BrainPad.Spi.Write4bpp(graphics);
graphics = [0]*(128*64/2)
# ...
BrainPad.Spi.Write4bpp(graphics);
BrainStorm
Where is the “bus” in SPI bus? Data is delivered down the wire by one as a stream of data. In computer world, this is called a data bus. What other busses are used around us? Think of how a Keyboard is wired to a PC.