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

 

2 REPLIES 2
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