29.2 SPI Mode Operation
Transmissions involve two Shift registers, eight bits in size, one in the host and one in the client. With either the host or the client device, data is always shifted out one bit at a time, with the Most Significant bit (MSb) shifted out first. At the same time, a new Least Significant bit (LSb) is shifted into the same register.
The following figure shows a typical connection between two processors configured as host and client devices.
Data is shifted out of both Shift registers on the programmed clock edge and latched onto the opposite edge of the clock.
The host device transmits information out on its SDO output pin, which is connected to and received by the client’s SDI input pin. The client device transmits information out on its SDO output pin, which is connected to and received by the host’s SDI input pin.
To begin communication, the host device first sends out the clock signal. Both the host and the client devices need to be configured for the same clock polarity.
The host device starts a transmission by sending out the MSb from its Shift register. The client device reads this bit from that same line and saves it into the LSb position of its Shift register.
During each SPI clock cycle, a full-duplex data transmission occurs. This means that while the host device is sending out the MSb from its Shift register (on its SDO pin) and the client device is reading this bit and saving it as the LSb of its Shift register, the client device is also sending out the MSb from its Shift register (on its SDO pin) and the host device is reading this bit and saving it as the LSb of its Shift register.
After eight bits have been shifted out, the host and the client have exchanged register values.
If there is more data to exchange, the Shift registers are loaded with new data and the process repeats itself.
Whether the data is meaningful or not (dummy data), depends on the application software. This leads to three scenarios for data transmission:
- Host sends useful data and client sends dummy data
- Host sends useful data and client sends useful data
- Host sends dummy data and client sends useful data
Transmissions may involve any number of clock cycles. When there is no more data to be transmitted, the host stops sending the clock signal and it deselects the client.
Every client device connected to the bus that has not been selected through its client select line must disregard the clock and transmission signals and must not transmit out any data of its own.
When initializing the SPI, several options need to be specified. This is done by programming the appropriate control bits (SSPxCON1[5:0] and SSPxSTAT[7:6]). These control bits allow the following to be specified:
- Host mode (SCK is the clock output)
- Client mode (SCK is the clock input)
- Clock Polarity (Idle state of SCK)
- Data Input Sample Phase (middle or end of data output time)
- Clock Edge (output data on rising/falling edge of SCK)
- Clock Rate (Host mode only)
- Client Select mode (Client mode only)
To enable the serial port, the SSP Enable (SSPEN) bit must be set. To reset or reconfigure SPI mode, clear the SSPEN bit, re-initialize the SSPxCONx registers and then set the SSPEN bit. The SDI, SDO, SCK and SS serial port pins are selected with the PPS controls. For the pins to behave as the serial port function, some must have their data direction bits (in the TRIS register) appropriately programmed as follows:
- SDI must have the corresponding TRIS bit set
- SDO must have the corresponding TRIS bit cleared
- SCK (Host mode) must have the corresponding TRIS bit cleared
- SCK (Client mode) must have the corresponding TRIS bit set
- The RxyPPS and SSPxCLKPPS controls must select the same pin
- SS must have the corresponding TRIS bit set
Any serial port function that is not desired may be overridden by programming the corresponding data direction (TRIS) register to the opposite value.
The MSSP consists of a Transmit/Receive Shift Register (SSPSR) and a buffer register (SSPxBUF). The SSPSR shifts the data in and out of the device, MSb first. The SSPxBUF holds the data that was written to the SSPSR until the received data is ready. Once the eight bits of data have been received, that byte is moved to the SSPxBUF register. Then, the Buffer Full Detect (BF) bit and the Interrupt Flag (SSPxIF) bit are set. This double-buffering of the received data (SSPxBUF) allows the next byte to start reception before reading the data that was just received. Any write to the SSPxBUF register during transmission/reception of data will be ignored and the Write Collision Detect (WCOL) bit will be set. User software must clear the WCOL bit to allow the following write(s) to the SSPxBUF register to complete successfully.
When the application software is expecting to receive valid data, the SSPxBUF must be read before the next byte of data to transfer is written to the SSPxBUF. The Buffer Full (BF) bit indicates when SSPxBUF has been loaded with the received data (transmission is complete). When the SSPxBUF is read, the BF bit is cleared. This data may be irrelevant if the SPI is only a transmitter. The MSSP interrupt is used to determine when the transmission/reception has completed. If the interrupt method is not going to be used, then software polling can be done to ensure that a write collision does not occur.
The SSPSR is not directly readable or writable and can only be accessed by addressing the SSPxBUF register. Additionally, the SSPxSTAT register indicates the various Status conditions.