Skip to main content
Explorer II
October 2, 2025
Question

UART idle transmission

  • October 2, 2025
  • 4 replies
  • 701 views

Hi,

I'm exploring using UART idle interrupt on RX to signal to my application that data has arrived.

I currently push data into a tx queue then start transmission. I rely on uart tx ISRs to check if there is any more data to send, then load up a DMA transfer.

UART TE is enabled once when the UART is enabled. I then rely on DMA to do everything. This currently works very well.

Can anyone suggest how I could squeeze and idle frame in? Ideally an idle frame will be inserted after each call to uart_dma_send, eg once per item in the transmit queue. My aim would be to keep my current transmit setup, where I can keep shoveling data into the transmit queue. Im using STM32F745. Probably I've missed something in the datasheet..

TX currently looks like:

void interface_uart_send_stuff(if_uart_t* p, uint8_t* stuff, uint16_t length) {
 tx_q_push(p, length, stuff);
 if (tx_state_is_busy()) {
 // TX already happening, just queue up more to send
 return;
 }
 // Start tx
 tx_q_dta_t tx = tx_q_popI(&p->tx_q);
 uart_dma_send(p->uart_dev, tx.n, tx.d);
}
// TX end of dma interrupt. Pack more data if needed
void interface_uart_tx_end_isr(if_uart_t* p) { 
 if (tx_q_sizeI(&p->tx_q) > 0) {
 tx_q_dta_t tx = tx_q_popI(&p->tx_q);
 // Send by DMA data d, length n
 uart_dma_send(p->uart_dev, tx.n, tx.d);
 } else {
 // We enable the TC interrupt here so that is only called on the last DMA transfer
 // from the transmit queue
 p->uart_dev->uart->CR1 |= USART_CR1_TCIE;
 }
}
// End of physical transmission interrupt
void interface_uart_tx_eot_isr(if_uart_t* p) {
 if (tx_q_sizeI(&p->tx_q) > 0) {
 tx_q_dta_t tx = tx_q_popI(&p->tx_q);
 uart_dma_send(p->uart_dev, tx.n, tx.d);
 } else {
 tx_next_state(p, tx_ready_s);
 }
}

 

    This topic has been closed for replies.

    4 replies

    Super User
    October 2, 2025

    @law__ wrote:

    I'm exploring using UART idle interrupt on RX to signal to my application that data has arrived.


    How would idle help you detect that data has arrived ?

    RXNE tells you when data has arrived.

    And how does this relate to the rest of the question - which seems to be all about transmit ?

    law__Author
    Explorer II
    October 2, 2025

    Hey,

    > I'm exploring using UART idle interrupt on RX to signal to my application that data has arrived.

    I'm just setting some context of what I'm doing. I have UART RX idle interrupt working well and it does what I want. The rest of my question is all about finding a pattern to insert an idle at the end of a TX by DMA. Ideally if there is data in the tx_q, I'd like to start it sending from within the interrupt. Otherwise I'll have to signal back to my application to start another UART transmit

    Thanks

    Super User
    October 2, 2025

    Wouldn't it be better to have a specific "end-of-message" marker?

    Super User
    October 2, 2025

    AFAIK there is no easy way to "inject" idle characters into the TX DMA flow. If you want to make pauses after each TX message, maybe start a timer at the TX DMA end event.

     

    Super User
    October 3, 2025

    Break can cause a frame error, the receiver should be ready to handle it.

     

    law__Author
    Explorer II
    October 28, 2025

    I've been experimenting with transmitting a break. The receive side is working well.

    Tesla Delorean mentioned:

    > Other might be able to send a slack or break character to the UART and catch a TC interrupt off that to light off next DMA TX operation.

    I've been experimenting with this a bit lately, but I wonder if anyone can confirm if transmitting a break (via setting SBKRQ or SBK bits) actually generates a TC interrupt? I can't see a mention of it doing so in the reference manuals.

    Im pretty sure it does not, though I would very much like to be told otherwise. In my existing TC handler I set SBKRQ/SBK then exit. If transmitting break did generate a TC interrupt I would expect a second call to TC handler soon after break transmitting. I've verified on the oscilloscope that no second TC happens.

    I looked at just spinning on the break status bit in the TC handler (eg while (p->usart->ISR & USART_ISR_SBKF) {}) but my system did not enjoy that. I end up spending a couple of us in the TC handler waiting.

    I did have some success enabling a GPIO interrupt (EXTI actually...) on the uart TX pin while in the TC handler, then exiting the TC handler. When the break finishes transmission the GPIO interrupt fires when the TX pin transitions. If it is not possible to fire a TC interrupt after the break, I'll probably push on with this method.

    Thanks