The Serial Peripheral Interface (SPI) module is a synchronous serial interface useful for communicating with other peripheral or microcontoller devices. The examples of the peripheral devices are: serial EEPROMs, shift registers, display drivers, serial A/D converters, etc. The SPI module is compatible with Motorola’s SPI and SIOP interfaces.
Depending on the variant, the dsPIC30F family offers one or two SPI modules on a single device. E.g. dsPIC30F3014 has one SPI interface module, whereas dsPIC30F6014A has two.
A standard SPI serial port consists of the following special function registers (SPR):
In addition, there is a 16-bit register, SPIxSR, that is not memory mapped. It is used for shifting in and out of the SPI port.
The memory mapped special function register SPIxBUF, the SPI data receive/transmit register, actually consists of two separate registers – SPIxTXB and SPIxRXB. If a user writes data to the SPIxBUF address, internally the data are written to the SPIxTXB (transmit buffer) register. Similarly, when the user reads the received data from the SPIxBUF, internally the data are read from the SPIxRXB (receive buffer) register. This double buffering of transmit and receive operations allows continuous data transfers in the background.
The user can not write to the SPIxTXB register or read from the SPIxRXB register directly. All reads and writes are performed on the SPIxBUF register.
Fig. 9-1 shows functional block diagram of the SPI module. In addition to the above registers, the SPI module serial interface consists of the following four pins:
NOTE: The SPI module can be configured to operate using 3 or 4 pins. In the 3-pin mode, the SSx pin is not used.
Fig. 9-1 Functional block diagram of SPI module
The SPI module has the following flexible operating modes:
A control bit MODE16 (SPIxCON<10>) allows the module to communicate in either 8-bit or 16-bit modes. The functionality will be the same for each mode except the number of bits that are received and transmitted. The following should be noted in this context:
In a multi-processor operation when the SPI interface is used, the microcontrollers operate in the master and slave modes. In master mode the microcontroller is in full control of the communication since it initiates and ends the communication session and generates the SPI clock signal. In slave mode the microcontroller listens when the master initiates and ends the communication session and uses the SPI clock signal generated by the master. SPI master/slave connection is shown in Fig. 9-2. The figure shows the 4-pin SPI interface even though this connection can also operate with the 3-pin SPI interface.
Fig. 9-2 Master/slave connection using SPI interface
NOTE: Using the SSx pin in slave mode of operation is optional.
The following steps should be taken to set up the SPI module for the master mode of operation:
In master mode, the system clock is prescaled and then used as the serial clock. The prescaling is based on the settings in the PPRE<1:0> (SPIxCON<1:0>) and SPRE<1:0> (SPIxCON<4:2>) control bits. The serial clock generated in the master device is via the SCKx pin sent to slave devices. Clock pulses are only generated when there are data to be transmitted/received. The CKP (SPIxCON<6>) and CKE (SPIxCON<8>) control bits determine on which edge of the clock data transmission occurs.
Fig. 9-3 SPI module in master mode of operation
With the help of Fig. 9-3, the following description of the SPI module operation in master mode can be given.
The following steps should be taken to set up the SPI module for the slave mode of operation:
In slave mode, data are transmitted and received as the external clock pulses appear on the SCKx pin. The CKP (SPIxCON<6>) and CKE (SPIxCON<8>) control bits determine on which edge of the clock data transmission occurs. Both data to be transmitted and data that are received are respectively written into or read from the SPIxBUF register.
A few additional features provided in the slave mode are:
Fig. 9-4 SPI slave mode: 3-pin SPI interface
Fig. 9-5 SPI slave mode: 4-pin SPI interface
Fig. 9-6 CKP and CKE bit functionality
The operation for 8-bit mode is shown. The 16-bit mode is similar.
When a new data word has been shifted into SPIxSR and the previous contents of SPIxRXB have not been read by the user software, the SPIROV bit (SPIxSTAT<6>) will be set (overflow condition). The module will not transfer the received data from SPIxSR to SPIxRXB. Further data reception is disabled until the SPIROV bit is cleared. The SPIROV bit is not cleared automatically by the module and must be cleared by the user software.
Setting the control bit DISSDO (SPIxCON<11>) disables transmission at the SDOx pin. This allows the SPIx module to be configured for a receive only mode of operation. If the DISSDO bit is set, the SDOx pin will be controlled by the respective port function (input or output).
The module supports a very basic framed SPI protocol while operating in either master or slave modes. The following features are provided in the SPI module to support framed SPI modes:
The following two framed SPI modes are supported by the SPI module:
The framed SPI modes are supported in conjunction with the master and slave modes. The following four framed SPI configurations are available to the user: SPI master mode and frame master mode, SPI master mode and frame slave mode, SPI slave mode and frame master mode, and SPI slave mode and frame slave mode. These four modes determine whether or not the SPIx module generates the serial clock and the frame synchronization pulse. Fig. 9-7 shows block diagram of the master and slave connection in master and frame slave mode.
Fig. 9-7 Master and slave connection in master and frame slave mode
The SPI clock at the SCKx pin is controlled by the FRMEN (SPIxCON<14>) and MSTEN (SPIxCON<5>) control bits. When FRMEN (SPIxCON<14>)=1 and MSTEN (SPIxCON<5>)=1, the SCKx pin becomes an output and the SPI clock at SCKx becomes a free running clock, i.e. it will exists irrespective of whether the module is transmitting data or waiting. This mode is intended for the master devices. When FRMEN (SPIxCON<14>)=1 and MSTEN (SPIxCON<5>)=0, the SCKx pin becomes an input pin. This mode is intended for the slave devices.
The polarity of the clock pulse is selected by the CKP (SPIxCON<6>) control bit. The CKE (SPIxCON<8>) control bit is not used for the framed SPI modes and should be cleared by the user software. When CKP (SPIxCON<6>)=0, the frame synchronization pulse output and the SDOx output change on the rising edge of the clock pulses at the SCKx pin. Input data are sampled at the SDOx input pin on the falling edge of the SPI clock pulses at the SCKx pin.
When the control bit CKP (SPIxCON<6>)=1 the frame synchronization pulse output and the SDOx data output change on the falling edge of the clock pulses at the SCKx pin. Input data are sampled at the SDIx input pin on the rising edge of the SPI clock at the SCKx pin.
When the SPIFSD (SPIxCON<13>) control bit is cleared, the SPIx module is in the frame master mode of operation. In this mode the frame synchronization pulse is initiated by the module when the user software writes the transmit data to SPIxBUF location, i.e. writing the SPIxTXB register with transmit data. At the end of the frame synchronization pulse, the SPIxTXB is transferred to the SPIxSR and data transmission/reception begins.
When the SPIFSD (SPIxCON<13>) control bit is set, the module is in frame slave mode. The frame synchrinization pulse is generated by an external source. When the module samples the frame synchronization pulse, it will transfer the contents of the SPIxTXB register to the SPIxSR register and data transmission/reception begins. The user must make sure that the correct data are loaded into the SPIxBUF for transmission before the frame synchronization pulse is received.
Receiving a frame synchronization pulse will start a transmission, regardless of whether data were written to SPIxBUF. If no write was performed, the old contents of SPIxBUF will be transmitted.
This framed SPI mode is enabled by setting the MSTEN (SPIxCON<5>) and FRMEN (SPIxCON<14>) bits to ‘1’ and SPIFSD (SPIxCON<13>) bit to ‘0’. In this mode, the serial clock will be output continuously at the SCKx pin, regardless of whether the module is transmitting. When the SPIxBUF is written, the SSx pin will be driven high on the next transmit edge of the SCKx clock (active edge depends on the control bit CKP). The SSx pin will be high for one SCKx clock cycle. The module will start transmitting data on the next transmit edge of the SCKx, as shown in Fig. 9-8. The connection of master and slave is shown in Fig. 9-7.
Fig. 9-8 Waveforms of the SPI module in master mode and frame master mode
This framed SPI mode is enabled by setting the MSTEN (SPIxCON<5>), FRMEN (SPIxCON<14>), and SPIFSD (SPIxCON<13>) bits to ‘1’. The SSx pin is an input, and it is sampled on the sample edge of the SPI clock. When it is sampled high, data will be transmitted on the subsequent transmit edge (controlled by the CKP bit) of the SPI clock. When the transmission is completed, the interrupt flag SPIxIF is generated by the SPIxSR register. The user must make sure that the correct data are loaded into the SPIxBUF for transmission before the signal is received at the SSx pin. Fig. 9-9 shows the waveforms of the SPI module in master mode and frame slave mode. Connection diagram of the module in master mode and frame slave mode is showm in Fig. 9-10.
Fig. 9-9 Waveforms of the SPI module in master mode and frame slave mode
Fig. 9-10 Connection diagram of the module in master mode and frame slave mode
This framed SPI mode is enabled by setting the MSTEN (SPIxCON<5>) bit to ‘0’, FRMEN (SPIxCON<14>) bit to ‘1’, and SPIFSD (SPIxCON<13>) bit to ‘0’. The input SPI clock will be continuous at the SCKx pin in slave mode. The SSx pin will be an output when the SPIFSD (SPIxCON<13>) bit is cleared. Therefore, when the SPIxBUF is written, the module will drive the SSx pin high on the next transmit edge of the SPI clock. The SSx pin will be driven high for one SPI clock cycle. Data will start transmitting on the next SPI clock falling edge. A connection diagram for this operating mode is shown in Fig. 9-11
Fig. 9-11 Connection diagram of the module in slave mode and frame master mode
This framed SPI mode is enabled by setting the MSTEN (SPIxCON<5>) bit to ‘0’, FRMEN (SPIxCON<14>) bit to ‘1’, and SPIFSD (SPIxCON<13>) bit to ‘1’. Therefore, both the SCKx and SSx pins will be the inputs. The SSx pin will be sampled on the sampling edge of the SPI clock (in the middle of the SPI cycle). When SSx is sampled high, data will be transmitted on the next transmit edge of SCKx (controlled by the CKP bit). A connection diagram for this mode of operation is shown in Fig. 9-12.
Fig. 9-12 Connection diagram of the module for slave mode and slave frame mode
In the master mode, the clock provided to the SPI module is the instruction cycle TCY . This clock will then be prescaled by the primary prescaler, specified by PPRE<1:0> (SPIxCON<1:0>), and the secondary prescaler, specified by SPRE<2:0> (SPIxCON<4:2>). The prescaled instruction clock becomes the serial clock and is provided to external devices via the SCKx pin.
Note that the SCKx signal clock is not free running for normal SPI modes (8-bit or 16-bit). It will only run for 8 or 16 pulses when the SPIxBUF is loaded with data. It will however, be continuous for framed modes.
The SCKx clock frequency as a function of the primary and secondary prescaler settings is calculated by the following equation
Examples of the SCKx frequencies as functions of the primary and secondary prescaler settings are shown in Table 9-1.
|Fcy = 30 Mhz||Secondary prescaler settings|
|Primary prescaler settings|
|1:1||30 000||15 000||7 500||5 000||3 750|
|4:1||7 500||3 750||1 875||1 250||938|
|Fcy = 5 Mhz|
|Primary prescaler settings|
|1:1||5 000||2 500||1 250||833||625|
Table 9-1 SCKx frequencies
NOTE: SCKx clock frequencies shown in kHz. All frequencies are not supported; electrical characteristics of individual microcontrollers of dsPIC30F family should be consulted.
The example shows the use of the specialized SPI library of the mikroPascal compiler for dsPIC microcontrollers which allows an easy initialization of the SPI module and write or read data from the transmit/receive buffer of the SPI module. The example shows the method of connecting the SPI2 module to the serial digital-to-analogue converter (DAC) MCP4921.
program SPITest; const CS_PIN = 0; // DAC CS pin var value : word; procedure InitMain(); begin TRISF.CS_PIN := 0; // CS pin LATF.CS_PIN := 1; // Set CS to inactive Spi1_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, _SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_1,_SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH,_SPI_ACTIVE_2_IDLE); // Init SPI end; // DAC increments (0..4095) --> output voltage (0..Vref) procedure DAC_Output(valueDAC : word) ; begin while (SPI1STAT.1 = 1) do // wait for SPI module to finish, if doing something nop; LATF.CS_PIN := 0; // CS enable for DAC SPI1BUF := 0x3000 or valueDAC; // Write CurrentValue to DAC (0x3 is required by DAC) while (SPI1STAT.1 = 1) do // Wait for SPI module to finish write nop; LATF.CS_PIN := 1; // CS disable for DAC end; begin InitMain(); while 1 = 1 do begin value := 1; while value < $FFF do begin DAC_Output(value); Delay_ms(5); value := value+1; end; end; // the output in the mid-range end.
Procedure Spi2_Init initializes the SPI module in master mode 8-bit formatted, without the SS2 pin, sampling in the middle of the SPI cycle, prescale 1:8, and the clock FCY:1 low while waiting. If another format or communication speed is desired, the procedure Spi2_Init_Advanced instead of Spi2_Init should be used. The procedure Spi2_Data_Ready reads the value of the status bit SPIRBF (SPI2STAT<0>) and checks if there are data loaded into the receive buffer register. The procedure Spi2_Write transmits data via the SPI module. Data reception is performed by the procedure Spi2_Read. The SPI moduled is disabled by the procedure Spi2_Stop (clearing the control bit SPIEN), and the SPI module enable (setting the control bit SPIEN) is performed automatically by the procedure Spi2_Init or Spi2_Init_Advanced.
When the device enters SLEEP mode, the system clock is disabled. If the SPI module is in master mode when the microcontroller enters SLEEP mode, the SPI clock is also disabled. If the SPIx module enters SLEEP mode in the middle of a transmission/reception, then the transmission/reception is aborted. Since there is no automatic way to prevent an entry into SLEEP mode, the user software must synchronize entry into SLEEP with SPI module operation. The transmitter or receiver does not continue with partially completed transmission at wake-up.
Since the clock pulses at SCKx are externally provided for slave mode, the module will continue to function in SLEEP mode. It will complete any transaction during the transition into SLEEP. On completion of a transaction, the SPIRBF status flag for interrupt request of the SPI module is set. If the SPI interrupts are enabled (SPIxIE=1), the device will wake-up from SLEEP. If the SPI interrupt periority level is greater than the present CPU priority level, code execution will resume at the SPIx interrupt vector location. Otherwise, code execution will continue with the instruction that previously invoked SLEEP mode. Entering or waking-up from SLEEP mode does not influence the operation of the SPI module in slave mode nor does it change the contents of the SPI module registers.
When the device enters IDLE mode, the system clock sources remain functional. The SPISIDL bit (SPIxSTAT<13>) selects whether the module will stop or continue functioning on IDLE.
If SPISID (SPIxSTAT<13>) bit is cleared, the SPI module will continue operation in IDLE mode.
If SPISID (SPIxSTAT<13>) bit is set, the SPI module will stop communication on entreing IDLE mode. It will operate in the same manner as it does in SLEEP mode.
Table 9-2 describes pins of the SPI module depending on the operational mode. At the end of this section a description of the UART registers for dsPIC30F is presented.
|SCKx||Input / Output||SPI clock signal output or input|
|SDIx||Input||SPI data reception input pin|
|SDOx||Output||SPI data transmisson output pin
SPI slave device selection control pin
Write/Read enable pin in slave mode if the control bit SSEN (SPIxCOPN<7>) is set
|SSx||Input / Output||Used as RAM synchronization pin when the control bits FRMEN and
SPIFSD (SPIxCON<13:14>) are set to the value 10 or 11
Table 9-2 Description of SPI module pins
Fig. 9-13a Pinout of dsPIC30F4013
Fig. 9-13b Pinout of dsPIC30F6014A
A brief description follows of the SPI module registers of a dsPIC30F4013 device.
Table 9-3 Status and control register SPI1STAT
SPIEN – SPI enable bit (SPIEN=0 disables module, SPIEN=1 enables module) SPISIDL – Stop in IDLE mode bit (SPISIDL=0 continue operation, SPISIDL=1 discontinue operation) SPIROV – Receive overflow flag bit SPITBF – SPI transmit buffer full status bit (SPITBF=0 transmit started, SPIxTBF empty, SPITBF=1 transmit not yet started, SPIxTBF is full) SPIRBF – SPI receive buffer full status bit (SPIRBF=0 receive is not complete SPIxRXB is empty, SPIRBF=1 receive complete SPIxRXB is full)
Table 9-4a Control register SPI1CON
Table 9-4b continued
FRMEN – Framed SPI support bit SPIFSD – Frame sync pulse direction control on SSx pin bit (SPIFSD=0 frame sync pulse output (master), SPIFSD=1 frame sync pulse input (slave)) DISSDO – Disable SDOx pin bit MODE16 – Word/byte communication select bit (MODE16=0 8-bit mode, MODE16=1 16-bit mode) SMP – SPI data input sample phase bit (Master mode: SMP=0 input data sampled at middle of data output time, SMP=1 input data sampled at end of data output time; Slave mode: SMP must be cleared) CKE – SPI clock edge select bit (CKE=0 serial output data changes on transition from IDLE clock state to active clock state, CKE=1 serial output data changes on transition from active clock state to IDLE clock state) SSEN – Slave select enable bit (SSEN=0 SS1 pin not used by module, SSEN=1 SS1 pin used for slave mode) CKP – Clock polarity select bit (CKO=0 IDLE state for clock is a low level, active state is a high level, CKO=1 IDLE state for clock is a high level, active state is a low level) MSTEN – Master mode enable bit (MSTEN=0 slave mode, MSTEN=1 master mode) SPRE<2:0> - Secondary prescale (master mode) bits 000 – secondary prescale 8:1 001 – secondary prescale 7:1 ... 110 – secondary prescale 2:1 111 – secondary prescale 1:1 PPRE<1:9> - Primary prescale (master mode) bits 00 – primary prescale 64:1 01 - primary prescale 16:1 10 – primary prescale 4:1 11 – primary prescale 1:1
|SPI1BUF||0x0224||Transmit/Receive buffer (shared by SPI1TXB and SPI1RXB registers)||0x0000|
Table 9-5 SPI1BUF register