cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Slave data is storing incorrectly in receive buffer sometimes

Nchun.1
Senior

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

Nchun1_1-1700294157522.png

Checksum pass sample

Nchun1_2-1700294188163.png

 

@waclawek.jan , @TDK ,@Imen.D , @Tesla DeLorean

 

Thanks 

Narendra . C

 

1 ACCEPTED SOLUTION

Accepted Solutions
Nchun.1
Senior

Hello Community ,

The issue is resolved now after increasing SPI clock speed .

Thank you 

View solution in original post

5 REPLIES 5
Tinnagit
Senior II

I'm unsure but I think that MOSI - Master Out Slave In is stored data correctly.
In image is start with 0x03 so that it get correct on.
So it's possible that master are do wrong. 

another thing is I'm unsure what kind of this protocol. It's like as the MCU has free to exchange the data directly.
there is no any protocol as something like read or write command.

it is SPI communication . I programmed SPI Slave, i used External pin interrupt as chip select where it enables and disables the SPI slave and talk to master .

SPI data is not saving correctly in rx_buffer . 0x03 should be at the end of the rx_buffer

Tinnagit
Senior II

but from this image

Tinnagit_0-1700301279285.png

it's start with 0x03.

Hi @Tinnagit ,

Channel 1 is MISO (it is the output from slave) .Here i am sending back the data which is received from master .

Thanks 

Narendra C 

Nchun.1
Senior

Hello Community ,

The issue is resolved now after increasing SPI clock speed .

Thank you