cancel
Showing results for 
Search instead for 
Did you mean: 

two usart problem

younhun
Associate
Posted on February 07, 2010 at 05:03

two usart problem

#usart_getitstatus-usart2-interrupt-usart_receivedata
10 REPLIES 10
damh
Associate II
Posted on May 17, 2011 at 13:39

If the interrupt is fired, check the reason. In most cases some registers have to be read, some flags have to be reset, ... If you don't do that, the interrupt is fired again and again. Make a breakpoint in the interrupt handler at the point, where you don't know, what have to be done. Then analyze the status registers. I2C, SPI, ... have the same behavior.

hemicuda2
Associate
Posted on May 17, 2011 at 13:39

I have same problem: use two usarts (USART1 and USART2), both transmitting and receiving. After some time of correct working, system is loop in usart1 interrupt.

Could anybody help with this?
chikos332
Associate II
Posted on May 17, 2011 at 13:39

Hi,

It is may be an overrun condition.

Try to add this code into your USART interrupt handler, and I think it will fix the issue:

  /* If Overrun occures, clear the OVR condition */

  if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)

  {

    (void)USART_ReceiveData(USART1);

  }

I met this issue before and this workarround solved it in most cases.

If it doesn't work, then you should test on all conditions that make your USART generate an interrupt and try to find out which one is stucking the communication.

Another possible issue: The priority between interrupts ... try to modify the priority group for each USART ...

hemicuda2
Associate
Posted on May 17, 2011 at 13:39

Thanks a lot! Looks like it was overrun.

But how it goes to interrupt by ORE_FLAG, inspite of disabled overrun interrupt?
jyoung
Associate II
Posted on May 17, 2011 at 13:39

The RXNEIE enables both RXNE and ORE events. You have to check and clear for both in your ISR.

rkeene
Associate II
Posted on May 17, 2011 at 13:39

One deadly possibility is that somewhere else code is defining RESET as non-zero.

This will mung up the code in the Std Periph Lib big time.

rkeene
Associate II
Posted on May 17, 2011 at 13:39

Lookout!  

If you follow the example code in the Std Periph Lib, it will blow up.  The sample code configures the interrupts before it configures the USART.  In my case I was on USART2 on the STM3210E-EVAL kit and I get an immediate interrupt on the serial port right when I do NVIC_Init(&NVIC_InitStructure);   

The problem is that my other structures and memory are not yet set up, so my references in the interrupt handler are NULL and thus it appears that the status bits are 0xFFFF in USART_GetITStatus.

rkeene
Associate II
Posted on May 17, 2011 at 13:39

That did not quite work.

I put the code back to where the NVIC_PriorityGroupConfig is first. Then it fails by giving an interrupt before my structures are set up.

BUT...

In the debugger it does not fail, and if I put a delay just after the NVIC_PriorityGroupConfig then it does not get the early interrupts.

The delay is a for loop for 500 loops.

So what is going on with the interrupts?

rkeene
Associate II
Posted on May 17, 2011 at 13:39

Ok, I found a solution.

Given the STM3210E-EVAL board and IAR Wmbedded Workbench and RTOS.

The setup of the NVIC is important.  With the flag NVIC_PriorityGroup_0 it does not work.

I changed to NVIC_PriorityGroup_4 and it works fine.

I set up the NVIC first.  So my code looks like this...

void Init_SerialPorts()

{

  NVIC_InitTypeDef NVIC_InitStructure;

  

  USART_DeInit(USART1);

  USART_DeInit(USART2);

      

  /* Configure the NVIC Preemption Priority Bits */  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

  //myDelay();

  

  /* Enable the USART1 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  

  /* Enable the USART2 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  

#ifdef UPSTREAM_UART

  // Robust setup of main USART in case flash settings are munged.

  upstreamPacketMode = settingsGetI32(SETTING_IDX_UP_MODE);

  if(upstreamPacketMode != PACKET_MODE_HDLC && 

     upstreamPacketMode != PACKET_MODE_PPP && 

       upstreamPacketMode != PACKET_MODE_SELEX_SSR)

  {

    upstreamPacketMode = PACKET_MODE_HDLC;

    settingsSetI32(SETTING_IDX_UP_MODE, PACKET_MODE_HDLC, true);

    settingsSetI32(SETTING_IDX_UP_BAUDRATE, 19200, true);

    settingsSetI32(SETTING_IDX_UP_RTSCTS, 1, true);

    settingsSave();

  }

  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 

  /* Configure USART2 Rx as input floating */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOA, &GPIO_InitStructure);  

  

  /* Configure USART2 Tx as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure); 

  

  USART_StructInit(&USART2_InitStructure);

  USART2_InitStructure.USART_BaudRate = settingsGetI32(SETTING_IDX_UP_BAUDRATE);

  USART2_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART2_InitStructure.USART_Parity = USART_Parity_No;

  USART2_InitStructure.USART_StopBits = USART_StopBits_1;

  USART2_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  if(settingsGetI32(SETTING_IDX_UP_RTSCTS))

  {

    USART2_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;

  } 

  else

  {

    USART2_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  }

  USART2_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_Init(USART2, &USART2_InitStructure);

  upstreamUartMgr = uartmgrNew(USART2  ,&USART2_InitStructure);

  USART_Cmd(USART2, ENABLE);

#endif

  

#ifdef GPS_SERIAL

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE);

  /* Configure USART1 Rx as input floating */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOA, &GPIO_InitStructure);  

  

  /* Configure USART1 Tx as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure); 

  

  USART_StructInit(&USART1_InitStructure);

  USART1_InitStructure.USART_BaudRate = 9600;

  USART1_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART1_InitStructure.USART_Parity = USART_Parity_No;

  USART1_InitStructure.USART_StopBits = USART_StopBits_1;

  USART1_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_Init(USART1, &USART1_InitStructure);

  gpsUartMgr = uartmgrNew(USART1  ,&USART1_InitStructure);

  USART_Cmd(USART1, ENABLE);

#endif 

  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

  USART_ITConfig(USART1, USART_IT_RXNE | USART_IT_IDLE, ENABLE);

}