2021-06-22 02:39 AM
Hello
I am using an STM32WB55. This microcontroller communicates in SPI with a second STM32F4 micrcontroller.
The STM32WB55 is slave and the STM32F4 is the master of communication.
During an electrostatic discharge, the SPI communication is disturbed.
The master sends the good requests but the STM32WB55 slave does not receive them. The slave SPI is in error, the HAL_SPI_ErrorCallback function is called.
In this case, I want to reset the SPI of the STM32WB55 but it doesn't work. I must have a software problem ... I can't find the solution.
Here is the configuration of the SPI and the initialization function.
SPI1 of the STM32WB55 in slave mode with 2 DMA:
- DMA1_Channel2: for sending RX
- DMA1_Channel3: for TX reception
The 2 DMA are linked on two buffers:
- COM_spi_drv_hdma_spi1_rx for the DMA1_Channel2
- COM_spi_drv_hdma_spi1_tx for the DMA1_Channel3
void COM_spi_init_com(void)
{
/* Peripheral clock enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA4 ------> SPI1_NSS
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = EXT_IO_CS_Pin ;
//GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
//GPIO_InitStruct.Speed = GPIO_MODE_INPUT;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(EXT_IO_CS_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = EXT_IO_SCK_Pin|EXT_IO_MISO_Pin|EXT_IO_MOSI_Pin /*| GPIO_PIN_4*/;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
COM_spi_s_HandleStruct.Instance = SPI1;
COM_spi_s_HandleStruct.Init.Mode = SPI_MODE_SLAVE;
COM_spi_s_HandleStruct.Init.Direction = SPI_DIRECTION_2LINES;
COM_spi_s_HandleStruct.Init.DataSize = SPI_DATASIZE_8BIT;
COM_spi_s_HandleStruct.Init.CLKPolarity = SPI_POLARITY_LOW;
COM_spi_s_HandleStruct.Init.CLKPhase = SPI_PHASE_1EDGE;
COM_spi_s_HandleStruct.Init.NSS = SPI_NSS_HARD_INPUT;
COM_spi_s_HandleStruct.Init.FirstBit = SPI_FIRSTBIT_MSB;
COM_spi_s_HandleStruct.Init.TIMode = SPI_TIMODE_DISABLE;
COM_spi_s_HandleStruct.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
COM_spi_s_HandleStruct.Init.CRCPolynomial = 1;
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0); //<--------------------
HAL_NVIC_EnableIRQ(SPI1_IRQn);
/* DMA controller clock enable */
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* DMA1_Channel3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
if (HAL_SPI_Init(&COM_spi_s_HandleStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI1 DMA Init */
/* SPI1_TX Init */
COM_spi_drv_hdma_spi1_tx.Instance = DMA1_Channel3;
COM_spi_drv_hdma_spi1_tx.Init.Request = DMA_REQUEST_SPI1_TX;
COM_spi_drv_hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
COM_spi_drv_hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
COM_spi_drv_hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
COM_spi_drv_hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
COM_spi_drv_hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
COM_spi_drv_hdma_spi1_tx.Init.Mode = DMA_NORMAL;
COM_spi_drv_hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&COM_spi_drv_hdma_spi1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&COM_spi_s_HandleStruct,hdmatx,COM_spi_drv_hdma_spi1_tx);
/* SPI1_RX Init */
COM_spi_drv_hdma_spi1_rx.Instance = DMA1_Channel2;
COM_spi_drv_hdma_spi1_rx.Init.Request = DMA_REQUEST_SPI1_RX;
COM_spi_drv_hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
COM_spi_drv_hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
COM_spi_drv_hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
COM_spi_drv_hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
COM_spi_drv_hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
COM_spi_drv_hdma_spi1_rx.Init.Mode = DMA_NORMAL;
COM_spi_drv_hdma_spi1_rx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&COM_spi_drv_hdma_spi1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&COM_spi_s_HandleStruct,hdmarx,COM_spi_drv_hdma_spi1_rx);
}
During an ESD fault on the SPI, the HAL_SPI_ErrorCallback callback is called:
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
if(hspi == &COM_spi_s_HandleStruct)
COM_spi_drv_reset();
}
At this time, here are the operations that are done
void COM_spi_drv_reset(void)
{
HAL_NVIC_DisableIRQ(SPI1_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel3_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel2_IRQn);
HAL_SPI_DeInit(&COM_spi_s_HandleStruct);
HAL_DMA_DeInit(&COM_spi_drv_hdma_spi1_tx);
HAL_DMA_DeInit(&COM_spi_drv_hdma_spi1_rx);
__HAL_RCC_SPI1_CLK_DISABLE();
__HAL_RCC_DMAMUX1_CLK_DISABLE();
__HAL_RCC_DMA1_CLK_DISABLE();
memset(COM_spi_u8t_buffRx,0,sizeof(COM_spi_u8t_buffRx));
memset(COM_spi_u8t_buffTx,0,sizeof(COM_spi_u8t_buffTx));
COM_spi_init_com();
}
This mechanism does not seem to have any effect, the SPI remains in ERROR state, no return to normal.
Can you help me?
Thank you in advance.