cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 USART2 Trapped in RXNE RESET

Rogers.Gary
Senior II
Posted on June 25, 2017 at 22:38

Hi,

I have been working on this for 2 days trying to figure out why my application just stops. After looking at posts on this forum, and other places, and reading the STM32F4 reference manual, I see no problems with my code, but seeing odd behaviour from USART2. Here's my code.

void USART_Response( char *s, uint16_t len )

{

    while( len-- )

    {

        while( USART_GetFlagStatus(USART2, USART_FLAG_TXE ) == RESET);

        USART_SendData( USART2, *s++ );

    }        

   //so I can see what this is doing

    printf('%i: SR = %x\n', srCtr++, USART2->SR);   // PRINTS 0xD0 == 11010000 = TXE, TC, IDLE are SET

            

    while( 1 ) // poll response

    {

        while( USART_GetFlagStatus(USART2, USART_FLAG_RXNE ) == RESET);     // ALWAYS STALLS HERE     

        rxCode = USART2->DR;

     

        if( rxCode == 0x3E ) //a regular '>' has been received

        {

            PROMPT_SET = TRUE;

            printf('%x, ', rxCode);

        }   

        else if( rxCode = 0xD )

        {

           PROMPT_SET = FALSE;

            printf('%x\n', rxCode);

           break;

        }

    }

}

The printf are there for debugging. It prints these 2 lines over, until it stalls on RXNE:

3e, d

0xd0

The strings sent out are to a screen. The target device first sends back a 0x3E, then a carriage return (0xD) That's it.It will sail along for 15 mins, sometimes an hour, then suddenly choke. With the SR at 0xD0, I cannot understand why this is getting stalled here. This happens with/without the  debugger running as well.

I could understand it if the ORE was set, or IDLE was not set, but what can I do to fix this? Any advice would be greatly appreciated, thanks. 

ADDED AFTER: USART SETUP CODE

void USART2_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;   

    //enable USART peripheral clock

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    //enable peripheral A clock

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = SCRN_UART_TX | SCRN_UART_RX;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;             

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;        

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;            

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;            

    GPIO_Init(GPIOA, &GPIO_InitStructure);                    

    //set to alternate function 1 for UART operation

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

    

    /* USARTx configured as:

        - SCRN_UART_BAUD= 115200 baud

        - Word Length = 8 Bits

        - One Stop Bit

        - No parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

    */

    USART_InitStructure.USART_BaudRate = SCRN_UART_BAUD;

    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_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    USART_Init(USART2, &USART_InitStructure);

    USART_Cmd(USART2, ENABLE);

}
6 REPLIES 6
Posted on June 26, 2017 at 03:45

i) Not receiving any data.

ii) IRQ Handler end-running code, ie goes to handler and you're not servicing it, never leaves interrupt context.

iii) The debug view is clearing the SR by showing the DR.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Rogers.Gary
Senior II
Posted on June 26, 2017 at 05:29

Hi,

I understand point #3. I'm lost on #1 and #2. Would you be so kind as to clarify?

Thanks.

Added this:

I see what you are saying in #1. There is no data to be received on these transactions. I send a string, and the screen sends back a '>' to indicate success, and then a 0xD (carriage return.

That just leaves #2, so can you please clarify that point ?

Thanks clive1

Rogers.Gary
Senior II
Posted on June 26, 2017 at 06:10

It's supposed to be a polling loop. I must be missing something? Maybe this is just a bad way to do this. I'm calling the function form a QueueReceive that handles output to a screen. When a message arrives in the receive queue, it sends the buffer pointer and the USART sends in this function. immediately after, it goes into the while( 1 ) loop, waiting for the RXNE flag to be set for response characters, then processes those characters (either a 0x3E or a 0xD) There is a 'receive' there: rxCode = USART2->DR

Does this not empty the data register?

Perhaps...if it doesn't make sense, maybe it should be changed. It was 'recommended' to do it this way. Perhaps it should be done in an interrupt and perform an interrupt safe QueueSend to notify the task the response was received.

Posted on June 26, 2017 at 05:49

I don't fully understand where this code is called.

You enable a RXNE interrupt. If that fires into the IRQHandler and you don't empty the DR, it will never execute foreground code again. If this loop is in foreground code that will never leave.

Equally if you wait for RXNE in foreground and service RXNE in the background, you are again unlikely to see RXNE in the foreground because it was cleared already in the background, and you then sit forever in your loop.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 26, 2017 at 06:23

If polling, then don't do this

USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Rogers.Gary
Senior II
Posted on June 26, 2017 at 08:27

That line: 'USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);'

was actually removed out and I'm not sure how it got pasted into my post. Sorry about that. I fully realize that line would be for interrupt driven code.

In any case, after trying further, I gave up on polling and went to a Queue driven mechanism. Coded it, have been testing, and I can say it works 100%.

Thanks for taking the time to answer my post clive1.