Clear SPI Rx buffer using DMA and resume receiving.
Hello.
Two NUCLEO-G431RBs are used for SPI communication.
One is used as SPI master and one as SPI slave, and the pins of SCK and MOSI are connected to each other using jumper cables.
Communication works fine most of the time.
However, when the other power line is energized, once the clock skips or excessive clock due to EMI occurs, and subsequent data cannot be received accurately. I assume this is due to data remaining in the Rx buffer.
Therefore, I have tried clearing the Rx buffer, but after clearing it, when I resume receiving, the receive callback is not called, so it seems it is not resumed.
Please let me know if you know the cause.
// master settings
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
HAL_SPI_Transmit_DMA(&hspi1, spi1Buffer, strlen((char const*) spi1Buffer));
// slave settings
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_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
hdma_spi2_rx.Instance = DMA1_Channel2;
hdma_spi2_rx.Init.Request = DMA_REQUEST_SPI2_RX;
hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_rx.Init.Mode = DMA_CIRCULAR;
hdma_spi2_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_SPI_Receive_DMA(&hspi2, spi2Buffer, strlen((char const*) spi2Buffer));
if(strncmp((char *)spi2Buffer, "HR", 2) != 0){
// Reset will normalize communication, but I don't want to reset.
// HAL_NVIC_SystemReset();
HAL_SPI_DMAStop(&hspi2);
while(HAL_SPI_DeInit(&hspi2) != HAL_OK);
__HAL_RCC_SPI2_FORCE_RESET();
__HAL_RCC_DMA1_FORCE_RESET();
__HAL_RCC_DMA1_RELEASE_RESET();
__HAL_RCC_SPI2_RELEASE_RESET();
/* DMA controller clock enable */
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
HAL_SPI_Init(&hspi2);
HAL_SPI_Receive_DMA(hspi2, spi2Buffer, strlen((char const*) spi2Buffer));
}