Electrical – STM32F411 SPI slave enters debug infinite loop

spistm32stm32cubemx

I've connected two NUCLEOSTM32F411RE together, and trying to send an ASCII letter from one PC to another PC in Simplex mode from master to slave.

When I send a character the slave enters a routine in startup_stn32f411xe.s
where it is written in the comment of the code
"This is the code that gets called when the processor receives an unexpected interrupt. This simply enters an infinite loop,
preserving the system state for examination by a debugger"

I've connected SPI2MOSI (master) to SPI2MOSI (slave) as described on page 6 (PC3 to PC3)

http://www2.st.com/content/ccc/resource/training/technical/product_training/d9/cf/69/ae/71/43/4f/23/STM32L4_Peripheral_SPI.pdf/files/STM32L4_Peripheral_SPI.pdf/jcr:content/translations/en.STM32L4_Peripheral_SPI.pdf

Also SPI2_SCK to SPI2_SCK (PB10) as well as
SPI2_NSS to SPI2_NSS (PB12)

CPOL and CPHA are configured the same in the Cube. For the slave only I have
in the NVIC checked the SPI2 global interrupt interrupt priority 0, also have USART2 global interrupt.

The configuration of the SPI slave is like this in main:

void MX_NVIC_Init(void)
{
  /* SPI2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(SPI2_IRQn);
  __HAL_SPI_ENABLE_IT(&hspi2, SPI_IT_RXNE);//My addition

 /* USART2_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(USART2_IRQn);
 __HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE); //My addition
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);//My addition

}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_SLAVE;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
 hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi2.Init.CRCPolynomial = 10;
 HAL_SPI_Init(&hspi2);
 __HAL_SPI_ENABLE(&hspi2); // My addition
 }

My IRQ handler in STM324fxx_it.c looks like this

void SPI2_IRQHandler(void)
{
 HAL_SPI_IRQHandler(&hspi2);
 uint8_t data1;
 HAL_SPI_Receive_IT(&hspi2,&data1,sizeof(data1));
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);
}

Why is the interrupt unexpected on the slave side?

//Adding more info after suggestion,init USART slave main
void MX_USART2_UART_Init(void)
{

 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 HAL_UART_Init(&huart2);
__HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}
//Masterside stm324fxx_it.c
void USART2_IRQHandler(void)
{  
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin,GPIO_PIN_SET);
  HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

}

The interrupt routine is prepared for bidirectional communication, and is not entered since I've initilizing it in nvic with

__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);

and I am not trying to send from the slave conntected PC. The transmission to the slaveside PC, I hope to accomplish with

HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

in

void SPI2_IRQHandler(void)//Thank's for your interest :)

Best Answer

This works in main of the master-board:

SPI2_MOSI (PC3) to SPI2_MOSI (PC3)
SPI2_NSS (PB12) to SPI2_NSS (PB12) 
SPI2_SCK (PB10) to SPI2_SCK (PB10)

Termainalprogram running on each PC connected to each board. Baud:115200, No-parity, CTS/RTS

void MX_NVIC_Init(void)
{
/* USART2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);

}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_MASTER;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
 hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
 hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi2.Init.CRCPolynomial = 10;
 HAL_SPI_Init(&hspi2);
 __HAL_SPI_ENABLE(&hspi2);
}


/* USART2 init function */
void MX_USART2_UART_Init(void)
{
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 HAL_UART_Init(&huart2);
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

On stm32f4xx_it.c for the master

void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  data1++; //Icrementing 'A' to 'B'
  HAL_SPI_Transmit(&hspi2,&data1,  (uint16_t)sizeof(data1),HAL_MAX_DELAY);
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);//echoing back to PC
}

On the slave side in main

void MX_NVIC_Init(void)
{
 HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(SPI2_IRQn);
 __HAL_SPI_ENABLE_IT(&hspi2, SPI_IT_RXNE);
 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(USART2_IRQn);
 __HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_SLAVE;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
 hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi2.Init.CRCPolynomial = 10;
 HAL_SPI_Init(&hspi2);
 __HAL_SPI_ENABLE(&hspi2);
}


/* USART2 init function */
void MX_USART2_UART_Init(void)
{
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);
  __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

In slave stm32f4xx_it.c

void SPI2_IRQHandler(void)
{
  HAL_SPI_IRQHandler(&hspi2);
 uint8_t data1;
 HAL_SPI_Receive_IT(&hspi2,&data1,sizeof(data1));
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

}

void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  data1++;
  HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);
}