You are on page 1of 5

Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI

Figure 15-4.  Modules needed in this chapter

We are going to define the SPI slave input and output ports, review Raspberry Pi SPI master, and then
define the detail requirements for the SPI slave.

15.3.1 New SPI Slave Module Port List


The new SPI slave (spi_slave.vhd) is used to receive SPI-formatted messages from the Raspberry Pi SPI
master and translate them to READ or WRITE commands. Therefore, the spi_slave module needs to have an
SPI slave with 4-pin ports and a read/write register interface. Table 15-2 shows the basic port list names and
functions. Figure 15-5 is the actual VHDL port list.

Table 15-2.  spi_slave.vhd Port List

Name Type Function


sys_clock std_logic 29.5 MHz clock
sys_rst Std_logic Active Low reset (logic 0 is reset)
rspi_sclk Std_logic SPI interface clock
rspi_ss Std_logic SPI interface slave select
rspi_mosi Std_logic SPI interface master out slave in
rspi_miso Std_logic SPI interface master in slave out
wr_enable Std_logic Back-end byte write enable
Data_out is valid when wr_enable is High (1)
data_out Std_logic_vector(7 downto 0) Back-end byte write data
data_in Std_logic_vector(7 downto 0) Back-end byte read data

350
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI

Figure 15-5.  Port list for the new SPI slave module

15.3.2 Raspberry Pi SPI Master 0 Default Setting and Data Format


The Raspberry Pi Python SPI library (SPIDEV) has the following default settings: clock speed is 500 kHz,
slave select is active low, data change is clock falling edge, and data capture is rising edge. Figure 15-6 shows
the default settings of the Raspberry Pi SPI master. In this example we added a simple protocol for READ and
WRITE on top of the simple SPI byte transfer.

Figure 15-6.  Raspberry Pi SPI Master 0 interface

Figure 15-6 also shows the protocols. The top one shows a read cycle. The SPI master (Raspberry Pi)
first byte is 0x01 and the SPI slave (FPGA) needs to send out one byte with the following eight clock cycles.
The bottom of Figure 15-6 shows a write cycle. The first and second bytes are sent from the SPI master
(Raspberry PI). The first byte is 0x0 to indicate a write cycle and the second byte is the byte from Raspberry
Pi written to the FPGA. We will use this byte to control the onboard LEDs.

351
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI

15.3.3 Writing VHDL for the SPI Slave


The SPI slave has two functions. The first is receiving two bytes from the SPI master and sending a one-byte
status during the read cycle. The second is generating a pulse with one-byte data from Raspberry which is
used by another module to control the LEDs. The pulse is set high when the data from Raspberry is valid.
We will divide the SPI slave into the following six processes (functions):
1.
SPI clock edge detection which is used to generate a one-clock cycle pulse when
an SPI clock rising edge or falling edge occurs.
2.
SPI clock cycle counter which is used to count 16 cycles (two bytes).
3.
SPI in which an 8-bit shift register is used to shift one bit of SPI master data into
the FPGA when the rising edge of SPI clock occurs.
4.
Read/write cycle which is used to detect write cycles or read cycles after the first
eight bits from from the SPI master are received.
5.
Write input process which generates a pulse (wr_enable ), registers the byte from
Raspberry SPI master, and sends it to the other module through output port
data_out.
6.
Read output is an 8-bit shift register to shift out one bit to the SPI master when
the falling edge of the SPI clock occurs.
Figure 15-7 shows the block diagram of the SPI slave design.

Figure 15-7.  SPI slave block diagram

We will need to create seven signals in the spi_slave module and we need to put the code in between
architecture and begin. Figure 15-8 shows all seven of the signals and their definitions.

352
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI

Figure 15-8.  Signals needed for SPI slave design

15.3.3.1 SPI Clock Edge Detection


In a lot of applications, we will not directly use the clock from outside the FPGA. If the outside clock is
four times slower than the FPGA clock, then we can use the following method to generate a virtual clock
edge inside the FPGA. We don't need to have a reset for this process because the outputs of this process
(spi_clk_rising_edge and spi_clk_falling_edge) are not going to create trouble for other logic in this module.
Figure 15-9 is the clock edge detection logic process VHDL (VHSIC (very high speed integrated circuit)
Hardware Description Language).

Figure 15-9.  SPI clock edge detection VHDL code

On line 45, we use a 3-bit shift register (spi_clk_dly_line) to sample the rspi_sclk by sys_clock. When the
change of the rspi_sclk is sampled and stored in the shift register we can do all the clock edge detection logic
in sys_clock domain. Figure 15-10 shows that the rising edge detection pulse is delayed two sys_clock clock
cycles. It is expected when we use a fast clock to sample a slow clock and do the clock edge detection. The
spi_clk_dly_line (2), (1), and (0) are storing the history of the rspi_sclk. We defined the rising edge as when
(2) and (1) are logic low and at the clock cycle (0) and rspi_sclk are logic high.

353
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI

Figure 15-10.  Rising edge detection simulation

Figure 15-11 shows the falling edge detection simulation. It uses the same concept of edge detection as
rising edge. It only changes the logic value.

Figure 15-11.  Falling edge detection simulation

This clock edge logic works like a clock tick for the rest of the logic.

15.3.3.2 SPI Clock Cycle Counter—Simple Counter


We know that every SPI transfer is started by the slave select (spi_ss) and each transfer is going to have 16
clock cycles, which means 16 rising edges. Figure 15-12 shows that the counter (spi_clk_count) gets reset to
zero when slave select is logic High. The counter starts counting when slave select is Low and SPI clock rising
edge happens. It will count to 16 and then reset to zero. We will use this counter to detect when the first byte
(counter value is 8) or second byte (counter value is 16) is done.

354

You might also like