SPI STM32f4 PDF
SPI STM32f4 PDF
SPI STM32f4 PDF
Application note
Full duplex SPI emulation for STM32F4 microcontrollers
Introduction
The STMCube™ initiative was originated by STMicroelectronics to ease developers life by
reducing development efforts, time and cost. STM32Cube covers the STM32 portfolio.
STM32Cube Version 1.x includes:
• The STM32CubeMX, a graphical software configuration tool that allows to generate C
initialization code using graphical wizards.
• A comprehensive embedded software platform, delivered per series (namely,
STM32CubeF4 for STM32F4 series)
– The STM32Cube HAL, an STM32 abstraction layer embedded software, ensuring
maximized portability across STM32 portfolio
– A consistent set of middleware components such as RTOS, USB, TCP/IP and
graphics
– All embedded software utilities coming with a full set of examples.
This Application Note describes how to implement a Serial Peripheral Interface (SPI)
emulator for the microcontrollers of the STM32F4 series.
An SPI interface is commonly emulated in software where a dedicated hardware peripheral
is not available. It is also needed in applications that require more SPIs than those offered
by STM32F4 microcontrollers. Using this software the user can compensate the limited
number of SPI peripherals, without the need to switch to higher level MCUs with sufficient
number of SPIs when the application doesn’t require additional performance and
functionality.
This SPI is full-duplex, supports 8, 16 data length bits and clock speed up to 6 MHz with
CPU operating at 168 MHz. It also offers a high flexibility since any I/O pin can be
configured as Master-Out/Slave-In (MOSI) and Master-In/Slave-Out (MISO). In addition,
this SPI emulation uses the DMA to minimize the software overhead and CPU load, which
may significantly impact the system ability to execute other tasks and to meet real-time
schedules.
This application note provides a basic example of communication between a hardware and
a software SPI as well as a summary of CPU load and firmware footprint.
A firmware package (X-CUBE-SPI-EMUL) is delivered with this document and contains the
source code of the SPI emulator with all the drivers needed to run the example.
Contents
2 Software description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.1 Implementation structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2 Package organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3 Transmission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.1 Format data procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.2 Transmission routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3.3 Peripheral settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.4 Reception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.4.1 Format data procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.4.2 Transmission routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.4.3 Peripheral settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5 SPI emulator API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5.1 HAL_SPI_Emul_Init function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5.2 HAL_SPI_Emul_InitTypeDef structure . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.5.3 HAL_SPI_Emul_Transmit_DMA function . . . . . . . . . . . . . . . . . . . . . . . 20
2.5.4 HAL_SPI_Emul_Receive_DMA function . . . . . . . . . . . . . . . . . . . . . . . . 21
2.5.5 HAL_SPI_Emul_TransmitReceive_DMA function . . . . . . . . . . . . . . . . . 21
2.5.6 Callback functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.1 Hardware requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.2 Software settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.3 Running the example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
6 Revision history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
List of tables
List of figures
This section describes the implementation of an SPI emulation by defining the system level
requirements.
The SPI emulator implementation is based on GPIO, timer and DMA peripherals.
• Three lines are used to connect the SPI emulator to external devices. Data are
transmitted to the BSRR and IDR registers in Tx and Rx mode respectively.
• Data transfers are performed by DMA2 with two dedicate channels:
– Channel6 Stream1 for data transfers in Tx mode
– Channel6 Stream2 for data transfers in Rx mode
• Timer overflow and IO capture compare events are used to control timing of SPI
emulator input sampling and output handling of the Rx and Tx signals. TIM1 generates
the clock signal in master mode, and sends requests to DMA to transfer data at the
required speed for both master and slave mode.
SPI emulator peripherals requirements and configurations are described in Table 1.
DMA2
Memory to Peripheral Memory to Peripheral
Configuration
peripheral to memory peripheral to memory
MOSI Any I/O configured as output Any I/O configured as input
GPIO MISO Any I/O configured as input Any I/O configured as output
SCK PA8 or PA9 configured in AF
Note: The peripherals required for full duplex communication are the combination of peripherals
used in Tx mode and Rx mode.
Note: Other Timers with the same features as TIM1 can be used.
If the CPHA parameter is configured as 2EDGE, the second edge on the SCK pin (rising
edge if CPOL is high, falling edge if CPOL is low) is the MSBit capture strobe. Data are
latched on the occurrence of the second clock transition.
The combination of the CPOL and CPHA parameter selects the data capture clock edge
(see Table 2).
Figure 2 shows an SPI transfer with the four combinations of the CPHA and CPOL. The
diagram may be interpreted as a master or slave timing diagram where the SCK pin, the
MISO pin, the MOSI pins are directly connected between the master and the slave device.
Single-frame transmission
1. The timer is configured in PWM mode to generate the clock signal with a frequency
determined by the value of the TIMx_ARR register, and a duty cycle determined by the
value of the TIMx_CCRx register.
2. The CPU formats the frame to be sent to the memory according to the First Bit
configuration.
3. The timer sends a request to the DMA at each period of the clock signal to transfer one
bit from memory to MOSI pin.
Once the frame transmission is complete, the timer stops generating the clock signal and
the TxC flag (SPI transmission complete) is set.
Multiple-frame transmission
Multiple-frame transmission is based on a FIFO buffer with a threshold level of ½, this
means that the buffer is effectively divided into two equal halves so data in one half can be
transferred by DMA while data is being formatted by CPU in the second half. This allows the
CPU to process one memory area while the second memory area is being used by the DMA
transfer. At each end of transaction a half transfer complete or a transfer complete interrupt
is generated by the DMA to ensure that the CPU swaps from one memory target to another.
This operation is repeated until all frames are transmitted. When this is done, the timer
stops generating the clock signal and the TxC flag is set.
Single-frame reception
The reception sequence includes the following steps:
1. The CPU checks if the SPI is ready and the RX buffer is empty.
2. The timer is configured in PWM mode to generate the clock signal with a frequency
determined by the value of the TIMx_ARR register, and a duty cycle determined by the
value of the TIMx_CCRx register.
3. The timer sends a request to the DMA at each period of the clock signal to transfer one
bit from MISO pin to the memory.
4. The CPU formats the received frame.
Once the frame reception is complete, the timer stops generating the clock signal and the
RxC flag (SPI reception complete) is set.
Multiple-frame reception
DMA transmits data to the memory. When the first half of the FIFO buffer is filled, a half
transfer complete interrupt is generated by the DMA so the CPU formats data and stores
them in SRAM. At the same time the DMA continues to fill the second half. When this is
done, a transfer complete interrupt is generated and the CPU formats this data. The DMA
configured in circular mode returns to the initial pointer and keeps going. This operation is
repeated until all frames are received. Once the frame reception is complete, the timer stops
generating the clock signal and the RxC flag is set.
The timer is configured in input capture mode, so the transmission process starts when the
clock signal is detected on the timer input channel.
Single-frame transmission
The transmission sequence includes the following steps:
1. The CPU formats the frame to be sent to the memory according to the First Bit
configuration.
2. The timer sends a request to the DMA at each period of the clock signal to transfer one
bit from memory to MISO pin. The requests are programmed to occur at the rising or
falling edge of the input signal, depending on CPHA configuration.
3. Once the frame transmission is complete, the TxC flag (SPI transmission complete) is
set.
Multiple-frame transmission
Multiple-frame transmission is based on a FIFO buffer with a threshold level of ½, this
means that the buffer is effectively divided into two equal halves so data in one half can be
transferred by the DMA while data is being formatted by the CPU in the second half. This
allows the CPU to process one memory area while the second memory area is being used
by the DMA transfer. At each end of transaction a half transfer complete or a transfer
complete interrupt is generated by the DMA to ensure that the CPU swaps from one
memory target to another. This operation is repeated until all frames are transmitted. When
this is done, the timer stops generating the clock signal and the TxC flag is set.
Single-frame reception
The transmission sequence includes the following steps:
1. The CPU checks if the SPI is ready and the RX buffer is empty.
2. On the rising (or falling) edge of the external trigger, the timer generates a DMA
request. As the GPIO data register address is set to DMA peripheral address, the DMA
controller reads the data from the GPIO port on each DMA request, and stores it into an
SRAM buffer.
3. The CPU formats the received frame.
4. Once the frame reception is complete, the RxC flag (SPI reception complete) is set.
Multiple-frame reception
DMA transmits data to the memory. When the first half of the FIFO buffer is filled, a half
transfer complete interrupt is generated by the DMA so the CPU can format data and store
them in the SRAM. The DMA continues to fill the second half, when it’s done, a transfer
complete interrupt is generated and the CPU formats these data. The DMA configured in
circular mode returns to the initial pointer and keeps going. This operation is repeated until
all frames are received. When this is done, the timer stops generating the clock signal and
the RxC flag is set.
2 Software description
STM32 SPI emulation package is located in middlewares level and support STM32F4
series. It is based on modular architecture that means other STM32 series can be supported
without any impact on the current implementation.
In Application layer, STM32 SPI emulation package provide a set of examples for the most
common development tools.
6XSSRUWHG670VHULHV
%63GULYHUV
IRUWKHVXSSRUWHGERDUG
&RQWDLQV670[[&06,6ILOHVWKDW
GHILQHSHULSKHUDOUHJLVWHUGHFODUDWLRQV
ELWVGHILQLWLRQVDQGDGGUHVVPDSSLQJ 670[[+$/
GULYHUVIRUDOO
67063,
HPXODWLRQGULYHUV
+HDGHUDQGVRXUFHILOHVRI
67063,HPXODWLRQGULYHUV
6XSSRUWHGERDUG
0LVFHOODQHRXVXWLOLWLHV
069
2.3 Transmission
Data package can be prepared in advance by the CPU and stored into an SRAM buffer. This
FIFO buffer can host 20 frames, and the threshold level is ½, so while DMA channel is
transferring data from the first half, CPU prepares the next block of data to be send in the
second half and vice versa. This is managed by the half transfer complete and transfer
complete interrupts generates by DMA after each transfer of 10 frames.
The principle of formatting and sending a given number of bytes using CPU and DMA in Tx
mode is shown in Figure 5.
2.4 Reception
Table 4. HAL_SPI_Emul_Init
Function name HAL_SPI_Emul_Init
Table 5. HAL_SPI_Emul_Init
Field name Description
Table 6. HAL_SPI_Emul_Transmit_DMA
Function name HAL_SPI_Emul_Transmit_DMA
HAL_StatusTypeDef HAL_SPI_Emul_Transmit_DMA
Prototype
(SPI_Emul_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
Behavior Transmit in simplex mode an amount of data in no-blocking mode with DMA
– *hspi: pointer to SPI_Emul_HandleTypeDef structure that contains the
configuration information for SPI emulator
Parameter
– *pData: Pointer to data buffer
– Size: Amount of data to be sent
Return value HAL status
Table 7. HAL_SPI_Emul_Receive_DMA
Function name HAL_SPI_Emul_Receive_DMA
HAL_StatusTypeDef HAL_SPI_Emul_Receive_DMA
Prototype
(SPI_Emul_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
Behavior Receive in simplex mode an amount of data in no-blocking mode with DMA
– *hspi: pointer to SPI_Emul_HandleTypeDef structure that contains the
configuration information for SPI emulator
Parameter
– *pData: Pointer to data buffer
– Size: Amount of data to be sent
Return value HAL status
Table 8. HAL_SPI_Emul_TransmitReceive_DMA
Function name HAL_SPI_Emul_TransmitReceive_DMA
HAL_StatusTypeDef HAL_SPI_Emul_TransmitReceive_DMA
Prototype
(SPI_Emul_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
Transmit and Receive in simplex mode an amount of data in no-blocking mode
Behavior
with DMA
– *hspi: pointer to SPI_Emul_HandleTypeDef structure that contains the
configuration information for SPI emulator
Parameter
– *pData: Pointer to data buffer
– Size: Amount of data to be sent
Return value HAL status
Table 9. HAL_SPI_Emul_TransmitReceive_DMA
Function name Parameters Description
__weak void
This function is called at the end
HAL_SPI_Emul_RxCpltCallback
of the reception process
(SPI_Emul_HandleTypeDef *hspi)
__weak void
This function is called at the half
HAL_SPI_Emul_RxHalfCpltCallback
of the reception process
(SPI_Emul_HandleTypeDef *hspi)
__weak void
This function is called at the end
HAL_SPI_Emul_TxCpltCallback hspi: SPI emulator handle
of the transmission process
(SPI_Emul_HandleTypeDef *hspi)
__weak void
This function is called at half of
HAL_SPI_Emul_TxHalfCpltCallback
the transmission process
(SPI_Emul_HandleTypeDef *hspi)
__weak void
This function is called when a
HAL_SPI_Emul_ErrorCallback
communication error is detected.
(SPI_Emul_HandleTypeDef *hspi)
3 Example
The example illustrates a data exchange between the SPI emulator and the hardware SPI.
Figure 10. Example MDK-ARM™ workspaces (SPI Master emul / Slave HW)
3URMHFWZRUNVSDFHV
3URMHFWGULYHUV
([DPSOHILOHV
67063,PDVWHUHPXODWLRQGULYHU
069
Figure 11. Example MDK-ARM™ workspaces (SPI Slave emul / Master HW)
3URMHFWZRUNVSDFHV
3URMHFWGULYHUV
([DPSOHILOHV
67063,PDVWHUHPXODWLRQGULYHU
069
Case 3 Case 4
– Clock speed = 3 MHz – Clock speed = 3 MHz
– Data length = 8 bits – Data length = 8 bits
– Data order = LSB first – Data order = LSB first
– CPOL = 0, CPHA = 1 – CPOL = 1, CPHA = 1
The SPI emulator uses the CPU for frames processing which includes:
• formatting data
• saving data in internal SRAM
• handling DMA interrupts
Transmission 116 × CPU clock cycles per frame 225 × CPU clock cycles per frame
Mode
Reception 108 × CPU clock cycles per frame 210 × CPU clock cycles per frame
Example:
The software settings used to obtain the results given in Figure 12 are the following:
• System clock: 84 MHz
• Data size: 8 bits
• SPI clock: 1 MHz
The program was compiled with MDK-ARM™ V5.14, optimization level3 (-O3) for speed,
so, applying the above formula
CPU load Tx = ((116 / (84 × 106)) × 106) / 8 × 100 =17.25 %
CPU load Rx = ((108 / (84 × 106)) × 106) /8 ×100 = 16.0%
CPU load full duplex= 17.25 % + 16.0 % = 33.25 %.
5 Conclusion
6 Revision history
STMicroelectronics NV and its subsidiaries (“ST”) reserve the right to make changes, corrections, enhancements, modifications, and
improvements to ST products and/or to this document at any time without notice. Purchasers should obtain the latest relevant information on
ST products before placing orders. ST products are sold pursuant to ST’s terms and conditions of sale in place at the time of order
acknowledgement.
Purchasers are solely responsible for the choice, selection, and use of ST products and ST assumes no liability for application assistance or
the design of Purchasers’ products.
Resale of ST products with provisions different from the information set forth herein shall void any warranty granted by ST for such product.
ST and the ST logo are trademarks of ST. All other product or service names are the property of their respective owners.
Information in this document supersedes and replaces information previously supplied in any prior versions of this document.