S100_Banner

HomeS-100 Boards HistoryNew BoardsSoftwareBoards For Sale
ForumOther Web SitesNewsIndex   
 
An SPI Master Controller Interface Demo using a Cyclone IV FPGA.
We will now go up a notch in circuit complexity we will add to our S100 bus V2_FPGA Prototype board. Here we will construct an FPGA SPI interface and use it to communicate with a simple chip Digital Potentiometer.  This is a simple IC device which outputs a voltage level (in this case),  from
0-5V, depending on an 8 bit value of 0 to FFH sent to it over a simple 4 wire SPI connection.

Introduction SPI
The Serial Peripheral Interface (SPI) is a synchronous serial communication interface used for short distance communication.  It is primarily used in embedded systems. The interface was developed by Motorola in the mid 1980s. Typical applications include SD cards and LCD displays. SPI devices communicate in a full duplex mode using a master-slave architecture with a single master. The master device originates the frame for both writing and reading to/from the slave(s). Multiple slave devices can be supported through selection with individual slave select (SS) lines.   SPI is minimally a four-wire serial bus.
    
    SPI Diagram
   
To begin communication, the bus master starts the clock, using a frequency supported by the slave device. Typically this can be in the 100's of KHz range. The master then selects the appropriate slave device by lowering that slaves SS input. If a waiting period is required, such as in for an analog-to-digital conversion, the master must wait for at least that period of time before issuing clock cycles.  This has to be agreed upon in the programming software. The master then sends a bits on the MOSI line and the slave reads them. At the same time the slave sends bits on the MISO line to the master. This sequence is maintained even when only one-directional data transfer is intended.
Its important to appreciate two things.
 
1.   The sending and receiving data to/from the slave is completely linked. There is just one loop like circuit with two shift registers (see below).
2.   The actual data format is completely determined by the software in the master and slave.  The number of bits transmitted can be 8, 16, 32 etc.  In theory any number.  
   
    SPI_Diagram

Most commonly,  the data is in 16 bit packages.  The first 8 bits are used to control the device, the second 8 bits are the actual data.   However its very important to appreciate that the protocol is completely fluid. You must carefully read the SPI device datasheet to determine the exact nature of the interface and what each bit in a CMD code does.  Worse, the master must also configure the clock polarity and phase with respect to the data. Motorola SPI specification names these two options as CPOL and CPHA respectively, and most vendors have adopted that convention. Getting into the weeds:-


CPOL=0 is a clock which idles at 0, and each cycle consists of a pulse of 1.
CPOL=1 is a clock which idles at 1, and each cycle consists of a pulse of 0.
CPHA=0, the slave captures the data on the leading edge of the clock cycle.

CPHA=1, the slave captures the data on the trailing edge of the clock cycle.


When the transmission is complete, the master stops toggling the clock signal, and typically deselects the slave.
On the slave side of things we will use a very simple SPI device,  a Microchip MCP42010 Digital Potentiometer
We will use the PDIP Dual version:-  
      
     Microchip Pinout
   
In the FPGA code below, depending on the 8 bit value fed (via the SPI connection) to pin 3, a voltage value ranging from 0 to about 5V will appear on pin 9 (and 6).   While not needed in this case,  it is interesting to note that the basic clock signal is a high frequency, running in this case at 400 KHz.

The FPGA SPI Code.
There are numerous examples of building a FPGA SPI interface on the web.   As a beginner, frankly I found a number of them overly complex and/or confusing.   Fortunately I discovered a simple and well explained example by Scott Larson here.  However the demonstration I used for the V1 FPGA Board was quite specific for a SPI device that had a two byte data input and a single byte output. While it works fine for our MCP42010 chip, I wanted to explore a more generalized data I/O FPGA module. The module below modifies Scotts code to have a single byte input and output but one can send multiple bytes by controlling separately the chip select line.  For most SPI chips you can send multiple bytes in any time frame you like so long as you keep CS* low.  That is what we do here.  I just modified Scott's VHDL code.

Fortunately the code was designed using Quartus II.  So in line with all our previous examples we simply take VHDL code and convert it to a block diagram (a
.bdf file).    To recap,  we do this by loading up the VHDL text file (spi_3_wire_master.vhd) and from the file menu drop down to Create/Update, Create a symbol file. The new symbol file module will then be in the Project dropdown menu.
Here is the core of the
spi_byte_master_X_bits bdf module:-  
    
  Code6

There are a number of simple inputs to the module:-
clock 1 in   System clock.
reset_n 1 in   Asynchronous active low reset.
enable 1 in   High: latches in settings, address, rw, command, and data to initiate a transaction
 Low: no transaction is initiated.
cpol 1 in   SPI clock polarity setting.
cpha 1 in   SPI clock phase setting.
clk_div 32 in   Speed setting.  The integer input is the number of system clocks per 1/2 period of sclk.
addr 32 in   Address of target slave.  Not used here.
rw 1 in   High: the transaction is a write, Low: the transaction is a read.
tx_data 8 in   Data to transmit.
sclk 1 buffer   SPI clock.
ss_n 32 buffer   Slave select signals. Not used here. We address CS* seperately.
sdio 1 inout   Serial data signal.
busy 1 out   Busy / data ready signal.
rx_data 8 out   Data received from target slave. Not used here
  
Most of the signals are fairly obvious.
clk_div is an input that can be up to 32 bits wide to be used as the clock input divider.  Here (and often) we simply deliver the final clock signal directly so (clk_div = 0). In our case 400KHz is  generated in out PLL frequency generator.  See the top of the .bdf file entry.   The number of slave devices is a 32 bit input. Zero here and not used.  We will use an 8 bit input for data (tx_data).  In this simple example we will not actually be using data returned from the SPI slave.

It important to appreciate that the way this module works is that the cmd and data inputs (8 bits each) much first be latched and stable as inputs to the module.  The actual SPI transmission then takes place when
enable is pulsed low.  However its essential this pulse only occurs on the rising edge of the clk input.  In order to insure this,  we need the following logic:-
  
    Code2
      
The S100 port write signal (
pWR*) is narrow and unsynchronized with the 400KHz clock signal.  We must latch it and pass it on to the SPI module as enable on the next rising edge of the 400KHz clock signal.  While not used here, one would do the same for SPI data reads.

We will use four S100 bus ports to interface and control the SPI interface. We will use a 74139 library module to brake up the address lines
A0 and A1 into 4 port selects. 68H, 69H, 6AH and 6BH.   In our .bdf file we will use port 68H to provide a latched S100 bus output to the  tx_data input.   We will then use port 6BH to pulse the enable signal. This will initiate the actual data transmission to the SPI slave.  The SPI module and slave device will actually require time to transmit the data. During this time the spi_byte_master_X_Bits busy line will go high.  This line can be read as bit 0 from input port 69H.  Port 6A, bit 0 is used for CS*

For this device we set
Set SW1 OPEN     (cpol HIGH)
Set SW2 CLOSED 
(cpha LOW)
 
When the  Microchip MCP42010 Digital Potentiometer powers up the potentiometer will be in its mid position and we will see a voltage of ~2.5V on its pin 9. 
I wrote the simple Z80 program SPI_MCP.Z80 to control this voltage.  This program can be downloaded from the bottom of this page.
You load the SPI_MCP.COM file into RAM at 100H using a program like XModem and the 'X' command of the Z80 master monitor.

Here is a picture of the interaction:-
 
     MCP_Z80

You need to study the MCP42010 data sheet to see how this chip works with a data write.  
Please study the SPI_MCP.Z80 code to see how we interface the chip. 
   
  Data sheet
   
This circuit is one of the components of the FPGA Board Shield #1 board.
    
    Chip Picture 
  
Here the simple board schematic.
 
    Chip_Schematic_Corrected
  
Again this is a very simple example of using our Cyclone IV to interface an SPI device. Please study the files below to understand completely what is going on.
 

BUGS
None to data. However this SPI module has now been supper-seeded by a more generalized SPI module interface used for a 24C512 EPROM.
Please use that one if you need a FPGA SPI interface.

MCP42010.pdf                                            (V1.0 2/21/2019)
SPI_MCP42010.ZIP                                   (V1.0 2/21/2019)

Z80_SPI_MCP42010.ZIP               (V1.0 2/21/2019)
SPI_MCP.Z80                               (V1.0 2/21/2019)
                                   
Other pages describing my S-100 hardware and software.
Please click here to continue...

This page was last modified on 07/28/2019