AnsweredAssumed Answered

STM32F3 USART Receive Interrupt hangs after receiving first set of data from Arduino

Question asked by miewjie.hoon.001 on May 20, 2014
Latest reply on May 20, 2014 by Clive One

hi, everyone.
i am using STM32F3 Discovery Kit to communicate with Arduino. i use EWARM IDE for coding and Putty, for serial terminal.

i did an echo test on stm32f3 usart2. The data is displayed on the serial terminal correctly, so i confirmed the usart communication is working as expected.

then, i try to transfer data from arduino to stm32f3 periodically but the usart on stm32f3 hangs after getting the first set of data (the stm32f3 debug shows the it keeps on checking USART_GetITStatus). The first set of the data is displayed on the serial terminal but most of the time, is garbled up with garbage characters.

i have been stuck for quite some time now. can anyone help? thanks in advance. Below is the coding i used for usart2. baudrate is set 9600.

/***********************************************************************************************************/
#define LINEMAX 15 // Maximal allowed/expected line length
 
volatile char line_buffer[LINEMAX + 1]; // Holding buffer with space for terminating NUL
volatile int line_valid = 0;


/**
  * @brief  Initialize USART2 for PD6 (USART2_RX) and PD5 (USART2_TX)
  *         used for receiving mouse data from arduino
  * @param  baudrate; by default is 115200
  * @retval None
  * link: http://eliaselectronics.com/stm32f4-usart-example-with-interrupt/
  */
void init_USART2(int baudrate)
{
       USART_InitTypeDef USART_InitStructure;    // this is for the GPIO pins used as TX and R
       GPIO_InitTypeDef GPIO_InitStructure;      // this is for the USART1 initilization
       NVIC_InitTypeDef NVIC_InitStructure;      // this is used to configure the NVIC (nested vector interrupt controller)
       
       /* Configure USART1 pins:  Rx and Tx ----------------------------*/
       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
       GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5 | GPIO_Pin_6;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
       GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
       GPIO_Init(GPIOD, &GPIO_InitStructure);   
       
       GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_7);
       GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_7);
       
       /* Configure USART1 pins:  --------------------------------------*/
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
       
       USART_DeInit(USART2);
       USART_InitStructure.USART_BaudRate = baudrate;
       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(USART2,&USART_InitStructure);
          
       USART_Cmd(USART2, ENABLE);
       
       /* Here the USART2 receive interrupt is enabled
        * and the interrupt controller is configured
        * to jump to the USART2_IRQHandler() function
        * if the USART2 receive interrupt occurs
        */
       USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // enable the USART2 receive interrupt


       NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;                  // we want to configure the USART1 interrupts
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;         // this sets the priority group of the USART1 interrupts
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          // this sets the subpriority inside the group
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;               // the USART2 interrupts are globally enabled
       NVIC_Init(&NVIC_InitStructure);                            // the properties are passed to the NVIC_Init function which takes care of the low level stuff


       // finally this enables the complete USART2 peripheral
       USART_Cmd(USART2, ENABLE);
}


void serial_prints (USART_TypeDef* USARTx, volatile char *buffer)
{
     /* transmit till NULL character is encountered */
     while(*buffer)
     {
       USART_SendData(USARTx, *buffer++);
       while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
       delay_us(5);
     }
}


void USART2_IRQHandler(void)
{
  static char rx_buffer[LINEMAX];   // Local holding buffer to build line
  static int rx_index = 0;
 
  if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // Received character?
  {
     char rx =  USART_ReceiveData(USART2);
 
     if ((rx == '\r') || (rx == '\n')) // Is this an end-of-line condition, either will suffice?
     {
          if (rx_index != 0) // Line has some content?
          
               memcpy((void *)line_buffer, rx_buffer, rx_index); // Copy to static line buffer from dynamic receive buffer
               line_buffer[rx_index] = 0; // Add terminating NUL
               line_valid = 1; // flag new line valid for processing
               serial_prints(USART2, rx_buffer);    
               rx_index = 0; // Reset content pointer
          }
     }
     else
     {
          if (rx_index == LINEMAX) // If overflows pull back to start
               rx_index = 0;
 
            rx_buffer[rx_index++] = rx; // Copy to buffer and increment
     }
  }
}
/*********************************************************************************************************/

for arduino reference, i use the following code and the data is displayed correctly in the serial terminal.

printf("%d, %d \n", X, Y);

thanks in advance.

Outcomes