cancel
Showing results for 
Search instead for 
Did you mean: 

UART hal RX interrupt modification

Manojkumar Subramaniam
Associate II

My scenario I have a master controller keep sending 30Bytes of data with every 500ms..

Issue when use to my slave controller is :

HAL_UART_Receive_IT(&huart1, varPtr, 20);

the packet might not be received properly as the slave is hot swapped.. it can be listening while the transmission going... so that HAL function get's crazy as it's using some pointer increment... So i was looking for a way for sync the start, my master always start with sending a char 'H' so in someway i have to keep the counter resetting to start point when first byte is not 'H'..

I did this hack it only works once why ? my hack start from line 34 to 45

static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
  uint16_t* tmp;
  
  /* Check that a Rx process is ongoing */
  if(huart->RxState == HAL_UART_STATE_BUSY_RX) 
  {
    if(huart->Init.WordLength == UART_WORDLENGTH_9B)
    {
      tmp = (uint16_t*) huart->pRxBuffPtr;
      if(huart->Init.Parity == UART_PARITY_NONE)
      {
        *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
        huart->pRxBuffPtr += 2U;
      }
      else
      {
        *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
        //if the pRx
        if( (huart->pRxBuffPtr == varPtr) && ( (uint8_t)(huart->Instance->DR & 0xFF) != 'H'  ) )
        {
        	huart->pRxBuffPtr = varPtr;
        }
        else
        {
        huart->pRxBuffPtr += 1U;
        }
      }
    }
    else
    {
      if(huart->Init.Parity == UART_PARITY_NONE)
      {
    	 // *tmp = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
    	  if( (huart->pRxBuffPtr == varPtr) && ( (uint8_t)(huart->Instance->DR & 0xFF) != 'H'  ) )
    	          {
 
    	          	huart->pRxBuffPtr = varPtr;
    	          	*huart->pRxBuffPtr = 'F';
    	          }
    	          else
    	          {
    	          //huart->pRxBuffPtr += 1U;
    	          *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
    	          }
 
 
      }
      else
      {
        *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
      }
    }
 
    if(--huart->RxXferCount == 0U)
    {
      /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
      CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
 
      /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
      CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
 
      /* Rx process is completed, restore huart->RxState to Ready */
      huart->RxState = HAL_UART_STATE_READY;
     
      HAL_UART_RxCpltCallback(huart);
 
      return HAL_OK;
    }
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

11 REPLIES 11
Manojkumar Subramaniam
Associate II
  else
 
  {
 
    uint8_t data = (uint8_t)(huart->Instance->DR & 0xFF);
 
   if(huart->Init.Parity == UART_PARITY_NONE)
 
   {
 
 
 
  	 if( (huart->pRxBuffPtr == varPtr) && ( data != 'H' ) )
 
  	     {
 
 
 
  	     	huart->pRxBuffPtr = varPtr;
 
  	     	*huart->pRxBuffPtr = 'F';
 
  	      	//__HAL_UART_FLUSH_DRREGISTER(huart);
 
  	     }
 
  	     else
 
  	     {
 
  	     *huart->pRxBuffPtr = data;
 
  	     huart->pRxBuffPtr += 1U;
 
  	     //*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
 
  	     }
 
 
 
 
 
   }
 
   else
 
   {
 
    *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
 
   }
 
  }

This is the current code but still have issue when I send say Hell which is 4bytes and then Hello55 which matches 7 bytes which the hello55 is shifted by some positon on the buffer variable...

Manojkumar Subramaniam
Associate II

Hi Guys i seemed to fixed my issue by using this code.. but I am open to feedback to make this code better.

Earlier my data was not fully receiving because of this if(--huart->RxXferCount == 0U) decrement the count so to solve that i returned from function once i found the data is not synced..

        //*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
        //if the pRx
    	 uint8_t data = (uint8_t)(huart->Instance->DR & 0xFF);
        if( (huart->pRxBuffPtr == varPtr) && ( data != 'H'  ) )
        {
        	huart->pRxBuffPtr = varPtr;
        }
        else
        {
        huart->pRxBuffPtr += 1U;
        }
      }
    }
    else
    {
       uint8_t data = (uint8_t)(huart->Instance->DR & 0xFF);
      if(huart->Init.Parity == UART_PARITY_NONE)
      {
 
    	  if( (huart->pRxBuffPtr == varPtr) && ( data != 'H'  ) )
    	          {
 
    	          	huart->pRxBuffPtr = varPtr;
    	          	*huart->pRxBuffPtr = 'F';
    	          	huart->RxState = HAL_UART_STATE_READY;
    	          	CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
    	          	CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
    	          	//__HAL_UART_FLUSH_DRREGISTER(huart);
    	          	HAL_UART_Receive_IT(huart,varPtr,7);
    	          	return HAL_BUSY;
 
    	          }
    	          else
    	          {
    	          *huart->pRxBuffPtr = data;
    	          huart->pRxBuffPtr += 1U;
    	          //*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
    	          }
 
 
      }
      else
      {
        *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
      }