diff --git a/boards/arduino/uno_q/Kconfig.arduino_uno_q b/boards/arduino/uno_q/Kconfig.arduino_uno_q new file mode 100644 index 0000000000000..dfc380667a143 --- /dev/null +++ b/boards/arduino/uno_q/Kconfig.arduino_uno_q @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ARDUINO_UNO_Q + select SOC_STM32U585XX diff --git a/boards/arduino/uno_q/Kconfig.defconfig b/boards/arduino/uno_q/Kconfig.defconfig new file mode 100644 index 0000000000000..418eee5588848 --- /dev/null +++ b/boards/arduino/uno_q/Kconfig.defconfig @@ -0,0 +1,21 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ARDUINO_UNO_Q + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +if BUILD_WITH_TFM + +# Initial Attestation key provisioned by the BL1 bootloader +config TFM_INITIAL_ATTESTATION_KEY + default y + +config TFM_DUMMY_PROVISIONING + default n + +endif # BUILD_WITH_TFM + +endif # BOARD_ARDUINO_UNO_Q diff --git a/boards/arduino/uno_q/arduino_r3_connector.dtsi b/boards/arduino/uno_q/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..222de9d2053d4 --- /dev/null +++ b/boards/arduino/uno_q/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 4 0>, /* A0 */ + <1 0 &gpioa 5 0>, /* A1 */ + <2 0 &gpioa 6 0>, /* A2 */ + <3 0 &gpioa 7 0>, /* A3 */ + <4 0 &gpioc 1 0>, /* A4 */ + <5 0 &gpioc 0 0>, /* A5 */ + <6 0 &gpiob 7 GPIO_ACTIVE_HIGH>, /* D0 */ + <7 0 &gpiob 6 GPIO_ACTIVE_HIGH>, /* D1 */ + <8 0 &gpiob 3 GPIO_ACTIVE_HIGH>, /* D2 */ + <9 0 &gpiob 0 GPIO_ACTIVE_HIGH>, /* D3 */ + <10 0 &gpioa 12 GPIO_ACTIVE_HIGH>, /* D4 */ + <11 0 &gpioa 11 GPIO_ACTIVE_HIGH>, /* D5 */ + <12 0 &gpiob 1 GPIO_ACTIVE_HIGH>, /* D6 */ + <13 0 &gpiob 2 GPIO_ACTIVE_HIGH>, /* D7 */ + <14 0 &gpiob 4 GPIO_ACTIVE_HIGH>, /* D8 */ + <15 0 &gpiob 8 GPIO_ACTIVE_HIGH>, /* D9 */ + <16 0 &gpiob 9 GPIO_ACTIVE_HIGH>, /* D10 */ + <17 0 &gpiob 15 GPIO_ACTIVE_HIGH>, /* D11 */ + <18 0 &gpiob 14 GPIO_ACTIVE_HIGH>, /* D12 */ + <19 0 &gpiob 13 GPIO_ACTIVE_HIGH>; /* D13 */ + }; +}; + +arduino_spi: &spi2 {}; + +arduino_i2c: &i2c2 {}; + +arduino_serial: &usart1 {}; diff --git a/boards/arduino/uno_q/arduino_uno_q-common.dtsi b/boards/arduino/uno_q/arduino_uno_q-common.dtsi new file mode 100644 index 0000000000000..95654a96a9a12 --- /dev/null +++ b/boards/arduino/uno_q/arduino_uno_q-common.dtsi @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2021 Linaro Limited + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "arduino_r3_connector.dtsi" +#include + +/ { + leds { + compatible = "gpio-leds"; + + led3_red: led3_red { + gpios = <&gpioh 10 GPIO_ACTIVE_LOW>; + label = "RGB LED 3 Red"; + }; + + led3_green: led3_green { + gpios = <&gpioh 11 GPIO_ACTIVE_LOW>; + label = "RGB LED 3 Green"; + }; + + led3_blue: led3_blue { + gpios = <&gpioh 12 GPIO_ACTIVE_LOW>; + label = "RGB LED 3 Blue"; + }; + + led4_red: led4_red { + gpios = <&gpioh 13 GPIO_ACTIVE_LOW>; + label = "RGB LED 4 Red"; + }; + + led4_green: led4_green { + gpios = <&gpioh 14 GPIO_ACTIVE_LOW>; + label = "RGB LED 4 Green"; + }; + + led4_blue: led4_blue { + gpios = <&gpioh 15 GPIO_ACTIVE_LOW>; + label = "RGB LED 4 Blue"; + }; + }; + + aliases { + watchdog0 = &iwdg; + die-temp0 = &die_temp; + volt-sensor0 = &vref1; + volt-sensor1 = &vbat4; + }; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&clk_lse { + clock-frequency = <32768>; + status = "okay"; +}; + +&clk_msis { + status = "okay"; + msi-range = <4>; + msi-pll-mode; +}; + +&pll1 { + div-m = <1>; + mul-n = <80>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_msis>; + status = "okay"; +}; + +&rcc { + clocks = <&pll1>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; + +stm32_lp_tick_source: &lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB3 0x00000800>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; + status = "okay"; +}; + +&lpuart1 { + pinctrl-0 = <&lpuart1_tx_pg7 &lpuart1_rx_pg8 &lpuart1_rts_pg6 &lpuart1_cts_pg5>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart1 { + status = "okay"; + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&i2c2 { + status = "okay"; + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&i2c4 { + status = "okay"; + pinctrl-0 = <&i2c4_scl_pd12 &i2c4_sda_pd13>; + /* use <&i2c4_scl_pf14 &i2c4_sda_pf15> for the JMISC connector */ + pinctrl-names = "default"; + clock-frequency = ; +}; + +&spi2 { + status = "okay"; + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15 &spi2_nss_pb9>; + /* use <&spi2_sck_pd1 &spi2_miso_pc2 &spi2_mosi_pc3> for the ICSP connector */ + pinctrl-names = "default"; +}; + +&spi3 { + status = "okay"; + pinctrl-0 = <&spi3_sck_pg9 &spi3_miso_pg10 &spi3_mosi_pb5 &spi3_nss_pg12>; + pinctrl-names = "default"; +}; + +&aes { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +zephyr_udc0: &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; + pinctrl-names = "default"; + status = "disabled"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in9_pa4 + &adc1_in10_pa5 + &adc1_in11_pa6 + &adc1_in12_pa7 + &adc1_in2_pc1 + &adc1_in1_pc0>; + pinctrl-names = "default"; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@9 { + reg = <9>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@a { + reg = <10>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@b { + reg = <11>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@c { + reg = <12>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; +}; + +&die_temp { + status = "okay"; +}; + +&dac1 { + pinctrl-0 = <&dac1_out1_pa4 &dac1_out2_pa5>; + pinctrl-names = "default"; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB3 0x00200000>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&vref1 { + status = "okay"; +}; + +&vbat4 { + status = "okay"; +}; + +&gpiog { + status = "okay"; +}; diff --git a/boards/arduino/uno_q/arduino_uno_q.dts b/boards/arduino/uno_q/arduino_uno_q.dts new file mode 100644 index 0000000000000..1a3c902d1659b --- /dev/null +++ b/boards/arduino/uno_q/arduino_uno_q.dts @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "arduino_uno_q-common.dtsi" +#include +#include + +/ { + model = "Arduino UNO Q"; + compatible = "arduino,uno_q"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + aliases { + led0 = &led3_green; + led1 = &led3_red; + die-temp0 = &die_temp; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * Following flash partition is dedicated to the use of stm32u585 + * with TZEN=0 (so w/o TFM). + * Set the partitions with first MB to make use of the whole Bank1 + */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(416)>; + }; + + slot1_partition: partition@78000 { + label = "image-1"; + reg = <0x00078000 DT_SIZE_K(416)>; + }; + + scratch_partition: partition@e0000 { + label = "image-scratch"; + reg = <0x000e0000 DT_SIZE_K(64)>; + }; + + storage_partition: partition@f0000 { + label = "storage"; + reg = <0x000f0000 DT_SIZE_K(64)>; + }; + }; +}; + +&gpdma1 { + status = "okay"; +}; + +&adc1 { + st,adc-prescaler = <4>; + status = "okay"; +}; diff --git a/boards/arduino/uno_q/arduino_uno_q.yaml b/boards/arduino/uno_q/arduino_uno_q.yaml new file mode 100644 index 0000000000000..9951280bc7177 --- /dev/null +++ b/boards/arduino/uno_q/arduino_uno_q.yaml @@ -0,0 +1,27 @@ +identifier: arduino_uno_q +name: Arduino UNO Q +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 786 +flash: 2048 +supported: + - arduino_i2c + - arduino_spi + - hts221 + - dma + - usb_device + - spi + - dac + - adc + - watchdog + - nvs + - backup_sram + - pwm + - counter + - i2c + - rtc + - usbd +vendor: arduino diff --git a/boards/arduino/uno_q/arduino_uno_q_defconfig b/boards/arduino/uno_q/arduino_uno_q_defconfig new file mode 100644 index 0000000000000..0f4ce3ee7b48b --- /dev/null +++ b/boards/arduino/uno_q/arduino_uno_q_defconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +# enable uart driver +CONFIG_SERIAL=y + +# enable GPIO +CONFIG_GPIO=y + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns.dts b/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns.dts new file mode 100644 index 0000000000000..3bb581b543044 --- /dev/null +++ b/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns.dts @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 Linaro Limited + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "uno_q-common.dtsi" + +/ { + model = "Arduino UNO Q"; + compatible = "arduino,uno_q"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_ns_partition; + }; + + aliases { + led0 = &led4_green; + led1 = &led4_red; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * Following flash partition is compatible with requirements + * given in TFM configuration given for current board. + * It might require adjustment depending on evolutions on TFM. + */ + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(224)>; + read-only; + }; + + /* Secure image primary slot */ + slot0_partition: partition@38000 { + label = "image-0"; + reg = <0x00038000 DT_SIZE_K(384)>; + }; + + /* Non-secure image primary slot */ + slot0_ns_partition: partition@98000 { + label = "image-0-nonsecure"; + reg = <0x00098000 DT_SIZE_K(512)>; + }; + + /* Secure image secondary slot */ + slot1_partition: partition@118000 { + label = "image-1"; + reg = <0x00118000 DT_SIZE_K(384)>; + }; + + /* Non-secure image secondary slot */ + slot1_ns_partition: partition@178000 { + label = "image-1-nonsecure"; + reg = <0x00178000 DT_SIZE_K(512)>; + }; + + /* Applicative Non Volatile Storage */ + storage_partition: partition@1f8000 { + label = "storage"; + reg = <0x001f8000 DT_SIZE_K(16)>; + }; + }; +}; diff --git a/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns.yaml b/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns.yaml new file mode 100644 index 0000000000000..efa07296f23b8 --- /dev/null +++ b/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns.yaml @@ -0,0 +1,10 @@ +identifier: uno_q/stm32u585xx/ns +name: Arduino UNO Q non secure target +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 786 +flash: 512 +vendor: arduino diff --git a/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns_defconfig b/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns_defconfig new file mode 100644 index 0000000000000..fdb90af54d27a --- /dev/null +++ b/boards/arduino/uno_q/arduino_uno_q_stm32u585xx_ns_defconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +# enable uart driver +CONFIG_SERIAL=y + +# enable GPIO +CONFIG_GPIO=y + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_ARM_TRUSTZONE_M=y +CONFIG_RUNTIME_NMI=y +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +CONFIG_TFM_MCUBOOT_SIGNATURE_TYPE="RSA-3072" diff --git a/boards/arduino/uno_q/board.cmake b/boards/arduino/uno_q/board.cmake new file mode 100644 index 0000000000000..fe8116ffcec62 --- /dev/null +++ b/boards/arduino/uno_q/board.cmake @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: Apache-2.0 +if(CONFIG_BUILD_WITH_TFM) + set(TFM_FLASH_BASE_ADDRESS 0x0C000000) + + # Flash merged TF-M + Zephyr binary + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) + + if(CONFIG_HAS_FLASH_LOAD_OFFSET) + MATH(EXPR TFM_HEX_BASE_ADDRESS_NS "${TFM_FLASH_BASE_ADDRESS}+${CONFIG_FLASH_LOAD_OFFSET}") + else() + set(TFM_HEX_BASE_ADDRESS_NS ${TFM_TFM_FLASH_BASE_ADDRESS}) + endif() +endif() + +board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") + +board_runner_args(openocd "--tcl-port=6666") +board_runner_args(openocd --cmd-pre-init "gdb_report_data_abort enable") +board_runner_args(openocd "--no-halt") + +board_runner_args(jlink "--device=STM32U585AI" "--reset-after-load") + +# keep first +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +# FIXME: openocd runner requires use of STMicro openocd fork. +# Check board documentation for more details. +include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arduino/uno_q/board.yml b/boards/arduino/uno_q/board.yml new file mode 100644 index 0000000000000..6812e18df7dc9 --- /dev/null +++ b/boards/arduino/uno_q/board.yml @@ -0,0 +1,8 @@ +board: + name: arduino_uno_q + full_name: Arduino UNO Q + vendor: arduino + socs: + - name: stm32u585xx + variants: + - name: ns diff --git a/boards/arduino/uno_q/doc/img/arduino_uno_q.webp b/boards/arduino/uno_q/doc/img/arduino_uno_q.webp new file mode 100644 index 0000000000000..42988e99d5c9f Binary files /dev/null and b/boards/arduino/uno_q/doc/img/arduino_uno_q.webp differ diff --git a/boards/arduino/uno_q/doc/index.rst b/boards/arduino/uno_q/doc/index.rst new file mode 100644 index 0000000000000..5014bf47a07e1 --- /dev/null +++ b/boards/arduino/uno_q/doc/index.rst @@ -0,0 +1,76 @@ +.. zephyr:board:: arduino_uno_q + +Overview +******** + +The Arduino UNO Q is a development board featuring a Qualcomm QRB2210 +processor (Quad core ARM Cortex-A53) and an STM32U585 microcontroller. +The board is designed around the Arduino form factor and is compatible +with traditional Arduino shields and accessories. +This port targets the STM32U585 microcontroller on the board. + +Hardware +******** + +- Qualcomm QRB2210 Processor (Quad core ARM Cortex-A53) +- STM32U585 Microcontroller (ARM Cortex-M33 at 160 MHz) +- 2 Mbyte of Flash memory and 786 Kbytes of RAM +- 2 RGB user LEDs +- One 13x8 LED Matrix +- Internal UART and SPI busses connected to the QRB2210 +- Built-in CMSIS-DAP debug adapter (through QRB2210) + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Programming and debugging +************************* + +.. zephyr:board-supported-runners:: + +Debug adapter +============= + +The QRB2210 microprocessor can act as an SWD debug adapter for the STM32U585. +This is supported by the ``openocd`` binary available in the board, and its +functionality can be made available to the computer via ``adb`` port forwarding +commands. + +This interface is not yet integrated with the ``west flash`` command, but +debugging is supported. + +Debugging +========= + +Debugging can be done with the usual ``west debug`` command after starting the +debug server on the board. The following commands, run from an USB-connected +computer, allow to debug the :zephyr:code-sample:`blinky` application on the +Uno Q board: + +.. code-block:: console + + adb forward tcp:3333 tcp:3333 && adb shell arduino-debug + # in a different shell + west build -b arduino_uno_q samples/basic/blinky + west debug -r openocd + +Restoring the Arduino sketch loader +=================================== + +The Arduino UNO Q comes with a pre-installed application that acts as a loader +for user sketches, and is shipped as part of the Arduino Zephyr cores. If you +overwrite this application, you can restore it later by issuing the following +command from an USB-connected computer: + +.. code-block:: console + + adb shell arduino-cli burn-bootloader -b arduino:zephyr:unoq -P jlink + +The same ``arduino-cli`` command can also be directly used on the board, when +in standalone mode: + +.. code-block:: console + + arduino-cli burn-bootloader -b arduino:zephyr:unoq -P jlink