2025-10-01 10:54 PM
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);
}
}
2025-10-27 5:59 PM - edited 2025-10-27 10:50 PM
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