SPI Slave data is storing incorrectly in receive buffer sometimes
Hello community ,
I have programmed stm32g030k06t6 MCU has SPI Slave . When trying to communicate with master for 10 times , 6 times checksum is getting failed and 4 times it is getting passed .
Master is sending 9 bytes of data i.e 0x1,0x2,0x3,0x4,0x5,0x6,0xc9,0x00,0x3 . when checksum is getting failed it is getting saved in buffer in following order 0x3,0x1,0x2,0x3,0x4,0x5,0x6,0xc9,0x00. one byte is getting shifted in rx_buffer when storing
Inorder to analyse the problem , i am copying rx_buffer to tx_buffer in order to analyse better where snaps are attached below .
kindly suggest
/******************************************************************************/
/*! \brief Handles an NSS interrupt to prepare and terminate SPI transfers.
* \param void
* \return void
*******************************************************************************/
void mb_spi_slave_interrupt_nss(void)
{
/* EXTI0 line interrupt detected */
if (__HAL_GPIO_EXTI_GET_IT((uint32_t)MB_SPI_NSS_PIN) != (uint32_t)0)
{
//HAL constants
__HAL_GPIO_EXTI_CLEAR_IT((uint32_t)MB_SPI_NSS_PIN);
mb_spi_handle.pTxBuffPtr = (uint8_t *)&tx_buffer[0] ;
mb_spi_handle.TxXferCount = (uint16_t)9;
mb_spi_handle.pRxBuffPtr = (uint8_t *)&rx_buffer[0] ;
mb_spi_handle.RxXferSize = (uint16_t)9;
mb_spi_handle.RxXferCount = 0;
/* Ignore the interrupt if SPI communication is disabled.
* SPI interrupts remain deactivated */
if (STATE_DISABLED != slave_state)
{
// Pin is low that means active to indicate master has started the transfer
if (!(MB_SPI_NSS_PORT->IDR & (uint32_t)MB_SPI_NSS_PIN))
{
/* Enable TXE, RXNE and ERR interrupt */
__HAL_SPI_ENABLE_IT(&mb_spi_handle, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(&mb_spi_handle);
/* Send the first character to the data register */
tx_isr();
}
/* Pin is high (inactive) to indicate master has terminated the transfer */
if ((MB_SPI_NSS_PORT->IDR & (uint32_t)MB_SPI_NSS_PIN))
{
// Disable the Slave Now
// slave_state = STATE_DISABLED;
/* Disable SPI peripheral */
__HAL_SPI_DISABLE(&mb_spi_handle);
/* Disable TXE, RXNE and ERR interrupt */
__HAL_SPI_DISABLE_IT(&mb_spi_handle, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
memcpy(tx_buffer,0,9);
memcpy(tx_buffer,rx_buffer,9);
// Verify the message checksum.
if (hctrl_verify_msg_checksum((uint8_t *)hctrl_input_msg,7) == true)
{
tx_buffer[0] = 0x4a;
}
else
{
tx_buffer[0] = 0x09
}
}
}
}
}
/******************************************************************************/
/*! /brief Interrupt Handler to transmit packets
*
******************************************************************************/
void tx_isr(void)
{
/* Transmit data in 8 Bit mode */
if ((uint16_t)0 < mb_spi_handle.TxXferCount)
{
// Monitor SPI fifo transmission level continously and send the data out
while(!(mb_spi_handle.Instance->SR & SPI_FLAG_FTLVL) && mb_spi_handle.TxXferCount > 0)
{
*((__IO uint8_t *)&mb_spi_handle.Instance->DR) = (*mb_spi_handle.pTxBuffPtr);
mb_spi_handle.pTxBuffPtr++;
mb_spi_handle.TxXferCount--;
}
}
else
{
__HAL_SPI_DISABLE_IT(&mb_spi_handle, SPI_IT_TXE);
}
}
/******************************************************************************/
/*! /brief Interrupt Handler to receive packets
*
******************************************************************************/
void rx_isr(void)
{
/* Receive data in 8 Bit mode */
if (mb_spi_handle.RxXferCount < mb_spi_handle.RxXferSize)
{
// Monitor SPI fifo reception level continously until we gets data
while(mb_spi_handle.Instance->SR & SPI_FLAG_FRLVL)
{
if (mb_spi_handle.RxXferCount > mb_spi_handle.RxXferSize)
{
break;
}
*(mb_spi_handle.pRxBuffPtr++) = *((__IO uint8_t *) &mb_spi_handle.Instance->DR); mb_spi_handle.RxXferCount++;
}
}
}
void mb_spi_slave_interrupt_spi(void)
{
FlagStatus tmp1;
FlagStatus tmp2;
FlagStatus tmp3;
tmp1 = __HAL_SPI_GET_FLAG(&mb_spi_handle, SPI_FLAG_RXNE)?SET:RESET;
tmp2 = __HAL_SPI_GET_IT_SOURCE(&mb_spi_handle, SPI_IT_RXNE);
tmp3 = __HAL_SPI_GET_FLAG(&mb_spi_handle, SPI_FLAG_OVR)?SET:RESET;
/* SPI in mode Receiver and Overrun not occurred ---------------------------*/
if ((tmp1 != RESET) && (tmp2 != RESET) && (tmp3 == RESET))
{
rx_isr();
}
tmp1 = __HAL_SPI_GET_FLAG(&mb_spi_handle, SPI_FLAG_TXE)?SET:RESET;
tmp2 = __HAL_SPI_GET_IT_SOURCE(&mb_spi_handle, SPI_IT_TXE);
/* SPI in mode Transmitter ---------------------------------------------------*/
if ((tmp1 != RESET) && (tmp2 != RESET))
{
tx_isr();
}
if (__HAL_SPI_GET_IT_SOURCE(&mb_spi_handle, SPI_IT_ERR) != RESET)
{
/* SPI CRC error interrupt occurred ---------------------------------------*/
if (__HAL_SPI_GET_FLAG(&mb_spi_handle, SPI_FLAG_CRCERR))
{
(&mb_spi_handle)->ErrorCode |= HAL_SPI_ERROR_CRC;
__HAL_SPI_CLEAR_CRCERRFLAG(&mb_spi_handle);
}
/* SPI Mode Fault error interrupt occurred --------------------------------*/
if (__HAL_SPI_GET_FLAG(&mb_spi_handle, SPI_FLAG_MODF))
{
(&mb_spi_handle)->ErrorCode |= HAL_SPI_ERROR_MODF;
__HAL_SPI_CLEAR_MODFFLAG(&mb_spi_handle);
}
/* SPI Overrun error interrupt occurred -----------------------------------*/
if (__HAL_SPI_GET_FLAG(&mb_spi_handle, SPI_FLAG_OVR))
{
(&mb_spi_handle)->ErrorCode |= HAL_SPI_ERROR_OVR;
__HAL_SPI_CLEAR_OVRFLAG(&mb_spi_handle);
}
/* SPI Frame error interrupt occurred -------------------------------------*/
if (__HAL_SPI_GET_FLAG(&mb_spi_handle, SPI_FLAG_FRE))
{
(&mb_spi_handle)->ErrorCode |= HAL_SPI_ERROR_FRE;
__HAL_SPI_CLEAR_FREFLAG(&mb_spi_handle);
}
}
return;
}
Checksum failing packet sample

Checksum pass sample

Thanks
Narendra . C
