Skip to content

Commit 6fc525c

Browse files
frankshuweilinnashif
authored andcommitted
drivers: serial: uart_cdns: fix interrupt driven
Fix interrupt driven for shell Signed-off-by: Frank Lin <[email protected]>
1 parent 49e8c98 commit 6fc525c

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

drivers/serial/uart_cdns.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ static int uart_cdns_fill_fifo(const struct device *dev, const uint8_t *tx_data,
8383

8484
for (i = 0; i < len && (!uart_cdns_is_tx_fifo_full(uart_regs)); i++) {
8585
uart_regs->rx_tx_fifo = tx_data[i];
86-
while (!uart_cdns_is_tx_fifo_empty(uart_regs)) {
87-
}
8886
}
8987
return i;
9088
}
@@ -108,14 +106,20 @@ void uart_cdns_enable_tx_irq(const struct device *dev)
108106
{
109107
struct uart_cdns_regs *uart_regs = DEV_UART(dev);
110108

111-
uart_regs->intr_enable |= CSR_TTRIG_MASK;
109+
/*
110+
* TX empty interrupt only triggered when TX removes the last byte from the
111+
* TX FIFO. We need another way generate the first interrupt. This is why
112+
* we have the timer involved here
113+
*/
114+
uart_regs->rx_timeout = DEFAULT_RTO_PERIODS_FACTOR;
115+
uart_regs->intr_enable = CSR_TEMPTY_MASK | CSR_TOUT_MASK;
112116
}
113117

114118
void uart_cdns_disable_tx_irq(const struct device *dev)
115119
{
116120
struct uart_cdns_regs *uart_regs = DEV_UART(dev);
117121

118-
uart_regs->intr_disable |= CSR_TTRIG_MASK;
122+
uart_regs->intr_disable = CSR_TEMPTY_MASK | CSR_TOUT_MASK;
119123
}
120124

121125
static int uart_cdns_irq_tx_ready(const struct device *dev)
@@ -132,16 +136,16 @@ void uart_cdns_enable_rx_irq(const struct device *dev)
132136
{
133137
struct uart_cdns_regs *uart_regs = DEV_UART(dev);
134138

135-
uart_regs->rx_timeout = DEFAULT_RTO_PERIODS_FACTOR;
136-
uart_regs->intr_enable |= (CSR_RTRIG_MASK | CSR_RBRK_MASK | CSR_TOUT_MASK);
139+
uart_regs->rx_fifo_trigger_level = 1;
140+
uart_regs->intr_enable = CSR_RTRIG_MASK;
137141
}
138142

139143
/** Disable RX UART interrupt */
140144
void uart_cdns_disable_rx_irq(const struct device *dev)
141145
{
142146
struct uart_cdns_regs *uart_regs = DEV_UART(dev);
143147

144-
uart_regs->intr_disable |= (CSR_RTRIG_MASK | CSR_RBRK_MASK | CSR_TOUT_MASK);
148+
uart_regs->intr_disable = CSR_RTRIG_MASK;
145149
}
146150

147151
static int uart_cdns_irq_rx_ready(const struct device *dev)
@@ -204,6 +208,10 @@ static void uart_cdns_irq_handler(const struct device *dev)
204208
/* need to make local copy of the status */
205209
isr_status = uart_regs->channel_intr_status;
206210

211+
if (isr_status & CSR_TOUT_MASK) {
212+
uart_regs->intr_disable = CSR_TOUT_MASK;
213+
}
214+
207215
irq_unlock(key);
208216
}
209217

0 commit comments

Comments
 (0)