diff --git a/CODEOWNERS b/CODEOWNERS index d40046f3c36..4ba97bc6f4c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -354,6 +354,7 @@ /drivers/serial/uart_mcux_iuart.c @Mani-Sadhasivam /drivers/serial/Kconfig.rtt @carlescufi @pkral78 /drivers/serial/uart_rtt.c @carlescufi @pkral78 +/drivers/serial/*rpi_pico* @yonsch /drivers/serial/Kconfig.xlnx @wjliang /drivers/serial/uart_xlnx_ps.c @wjliang /drivers/serial/uart_xlnx_uartlite.c @henrikbrixandersen diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index acb5195d73a..5eef4eab5ff 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -32,6 +32,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_SAM0 uart_sam0.c) zephyr_library_sources_ifdef(CONFIG_UART_PSOC6 uart_psoc6.c) zephyr_library_sources_ifdef(CONFIG_UART_PL011 uart_pl011.c) zephyr_library_sources_ifdef(CONFIG_UART_RV32M1_LPUART uart_rv32m1_lpuart.c) +zephyr_library_sources_ifdef(CONFIG_UART_RPI_PICO uart_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_UART_LITEUART uart_liteuart.c) zephyr_library_sources_ifdef(CONFIG_UART_RTT_DRIVER uart_rtt.c) zephyr_library_sources_ifdef(CONFIG_UART_XLNX_PS uart_xlnx_ps.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 2455174ae42..3d110543d92 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -159,6 +159,8 @@ source "drivers/serial/Kconfig.pl011" source "drivers/serial/Kconfig.rv32m1_lpuart" +source "drivers/serial/Kconfig.rpi_pico" + source "drivers/serial/Kconfig.litex" source "drivers/serial/Kconfig.rtt" diff --git a/drivers/serial/Kconfig.rpi_pico b/drivers/serial/Kconfig.rpi_pico new file mode 100644 index 00000000000..bab871be581 --- /dev/null +++ b/drivers/serial/Kconfig.rpi_pico @@ -0,0 +1,11 @@ +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +# Workaround for not being able to have commas in macro arguments +DT_COMPAT_RPI_PICO_UART := raspberrypi,pico-uart + +config UART_RPI_PICO + bool "Raspberry Pi UART driver" + default $(dt_compat_enabled,$(DT_COMPAT_RPI_PICO_UART)) + select SERIAL_HAS_DRIVER + select PICOSDK_USE_UART diff --git a/drivers/serial/uart_rpi_pico.c b/drivers/serial/uart_rpi_pico.c new file mode 100644 index 00000000000..b0f4e280345 --- /dev/null +++ b/drivers/serial/uart_rpi_pico.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021, Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* pico-sdk includes */ +#include + +#define DT_DRV_COMPAT raspberrypi_pico_uart + +struct uart_rpi_config { + uart_inst_t *const uart_dev; + uint32_t baudrate; + const struct pinctrl_dev_config *pcfg; +}; + +static int uart_rpi_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_rpi_config *config = dev->config; + + if (!uart_is_readable(config->uart_dev)) { + return -1; + } + + *c = (unsigned char)uart_get_hw(config->uart_dev)->dr; + return 0; +} + +static void uart_rpi_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_rpi_config *config = dev->config; + + uart_putc_raw(config->uart_dev, c); +} + +static int uart_rpi_init(const struct device *dev) +{ + const struct uart_rpi_config *config = dev->config; + int ret; + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + uart_init(config->uart_dev, config->baudrate); + + return 0; +} + +static const struct uart_driver_api uart_rpi_driver_api = { + .poll_in = uart_rpi_poll_in, + .poll_out = uart_rpi_poll_out, +}; + +#define RPI_UART_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ + static const struct uart_rpi_config uart_rpi_cfg_##idx = { \ + .uart_dev = (uart_inst_t *)DT_INST_REG_ADDR(idx), \ + .baudrate = DT_INST_PROP(idx, current_speed), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, &uart_rpi_init, \ + NULL, \ + NULL, \ + &uart_rpi_cfg_##idx, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_rpi_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RPI_UART_INIT) diff --git a/dts/arm/rpi_pico/rp2040.dtsi b/dts/arm/rpi_pico/rp2040.dtsi index 9cbe7c4f50b..dd48076e02b 100644 --- a/dts/arm/rpi_pico/rp2040.dtsi +++ b/dts/arm/rpi_pico/rp2040.dtsi @@ -50,6 +50,26 @@ status = "okay"; label = "PINCTRL"; }; + + uart0: uart@40034000 { + compatible = "raspberrypi,pico-uart"; + reg = <0x40034000 DT_SIZE_K(4)>; + clocks = <&peripheral_clk>; + interrupts = <20 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "uart0"; + label = "UART_0"; + status = "disabled"; + }; + + uart1: uart@40038000 { + compatible = "raspberrypi,pico-uart"; + reg = <0x40038000 DT_SIZE_K(4)>; + clocks = <&peripheral_clk>; + interrupts = <21 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "uart1"; + label = "UART_1"; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/serial/raspberrypi,pico-uart.yaml b/dts/bindings/serial/raspberrypi,pico-uart.yaml new file mode 100644 index 00000000000..50c3bd44d74 --- /dev/null +++ b/dts/bindings/serial/raspberrypi,pico-uart.yaml @@ -0,0 +1,12 @@ +description: Raspberry Pi Pico UART + +compatible: "raspberrypi,pico-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true