SPI is a synchronous serial communication protocol used primarily in embedded systems for short distance wired communications. It was developed by Motorola in the mid-1980s. It is a full duplex communication where the master and slave can exchange data in the same time. It is a single master multi slave protocol where a master can select which slave he wants to communicate with.
SPI has four main signals as shown in the figure below.
The master is responsible for generating the clock in which the whole system works on and it selects which slave he will communicate with.
With regards to the architecture, we developed our own architecture as shown in the figure below.
SPI can work with 4 modes of operations according to 2 signals which are CPOL and CPHA as shown in the figure below. The choice of which mode depends on which type of slave we are communicating with.
We have 4 main registers which are:
-
SPI Control register (SPICR):
This register is mainly responsible for enabling the SPI, controlling whether it is master or slave and controlling the mode of operation if it is a master. -
SPI Data register (SPIDR):
This register contains the data which needed to be sent and also received data. -
SPI BaudRate register (SPIBR):
It is responsible for the SPR signal which is the prescalar the is used to calculate the value the clock is divided by. -
SPI Status register (SPISR):
This register raises a flag when the data is successfully sent.
This module divides the system clock frequency by the Divisor which can be calculated from SPR bits from the SPIBR register.
This block has an inputs of CPOL and CPHA and then it generates the output clock on which the SPI sends data with. It also generates 2 signals which are Shift clock and Sample clock. The Master Block takes the M_BaudRate Signal and outputs the SCK_out. Whule the Slave Block takes the SCK_in and outputs the S_BaudRate signal.
-
Shift clock
is when the data is Driven to output. -
Sample clock
is when the master/slave samples the data which is already driven by other device.
Depending on the MSTR signal coming from the SPDR register, this block selects whether the Shift and Sample clocks produced by SCK_control_master or SCK_control_slave is propagated into the Shifter. This Block also produces the control_BaudRate which is the main count signal of the controller.
The shifter block is the block which takes the shift and sample clocks from the Master_slave_select to Drive the data to be sent and sample the recieved data.
Start State
is a state used for synchronization between the Slave and Master so that the idle state starts at the same edge.Idle State
is a state signaling the start of operation. In this state, data in the SPDR is recieved from the user and propagated into the Shifter Shift register, and the SPIF is set to zero.Run State
is the state of sending and recieving data. The bit counter starts to be enabled and counts from 0 to 7 a total of 8 counts. The shifter is enabled as well in this state.Update State
signals finishing the sending/recieving of data. The data from the shifter is transferred to the SPDR to be taken by the user. The next state from here returns to the Idle state since the Master and Slave is already synchronized.
A simple testbench was created consisting of a few directed tests where a value of the SPDR is set at periodic intervals and then it is checked to see whether the data recieved at the corresponding device is the same.