cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Between Two STM32 Boards - Data Not Received

Brian_Azzopardi
Associate III

Hello ST Community,

 

I am trying to set up SPI communication between two STM32 microcontrollers (two NUCLEO-F401RE boards); one as an SPI master and the other as an SPI slave. For now, I am only trying to transmit only one byte (0x61). For this I am using STM32’s HAL Library, and its functions HAL_SPI_Transmit_IT() and HAL_SPI_Receive_IT.

On the slave, the HAL_SPI_RxCpltCallback() and the code inside it (setting a flag) are being executed, meaning that the slave is attempting to receive data sent by the master. However, the data in the SPI receive buffer is always 0x00 (serial terminal shown below; displaying "0" for every SPI receive interrupt occurrence).

 

Termite serial terminal outputting "0" upon every occurance of SPI receive interruptTermite serial terminal outputting "0" upon every occurance of SPI receive interrupt

 

I need to have the master and the slave operating in Full-Duplex Master and Full-Duplex Slave modes respectively (both with interrupts), however, when setting them in Transmit Only Master and Receive Only Slave, and disabling interrupts, for debugging purposes, the same issue persisted.

 

Below are the hardware connections (short wires from one NUCLEO board to another):

 

  • SPI2_SCK on PB10 of NUCLEO-F401RE Board 1 (MASTER) -> SPI2_SCK on PB10 of NUCLEO-F401RE Board 2 (SLAVE)
  • SPI2_MISO on PC2 of NUCLEO-F401RE Board 1 (MASTER) -> SPI2_MISO on PC2 of NUCLEO-F401RE Board 2 (SLAVE)
  • SPI2_MOSI on PC3 of NUCLEO-F401RE Board 1 (MASTER) -> SPI2_MOSI on PC3 of NUCLEO-F401RE Board 2 (SLAVE)
  • GPIO_Output on PA10 of NUCLEO-F401RE Board 1 (MASTER) (controlled through software) -> SPI2_NSS on PB12 of NUCLEO-F401RE Board 2 (SLAVE) – I need this because when I get this to work with one slave, I will move on to a multi-slave system
  • GND of NUCLEO-F401RE Board 1 (MASTER) -> GND of NUCLEO-F401RE Board 2 (SLAVE)

 

Connection diagram of the two NUCLEO-F401RE boardsConnection diagram of the two NUCLEO-F401RE boards

 

Other information related to hardware:

  • NUCLEO-F401RE boards have a Green LED on PA5 which I am using for debugging purposes

 

Code snippets below. I am only showing the user-inputted code, not the auto-generated code.

 

Attached are the Master and Slave configuration settings in STM32CubeIDE Code Configurator.

 

NUCLEO-F401RE Board 1 (MASTER) Code:

 

/* USER CODE BEGIN PV */

/* Private variables */

uint8_t spi_tx_buf[] = "a";	// Data to send... 0x61 or Decimal 97

/* USER CODE END PV */

 

 

In main():

 /* USER CODE BEGIN 2 */

  // Start with green LED OFF
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

  // Slave NSS (PA10) normally high
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);

  HAL_Delay(2000); // Give slave time to prepare...

  /* USER CODE END 2 */

 

In while(1):

  /* USER CODE BEGIN WHILE */
  while (1)
  {

	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);	// Pull slave NSS (PA10) low
//	  HAL_Delay(100);		// No effect
	  HAL_Delay(500);		// No effect
	  HAL_SPI_Transmit_IT(&hspi2, spi_tx_buf, 1); //Sending in Interrupt mode
	  HAL_Delay(100);		// No effect
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);	// Slave NSS (PA10) back high

	  // Blink green LED
	  // LED ON
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
	  HAL_Delay(100);
	  // LED OFF
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

	  HAL_Delay(5000);		// 5s delay before next transmit

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

 

(In the above code snippet, adding delays right after setting the NSS line low and before setting it bac high, had not effect on the data received by the slave.)

 

NUCLEO-F401RE Board 2 (SLAVE) Code:

 

/* USER CODE BEGIN PV */

/* Private variables */

volatile uint8_t spi_rx_buf[1]; // Data to receive
volatile uint8_t spi_rx_flag = 0;

uint8_t uart_tx_buf[20];

/* USER CODE END PV */

 

In main():

  /* USER CODE BEGIN 2 */

  // Start with green LED off
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

  HAL_SPI_Receive_IT(&hspi2, spi_rx_buf, 1); //Receive in Interrupt mode

  /* USER CODE END 2 */

 

In while(1):

  /* USER CODE BEGIN WHILE */
  while (1)
  {

	  if (spi_rx_flag==1){

		  spi_rx_flag=0;	// Reset flag immediately

		  sprintf((char*)uart_tx_buf, "%u\r\n", spi_rx_buf[0]);
		  HAL_UART_Transmit(&huart2, uart_tx_buf, strlen((char*)uart_tx_buf), 50);

		  // Blink the green LED
		  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
		  HAL_Delay(100);
		  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

		  HAL_SPI_Receive_IT(&hspi2, spi_rx_buf, 1); // Receive again in interrupt mode

	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

 

SPI ISR:

/* USER CODE BEGIN 4 */

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)
{
    // RX Done
	spi_rx_flag = 1;
}

/* USER CODE END 4 */

 

I checked the SCK, MOSI and NSS signals using an oscilloscope, and nothing looks wrong there, so I believe the problem lies within the slave's receiving data code... MOSI and SCK signals shown below and are in synch, with MOSI showing bits for 0x61 one-byte message transmitted by the Master (apologies for the bad image quality, I'll try to update the picture ASAP)... NSS signal has also been verified.

 

Photo of scope showing SCK signal (blue) and MOSI signal (yellow) during transmission of 0x61 single-byte messagePhoto of scope showing SCK signal (blue) and MOSI signal (yellow) during transmission of 0x61 single-byte message

 

I really appreciate your help in getting this very basic code to work. I have been trying various code examples, including from ST WIKI (https://wiki.st.com/stm32mcu/wiki/Getting_started_with_SPI) and still cannot get this board-to-board SPI communication working. I have also tried changing the NUCLEO boards to exclude hardware malfunctions, and switching from SPI2 to SPI3 peripherals.

 

Thanks!

 

Brian

Brian

RSO (RDI) at the University of Malta Department of Electronic Systems Engineering
11 REPLIES 11
Brian_Azzopardi
Associate III

Hello All,

 

An update on the above issue, which has been solved.

 

The following was done, which did not lead to any positive results:

  • NUCLEO-F401RE boards were checked by running other programs 
  • Different SPI modules were used (SPI3 instead of SPI2)
  • Baud rate was varied (lowered significantly)
  • All hardware connections were checked, including ground connection between the two boards
  • Code was checked

 

After reverting to the original code / SPI configuration (as shown in my original post), I restarted by Windows PC, and right after that, the Slave started receiving the byte sent by the Master. Following this, multi-byte and multi-slave (with software control of NSS pins) transmission was tested and worked fine.

 

There were no updates available at the time of PC restart, and I had restarted the IDE and PC previously. I cannot recall changing anything else to software or hardware, apart from restarting my machine, so I cannot really say what was causing the problem.

 

Thanks all for your help!

 

Brian

Brian

RSO (RDI) at the University of Malta Department of Electronic Systems Engineering

Hi @TDK ,

 

I appreciate your help and offer to investigate this issue, and I apologise for the delayed reply.

 

This issue had been solved and I have just posted an update.

 

Brian

Brian

RSO (RDI) at the University of Malta Department of Electronic Systems Engineering