cancel
Showing results for 
Search instead for 
Did you mean: 

UART idle transmission

law__
Associate

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);
    }
}

 

3 REPLIES 3
Andrew Neil
Super User

@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 ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

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

Pavel A.
Super User

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.