Skip to main content
stbbrad3
Associate III
June 4, 2012
Question

F207 USART TXE issues

  • June 4, 2012
  • 3 replies
  • 856 views
Posted on June 04, 2012 at 16:29

Hello.

I am seeing issues witht he TXE interrupt firing for no reason.

Here is my IRQ handler:

#define COM3       USART3

void USART3_IRQHandler(void)

{

    uint8_t x;

    // Get Byte from DR in case of Overrun

    if ( COM3->SR & USART_FLAG_ORE )

    {

        x = COM3->DR;

    }

    if ( COM3->SR & USART_FLAG_RXNE )

    {

        while ( COM3->SR & USART_FLAG_RXNE )

        {

            DIL_Serial_RX_Receive ( PROTOCOL_PORT );

        }

    }

    else if ( COM3->SR & USART_FLAG_TXE )

    {

        DIL_Serial_TX_Send ( PROTOCOL_PORT );

    }

}

The snippit of the write function my ISR calls:

        case PROTOCOL_PORT:

            if ( Com3TxQue.Head != Com3TxQue.Tail )

            {

                COM3->DR = *Com3TxQue.Tail;

                if ( ++Com3TxQue.Tail == &Com3TxQue.Buff[COM3_TX_BUFFER_SIZE] )

                {

                    Com3TxQue.Tail = &Com3TxQue.Buff[0];

                }

                Com3TxQue.BytesOut--;

                Com3TxQue.Flag &= ~FULL;

            }

            else

            {

                // Disable the TX enable line

                GPIO_ResetBits ( RS485_TX_EN_GPIO_PORT, RS485_TX_EN_PIN );

                // Disable TX              

                USART_ITConfig  ( COM3, USART_IT_TXE, DISABLE );

                USART3->CR1 &= !USART_CR1_TXEIE;

            }

Can anyone explain why this interrupt would fire if there is no RX data and TXEIE in CR1 is reset?

I have read about a delay being needed before disabling the TXEIE flag and have tried a double for loops before disabling with no avail.

This does not happen at run time, but after a few seconds of running and receieving packets.

Anyone with similar problems, ideas, solutions?

Thanks.
    This topic has been closed for replies.

    3 replies

    stbbrad3
    stbbrad3Author
    Associate III
    June 4, 2012
    Posted on June 04, 2012 at 16:51

    Sorry guys,

    I guess I should have searched these forums a little better...

    I changed my ISR to:

        // Get Byte from DR in case of Overrun

        if ( USART_GetITStatus ( COM3, USART_IT_ORE ) )

        {

            x = COM3->DR;

        }

        if ( USART_GetITStatus ( COM3, USART_IT_RXNE ) )

        {

            while ( USART_GetITStatus ( COM3, USART_IT_RXNE ) )

            {

                DIL_Serial_RX_Receive ( PROTOCOL_PORT );

            }

        }

        if ( USART_GetITStatus ( COM3, USART_IT_TXE ) )

        {

            DIL_Serial_TX_Send ( PROTOCOL_PORT );

        } This seemed to fix the issue and makles much more sense.

    I was just confused why have USART_GetFlagStatus if there is a USART_GetITStatus.

    Cheers

    Tesla DeLorean
    Guru
    June 4, 2012
    Posted on June 04, 2012 at 16:55

    Can you disable the flag? or just the interrupt it generates?

    I'm pretty sure TXE flags whenever the buffer is empty, and only gets cleared when you physically put data in the buffer, and it will go high again almost immediately if the shift register was empty. So unless both the shift register and holding register are full it's going to signal.

    I think you should assume the interrupt enabling bit gates the flag to NVIC through some AND-OR construct for the USARTx_IRQ

    Also it's USART3->CR1 &= ~USART_CR1_TXEIE; // not !USART_CR1_TXEIE

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    stbbrad3
    stbbrad3Author
    Associate III
    June 4, 2012
    Posted on June 04, 2012 at 17:46

    Clive,

    Yeah, thanks.

    I found a good illustration in the referance manual that shows the gating of the interrupts.

    All seems to be well now.

    And thanks for catching my mistake! Though that was just a test and is removed now.