diff --git a/CODEOWNERS b/CODEOWNERS index 04f7c19f02b..f022e3a3915 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -46,6 +46,7 @@ /soc/arm/nuvoton_npcx/ @MulinChao @WealianLiao @ChiHuaL /soc/arm/nuvoton_numicro/ @ssekar15 /soc/arm/quicklogic_eos_s3/ @kowalewskijan @kgugala +/soc/arm/rpi_pico/ @yonsch /soc/arm/silabs_exx32/efm32pg1b/ @rdmeneze /soc/arm/silabs_exx32/efr32mg21/ @l-alfred /soc/arm/st_stm32/ @erwango @@ -448,6 +449,7 @@ /dts/arm/nuvoton/ @ssekar15 @MulinChao @WealianLiao @ChiHuaL /dts/arm/nxp/ @mmahadevan108 @dleach02 /dts/arm/microchip/ @franciscomunoz @albertofloyd @sjvasanth1 +/dts/arm/rpi_pico/ @yonsch /dts/arm/silabs/efm32_pg_1b.dtsi @rdmeneze /dts/arm/silabs/efm32gg11b* @oanerer /dts/arm/silabs/efm32_jg_pg* @chrta diff --git a/dts/arm/rpi_pico/rp2040.dtsi b/dts/arm/rpi_pico/rp2040.dtsi new file mode 100644 index 00000000000..b0714f02157 --- /dev/null +++ b/dts/arm/rpi_pico/rp2040.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "rpi_pico_common.dtsi" + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m0+"; + reg = <0>; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-m0+"; + reg = <1>; + }; + }; + + soc { + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(264)>; + }; + + flash0: flash@10000000 { + compatible = "soc-nv-flash"; + label = "FLASH_RP2"; + + write-block-size = <1>; + }; + + peripheral_clk: peripheral-clk { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + #clock-cells = <0>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/arm/rpi_pico/rpi_pico_common.dtsi b/dts/arm/rpi_pico/rpi_pico_common.dtsi new file mode 100644 index 00000000000..738cae8e7ae --- /dev/null +++ b/dts/arm/rpi_pico/rpi_pico_common.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef RPI_PICO_DEFAULT_IRQ_PRIORITY +#define RPI_PICO_DEFAULT_IRQ_PRIORITY 3 +#endif diff --git a/modules/hal_rpi_pico/CMakeLists.txt b/modules/hal_rpi_pico/CMakeLists.txt new file mode 100644 index 00000000000..5df7a48660f --- /dev/null +++ b/modules/hal_rpi_pico/CMakeLists.txt @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) + +if(CONFIG_HAS_RPI_PICO) + zephyr_library() + + set(rp2_common_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/rp2_common) + set(rp2040_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/rp2040) + set(common_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/common) + set(boot_stage_dir ${rp2_common_dir}/boot_stage2) + + # The Second Stage Bootloader is only linked to the app that resides + # at 0x100. Therefore, only if the app's offset is 0x100, the second + # stage bootloader should be compiled. + if(CONFIG_RP2_REQUIRES_SECOND_STAGE_BOOT) + foreach(flash W25Q080 GENERIC_03H IS25LP080 W25X10CL AT25SF128A) + if(CONFIG_RP2_FLASH_${flash}) + set(flash_type ${flash}) + break() + endif() + endforeach() + + set(rp2_bootloader_prefix ${CMAKE_BINARY_DIR}/bootloader) + ExternalProject_Add( + second_stage_bootloader + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/bootloader + BINARY_DIR ${rp2_bootloader_prefix} + CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_ASM_COMPILER=${CMAKE_ASM_COMPILER} + -DZEPHYR_HAL_RPI_PICO_MODULE_DIR=${ZEPHYR_HAL_RPI_PICO_MODULE_DIR} + -DZEPHYR_BASE=${ZEPHYR_BASE} + -DFLASH_TYPE=${flash_type} + -DPYTHON_EXECUTABLE=${Python3_EXECUTABLE} + INSTALL_COMMAND "" # No installation needed + BUILD_BYPRODUCTS ${rp2_bootloader_prefix}/boot_stage2.S + BUILD_ALWAYS TRUE + ) + zephyr_library_sources(${rp2_bootloader_prefix}/boot_stage2.S) + endif() + + # Pico sources and headers necessary for every build. + # These contain definitions and implementation used mostly for + # initializing the SoC, and therefore are always required. + + zephyr_library_sources( + ${rp2_common_dir}/hardware_clocks/clocks.c + ${rp2_common_dir}/hardware_pll/pll.c + ${rp2_common_dir}/hardware_xosc/xosc.c + ${rp2_common_dir}/hardware_watchdog/watchdog.c + ${rp2_common_dir}/pico_platform/platform.c + ) + + zephyr_include_directories( + ${rp2_common_dir}/hardware_base/include + ${rp2_common_dir}/hardware_clocks/include + ${rp2_common_dir}/hardware_watchdog/include + ${rp2_common_dir}/hardware_xosc/include + ${rp2_common_dir}/hardware_pll/include + ${rp2_common_dir}/hardware_irq/include + ${rp2_common_dir}/hardware_sync/include + ${rp2_common_dir}/hardware_timer/include + ${rp2_common_dir}/hardware_resets/include + ${rp2040_dir}/hardware_regs/include + ${rp2040_dir}/hardware_structs/include + ${common_dir}/pico_base/include + ${rp2_common_dir}/pico_platform/include + ${CMAKE_CURRENT_LIST_DIR} + ) + + zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_GPIO + ${rp2_common_dir}/hardware_gpio/gpio.c) + zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_GPIO + ${rp2_common_dir}/hardware_gpio/include) + + zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_UART + ${rp2_common_dir}/hardware_uart/uart.c) + zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_UART + ${rp2_common_dir}/hardware_uart/include) +endif() diff --git a/modules/hal_rpi_pico/Kconfig b/modules/hal_rpi_pico/Kconfig new file mode 100644 index 00000000000..70cd6ede535 --- /dev/null +++ b/modules/hal_rpi_pico/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +config HAS_RPI_PICO + bool + +config PICOSDK_USE_UART + bool + help + Use the UART driver from pico-sdk + +config PICOSDK_USE_GPIO + bool + help + Use the GPIO driver from pico-sdk diff --git a/modules/hal_rpi_pico/bootloader/CMakeLists.txt b/modules/hal_rpi_pico/bootloader/CMakeLists.txt new file mode 100644 index 00000000000..172bed0cd0b --- /dev/null +++ b/modules/hal_rpi_pico/bootloader/CMakeLists.txt @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +# Skip compiler checking +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +project(second_stage_bootloader) +enable_language(ASM) + +set(rp2_common_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/rp2_common) +set(rp2040_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/rp2040) +set(common_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/common) +set(boot_stage_dir ${rp2_common_dir}/boot_stage2) + +add_executable(boot_stage2) + +if(${FLASH_TYPE} STREQUAL W25Q080) + set(flash_type_file boot2_w25q080.S) +elseif(${FLASH_TYPE} STREQUAL GENERIC_03H) + set(flash_type_file boot2_generic_03h.S) +elseif(${FLASH_TYPE} STREQUAL IS25LP080) + set(flash_type_file boot2_is25lp080.S) +elseif(${FLASH_TYPE} STREQUAL W25X10CL) + set(flash_type_file boot2_w25x10cl.S) +elseif(${FLASH_TYPE} STREQUAL AT25SF128A) + set(flash_type_file boot2_at25sf128a.S) +else() + message(FATAL_ERROR "No flash type selected") +endif() + +target_sources(boot_stage2 PRIVATE ${boot_stage_dir}/${flash_type_file}) + +target_include_directories(boot_stage2 PUBLIC + .. + ${boot_stage_dir}/asminclude + ${rp2_common_dir}/pico_platform/include + ${rp2040_dir}/hardware_regs/include + ${common_dir}/pico_base/include + ${ZEPHYR_BASE}/include + ) + +target_link_options(boot_stage2 PRIVATE + "-nostartfiles" + "--specs=nosys.specs" + "LINKER:--script=${boot_stage_dir}/boot_stage2.ld" + ) + +# The second stage bootloader is compiled without kconfig definitions. +# Therefore, in order to use toolchain.h, it needs to define CONFIG_ARM. +target_compile_definitions(boot_stage2 PRIVATE -DCONFIG_ARM=1) + +# Generates a binary file from the compiled bootloader +add_custom_command(TARGET boot_stage2 + POST_BUILD + BYPRODUCTS boot_stage2.bin + COMMAND ${CMAKE_OBJCOPY} -Obinary $ boot_stage2.bin + ) + +# Checksums the binary, pads it, and generates an assembly file +add_custom_command(TARGET boot_stage2 + POST_BUILD + BYPRODUCTS boot_stage2.S + COMMAND ${PYTHON_EXECUTABLE} ${boot_stage_dir}/pad_checksum + -s 0xffffffff boot_stage2.bin boot_stage2.S + ) diff --git a/modules/hal_rpi_pico/pico/config_autogen.h b/modules/hal_rpi_pico/pico/config_autogen.h new file mode 100644 index 00000000000..4cb7452e19e --- /dev/null +++ b/modules/hal_rpi_pico/pico/config_autogen.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021, Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Originally this file is generated by pico-sdk, and some files + * try to include it. Therefore, we have to provide that file, + * with this exact name. + * Since this file ends up included in all pico-sdk code, it's + * used to inject workarounds to make pico-sdk compile with Zephyr. + */ + +#ifndef _CONFIG_AUTOGEN_H_ +#define _CONFIG_AUTOGEN_H_ + +/* WORKAROUNDS */ + +/* + * static_assert is not supported, so BUILD_ASSERT is used instead. + * BUILD_ASSERT is included through toolchain.h. + */ +#include +#define static_assert(expr, msg...) BUILD_ASSERT((expr), "" msg) + +/* Convert uses of asm, which is not supported in c99, to __asm */ +#define asm __asm + +/* Disable binary info */ +#define PICO_NO_BINARY_INFO 1 + +/* Zephyr compatible way of forcing inline */ +#ifndef __always_inline +#define __always_inline ALWAYS_INLINE +#endif /* __always_inline */ + +#endif diff --git a/modules/hal_rpi_pico/pico/version.h b/modules/hal_rpi_pico/pico/version.h new file mode 100644 index 00000000000..00ea81156cb --- /dev/null +++ b/modules/hal_rpi_pico/pico/version.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2021, Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* File intentionally left blank. It's expected by pico-sdk, but isn't used. */ diff --git a/soc/arm/rpi_pico/CMakeLists.txt b/soc/arm/rpi_pico/CMakeLists.txt new file mode 100644 index 00000000000..226f3bd626f --- /dev/null +++ b/soc/arm/rpi_pico/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/arm/rpi_pico/Kconfig b/soc/arm/rpi_pico/Kconfig new file mode 100644 index 00000000000..7d0f4215aad --- /dev/null +++ b/soc/arm/rpi_pico/Kconfig @@ -0,0 +1,18 @@ +# Raspberry Pi (RP) MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_RPI_PICO + bool + +if SOC_FAMILY_RPI_PICO + +config SOC_FAMILY + string + default "rpi_pico" + +source "soc/arm/rpi_pico/*/Kconfig.soc" + +endif # SOC_FAMILY_RPI_PICO diff --git a/soc/arm/rpi_pico/Kconfig.defconfig b/soc/arm/rpi_pico/Kconfig.defconfig new file mode 100644 index 00000000000..e05525f1aa1 --- /dev/null +++ b/soc/arm/rpi_pico/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Raspberry Pi (RP) MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_RPI_PICO + +source "soc/arm/rpi_pico/*/Kconfig.defconfig.series" + +endif # SOC_FAMILY_RPI_PICO diff --git a/soc/arm/rpi_pico/Kconfig.soc b/soc/arm/rpi_pico/Kconfig.soc new file mode 100644 index 00000000000..d53c18307e0 --- /dev/null +++ b/soc/arm/rpi_pico/Kconfig.soc @@ -0,0 +1,6 @@ +# Raspberry Pi (RP) MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/arm/rpi_pico/*/Kconfig.series" diff --git a/soc/arm/rpi_pico/rp2/CMakeLists.txt b/soc/arm/rpi_pico/rp2/CMakeLists.txt new file mode 100644 index 00000000000..210f5623ae9 --- /dev/null +++ b/soc/arm/rpi_pico/rp2/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(soc.c) diff --git a/soc/arm/rpi_pico/rp2/Kconfig.defconfig.rp2040 b/soc/arm/rpi_pico/rp2/Kconfig.defconfig.rp2040 new file mode 100644 index 00000000000..a410181900c --- /dev/null +++ b/soc/arm/rpi_pico/rp2/Kconfig.defconfig.rp2040 @@ -0,0 +1,8 @@ +# # Raspberry Pi RP2040 MCU + +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "rp2040" + depends on SOC_RP2040 diff --git a/soc/arm/rpi_pico/rp2/Kconfig.defconfig.series b/soc/arm/rpi_pico/rp2/Kconfig.defconfig.series new file mode 100644 index 00000000000..7df057ae441 --- /dev/null +++ b/soc/arm/rpi_pico/rp2/Kconfig.defconfig.series @@ -0,0 +1,17 @@ +# Raspberry Pi RP2XXX MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RP2XXX + +source "soc/arm/rpi_pico/rp2/Kconfig.defconfig.rp2*" + +config SOC_SERIES + default "rp2" + +config NUM_IRQS + default 26 + +endif # SOC_SERIES_RP2XXX diff --git a/soc/arm/rpi_pico/rp2/Kconfig.series b/soc/arm/rpi_pico/rp2/Kconfig.series new file mode 100644 index 00000000000..b13942234d4 --- /dev/null +++ b/soc/arm/rpi_pico/rp2/Kconfig.series @@ -0,0 +1,18 @@ +# Raspberry Pi RP2XXX MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RP2XXX + bool "Raspberry Pi RP2 series MCU" + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU + select SOC_FAMILY_RPI_PICO + select HAS_RPI_PICO + select XIP + help + Enable support for Raspberry Pi RP2 MCU series diff --git a/soc/arm/rpi_pico/rp2/Kconfig.soc b/soc/arm/rpi_pico/rp2/Kconfig.soc new file mode 100644 index 00000000000..601182672db --- /dev/null +++ b/soc/arm/rpi_pico/rp2/Kconfig.soc @@ -0,0 +1,50 @@ +# Raspberry Pi RP2XXX MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "RP2xxx MCU Selection" + depends on SOC_SERIES_RP2XXX + +config SOC_RP2040 + bool "Raspberry Pi RP2040" + +endchoice + +config RP2_REQUIRES_SECOND_STAGE_BOOT + bool + default y if FLASH_LOAD_OFFSET = 0x100 + +# Flash type used by the SoC. The board should select the one used. + +config RP2_FLASH_W25Q080 + bool + help + Configure RP2 to use a W25Q080 flash chip, or similar. Should be selected + by the board definition, not the user. + +config RP2_FLASH_GENERIC_03H + bool + help + Configure RP2 to use a flash chip supporting the standard 03h command. + Should be selected by the board definition, not the user. + +config RP2_FLASH_IS25LP080 + bool + help + Configure RP2 to use a IS25LP080 flash chip, or similar. Should be selected + by the board definition, not the user. + +config RP2_FLASH_W25X10CL + bool + help + Configure RP2 to use a W25X10CL flash chip, or similar. Should be selected + by the board definition, not the user. + +config RP2_FLASH_AT25SF128A + bool + help + Configure RP2 to use a AT25SF128A flash chip, or similar. Should be selected + by the board definition, not the user. diff --git a/soc/arm/rpi_pico/rp2/linker.ld b/soc/arm/rpi_pico/rp2/linker.ld new file mode 100644 index 00000000000..319f9c29b9c --- /dev/null +++ b/soc/arm/rpi_pico/rp2/linker.ld @@ -0,0 +1,29 @@ +/* linker.ld - Linker command/script file */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * The Second Stage Bootloader is only linked to the app that + * resides at 0x100. This can be the application, or a bootloader + * such as mcuboot. + */ +#if CONFIG_RP2_REQUIRES_SECOND_STAGE_BOOT +MEMORY +{ + BOOT_FLASH (r) : ORIGIN = 0x10000000, LENGTH = 256 +} + +SECTIONS +{ + .boot2 : { + KEEP(*(.boot2)) + } > BOOT_FLASH +} +#endif /* CONFIG_RP2_REQUIRES_SECOND_STAGE_BOOT */ + +#include diff --git a/soc/arm/rpi_pico/rp2/soc.c b/soc/arm/rpi_pico/rp2/soc.c new file mode 100644 index 00000000000..233b09f7e6d --- /dev/null +++ b/soc/arm/rpi_pico/rp2/soc.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Raspberry Pi RP2040 family processor + * + * This module provides routines to initialize and support board-level hardware + * for the Raspberry Pi RP2040 family processor. + */ + +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_RUNTIME_NMI +extern void z_arm_nmi_init(void); +#define NMI_INIT() z_arm_nmi_init() +#else +#define NMI_INIT() +#endif + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +static int rp2040_init(const struct device *arg) +{ + uint32_t key; + + reset_block(~(RESETS_RESET_IO_QSPI_BITS | RESETS_RESET_PADS_QSPI_BITS | + RESETS_RESET_PLL_USB_BITS | RESETS_RESET_PLL_SYS_BITS)); + + unreset_block_wait(RESETS_RESET_BITS & + ~(RESETS_RESET_ADC_BITS | RESETS_RESET_RTC_BITS | + RESETS_RESET_SPI0_BITS | RESETS_RESET_SPI1_BITS | + RESETS_RESET_UART0_BITS | RESETS_RESET_UART1_BITS | + RESETS_RESET_USBCTRL_BITS)); + + clocks_init(); + + unreset_block_wait(RESETS_RESET_BITS); + + ARG_UNUSED(arg); + + key = irq_lock(); + + /* Install default handler that simply resets the CPU + * if configured in the kernel, NOP otherwise + */ + NMI_INIT(); + + irq_unlock(key); + + return 0; +} + +SYS_INIT(rp2040_init, PRE_KERNEL_1, 0); diff --git a/soc/arm/rpi_pico/rp2/soc.h b/soc/arm/rpi_pico/rp2/soc.h new file mode 100644 index 00000000000..dc47618334e --- /dev/null +++ b/soc/arm/rpi_pico/rp2/soc.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016 Linaro Limited + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Raspberry Pi RP2040 family processors + */ + +#ifndef _RPI_PICO_RP2040_SOC_H_ +#define _RPI_PICO_RP2040_SOC_H_ + +#include + +#define __VTOR_PRESENT CONFIG_CPU_CORTEX_M_HAS_VTOR +#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU + +#endif /* _RPI_PICO_RP2040_SOC_H_ */