2023-06-25 06:41 PM
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));
}
2023-06-28 10:46 AM
Since you de-initialized DMA, you will need to do the appropriate HAL_DMA_Init call. Or don't do the FORCE_RESET stuff. Either use HAL, or use registers, but trying to do both often leads to issues.
Compare DMA and SPI registers after the first initialization and after your re-initialization to determine quickly what is different.
> strlen((char const*) spi2Buffer)
This is almost assuredly not what you want, as you don't know what the contents of the buffer are. Perhaps you wanted sizeof(spi2Buffer).