2024-01-26 02:08 AM - edited 2024-01-26 02:11 AM
Hello community ,
I have configured STM32G030 as SPI Slave in DMA mode where master commands poll rate at 50 ms . I have set NSS pin as Hardware input as it is slave .
As soon as NSS pin PB0 detects ,SPI DMA transmission starts in hardware level.
Payload length is 9 Bytes where last two bytes are dummy . sometimes one bit is in 7th byte's nibble(checksum) is getting left shifted by 1 . so checksum is getting failed .
example:- {0x44,0x00,0x00,0x11,0x00,0x00,0x8a,0x00,0x00,};(checksum should be 0x89 (1000 1001) ,but it is received as 0x8a(1000 1010))
kindly give your suggestions for solving this
SPI_HandleTypeDef spi_handle;
DMA_HandleTypeDef hdma_spi1_tx;
DMA_HandleTypeDef hdma_spi1_rx;
uint8_t hctrl_input_msg[10];
uint8_t hctrl_output_msg[10] ;
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance == MB_SPI)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
PB0 ------> SPI1_NSS
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI1 DMA Init */
/* SPI1_RX Init */
hdma_spi1_rx.Instance = DMA1_Channel2;
hdma_spi1_rx.Init.Request = DMA_REQUEST_SPI1_RX;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_CIRCULAR;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx);
/* SPI1_TX Init */
hdma_spi1_tx.Instance = DMA1_Channel3;
hdma_spi1_tx.Init.Request = DMA_REQUEST_SPI1_TX;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
void spi_slave_init(void)
{
spi_dma_enable();
/* Set the SPI parameters */
spi_handle.Instance = SPI1;
spi_handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
spi_handle.Init.Direction = SPI_DIRECTION_2LINES;
spi_handle.Init.CLKPhase = SPI_PHASE_2EDGE;
spi_handle.Init.CLKPolarity = SPI_POLARITY_LOW;
spi_handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi_handle.Init.CRCPolynomial = (uint32_t)7;
spi_handle.Init.DataSize = SPI_DATASIZE_8BIT;
spi_handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
spi_handle.Init.NSS = SPI_NSS_HARD_INPUT;
spi_handle.Init.TIMode = SPI_TIMODE_DISABLE;
spi_handle.Init.Mode = SPI_MODE_SLAVE;
spi_handle.Init.NSSPMode = SPI_NSS_HARD_INPUT;
if (HAL_SPI_Init(&mb_spi_handle) != HAL_OK)
{
Error_Handler();
}
// set DMA TRANSMIT /RECEIVE source ,destination addressses
if(HAL_OK != HAL_SPI_TransmitReceive_DMA(&spi_handle,(uint8_t *)hctrl_output_msg,(uint8_t *)hctrl_input_msg,7))
{
Error_Handler();
}
}
static void spi_dma_enable(void)
{
__DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel2_3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn,0,0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
}
/******************************************************************************/
/*! \brief Handles an NSS interrupt to prepare and terminate SPI transfers.
* \param void
* \return void
*******************************************************************************/
void EXTI0_1_IRQHandler()
{
__HAL_GPIO_EXTI_CLEAR_IT((uint32_t)GPIO_PIN_0);
}
//End of Transmission & Reception
void DMA1_Channel2_3_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_spi1_tx);
HAL_DMA_IRQHandler(&hdma_spi1_rx);
if((hdma_spi1_tx.ErrorCode == HAL_DMA_ERROR_NONE) && (hdma_spi1_rx.ErrorCode == HAL_DMA_ERROR_NONE))
{
notify_exchange_complete();
}
else
{
notify_exchange_fail();
}
}
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
hspi->State = HAL_SPI_STATE_READY;
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
notify_exchange_fail();
}
Thanks
Narendra C
Solved! Go to Solution.
2024-01-26 06:31 AM
Possibly a noise issue. Get a scope and examine the signal at the STM32 pin and at the master pin. Slow down the SPI clock to see if it improves.
If it's consistently the same bit, consider the possibility that what you're receiving is actually what's being sent and the issue is within the code.
2024-01-26 06:31 AM
Possibly a noise issue. Get a scope and examine the signal at the STM32 pin and at the master pin. Slow down the SPI clock to see if it improves.
If it's consistently the same bit, consider the possibility that what you're receiving is actually what's being sent and the issue is within the code.