STM32-Peripheral’s-SPI: Interrupt Mode

STM32-Peripheral’s-SPI: Interrupt Mode

SPI introduction


The SPI interface provides two main functions, supporting either the SPI protocol or the I2S
audio protocol. By default, it is the SPI function that is selected. It is possible to switch the
interface from SPI to I2S by software.
The serial peripheral interface (SPI) allows half/ full-duplex, synchronous, serial
communication with external devices. The interface can be configured as the master and in
this case it provides the communication clock (SCK) to the external slave device. The
interface is also capable of operating in multimaster configuration.
It may be used for a variety of purposes, including simplex synchronous transfers on two
lines with a possible bidirectional data line or reliable communication using CRC checking.
The I2S is also a synchronous serial communication interface. It can address four different
audio standards including the I2S Philips standard, the MSB- and LSB-justified standards,
and the PCM standard. It can operate as a slave or a master device in full-duplex mode
(using 4 pins) or in half-duplex mode (using 3 pins). Master clock can be provided by the
interface to an external slave component when the I2S is configured as the communication
master.

SPI Features:

· Full-duplex synchronous transfers on three lines
· Simplex synchronous transfers on two lines with or without a bidirectional data line
· 8- or 16-bit transfer frame format selection
· Master or slave operation
· Multimaster mode capability
· 8 master mode baud rate prescalers (fPCLK/2 max.)
· Slave mode frequency (fPCLK/2 max)
· Faster communication for both master and slave
· NSS management by hardware or software for both master and slave: dynamic change
of master/slave operations
· Programmable clock polarity and phase
· Programmable data order with MSB-first or LSB-first shifting
· Dedicated transmission and reception flags with interrupt capability
· SPI bus busy status flag
· SPI TI mode
· Hardware CRC feature for reliable communication:
– CRC value can be transmitted as last byte in Tx mode
– Automatic CRC error checking for last received byte
· Master mode fault, overrun and CRC error flags with interrupt capability
· 1-byte transmission and reception buffer with DMA capability: Tx and Rx requests

How to use this driver


The SPI HAL driver can be used as follows:
1. Declare a SPI_HandleTypeDef handle structure, for example: SPI_HandleTypeDef hspi;
2. Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
a. Enable the SPIx interface clock
b. SPI pins configuration
◦ Enable the clock for the SPI GPIOs
◦ Configure these SPI pins as alternate function push-pull
c. NVIC configuration if you need to use interrupt process
◦ Configure the SPIx interrupt priority
◦ Enable the NVIC SPI IRQ handle
d. DMA Configuration if you need to use DMA process
◦ Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel
◦ Enable the DMAx clock
◦ Configure the DMA handle parameters
◦ Configure the DMA Tx or Rx Stream/Channel
◦ Associate the initialized hdma_tx(or _rx) handle to the hspi DMA Tx or Rx handle
◦ Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or
Rx Stream/Channel
3. Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS management, Clock polarity
and phase, FirstBit and CRC configuration in the hspi Init structure.
4. Initialize the SPI registers by calling the HAL_SPI_Init() API:
– This API configures also the low level Hardware GPIO, CLOCK, CORTEX…etc) by calling the
customized HAL_SPI_MspInit() API.

IO operation functions


This subsection provides a set of functions allowing to manage the SPI data transfers.
The SPI supports master and slave mode :
1. There are two modes of transfer:
– Blocking mode: The communication is performed in polling mode. The HAL status of all data
processing is returned by the same function after finishing transfer.
– No-Blocking mode: The communication is performed using Interrupts or DMA, These APIs return the
HAL status. The end of the data processing will be indicated through the dedicated SPI IRQ when
using Interrupt mode or the DMA IRQ when using DMA mode. The HAL_SPI_TxCpltCallback(),
HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks will be executed
respectively at the end of the transmit or Receive process The HAL_SPI_ErrorCallback()user callback
will be executed when a communication error is detected
2. APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) exist for 1Line (simplex) and 2Lines (full duplex) modes.

For this blog we are going to use SPI in interrupt mode ( Full duplex master)

Creating STM32 executable projects steps are available on this link , please follow steps 1 to 10 as per blog, here we will start from step 11. PA9 & PA10 Pin used for debugging purpose as UART Tx & UART Rx respectively. this blog is specially for SPI configuration & its usage in interrupt mode (MOSI & MISO pins connected in close loop for demo purpose), output will be available in serial terminal

SPI in poling mode click here , SPI in DMA mode click here

11. Enable SPI Configuration

Go to System mode > Connectivity > SPI1 > Mode > Full duplex master

Go to System mode > Connectivity > SPI1 > Parameter settings > Default

Figure 2: SPI Default Configuration as Full duplex master

12. Enable the Interrupt

Figure 3: Enable SPI Interrupt


13. Pin configuration

Figure 4: Pin configuration

PA9 : USART_Tx & PA10: USART_Rx

Figure 5: UART Pins for debug

14. Press below icon for code generation

Figure 6 Cube IDE Code Generation

15. Sample Code:

/* USER CODE BEGIN PV */
uint8_t Tx_data[10] = "123456";
uint8_t Rx_data[10] = "0";
uint8_t Rxflag = 0;
/* USER CODE END PV */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
	 if(hspi1.Instance == SPI1)
	 {
		 Rxflag = 1;
	 }
}
/* USER CODE END 0 */

 /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  HAL_SPI_TransmitReceive_IT(&hspi1, Tx_data, Rx_data, 5);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	HAL_Delay(1000);
	if (Rxflag == 1)
	{
		Rxflag = 0;
		uart1_printf_debug(GRN"Data is %s\n",&Rx_data);
		memset(Rx_data,0,sizeof(Rx_data));
		HAL_SPI_TransmitReceive_IT(&hspi1, Tx_data, Rx_data, 5);
	}
  }
  /* USER CODE END 3 */

16. Output at Serial terminal

Figure 7: Output at Serial terminal
Software Tools:
  1. STM32CubeIDE
  2. STM32CubeMx
  3. Teraterm
Hardware Setup:
  1. STM32F429IDISCOVERY board
  2. Mini USB Cable
  3. Jumper wire
Conclusion:

Successfully demonstrated SPI functionality in Interrupt mode. output captured in serial terminal.

References:
  1. STM32 HAL Library
  2. STM32 UM1718 document
Similar topics:
  1. https://kalapiinfotech.in/stm32-cube-ide-freertos-code-generation-using-cubemx/
  2. STM32 Peripherals: GPIO
  3. STM32 Peripherals: DAC
  4. STM32 Peripherals: ADC using Polling Mode
  5. STM32 Peripherals: UART Interrupt Mode
  6. STM32-Peripheral’s-SPI: Polling Mode

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: