boards: riscv: neorv32: Updates compatibility to neoverse v1.8.6

With NEORV32 v1.8.2 the UART module was changed to a simpler
implementation. This updates the UART driver for the open-source NEORV32
RISC-V compatible processor system (SOC).

Signed-off-by: Tim-Marek Thomas <thomas@sra.uni-hannover.de>
This commit is contained in:
Tim-Marek Thomas 2023-07-11 13:39:33 +02:00 committed by Fabio Baltieri
commit 5d75940ae3
6 changed files with 33 additions and 59 deletions

View file

@ -16,6 +16,8 @@ For more information about the NEORV32, see the following websites:
- `The NEORV32 RISC-V Processor Datasheet`_ - `The NEORV32 RISC-V Processor Datasheet`_
- `The NEORV32 RISC-V Processor User Guide`_ - `The NEORV32 RISC-V Processor User Guide`_
The currently supported version is 1.8.6.
Supported Features Supported Features
================== ==================

View file

@ -1,4 +1,4 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk> # Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
CONFIG_SOC_NEORV32_V1_6_1=y CONFIG_SOC_NEORV32_V1_8_6=y

View file

@ -3,5 +3,5 @@
board_check_revision( board_check_revision(
FORMAT MAJOR.MINOR.PATCH FORMAT MAJOR.MINOR.PATCH
DEFAULT_REVISION 1.6.1 DEFAULT_REVISION 1.8.6
) )

View file

@ -21,23 +21,26 @@ LOG_MODULE_REGISTER(uart_neorv32, CONFIG_UART_LOG_LEVEL);
#define NEORV32_UART_DATA_OFFSET 0x04 #define NEORV32_UART_DATA_OFFSET 0x04
/* UART_CTRL register bits */ /* UART_CTRL register bits */
#define NEORV32_UART_CTRL_BAUD_MASK BIT_MASK(12) #define NEORV32_UART_CTRL_EN BIT(0)
#define NEORV32_UART_CTRL_BAUD_POS 0U #define NEORV32_UART_CTRL_SIM_MODE BIT(1)
#define NEORV32_UART_CTRL_PRSC_MASK BIT_MASK(3) #define NEORV32_UART_CTRL_HWFC_EN BIT(2)
#define NEORV32_UART_CTRL_PRSC_POS 24U #define NEORV32_UART_CTRL_PRSC_POS 3U
#define NEORV32_UART_CTRL_RTS_EN BIT(20) #define NEORV32_UART_CTRL_PRSC_MASK BIT_MASK(3)
#define NEORV32_UART_CTRL_CTS_EN BIT(21) #define NEORV32_UART_CTRL_BAUD_POS 6U
#define NEORV32_UART_CTRL_PMODE_NONE BIT(22) #define NEORV32_UART_CTRL_BAUD_MASK BIT_MASK(10)
#define NEORV32_UART_CTRL_PMODE_EVEN BIT(23) #define NEORV32_UART_CTRL_RX_NEMPTY BIT(16)
#define NEORV32_UART_CTRL_PMODE_ODD (BIT(22) | BIT(23)) #define NEORV32_UART_CTRL_RX_HALF BIT(17)
#define NEORV32_UART_CTRL_EN BIT(28) #define NEORV32_UART_CTRL_RX_FULL BIT(18)
#define NEORV32_UART_CTRL_TX_BUSY BIT(31) #define NEORV32_UART_CTRL_TX_NEMPTY BIT(19)
#define NEORV32_UART_CTRL_TX_HALF BIT(20)
/* UART_DATA register status bits */ #define NEORV32_UART_CTRL_TX_FULL BIT(21)
#define NEORV32_UART_DATA_PERR BIT(28) #define NEORV32_UART_CTRL_IRQ_RX_NEMPTY BIT(22)
#define NEORV32_UART_DATA_FERR BIT(29) #define NEORV32_UART_CTRL_IRQ_RX_HALF BIT(23)
#define NEORV32_UART_DATA_OVERR BIT(30) #define NEORV32_UART_CTRL_IRQ_RX_FULL BIT(24)
#define NEORV32_UART_DATA_AVAIL BIT(31) #define NEORV32_UART_CTRL_IRQ_TX_EMPTY BIT(25)
#define NEORV32_UART_CTRL_IRQ_TX_NHALF BIT(26)
#define NEORV32_UART_CTRL_RX_OVER BIT(30)
#define NEORV32_UART_CTRL_TX_BUSY BIT(31)
struct neorv32_uart_config { struct neorv32_uart_config {
const struct device *syscon; const struct device *syscon;
@ -100,7 +103,7 @@ static int neorv32_uart_poll_in(const struct device *dev, unsigned char *c)
data = neorv32_uart_read_data(dev); data = neorv32_uart_read_data(dev);
if ((data & NEORV32_UART_DATA_AVAIL) != 0) { if ((data & NEORV32_UART_CTRL_RX_NEMPTY) != 0) {
*c = data & BIT_MASK(8); *c = data & BIT_MASK(8);
return 0; return 0;
} }
@ -116,29 +119,6 @@ static void neorv32_uart_poll_out(const struct device *dev, unsigned char c)
neorv32_uart_write_data(dev, c); neorv32_uart_write_data(dev, c);
} }
static int neorv32_uart_err_check(const struct device *dev)
{
struct neorv32_uart_data *data = dev->data;
int err = 0;
if ((data->last_data & NEORV32_UART_DATA_OVERR) != 0) {
err |= UART_ERROR_OVERRUN;
}
if ((data->last_data & NEORV32_UART_DATA_PERR) != 0) {
err |= UART_ERROR_PARITY;
}
if ((data->last_data & NEORV32_UART_DATA_FERR) != 0) {
err |= UART_ERROR_FRAMING;
}
data->last_data &= ~(NEORV32_UART_DATA_OVERR | NEORV32_UART_DATA_PERR |
NEORV32_UART_DATA_FERR);
return err;
}
static int neorv32_uart_configure(const struct device *dev, const struct uart_config *cfg) static int neorv32_uart_configure(const struct device *dev, const struct uart_config *cfg)
{ {
const struct neorv32_uart_config *config = dev->config; const struct neorv32_uart_config *config = dev->config;
@ -163,13 +143,6 @@ static int neorv32_uart_configure(const struct device *dev, const struct uart_co
switch (cfg->parity) { switch (cfg->parity) {
case UART_CFG_PARITY_NONE: case UART_CFG_PARITY_NONE:
ctrl |= NEORV32_UART_CTRL_PMODE_NONE;
break;
case UART_CFG_PARITY_ODD:
ctrl |= NEORV32_UART_CTRL_PMODE_ODD;
break;
case UART_CFG_PARITY_EVEN:
ctrl |= NEORV32_UART_CTRL_PMODE_EVEN;
break; break;
default: default:
LOG_ERR("unsupported parity mode %d", cfg->parity); LOG_ERR("unsupported parity mode %d", cfg->parity);
@ -181,7 +154,7 @@ static int neorv32_uart_configure(const struct device *dev, const struct uart_co
ctrl |= 0; ctrl |= 0;
break; break;
case UART_CFG_FLOW_CTRL_RTS_CTS: case UART_CFG_FLOW_CTRL_RTS_CTS:
ctrl |= NEORV32_UART_CTRL_RTS_EN | NEORV32_UART_CTRL_CTS_EN; ctrl |= NEORV32_UART_CTRL_HWFC_EN;
break; break;
default: default:
LOG_ERR("unsupported flow control mode %d", cfg->flow_ctrl); LOG_ERR("unsupported flow control mode %d", cfg->flow_ctrl);
@ -270,9 +243,9 @@ static int neorv32_uart_fifo_read(const struct device *dev, uint8_t *rx_data, co
__ASSERT_NO_MSG(rx_data != NULL); __ASSERT_NO_MSG(rx_data != NULL);
while ((data->last_data & NEORV32_UART_DATA_AVAIL) != 0) { while ((data->last_data & NEORV32_UART_CTRL_RX_NEMPTY) != 0) {
rx_data[count++] = data->last_data & BIT_MASK(8); rx_data[count++] = data->last_data & BIT_MASK(8);
data->last_data &= ~(NEORV32_UART_DATA_AVAIL); data->last_data &= ~(NEORV32_UART_CTRL_RX_NEMPTY);
if (count >= size) { if (count >= size) {
break; break;
@ -367,7 +340,7 @@ static int neorv32_uart_irq_rx_ready(const struct device *dev)
return 0; return 0;
} }
return (data->last_data & NEORV32_UART_DATA_AVAIL) != 0; return (data->last_data & NEORV32_UART_CTRL_RX_NEMPTY) != 0;
} }
static int neorv32_uart_irq_is_pending(const struct device *dev) static int neorv32_uart_irq_is_pending(const struct device *dev)
@ -467,7 +440,6 @@ static int neorv32_uart_pm_action(const struct device *dev,
static const struct uart_driver_api neorv32_uart_driver_api = { static const struct uart_driver_api neorv32_uart_driver_api = {
.poll_in = neorv32_uart_poll_in, .poll_in = neorv32_uart_poll_in,
.poll_out = neorv32_uart_poll_out, .poll_out = neorv32_uart_poll_out,
.err_check = neorv32_uart_err_check,
.configure = neorv32_uart_configure, .configure = neorv32_uart_configure,
.config_get = neorv32_uart_config_get, .config_get = neorv32_uart_config_get,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN

View file

@ -5,8 +5,8 @@ choice
prompt "NEORV32 Version" prompt "NEORV32 Version"
depends on SOC_SERIES_NEORV32 depends on SOC_SERIES_NEORV32
config SOC_NEORV32_V1_6_1 config SOC_NEORV32_V1_8_6
bool "v1.6.1" bool "v1.8.6"
# NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO # NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO
select ATOMIC_OPERATIONS_C select ATOMIC_OPERATIONS_C
@ -16,7 +16,7 @@ if SOC_SERIES_NEORV32
config SOC_NEORV32_VERSION config SOC_NEORV32_VERSION
hex hex
default 0x01060100 if SOC_NEORV32_V1_6_1 default 0x01080600 if SOC_NEORV32_V1_8_6
help help
The targeted NEORV32 version as BCD-coded number. The format is The targeted NEORV32 version as BCD-coded number. The format is
identical to that of the NEORV32 Machine implementation ID (mimpid) identical to that of the NEORV32 Machine implementation ID (mimpid)

View file

@ -26,7 +26,7 @@ SECTION_FUNC(reset, __reset)
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
/* Allow mcycle and minstret counters to increment */ /* Allow mcycle and minstret counters to increment */
li x11, ~5 li x11, ~2
csrw mcountinhibit, x11 csrw mcountinhibit, x11
/* Zerorize counters */ /* Zerorize counters */