Skip to main content
Visitor II
November 5, 2008
Question

UART TX finished interrupt needed

  • November 5, 2008
  • 12 replies
  • 2570 views
Posted on November 05, 2008 at 22:02

UART TX finished interrupt needed

    This topic has been closed for replies.

    12 replies

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    Hi! Try to use this:

    while(UART_GetFlagStatus(UART0, UART_FLAG_Busy));

    & RTFM!!!

    BUSY: UART Busy

    If this bit is set to 1, the UART is busy transmitting data. This bit remains set until the complete byte, including all the stop bits, has been sent from the shift register. This bit is set as soon as the transmit FIFO becomes non-empty (regardless of whether the UART is enabled or not).

    UM0216 page 264

    d_steffenAuthor
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    I use uart interrupt and uart hardware fifo based transmitting and

    receiving on the ST912FW44.

    How can I get the information (an interrupt), if the

    uart transmit (hw fifo used) finished, after the the last

    byte is sended on the port pin output including the stop bit(s) ?

    d_steffenAuthor
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    Hi Andy,

    I can't use busy waiting, I need to control how fast as possible

    after (and before) trinsmitting a RX485 tx-enable pin in the interrupt handler.

    Other controllers like atmel avr have an tx emtpy or

    tx finished interrupt flag.

    The busy flag can only polled outside the interrupt function in the application.

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    Quote:

    The busy flag can only polled outside the interrupt function in the application.

    OK. In this case you should use buffer FIFO and fill data in it in process of a transmitting on interruption. The basic program will be carried out further.

    if(UART_GetITStatus(UART0, UART_IT_Transmit) != RESET)

    {

    for(i = 0; (i < 8) && (TxCounter < NbrOfDataToTransfer); i++)

    {

    UART_SendData(UART0, TxBuffer[TxCounter++]);

    }

    if(TxCounter != NbrOfDataToTransfer)

    {

    /* Clear the UART0 transmit interrupt */

    UART_ClearITPendingBit(UART0, UART_IT_Transmit);

    }

    else

    {

    /* Disable the UART Transmit interrupt */

    UART_ITConfig(UART0, UART_IT_Transmit, DISABLE);

    }

    }

    d_steffenAuthor
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    I think you don't understand my question in

    case of transmitting data with a RS485 communication.

    1.) before you send any data from the uart you have

    to switch on the tx enable line of the RS485 transceiver

    2.) send out the data from the uart (hardware fifo, software fifo)

    interrupt controlled

    3.) switch off the tx enable line of the RS485 transceiver

    immediately after the last stop bit from the last byte

    of the transmitting frame ist sendet out from the uart

    this all should be done in the uart ty interrupt handler,

    the application only fills the software fifo and starts the

    transmit interrupt

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    Barricade wroute:

    Quote:

    1.) before you send any data from the uart you have

    to switch on the tx enable line of the RS485 transceiver

    ...

    3.) switch off the tx enable line of the RS485 transceiver

    immediately after the last stop bit from the last byte

    of the transmitting frame ist sendet out from the uart

    this all should be done in the uart ty interrupt handler,

    the application only fills the software fifo and starts the

    transmit interrupt

    All above could not be done inside UART tx interrupt handler!

    At least you shoud switch on the tx enable line outside interrupt handler.

    About p.3. I can not anderstand what for you want ''switch off the tx enable line ... immediately after the last stop bit from the last byte of the transmitting frame is sended out from the uart''? It is not nessasary. You may switch it off after you stop sending bytes into FIFO, even bytes steel staing in UART FIFO. Any way the bytes steel staing in FIFO will be sent out UART FIFO after that.

    d_steffenAuthor
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    read this for understanding RS485 communication

    http://www.netrino.com/Articles/RS485Enable/index.php

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    You could use a timer interrupt to poll the status. Not nice, but the UART macrocell does not appear to have any support beyond the status bit.

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    Barricade: did you find a solution to your problem?

    Or has anyone else found how to detect end of transmission without polling?

    Cheers,

    Paul :)

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:45

    Hi

    We are using RS-485 & the enable is on P6.3

    And some Macros we use are:

    // P6.3

    // RS-485 Direction

    // Actually taken care of by the OCMP2 used as a One-Shot

    #define m_RS485BitDirOut() GPIO6->DR[GPIO_Pin_3 BitAddr] = GPIO_Pin_3

    #define m_RS485BitDirIn() GPIO6->DR[GPIO_Pin_3 BitAddr] = 0

    In the Init do

    // P6.3 AltOut2 Timer1 OutComp2

    // P6.3 is the RS-485 Direction Pin

    SCU->GPIOOUT[6] |= 0x0080;

    GPIO6->DDR |= 0x08; // P6.3 Output

    m_RS485BitDirIn(); // Enable UART1 RS-485 to Rx

    Then in the Tx do

    __disable_interrupt();

    TIM1->CR1 |= 0xA80; // force high (FLV2 + OLV2 + OC2E)

    // maybe should be using UART_Mode_Tx (0x0100) and not UART_Enable_Mask (0x0001)

    UART1->CR &= ~0x00000001; // disable UART1

    UART1->LCR |= 0x00000004; // set even parity for local mode

    UART1->DR = cData; // Load single Character to output

    // Used to control an output waveform (RS-485 Direction)

    // P6.3 AltOut2 Timer1 OutComp2

    // P6.3 is the RS-485 Direction Pin

    // At a Baud rate of 625000, we get 16 usec for a character

    // For this Function we need a Minimum or 16 usec (1 char)

    // Force low for 28 usec (16 usec/char)

    TIM1->OC2R = TIM1->CNTRX + (18 + 10);

    TIM1->CR1 &= ~0xA00; // remove (FLV2 + OLV2) force make comapare level low

    UART1->CR |= 0x00000001; // enable

    __enable_interrupt();

    For more than One byte

    // Calc number of Usec needed for the number of char Tx'ed

    lTimerCounts = (lLength * 176)+120;

    lTimerCounts /= 10;

    // lTimerCounts = (lLength * 18) + 12; // This maybe faster REG 07/31/2008

    __disable_interrupt();

    TIM1->CR1 |= 0xA80; // force high (FLV2 + OLV2 + OC2E)

    UART1->CR &= ~0x00000001; // disable

    UART1->LCR |= 0x00000004; // set even parity for local mode

    UART1->CR |= 0x00000001; // enable

    // Used to control an output waveform (RS-485 Direction)

    // P6.3 AltOut2 Timer1 OutComp2

    // P6.3 is the RS-485 Direction Pin

    // At a Baud rate of 625000, we get 16 usec for a character

    // For this Function we need a Minimum or 16 usec * lLength

    // Force low for ?? usec (16 usec/char)

    TIM1->OC2R = TIM1->CNTRX + (short)lTimerCounts;

    TIM1->CR1 &= ~0xA00; // remove (FLV2 + OLV2) force make comapare level low