AnsweredAssumed Answered

USART missed rx interrupt

Question asked by giso on Jul 4, 2013
Hi,

I have an STM3220g-sk/iar demo kit.
I try to configure the STM32F2 device to receive data with UART interrupt.
I have the following code
int main()
{
  /* Reset all the ports to default values */
  GPIO_DeInit(GPIOA);
  GPIO_DeInit(GPIOB);
  GPIO_DeInit(GPIOC);
  GPIO_DeInit(GPIOD);
  GPIO_DeInit(GPIOE);
  GPIO_DeInit(GPIOF);
  GPIO_DeInit(GPIOG);
  uart1_init();            
  while(1)
  {
    /* wait */    
  }
}

/*------------------------------------------------------------------------------
 * DESCRIPTION:     intialize USART1  for serial communication
 *----------------------------------------------------------------------------*/
void uart1_init (void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;  

  // Enable UART clock 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6 , ENABLE); 
  
  // Enable GPIOA Clock
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC , ENABLE); 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG , ENABLE); 
  
   // Connect PA9 to USARTx_Tx
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
  
  // Connect PA10 to USARTx_Rx
  GPIO_PinAFConfig(GPIOG, GPIO_PinSource9, GPIO_AF_USART6);
  
  // Configure USART Tx as alternate function
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  // Configure USART Rx as alternate function
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_Init(GPIOG, &GPIO_InitStructure);

  /* UART0 configuration -----------------------------------------------------*/
  /* UART0 configured as follow:
  - Word Length = 8 Bits
  - Two Stop Bit
  - No parity
  - BaudRate = 115200 baud
  - Hardware flow control disabled 
  - Receive and transmit enabled
  */

  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl =     USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 
  USART_Init(USART6, &USART_InitStructure);
  
  USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);
  NVIC_InitTypeDef NVIC_InitStructure;

  // * Enable the USART Interrupt * /
  NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
 
  /* Enable UART0 */
  USART_Cmd(USART6, ENABLE);
}


void USART6_IRQHandler(void)
{
  u8 c;
  u8 info = 0;
  static u32 temp=0;
  static u32 int_count =0;
  static u32 rx_int_count =0;
  
  int_count++;
  if ( USART_GetITStatus ( USART6, USART_IT_ORE ) )
    {
        USART_ReceiveData(USART6);
    }
  /* TX INTERUPT IS TRIGGERED */
  /*
  if(USART_GetITStatus(RS422_HW.USART, USART_IT_TXE) != RESET)
  {
    info++;
    if(tx_cnt)                                           // if still some bytes to be sent, go on to the next one.  
    {
      tx_cnt--;                                                     // one byte has been sent              
      USART_SendData(USART6, (u16)tx_buf[tx_buf_index++]);
    }
    else                                       // Otherwise wait a bit before closing the TX slave port
    {
      RS422_sending_over = true;  
      USART_ITConfig(USART6, USART_IT_TXE, DISABLE);
      it_counter_rs422++;
    }
    
    led_control(LED_BUS_GREEN,2,0,1);                             // Blinks the BUS LED 10ms 
    led_control(LED_BUS_RED,2,0,1);                               // Blinks the BUS LED 10ms 
    
  }*/
  /* RX INTERUPT IS TRIGGERED */
  if(USART_GetITStatus(USART6, USART_IT_RXNE) != RESET)
  {  
    info++;
    {
      rx_int_count++;
      temp++;
      c = (u8)USART_ReceiveData(USART6) & (u8)(0xFF);    
    }
  }
  
  if (info ==0)
  {
        c = (u8)USART_ReceiveData(USART6) & (u8)(0xFF); 
        /* (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
    ITStatus stat = USART_GetITStatus(RS422_HW.USART, USART_IT_TC);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_PE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_TXE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_TC);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_RXNE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_TC);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_ORE_RX);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_IDLE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_LBD);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_CTS);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_ERR);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_ORE_ER);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_NE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_FE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_TXE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_RXNE);
    stat = USART_GetITStatus(RS422_HW.USART, USART_IT_TXE);
        */
  } 
}

The main issue is that when sending byte 1 by 1, it works but when I sent more bytes with no pause in between each byte, I get only 1 time in the interrupt.
If instead of using the interrupt I do poll the  USART_FLAG_RXNE flag, it works fine and I do not miss any byte.

Any idea?

Attachments

Outcomes