Skip to content

Commit 40ab00a

Browse files
tbr-ttnashif
authored andcommitted
drivers/apbuart: add TX FIFO interrupt support
Use TX FIFO level interrupt if available in hardware. It matches the Zephyr UART API and avoids "bootstrapping" which is needed when using the TX edge interrupt ("TI"). TX FIFO has room for up to 32 characters and will typically reduce the number of interrupts. Details: APBUART can be synthesized with or without support for TX/RX FIFO. Edge interrupts which fire when TX holding register changes and RX data available are always available, independent of the FIFO configuration. If FIFO is made available at synthesis time, two additional interrupts become available: TX FIFO half-empty and RX FIFO half-full. These are level interrupts. Signed-off-by: Martin Åberg <[email protected]>
1 parent 697baf1 commit 40ab00a

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

drivers/serial/uart_apbuart.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,17 @@ static int apbuart_fifo_fill(const struct device *dev, const uint8_t *tx_data,
312312
volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
313313
int i;
314314

315+
if (DEV_DATA(dev)->usefifo) {
316+
/* Transmitter FIFO full flag is available. */
317+
for (
318+
i = 0;
319+
(i < size) && !(regs->status & APBUART_STATUS_TF);
320+
i++
321+
) {
322+
regs->data = tx_data[i];
323+
}
324+
return i;
325+
}
315326
for (i = 0; (i < size) && (regs->status & APBUART_STATUS_TE); i++) {
316327
regs->data = tx_data[i];
317328
}
@@ -337,6 +348,12 @@ static void apbuart_irq_tx_enable(const struct device *dev)
337348
volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
338349
unsigned int key;
339350

351+
if (DEV_DATA(dev)->usefifo) {
352+
/* Enable the FIFO level interrupt */
353+
regs->ctrl |= APBUART_CTRL_TF;
354+
return;
355+
}
356+
340357
regs->ctrl |= APBUART_CTRL_TI;
341358
/*
342359
* The "TI" interrupt is an edge interrupt. It fires each time the TX
@@ -358,13 +375,16 @@ static void apbuart_irq_tx_disable(const struct device *dev)
358375
{
359376
volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
360377

361-
regs->ctrl &= ~APBUART_CTRL_TI;
378+
regs->ctrl &= ~(APBUART_CTRL_TF | APBUART_CTRL_TI);
362379
}
363380

364381
static int apbuart_irq_tx_ready(const struct device *dev)
365382
{
366383
volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
367384

385+
if (DEV_DATA(dev)->usefifo) {
386+
return !(regs->status & APBUART_STATUS_TF);
387+
}
368388
return !!(regs->status & APBUART_STATUS_TE);
369389
}
370390

@@ -405,9 +425,18 @@ static int apbuart_irq_is_pending(const struct device *dev)
405425
if ((ctrl & APBUART_CTRL_RI) && (status & APBUART_STATUS_DR)) {
406426
return 1;
407427
}
408-
if ((ctrl & APBUART_CTRL_TI) && (status & APBUART_STATUS_TE)) {
409-
return 1;
428+
429+
if (DEV_DATA(dev)->usefifo) {
430+
/* TH is the TX FIFO half-empty flag */
431+
if (status & APBUART_STATUS_TH) {
432+
return 1;
433+
}
434+
} else {
435+
if ((ctrl & APBUART_CTRL_TI) && (status & APBUART_STATUS_TE)) {
436+
return 1;
437+
}
410438
}
439+
411440
return 0;
412441
}
413442

0 commit comments

Comments
 (0)