diff --git a/boards/rpi-pico/Kconfig b/boards/rpi-pico/Kconfig new file mode 100644 index 0000000000..d1a6ca0479 --- /dev/null +++ b/boards/rpi-pico/Kconfig @@ -0,0 +1,17 @@ +# Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +config BOARD + default "rpi-pico" if BOARD_RPI_PICO + +config BOARD_RPI_PICO + bool + default y + select CPU_MODEL_RP2040 + select HAS_PERIPH_UART + + select HAVE_SAUL_GPIO diff --git a/boards/rpi-pico/Makefile b/boards/rpi-pico/Makefile new file mode 100644 index 0000000000..f8fcbb53a0 --- /dev/null +++ b/boards/rpi-pico/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/rpi-pico/Makefile.dep b/boards/rpi-pico/Makefile.dep new file mode 100644 index 0000000000..5472bf8b8d --- /dev/null +++ b/boards/rpi-pico/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter saul_default,$(USEMODULE))) + USEMODULE += saul_gpio +endif diff --git a/boards/rpi-pico/Makefile.features b/boards/rpi-pico/Makefile.features new file mode 100644 index 0000000000..d807338931 --- /dev/null +++ b/boards/rpi-pico/Makefile.features @@ -0,0 +1,4 @@ +CPU := rpx0xx + +# Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_uart diff --git a/boards/rpi-pico/Makefile.include b/boards/rpi-pico/Makefile.include new file mode 100644 index 0000000000..10814e8919 --- /dev/null +++ b/boards/rpi-pico/Makefile.include @@ -0,0 +1,2 @@ +CPU_MODEL := RP2040 +PORT_LINUX ?= /dev/ttyUSB0 diff --git a/boards/rpi-pico/board.c b/boards/rpi-pico/board.c new file mode 100644 index 0000000000..e282543b93 --- /dev/null +++ b/boards/rpi-pico/board.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_rpi_pico + * @{ + * + * @file + * @brief Board specific implementations for the Raspberry Pi Pico + * + * @author Marian Buschsieweke + * @} + */ + +#include "board.h" +#include "periph/gpio.h" + +void board_init(void) +{ + /* initialize the CPU */ + cpu_init(); + + gpio_init(LED0_PIN, GPIO_OUT); +} diff --git a/boards/rpi-pico/dist/openocd.cfg b/boards/rpi-pico/dist/openocd.cfg new file mode 100644 index 0000000000..8da868c880 --- /dev/null +++ b/boards/rpi-pico/dist/openocd.cfg @@ -0,0 +1,3 @@ +source [find target/rp2040-core0.cfg] +$_TARGETNAME configure -rtos auto +adapter speed 4000 diff --git a/boards/rpi-pico/doc.txt b/boards/rpi-pico/doc.txt new file mode 100644 index 0000000000..57a4dc1686 --- /dev/null +++ b/boards/rpi-pico/doc.txt @@ -0,0 +1,142 @@ +/** +@defgroup boards_rpi_pico Raspberry Pi Pico +@ingroup boards +@brief Support for the RP2040 based Raspberry Pi Pico board + +## Overview + +The Raspberry Pi Pico is sold by the Raspberry Pi foundation for about 4 USD. It features the +RP2040 MCU, a custom dual core ARM Cortex-M0+ MCU with relatively high CPU clock, plenty of RAM and +some unique peripheral (the Programmable IO). + +## Hardware + +![Raspberry Pi Pico](https://www.raspberrypi.org/homepage-9df4b/static/rp2040@2x-d1b9dae9345ad2bd15a23c6a567edb5c.jpg) + +### MCU + +The Programmable IO (PIO) peripheral and the SSI/QSPI peripheral that supports execution from +flash (XIP) are the most distinguishing features of the MCU. The latter is especially important, +since the RP2040 contains no internal flash. + +| MCU | RP2040 | +|:-----------|:------------------------------------------------------------ | +| Family | (2x) ARM Cortex-M0+ | +| Vendor | Raspberry Pi | +| RAM | 264 KiB | +| Flash | 2 MiB (up to 16 MiB) | +| Frequency | up to 133 MHz | +| FPU | no | +| PIOs | 8 | +| Timers | 1 x 64-bit | +| ADCs | 1x 12-bit (4 channels + temperature sensor) | +| UARTs | 2 | +| SPIs | 2 | +| I2Cs | 2 | +| RTCs | 1 | +| USBs | 1 (USB 2.0) | +| Watchdog | 1 | +| SSI/QSPI | 1 (connected to flash, with XIP support) | +| Vcc | 1.62V - 3.63V | +| Datasheet | [Datasheet](https://www.raspberrypi.org/homepage-9df4b/static/rp2040@2x-d1b9dae9345ad2bd15a23c6a567edb5c.jpg) | + +### User Interface + +1 button (also used for boot selection) and 1 LED: + +| Device | PIN | +|:------ |:---------------- | +| LED0 | 25 | +| SW0 | QSPI_SS_N (*) | + +(*) Since the switch is connected to the chip-select pin of the QSPI interface the flash chip RIOT +is running from via XIP, the switch is difficult to read out from software. This is currently not +supported. + +### Pinout + +![Pinout Diagram of RPi Pico](https://projects-static.raspberrypi.org/projects/getting-started-with-the-pico/f009ad94826c2f0cd7573a295897e76955301096/en/images/Pico-R3-Pinout.png) + +## Flashing the Board + +### Flashing the Board Using OpenOCD + +Currently (June 2021), only two methods for debugging via OpenOCD are supported: + +1. Using a bit-banging low-level adapter, e.g. via the GPIOs of a Raspberry Pi 4B +2. Using a virtual CMSIS-DAP adapter provided by the second CPU core via + https://github.com/majbthrd/pico-debug + +Since option 2 requires no additional hardware, this is currently the default. However, you need to +first "flash" the gimme-cache variant of [pico-debug](https://github.com/majbthrd/pico-debug) +into RAM using the UF2 bootloader. For this, plug in the USB cable while holding down the BOOTSEL +button of the Pico and copy the `pico-debug-gimmecache.uf2` from the +[latest pico-debug release](https://github.com/majbthrd/pico-debug/releases) into the virtual FAT +formatted drive the bootloader provides. Once this drive is unmounted again, this will result in +the Raspberry Pi Pico showing up as CMSIS-DAP debugger. Afterwards run: + +``` +make BOARD=rpi-pico flash +``` + +***Beware:*** The `rpi-pico` virtual debugger is not persistent and needs to be "flashed" into RAM +again after each cold boot. + +### Flashing the Board Using the Bootloader + +Connect the device to your Micro-USB cable while the button (labeled `BOOTSEL` on the silkscreen +of the PCB) is pressed to enter the bootloader. Afterwards run: + +``` +make BOARD=rpi-pico PROGRAMMER=uf2conv flash +``` + +### Flashing the Board Using J-Link + +Connect the Board to an Segger J-Link debugger, e.g. the EDU mini debugger is relatively affordable, +but limited to educational purposes. Afterwards run: + +``` +make BOARD=rpi-pico PROGRAMMER=jlink flash +``` + +## On-Chip Debugging + +There are currently (June 2021) few hardware options for debugging the Raspberry Pi Pico: + +1. Via J-Link using one of Seggers debuggers +2. Via OpenOCD using a low-level bit-banging debugger (e.g. a Raspberry Pi 4B with the GPIOs + connected to the Raspberry Pi Pico via jump wires) +3. Via a recently updated [Black Magic Probe](https://github.com/blacksphere/blackmagic) + +In addition, a software-only option is possible using +[pico-debug](https://github.com/majbthrd/pico-debug). The default linker script reserved 16 KiB of +RAM for this debugger, hence just "flash" the "gimme-cache" flavor into RAM using the UF2 +bootloader. Once this is done, debugging is as simple as running: + +``` +make BOARD=rpi-pico debug +``` + +***Beware:*** The `rpi-pico` virtual debugger is not persistent and needs to be "flashed" into RAM +again after each cold boot. The initialization code of RIOT now seems to play well with the +debugger, so it remains persistent on soft reboots. If you face issues with losing connection to +the debugger on reboot, try `monitor reset init` in GDB to soft-reboot instead. + +## Known Issues / Problems + +### Early state Implementation + +Currently no support for the following peripherals is implemented: + +- Timers +- ADC +- SPI +- I2C +- USB +- PIO +- RTC +- Watchdog +- SMP support (multi CPU support is not implemented in RIOT) + + */ diff --git a/boards/rpi-pico/include/board.h b/boards/rpi-pico/include/board.h new file mode 100644 index 0000000000..7dfb2d0ca6 --- /dev/null +++ b/boards/rpi-pico/include/board.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_rpi_pico + * @{ + * + * @file + * @brief Board specific definitions for the Raspberry Pi Pico + * + * @author Marian Buschsieweke + */ + +#ifndef BOARD_H +#define BOARD_H + +#include "cpu.h" +#include "periph_conf.h" +#include "periph_cpu.h" +#include "periph/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name LED configuration + * @{ + */ +#define LED0_PIN GPIO_PIN(0, 25) +#define LED0_ON do {SIO->GPIO_OUT_SET.reg = 1UL << 25;} while (0) +#define LED0_OFF do {SIO->GPIO_OUT_CLR.reg = 1UL << 25;} while (0) +#define LED0_TOGGLE do {SIO->GPIO_OUT_XOR.reg = 1UL << 25;} while (0) +#define LED0_NAME "LED(Green)" +/** @} */ + +/** + * @brief Initialize board specific hardware, including clock, LEDs and std-IO + */ +void board_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/rpi-pico/include/gpio_params.h b/boards/rpi-pico/include/gpio_params.h new file mode 100644 index 0000000000..55a646cc05 --- /dev/null +++ b/boards/rpi-pico/include/gpio_params.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 Franz Freitag, Justus Krebs, Nick Weiler + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_rpi_pico + * @{ + * + * @file + * @brief Board specific configuration of direct mapped GPIOs + * + * @author Franz Freitag + * @author Justus Krebs + * @author Nick Weiler + */ + +#ifndef GPIO_PARAMS_H +#define GPIO_PARAMS_H + +#include "board.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief GPIO pin configuration + */ +static const saul_gpio_params_t saul_gpio_params[] = +{ + { + .name = LED0_NAME, + .pin = LED0_PIN, + .mode = GPIO_OUT, + } +}; + +#ifdef __cplusplus +} +#endif + +#endif /* GPIO_PARAMS_H */ +/** @} */ diff --git a/boards/rpi-pico/include/periph_conf.h b/boards/rpi-pico/include/periph_conf.h new file mode 100644 index 0000000000..3b54fd7f08 --- /dev/null +++ b/boards/rpi-pico/include/periph_conf.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_rpi_pico + * @{ + * + * @file + * @brief Configuration of CPU peripherals for the Raspberry Pi Pico + * @author Marian Buschsieweke + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#include + +#include "cpu.h" +#include "periph_cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static const uart_conf_t uart_config[] = { + { + .dev = UART0, + .rx_pin = GPIO_PIN(0, 1), + .tx_pin = GPIO_PIN(0, 0), + .irqn = UART0_IRQ_IRQn + }, + { + .dev = UART1, + .rx_pin = GPIO_PIN(0, 9), + .tx_pin = GPIO_PIN(0, 8), + .irqn = UART1_IRQ_IRQn + } +}; + +#define UART_0_ISR (isr_uart0) +#define UART_1_ISR (isr_uart1) + +#define UART_NUMOF ARRAY_SIZE(uart_config) + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H */ +/** @} */