Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions boards/sparc/generic_leon3/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ config SPARC_CASA
config SYS_CLOCK_HW_CYCLES_PER_SEC
default 50000000

config UART_INTERRUPT_DRIVEN
default y

endif
2 changes: 1 addition & 1 deletion boards/sparc/generic_leon3/board.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ set(EMU_PLATFORM tsim)

find_program(TSIM tsim-leon3)

set(TSIM_SYS)
set(TSIM_SYS -uart_fs 32)
3 changes: 3 additions & 0 deletions boards/sparc/gr716a_mini/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ config BOARD
config SYS_CLOCK_HW_CYCLES_PER_SEC
default 20000000

config UART_INTERRUPT_DRIVEN
default y

endif
3 changes: 3 additions & 0 deletions boards/sparc/qemu_leon3/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ if BOARD_QEMU_LEON3
config BOARD
default "qemu_leon3"

config UART_INTERRUPT_DRIVEN
default y

endif
52 changes: 49 additions & 3 deletions drivers/serial/uart_apbuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,25 @@ static int apbuart_config_get(const struct device *dev, struct uart_config *cfg)
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void apbuart_isr(const struct device *dev);

static int apbuart_fifo_fill(const struct device *dev, const uint8_t *tx_data,
int size)
{
volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
int i;

if (DEV_DATA(dev)->usefifo) {
/* Transmitter FIFO full flag is available. */
for (
i = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've increased the line length, so maybe just put this all on one line now.

(i < size) && !(regs->status & APBUART_STATUS_TF);
i++
) {
regs->data = tx_data[i];
}
return i;
}
for (i = 0; (i < size) && (regs->status & APBUART_STATUS_TE); i++) {
regs->data = tx_data[i];
}
Expand All @@ -333,21 +346,45 @@ static int apbuart_fifo_read(const struct device *dev, uint8_t *rx_data,
static void apbuart_irq_tx_enable(const struct device *dev)
{
volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
unsigned int key;

if (DEV_DATA(dev)->usefifo) {
/* Enable the FIFO level interrupt */
regs->ctrl |= APBUART_CTRL_TF;
return;
}

regs->ctrl |= APBUART_CTRL_TI;
/*
* The "TI" interrupt is an edge interrupt. It fires each time the TX
* holding register (or FIFO if implemented) moves from non-empty to
* empty.
*
* When the APBUART is implemented _without_ FIFO, the TI interrupt is
* the only TX interrupt we have. When the APBUART is implemented
* _with_ FIFO, the TI will fire on each TX byte.
*/
regs->ctrl |= APBUART_CTRL_TI;
/* Fire the first "TI" edge interrupt to get things going. */
key = irq_lock();
apbuart_isr(dev);
irq_unlock(key);
}

static void apbuart_irq_tx_disable(const struct device *dev)
{
volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

regs->ctrl &= ~APBUART_CTRL_TI;
regs->ctrl &= ~(APBUART_CTRL_TF | APBUART_CTRL_TI);
}

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

if (DEV_DATA(dev)->usefifo) {
return !(regs->status & APBUART_STATUS_TF);
}
return !!(regs->status & APBUART_STATUS_TE);
}

Expand Down Expand Up @@ -388,9 +425,18 @@ static int apbuart_irq_is_pending(const struct device *dev)
if ((ctrl & APBUART_CTRL_RI) && (status & APBUART_STATUS_DR)) {
return 1;
}
if ((ctrl & APBUART_CTRL_TI) && (status & APBUART_STATUS_TE)) {
return 1;

if (DEV_DATA(dev)->usefifo) {
/* TH is the TX FIFO half-empty flag */
if (status & APBUART_STATUS_TH) {
return 1;
}
} else {
if ((ctrl & APBUART_CTRL_TI) && (status & APBUART_STATUS_TE)) {
return 1;
}
}

return 0;
}

Expand Down