Skip to content

Commit 811d77a

Browse files
ibirnbaumcarlescufi
authored andcommitted
drivers: serial: xlnx_xuartps: Fix interrupt-driven operation
Fixes interrupt-driven operation. With the previous way of handling the TX FIFO and the interrupt flags, the operation of the UART was prone to stalling when using it as the console I/O device. Signed-off-by: Immo Birnbaum <[email protected]>
1 parent fe33a24 commit 811d77a

File tree

1 file changed

+15
-27
lines changed

1 file changed

+15
-27
lines changed

drivers/serial/uart_xlnx_ps.c

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,6 @@ static int uart_xlnx_ps_init(const struct device *dev)
303303
/* Set RX FIFO trigger at 1 data bytes. */
304304
sys_write32(0x01U, reg_base + XUARTPS_RXWM_OFFSET);
305305

306-
/* Set RX timeout to 1, which will be 4 character time */
307-
sys_write32(0x1U, reg_base + XUARTPS_RXTOUT_OFFSET);
308-
309306
/* Disable all interrupts, polling mode is default */
310307
sys_write32(XUARTPS_IXR_MASK, reg_base + XUARTPS_IDR_OFFSET);
311308

@@ -845,20 +842,18 @@ static int uart_xlnx_ps_fifo_fill(const struct device *dev,
845842
int size)
846843
{
847844
const struct uart_xlnx_ps_dev_config *dev_cfg = DEV_CFG(dev);
848-
uint32_t reg_val;
849-
uint32_t reg_base;
850-
int onum = 0;
845+
uint32_t reg_base = dev_cfg->uconf.regs;
846+
uint32_t data_iter = 0;
851847

852-
reg_base = dev_cfg->uconf.regs;
853-
reg_val = sys_read32(reg_base + XUARTPS_SR_OFFSET);
854-
while (onum < size && (reg_val & XUARTPS_SR_TXFULL) == 0) {
855-
sys_write32((uint32_t)(tx_data[onum] & 0xFF),
856-
reg_base + XUARTPS_FIFO_OFFSET);
857-
onum++;
858-
reg_val = sys_read32(reg_base + XUARTPS_SR_OFFSET);
848+
sys_write32(XUARTPS_IXR_TXEMPTY, reg_base + XUARTPS_IDR_OFFSET);
849+
while (size--) {
850+
while ((sys_read32(reg_base + XUARTPS_SR_OFFSET) & XUARTPS_SR_TXFULL) != 0) {
851+
}
852+
sys_write32((uint32_t)tx_data[data_iter++], reg_base + XUARTPS_FIFO_OFFSET);
859853
}
854+
sys_write32(XUARTPS_IXR_TXEMPTY, reg_base + XUARTPS_IER_OFFSET);
860855

861-
return onum;
856+
return data_iter;
862857
}
863858

864859
/**
@@ -937,17 +932,12 @@ static void uart_xlnx_ps_irq_tx_disable(const struct device *dev)
937932
static int uart_xlnx_ps_irq_tx_ready(const struct device *dev)
938933
{
939934
const struct uart_xlnx_ps_dev_config *dev_cfg = DEV_CFG(dev);
940-
uint32_t reg_base;
941-
uint32_t reg_val;
935+
uint32_t reg_base = dev_cfg->uconf.regs;
936+
uint32_t reg_val = sys_read32(reg_base + XUARTPS_SR_OFFSET);
942937

943-
reg_base = dev_cfg->uconf.regs;
944-
reg_val = sys_read32(reg_base + XUARTPS_ISR_OFFSET);
945-
if ((reg_val & (XUARTPS_IXR_TTRIG | XUARTPS_IXR_TXEMPTY)) == 0) {
938+
if ((reg_val & (XUARTPS_SR_TTRIG | XUARTPS_SR_TXEMPTY)) == 0) {
946939
return 0;
947940
} else {
948-
sys_write32(
949-
(XUARTPS_IXR_TTRIG | XUARTPS_IXR_TXEMPTY),
950-
reg_base + XUARTPS_ISR_OFFSET);
951941
return 1;
952942
}
953943
}
@@ -1016,11 +1006,9 @@ static void uart_xlnx_ps_irq_rx_disable(const struct device *dev)
10161006
static int uart_xlnx_ps_irq_rx_ready(const struct device *dev)
10171007
{
10181008
const struct uart_xlnx_ps_dev_config *dev_cfg = DEV_CFG(dev);
1019-
uint32_t reg_base;
1020-
uint32_t reg_val;
1009+
uint32_t reg_base = dev_cfg->uconf.regs;
1010+
uint32_t reg_val = sys_read32(reg_base + XUARTPS_ISR_OFFSET);
10211011

1022-
reg_base = dev_cfg->uconf.regs;
1023-
reg_val = sys_read32(reg_base + XUARTPS_ISR_OFFSET);
10241012
if ((reg_val & XUARTPS_IXR_RTRIG) == 0) {
10251013
return 0;
10261014
} else {
@@ -1107,7 +1095,7 @@ static int uart_xlnx_ps_irq_is_pending(const struct device *dev)
11071095
*/
11081096
static int uart_xlnx_ps_irq_update(const struct device *dev)
11091097
{
1110-
(void)dev;
1098+
ARG_UNUSED(dev);
11111099
return 1;
11121100
}
11131101

0 commit comments

Comments
 (0)