diff --git a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts index 5d6e0dd7d883c..7505ba0f2df7a 100644 --- a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts +++ b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts @@ -252,3 +252,9 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; pinctrl-names = "default"; }; + +/* alias used by display shields */ +zephyr_mipi_dsi: &mipi_dsi {}; + +/* alias used by LCD display shields */ +zephyr_lcd_controller: <dc {}; diff --git a/boards/arduino/portenta_c33/CMakeLists.txt b/boards/arduino/portenta_c33/CMakeLists.txt new file mode 100644 index 0000000000000..973775b8077c1 --- /dev/null +++ b/boards/arduino/portenta_c33/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_NETWORKING eth_pwm_clock.c) diff --git a/boards/arduino/portenta_c33/Kconfig.arduino_portenta_c33 b/boards/arduino/portenta_c33/Kconfig.arduino_portenta_c33 new file mode 100644 index 0000000000000..1db7ac3de08d9 --- /dev/null +++ b/boards/arduino/portenta_c33/Kconfig.arduino_portenta_c33 @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ARDUINO_PORTENTA_C33 + select SOC_R7FA6M5BH3CFC diff --git a/boards/arduino/portenta_c33/Kconfig.defconfig b/boards/arduino/portenta_c33/Kconfig.defconfig new file mode 100644 index 0000000000000..5c68a2fdc6f3d --- /dev/null +++ b/boards/arduino/portenta_c33/Kconfig.defconfig @@ -0,0 +1,13 @@ +# Copyright 2024 Rahul Arasikere +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ARDUINO_PORTENTA_C33 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_ARDUINO_PORTENTA_C33 diff --git a/boards/arduino/portenta_c33/arduino_portenta_c33-pinctrl.dtsi b/boards/arduino/portenta_c33/arduino_portenta_c33-pinctrl.dtsi new file mode 100644 index 0000000000000..a2fa71311c284 --- /dev/null +++ b/boards/arduino/portenta_c33/arduino_portenta_c33-pinctrl.dtsi @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2024 Arduino SA + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci7_default: sci7_default { + group1 { + /* tx rx */ + psels = , + , + , + ; + }; + }; + + sci9_default: sci9_default { + group1 { + /* tx rx */ + psels = , + , + , + ; + }; + }; + + sci5_default: sci5_default { + group1 { + /* tx rx */ + psels = , + , + , + ; + }; + }; + + sci6_default: sci6_default { + group1 { + /* tx rx */ + psels = , + , + , + ; + }; + }; + + sci8_default: sci8_default { + group1 { + /* tx rx rts cts - BLE */ + psels = , + , + , + ; + }; + }; + + iic1_default: iic1_default { + group1 { + /* SCL1 SDA1 */ + psels = , + ; + drive-strength = "medium"; + }; + }; + + spi1_default: spi1_default { + group1 { + /* MISO MOSI RSPCK SSL0 SSL1 */ + psels = , + , + , + , + ; + }; + }; + + usbhs_default: usbhs_default { + group1 { + psels = ; /* USBHS-VBUS */ + drive-strength = "high"; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = , + , + , + , + , + , + , + ; + renesas,analog-enable; + }; + }; + + ether_default: ether_default { + group1 { + psels = , /* ET0_MDC */ + , /* ET0_MDIO */ + , /* RMII0_TXD_EN_B */ + , /* RMII0_TXD1_BR */ + , /* RMII0_TXD0_B */ + , /* REF50CK0_B */ + , /* RMII0_RXD0_B */ + , /* RMII0_RXD1_B */ + , /* RMII0_RX_ER_B */ + ; /* RMII0_CRS_DV_B */ + drive-strength = "high"; + }; + }; + + pwm1_default: pwm1_default { + group1 { + psels = ; + }; + }; + + pwm3_default: pwm3_default { + group1 { + psels = ; + }; + }; + + pwm4_default: pwm4_default { + group1 { + psels = ; + }; + }; + + pwm6_default: pwm6_default { + group1 { + psels = , + ; + }; + }; + + pwm7_default: pwm7_default { + group1 { + psels = ; + }; + }; + + pwm8_default: pwm8_default { + group1 { + psels = , + ; + }; + }; +}; diff --git a/boards/arduino/portenta_c33/arduino_portenta_c33.dts b/boards/arduino/portenta_c33/arduino_portenta_c33.dts new file mode 100644 index 0000000000000..dd8a73a1fa1a3 --- /dev/null +++ b/boards/arduino/portenta_c33/arduino_portenta_c33.dts @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2025 Arduino SA + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include + +#include "arduino_portenta_c33-pinctrl.dtsi" + +/ { + model = "Arduino Portenta C33"; + compatible = "renesas,ra6m5", "renesas,ra"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; + zephyr,code-partition = &code_partition; + zephyr,flash = &flash0; + zephyr,console = &uart9; + zephyr,shell-uart = &uart9; + zephyr,entropy = &trng; + zephyr,bt-hci = &bt_hci_uart; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&ioport1 7 GPIO_ACTIVE_LOW>; + label = "LEDR"; + }; + + led2: led2 { + gpios = <&ioport4 0 GPIO_ACTIVE_HIGH>; + label = "LEDG"; + }; + + led3: led3 { + gpios = <&ioport8 0 GPIO_ACTIVE_HIGH>; + label = "LEDB"; + }; + }; + + download-esp32 { + compatible = "regulator-fixed"; + regulator-name = "download_esp32"; + enable-gpios = <&ioport8 3 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + }; + + aliases { + led0 = &led1; + }; +}; + +&sci9 { + pinctrl-0 = <&sci9_default>; + pinctrl-names = "default"; + status = "okay"; + + uart9: uart { + current-speed = <115200>; + status = "okay"; + }; +}; + +&sci8 { + pinctrl-0 = <&sci8_default>; + pinctrl-names = "default"; + status = "okay"; + + uart8: uart { + current-speed = <921600>; + status = "okay"; + hw-flow-control; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + + esp32 { + compatible = "renesas,bt-hci-da1453x"; + status = "okay"; + reset-gpios = <&ioport8 4 GPIO_ACTIVE_LOW>; + reset-assert-duration-ms = <100>; + boot-duration-ms = <2000>; + }; + }; + }; +}; + +&option_setting_s { + status = "disabled"; +}; + +&option_setting_sas { + status = "disabled"; +}; + +&option_setting_ofs { + status = "disabled"; +}; + +&iic1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <91 1>, <92 1>, <93 1>, <94 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + clock-frequency = ; + pinctrl-0 = <&iic1_default>; + pinctrl-names = "default"; +}; + +&spi1 { + pinctrl-0 = <&spi1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&ioport0 { + status = "okay"; +}; + +&ioport1 { + status = "okay"; +}; + +&ioport2 { + status = "okay"; +}; + +&ioport3 { + status = "okay"; +}; + +&ioport4 { + status = "okay"; +}; + +&ioport5 { + status = "okay"; +}; + +&ioport6 { + status = "okay"; +}; + +&ioport7 { + status = "okay"; +}; + +&ioport8 { + status = "okay"; +}; + +&ioport9 { + status = "okay"; +}; + +&ioporta { + status = "okay"; +}; + +&ioportb { + status = "okay"; +}; + +&xtal { + clock-frequency = ; + mosel = <0>; + #clock-cells = <0>; + status = "okay"; +}; + +&subclk { + status = "okay"; +}; + +&pll { + clocks = <&xtal>; + div = <3>; + mul = <25 0>; + status = "okay"; +}; + +&usbhs { + pinctrl-0 = <&usbhs_default>; + pinctrl-names = "default"; + maximum-speed = "high-speed"; + status = "okay"; + + zephyr_udc0: udc { + status = "okay"; + }; +}; + +&usbhs_phy { + phys-clock-src = "xtal"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&port_irq9 { + interrupts = <41 12>; + status = "okay"; +}; + +&port_irq10 { + interrupts = <42 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; + }; + + code_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 (DT_SIZE_M(2) - DT_SIZE_K(64))>; + }; + }; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; + +&trng { + status = "okay"; +}; + +ð { + local-mac-address = [74 90 50 B0 5D E9]; + status = "okay"; + phy-handle = <&phy>; +}; + +&mdio { + pinctrl-0 = <ðer_default>; + pinctrl-names = "default"; + status = "okay"; + + phy: ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0>; + status = "okay"; + }; +}; + +&pwm6 { + pinctrl-0 = <&pwm6_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; + + pwmclock: pwmclock { + status = "okay"; + compatible = "pwm-clock"; + clock-frequency = <25000000>; + #clock-cells = <1>; + pwms = <&pwm6 1 PWM_HZ(25000000) PWM_POLARITY_NORMAL>; + }; +}; diff --git a/boards/arduino/portenta_c33/arduino_portenta_c33.yaml b/boards/arduino/portenta_c33/arduino_portenta_c33.yaml new file mode 100644 index 0000000000000..29764cfcd4d11 --- /dev/null +++ b/boards/arduino/portenta_c33/arduino_portenta_c33.yaml @@ -0,0 +1,11 @@ +identifier: portenta_c33 +name: Arduino Portenta C33 +type: mcu +arch: arm +ram: 512 +flash: 2048 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio diff --git a/boards/arduino/portenta_c33/arduino_portenta_c33_defconfig b/boards/arduino/portenta_c33/arduino_portenta_c33_defconfig new file mode 100644 index 0000000000000..11b6a78abebd9 --- /dev/null +++ b/boards/arduino/portenta_c33/arduino_portenta_c33_defconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 + +CONFIG_GPIO=y + +CONFIG_BUILD_OUTPUT_BIN=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_CLOCK_CONTROL=y + +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y + +CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_DYNAMIC_INTERRUPTS=y + +CONFIG_REGULATOR=y diff --git a/boards/arduino/portenta_c33/board.cmake b/boards/arduino/portenta_c33/board.cmake new file mode 100644 index 0000000000000..3375cade093f8 --- /dev/null +++ b/boards/arduino/portenta_c33/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + + +# FIXME: Arduino dfu-util provides -Q to reset the board after flashing +board_runner_args(dfu-util "--pid=2341:0368" "--alt=0") +board_runner_args(jlink "--device=R7FA6M5BH") + +include(${ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arduino/portenta_c33/board.yml b/boards/arduino/portenta_c33/board.yml new file mode 100644 index 0000000000000..111e046ca645f --- /dev/null +++ b/boards/arduino/portenta_c33/board.yml @@ -0,0 +1,6 @@ +board: + name: arduino_portenta_c33 + full_name: Arduino Portenta C33 + vendor: arduino + socs: + - name: r7fa6m5bh3cfc diff --git a/boards/arduino/portenta_c33/eth_pwm_clock.c b/boards/arduino/portenta_c33/eth_pwm_clock.c new file mode 100644 index 0000000000000..1bf4f6c422901 --- /dev/null +++ b/boards/arduino/portenta_c33/eth_pwm_clock.c @@ -0,0 +1,42 @@ +/* + * Copyright 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(eth_pwm_clock, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +int eth_pwm_clock_enable(void) +{ + int ret; + uint32_t rate; + const struct device *eth_pwm_clk_dev = DEVICE_DT_GET(DT_NODELABEL(pwmclock)); + + if (!device_is_ready(eth_pwm_clk_dev)) { + LOG_ERR("Camera external clock source device is not ready!"); + return -ENODEV; + } + + ret = clock_control_on(eth_pwm_clk_dev, (clock_control_subsys_t)0); + if (ret < 0) { + LOG_ERR("Failed to enable camera external clock error: (%d)", ret); + return ret; + } + + ret = clock_control_get_rate(eth_pwm_clk_dev, (clock_control_subsys_t)0, &rate); + if (ret < 0) { + LOG_ERR("Failed to get camera external clock rate, error: (%d)", ret); + return ret; + } + + LOG_INF("Camera external clock rate: (%u) Hz", rate); + + return 0; +} + +SYS_INIT(eth_pwm_clock_enable, POST_KERNEL, CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY); diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts index 001d8509059e2..fe77a36963303 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts @@ -8,7 +8,7 @@ #include #include #include "arduino_portenta_h7-common.dtsi" -#include <../boards/common/usb/cdc_acm_serial.dtsi> +/* #include <../boards/common/usb/cdc_acm_serial.dtsi> */ / { model = "Arduino Portenta H7 board"; diff --git a/boards/shields/giga_display_shield/Kconfig.defconfig b/boards/shields/giga_display_shield/Kconfig.defconfig new file mode 100644 index 0000000000000..03eff24537300 --- /dev/null +++ b/boards/shields/giga_display_shield/Kconfig.defconfig @@ -0,0 +1,37 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_ARDUINO_GIGA_DISPLAY_SHIELD + +# Double frame buffer maintained by lvgl. +if LVGL + +config STM32_LTDC_FB_NUM + default 0 + +config INPUT + default y + +config LV_Z_DOUBLE_VDB + default y + +config LV_Z_FULL_REFRESH + default y + +config LV_Z_BITS_PER_PIXEL + default 16 + +config LV_DPI_DEF + default 128 + +config LV_Z_FLUSH_THREAD + default y + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_16 + +endchoice + +endif # LVGL + +endif # SHIELD_ARDUINO_GIGA_DISPLAY_SHIELD diff --git a/boards/shields/giga_display_shield/Kconfig.shield b/boards/shields/giga_display_shield/Kconfig.shield new file mode 100644 index 0000000000000..16714a397c941 --- /dev/null +++ b/boards/shields/giga_display_shield/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ARDUINO_GIGA_DISPLAY_SHIELD + def_bool $(shields_list_contains,arduino_giga_display_shield) diff --git a/boards/shields/giga_display_shield/boards/arduino_giga_r1_m7.conf b/boards/shields/giga_display_shield/boards/arduino_giga_r1_m7.conf new file mode 100644 index 0000000000000..31d6841989807 --- /dev/null +++ b/boards/shields/giga_display_shield/boards/arduino_giga_r1_m7.conf @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MEMC=y +CONFIG_STM32_LTDC_RGB565=y +CONFIG_HEAP_MEM_POOL_SIZE=65536 +CONFIG_DISPLAY_ST7701_INIT_PRIORITY=87 +CONFIG_STM32_LTDC_DISABLE_FMC_BANK1=y +CONFIG_INPUT_GT911_INTERRUPT=y diff --git a/boards/shields/giga_display_shield/boards/arduino_giga_r1_m7.overlay b/boards/shields/giga_display_shield/boards/arduino_giga_r1_m7.overlay new file mode 100644 index 0000000000000..72fe8031f71f1 --- /dev/null +++ b/boards/shields/giga_display_shield/boards/arduino_giga_r1_m7.overlay @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <>911>; + }; + + aliases { + accel0 = >911; + }; + + chosen { + zephyr,display = &zephyr_lcd_controller; + zephyr,touch = >911; + }; +}; + +&sdram1 { + /* Frame buffer memory cache will cause screen flickering. */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; +}; + +&zephyr_lcd_controller { + status = "okay"; + ext-sdram = <&sdram1>; + width = <480>; + height = <800>; + def-back-color-red = <0>; + def-back-color-green = <0>; + def-back-color-blue = <0>; + pixel-format = ; + + disp-on-gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>; + bl-ctrl-gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>; + + /* sitronix, st7701 */ + display-timings { + compatible = "zephyr,panel-timing"; + hsync-active = <1>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + hback-porch = <40>; + hsync-len = <32>; + hfront-porch = <8>; + vback-porch = <6>; + vsync-len = <8>; + vfront-porch = <9>; + }; +}; + +/* ltdc uses pll3_r as pixel clock */ +&pll3 { + status = "okay"; + clocks = <&clk_hse>; + div-m = <16>; + mul-n = <110>; + div-p = <2>; + div-q = <2>; + div-r = <4>; /* 27.5 MHz */ +}; + +&zephyr_mipi_dsi { + status = "okay"; + + pll-ndiv = <125>; + pll-idf = <4>; + pll-odf = <0>; + + de-active-high; + largest-packet-size = <0>; + + phy-timings = <35 35 35 35 0 10>; +}; + +&i2c4 { + pinctrl-0 = <&i2c4_scl_pb6 &i2c4_sda_ph12>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; + + gt911: gt911@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + alt-addr = <0x14>; + reset-gpios = <&gpioi 2 GPIO_ACTIVE_LOW>; + irq-gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/boards/shields/giga_display_shield/giga_display_shield.overlay b/boards/shields/giga_display_shield/giga_display_shield.overlay new file mode 100644 index 0000000000000..5da125332dbd7 --- /dev/null +++ b/boards/shields/giga_display_shield/giga_display_shield.overlay @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&zephyr_mipi_dsi { + st7701: st7701@0 { + status = "okay"; + compatible = "sitronix,st7701"; + reg = <0x0>; + height = <800>; + width = <480>; + data-lanes = <2>; + pixel-format = ; + rotation = <0>; + gip-e0 = [E0 00 00 02]; + gip-e1 = [E1 08 00 0A 00 07 00 09 00 00 33 33]; + gip-e2 = [E2 00 00 00 00 00 00 00 00 00 00 00 00 00]; + gip-e3 = [E3 00 00 33 33]; + gip-e4 = [E4 44 44]; + gip-e5 = [E5 0E 60 A0 A0 10 60 A0 A0 0A 60 A0 A0 0C 60 A0 A0]; + gip-e6 = [E6 00 00 33 33]; + gip-e7 = [E7 44 44]; + gip-e8 = [E8 0D 60 A0 A0 0F 60 A0 A0 09 60 A0 A0 0B 60 A0 A0]; + gip-eb = [EB 02 01 E4 E4 44 00 40]; + gip-ec = [EC 02 01]; + gip-ed = [ED AB 89 76 54 01 FF FF FF FF FF FF 10 45 67 98 BA]; + gip-ed = [ED AB 89 76 54 01 FF FF FF FF FF FF 10 45 67 98 BA]; + pvgamctrl = [B0 40 C9 91 0D 12 07 02 09 09 1F 04 50 0F E4 29 DF]; + nvgamctrl = [B1 40 CB D0 11 92 07 00 08 07 1C 06 53 12 63 EB DF]; + + display-timings { + compatible = "zephyr,panel-timing"; + hsync-active = <1>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + hback-porch = <40>; + hsync-len = <32>; + hfront-porch = <8>; + vback-porch = <6>; + vsync-len = <8>; + vfront-porch = <9>; + }; + }; +}; diff --git a/cmake/llext-edk.cmake b/cmake/llext-edk.cmake index 1fca00322659f..1475931968dd2 100644 --- a/cmake/llext-edk.cmake +++ b/cmake/llext-edk.cmake @@ -166,8 +166,7 @@ yaml_get(board_qualifiers NAME build_info KEY cmake board qualifiers) yaml_get(board_revision NAME build_info KEY cmake board revision) zephyr_build_string(normalized_board_target BOARD ${board_name} - BOARD_QUALIFIERS ${board_qualifiers} - BOARD_REVISION ${board_revision}) + BOARD_QUALIFIERS ${board_qualifiers}) set(llext_edk_name ${CONFIG_LLEXT_EDK_NAME}) set(llext_edk ${PROJECT_BINARY_DIR}/${llext_edk_name}) diff --git a/cmake/package_helper.cmake b/cmake/package_helper.cmake index 886dbfff71ddf..a360f2032c48d 100644 --- a/cmake/package_helper.cmake +++ b/cmake/package_helper.cmake @@ -19,6 +19,9 @@ # The build directory will default to current working directory but can be # controlled with: '-B ' # +# After the modules have been loaded, additional commands can be optionally +# executed in the current context by providing the '-R ' option. +# # For example, if you were invoking CMake for 'hello_world' sample as: # $ cmake -DBOARD= -B build -S samples/hello_world # @@ -49,10 +52,12 @@ foreach(i RANGE ${CMAKE_ARGC}) if(CMAKE_ARGV${i} MATCHES "^-B(.*)") set(argB ${CMAKE_MATCH_1}) set(argB_index ${i}) - elseif() elseif(CMAKE_ARGV${i} MATCHES "^-S(.*)") set(argS_index ${i}) set(argS ${CMAKE_MATCH_1}) + elseif(CMAKE_ARGV${i} MATCHES "^-R(.*)") + set(argR_index ${i}) + set(argR ${CMAKE_MATCH_1}) endif() endforeach() @@ -76,6 +81,16 @@ if(DEFINED argS_index) endif() endif() +if(DEFINED argR_index) + if(DEFINED argR) + set(RUN_SCRIPT ${argR}) + else() + # value of -R follows in next index + math(EXPR argR_value_index "${argR_index} + 1") + set(RUN_SCRIPT ${CMAKE_ARGV${argR_value_index}}) + endif() +endif() + if(NOT DEFINED APPLICATION_SOURCE_DIR) message(FATAL_ERROR "Source directory not defined, please use '-S ' to the " @@ -99,3 +114,7 @@ endif() string(REPLACE ";" "," MODULES "${MODULES}") find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS zephyr_default:${MODULES}) + +if (DEFINED RUN_SCRIPT) + include(${RUN_SCRIPT}) +endif() diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 7071303dfb6fe..5123faeafd085 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -34,6 +34,7 @@ zephyr_library_sources_ifdef(CONFIG_DISPLAY_RENESAS_LCDC display_renesas_lcdc.c) zephyr_library_sources_ifdef(CONFIG_NT35510 display_nt35510.c) zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_GLCDC display_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_ILI9806E_DSI display_ili9806e_dsi.c) +zephyr_library_sources_ifdef(CONFIG_ST7701 display_st7701.c) zephyr_library_sources_ifdef(CONFIG_MICROBIT_DISPLAY mb_display.c diff --git a/drivers/display/Kconfig b/drivers/display/Kconfig index 13206b8a63c78..08de8a09ce532 100644 --- a/drivers/display/Kconfig +++ b/drivers/display/Kconfig @@ -51,5 +51,6 @@ source "drivers/display/Kconfig.renesas_lcdc" source "drivers/display/Kconfig.nt35510" source "drivers/display/Kconfig.renesas_ra" source "drivers/display/Kconfig.ili9806e_dsi" +source "drivers/display/Kconfig.st7701" endif # DISPLAY diff --git a/drivers/display/Kconfig.st7701 b/drivers/display/Kconfig.st7701 new file mode 100644 index 0000000000000..10752b70d65d4 --- /dev/null +++ b/drivers/display/Kconfig.st7701 @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config ST7701 + bool "ST7701 display driver" + default y + depends on DT_HAS_SITRONIX_ST7701_ENABLED + select MIPI_DSI + help + Enable driver for ST7701 display driver. + +if ST7701 + +config DISPLAY_ST7701_INIT_PRIORITY + int "Initialization priority" + default DISPLAY_INIT_PRIORITY + help + ST7701 display driver initialization priority. + +endif diff --git a/drivers/display/display_st7701.c b/drivers/display/display_st7701.c new file mode 100644 index 0000000000000..cc53f00fa9b12 --- /dev/null +++ b/drivers/display/display_st7701.c @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sitronix_st7701 + +#include +#include +#include +#include +#include +#include +#include "display_st7701.h" + +LOG_MODULE_REGISTER(st7701, CONFIG_DISPLAY_LOG_LEVEL); + +struct st7701_config { + const struct device *mipi_dsi; + const struct gpio_dt_spec reset; + const struct gpio_dt_spec backlight; + uint8_t data_lanes; + uint16_t width; + uint16_t height; + uint8_t channel; + uint16_t rotation; + uint32_t hbp; + uint32_t hsync; + uint32_t hfp; + uint32_t vbp; + uint32_t vsync; + uint32_t vfp; + uint8_t gip_e0[4]; + uint8_t gip_e1[12]; + uint8_t gip_e2[14]; + uint8_t gip_e3[5]; + uint8_t gip_e4[3]; + uint8_t gip_e5[17]; + uint8_t gip_e6[5]; + uint8_t gip_e7[3]; + uint8_t gip_e8[17]; + uint8_t gip_eb[8]; + uint8_t gip_ec[3]; + uint8_t gip_ed[17]; + uint8_t pvgamctrl[17]; + uint8_t nvgamctrl[17]; +}; + +struct st7701_data { + uint16_t xres; + uint16_t yres; + uint8_t dsi_pixel_format; + enum display_pixel_format pixel_format; + enum display_orientation orientation; +}; + +static inline int st7701_dcs_write(const struct device *dev, uint8_t cmd, const void *buf, + size_t len) +{ + const struct st7701_config *cfg = dev->config; + int ret; + + ret = mipi_dsi_dcs_write(cfg->mipi_dsi, cfg->channel, cmd, buf, len); + if (ret < 0) { + LOG_ERR("DCS 0x%x write failed! (%d)", cmd, ret); + return ret; + } + + return 0; +} + +static int st7701_short_write_1p(const struct device *dev, uint8_t cmd, uint8_t val) +{ + const struct st7701_config *cfg = dev->config; + int ret; + uint8_t buf[] = {cmd, val}; + + ret = mipi_dsi_generic_write(cfg->mipi_dsi, cfg->channel, buf, sizeof(val)); + if (ret < 0) { + LOG_ERR("Short write failed! (%d)", ret); + return ret; + } + + return 0; +} + +static int st7701_generic_write(const struct device *dev, const void *buf, size_t len) +{ + const struct st7701_config *cfg = dev->config; + int ret; + + ret = mipi_dsi_generic_write(cfg->mipi_dsi, cfg->channel, buf, len); + if (ret < 0) { + LOG_ERR("Generic write failed! (%d)", ret); + return ret; + } + + return 0; +} + +static int st7701_check_id(const struct device *dev) +{ + const struct st7701_config *cfg = dev->config; + uint32_t id = 0; + int ret; + + ret = mipi_dsi_dcs_read(cfg->mipi_dsi, cfg->channel, ST7701_CMD_ID1, &id, sizeof(id)); + if (ret != sizeof(id)) { + LOG_ERR("Read panel ID failed! (%d)", ret); + return -EIO; + } + + if (id != ST7701_ID) { + LOG_ERR("ID 0x%x (should 0x%x)", id, ST7701_ID); + return -EINVAL; + } + + return 0; +} + +static int st7701_configure(const struct device *dev) +{ + struct st7701_data *data = dev->data; + const struct st7701_config *cfg = dev->config; + uint8_t buf[4]; + int ret; + + const uint8_t control0[] = {DSI_CMD2BKX_SEL, 0x77, 0x01, 0x00, 0x00, DSI_CMD2BK0_SEL}; + const uint8_t control1[] = {0xC0, 0x63, 0x00}; + const uint8_t control2[] = {0xC1, 0x11, 0x02}; + const uint8_t control3[] = {0xC2, 0x01, 0x08}; + const uint8_t control4[] = {0xCC, 0x18}; + + st7701_generic_write(dev, control0, sizeof(control0)); + st7701_generic_write(dev, control1, sizeof(control1)); + st7701_generic_write(dev, control2, sizeof(control2)); + st7701_generic_write(dev, control3, sizeof(control3)); + st7701_generic_write(dev, control4, sizeof(control4)); + + /* Gamma Cluster Setting */ + st7701_generic_write(dev, cfg->pvgamctrl, sizeof(cfg->pvgamctrl)); + st7701_generic_write(dev, cfg->nvgamctrl, sizeof(cfg->nvgamctrl)); + + /* Initial power control registers */ + const uint8_t _FF1[] = {DSI_CMD2BKX_SEL, 0x77, 0x01, 0x00, 0x00, DSI_CMD2BK1_SEL}; + + st7701_generic_write(dev, _FF1, sizeof(_FF1)); + + st7701_short_write_1p(dev, DSI_CMD2_BK1_VRHS, 0x65); + st7701_short_write_1p(dev, DSI_CMD2_BK1_VCOM, 0x34); + st7701_short_write_1p(dev, DSI_CMD2_BK1_VGHSS, 0x87); + st7701_short_write_1p(dev, DSI_CMD2_BK1_TESTCMD, 0x80); + + st7701_short_write_1p(dev, DSI_CMD2_BK1_VGLS, 0x49); + st7701_short_write_1p(dev, DSI_CMD2_BK1_PWCTLR1, 0x85); + + st7701_short_write_1p(dev, DSI_CMD2_BK1_PWCTLR2, 0x20); + st7701_short_write_1p(dev, 0xB9, 0x10); + st7701_short_write_1p(dev, DSI_CMD2_BK1_SPD1, 0x78); + st7701_short_write_1p(dev, DSI_CMD2_BK1_SPD2, 0x78); + st7701_short_write_1p(dev, DSI_CMD2_BK1_MIPISET1, 0x88); + k_msleep(100); + + /* GIP Setting */ + st7701_generic_write(dev, cfg->gip_e0, sizeof(cfg->gip_e0)); + st7701_generic_write(dev, cfg->gip_e1, sizeof(cfg->gip_e1)); + st7701_generic_write(dev, cfg->gip_e2, sizeof(cfg->gip_e2)); + st7701_generic_write(dev, cfg->gip_e3, sizeof(cfg->gip_e3)); + st7701_generic_write(dev, cfg->gip_e4, sizeof(cfg->gip_e4)); + st7701_generic_write(dev, cfg->gip_e5, sizeof(cfg->gip_e5)); + st7701_generic_write(dev, cfg->gip_e6, sizeof(cfg->gip_e6)); + st7701_generic_write(dev, cfg->gip_e7, sizeof(cfg->gip_e7)); + st7701_generic_write(dev, cfg->gip_e8, sizeof(cfg->gip_e8)); + st7701_generic_write(dev, cfg->gip_eb, sizeof(cfg->gip_eb)); + st7701_generic_write(dev, cfg->gip_ec, sizeof(cfg->gip_ec)); + st7701_generic_write(dev, cfg->gip_ed, sizeof(cfg->gip_ed)); + + /* Bank1 setting */ + const uint8_t _FF2[] = {DSI_CMD2BKX_SEL, 0x77, 0x01, 0x00, 0x00, DSI_CMD2BKX_SEL_NONE}; + + st7701_generic_write(dev, _FF2, sizeof(_FF2)); + + /* Exit sleep mode */ + ret = st7701_dcs_write(dev, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); + if (ret < 0) { + return ret; + } + + k_msleep(50); + + /* Set pixel color format */ + switch (data->dsi_pixel_format) { + case MIPI_DSI_PIXFMT_RGB565: + buf[0] = MIPI_DCS_PIXEL_FORMAT_16BIT; + break; + case MIPI_DSI_PIXFMT_RGB888: + buf[0] = MIPI_DCS_PIXEL_FORMAT_24BIT; + break; + default: + LOG_ERR("Unsupported pixel format 0x%x!", data->dsi_pixel_format); + return -ENOTSUP; + } + + ret = st7701_dcs_write(dev, MIPI_DCS_SET_PIXEL_FORMAT, buf, 1); + if (ret < 0) { + return ret; + } + + buf[0] = 0x00; + buf[1] = 0x00; + sys_put_be16(data->xres, (uint8_t *)&buf[2]); + ret = st7701_dcs_write(dev, MIPI_DCS_SET_COLUMN_ADDRESS, buf, 4); + if (ret < 0) { + return ret; + } + + buf[0] = 0x00; + buf[1] = 0x00; + sys_put_be16(data->yres, (uint8_t *)&buf[2]); + ret = st7701_dcs_write(dev, MIPI_DCS_SET_PAGE_ADDRESS, buf, 4); + if (ret < 0) { + return ret; + } + + /* Backlight control */ + buf[0] = ST7701_WRCTRLD_BCTRL | ST7701_WRCTRLD_DD | ST7701_WRCTRLD_BL; + ret = st7701_dcs_write(dev, MIPI_DCS_WRITE_CONTROL_DISPLAY, buf, 1); + if (ret < 0) { + return ret; + } + + /* Adaptive brightness control */ + buf[0] = ST7701_WRCABC_UI; + ret = st7701_dcs_write(dev, MIPI_DCS_WRITE_POWER_SAVE, buf, 1); + if (ret < 0) { + return ret; + } + + /* Adaptive brightness control minimum brightness */ + buf[0] = 0xFF; + ret = st7701_dcs_write(dev, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, buf, 1); + if (ret < 0) { + return ret; + } + + /* Brightness */ + buf[0] = 0xFF; + ret = st7701_dcs_write(dev, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, buf, 1); + if (ret < 0) { + return ret; + } + + /* Display On */ + ret = st7701_dcs_write(dev, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); + if (ret < 0) { + return ret; + } + + return 0; +} + +static int st7701_blanking_on(const struct device *dev) +{ + const struct st7701_config *cfg = dev->config; + int ret; + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_set_dt(&cfg->backlight, 0); + if (ret) { + LOG_ERR("Disable backlight failed! (%d)", ret); + return ret; + } + } + + return st7701_dcs_write(dev, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); +} + +static int st7701_blanking_off(const struct device *dev) +{ + const struct st7701_config *cfg = dev->config; + int ret; + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_set_dt(&cfg->backlight, 1); + if (ret) { + LOG_ERR("Enable backlight failed! (%d)", ret); + return ret; + } + } + + return st7701_dcs_write(dev, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); +} + +static int st7701_set_brightness(const struct device *dev, uint8_t brightness) +{ + return st7701_dcs_write(dev, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, &brightness, 1); +} + +static void st7701_get_capabilities(const struct device *dev, + struct display_capabilities *capabilities) +{ + const struct st7701_config *cfg = dev->config; + struct st7701_data *data = dev->data; + + if (!capabilities) { + return; + } + + memset(capabilities, 0, sizeof(struct display_capabilities)); + capabilities->x_resolution = cfg->width; + capabilities->y_resolution = cfg->height; + capabilities->supported_pixel_formats = data->pixel_format; + capabilities->current_pixel_format = data->pixel_format; + capabilities->current_orientation = data->orientation; +} + +static DEVICE_API(display, st7701_api) = { + .blanking_on = st7701_blanking_on, + .blanking_off = st7701_blanking_off, + .set_brightness = st7701_set_brightness, + .get_capabilities = st7701_get_capabilities, +}; + +static int st7701_init(const struct device *dev) +{ + const struct st7701_config *cfg = dev->config; + struct st7701_data *data = dev->data; + struct mipi_dsi_device mdev; + int ret; + + if (cfg->reset.port) { + if (!gpio_is_ready_dt(&cfg->reset)) { + LOG_ERR("Reset GPIO device is not ready!"); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Reset display failed! (%d)", ret); + return ret; + } + k_msleep(10); + ret = gpio_pin_set_dt(&cfg->reset, 1); + if (ret < 0) { + LOG_ERR("Enable display failed! (%d)", ret); + return ret; + } + k_msleep(100); + } + + /* store x/y resolution & rotation */ + if (cfg->rotation == 0) { + data->xres = cfg->width; + data->yres = cfg->height; + data->orientation = DISPLAY_ORIENTATION_NORMAL; + } else if (cfg->rotation == 90) { + data->xres = cfg->height; + data->yres = cfg->width; + data->orientation = DISPLAY_ORIENTATION_ROTATED_90; + } else if (cfg->rotation == 180) { + data->xres = cfg->width; + data->yres = cfg->height; + data->orientation = DISPLAY_ORIENTATION_ROTATED_180; + } else if (cfg->rotation == 270) { + data->xres = cfg->height; + data->yres = cfg->width; + data->orientation = DISPLAY_ORIENTATION_ROTATED_270; + } + + /* attach to MIPI-DSI host */ + mdev.data_lanes = cfg->data_lanes; + mdev.pixfmt = data->dsi_pixel_format; + mdev.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM; + + mdev.timings.hactive = cfg->width; + mdev.timings.hbp = cfg->hbp; + mdev.timings.hsync = cfg->hsync; + mdev.timings.hfp = cfg->hfp; + mdev.timings.vactive = cfg->height; + mdev.timings.vbp = cfg->vbp; + mdev.timings.vsync = cfg->vsync; + mdev.timings.vfp = cfg->vfp; + + ret = mipi_dsi_attach(cfg->mipi_dsi, cfg->channel, &mdev); + if (ret < 0) { + LOG_ERR("MIPI-DSI attach failed! (%d)", ret); + return ret; + } + + ret = st7701_check_id(dev); + if (ret) { + LOG_ERR("Panel ID check failed! (%d)", ret); + return ret; + } + + ret = st7701_configure(dev); + if (ret) { + LOG_ERR("DSI init sequence failed! (%d)", ret); + return ret; + } + + ret = st7701_blanking_off(dev); + if (ret) { + LOG_ERR("Display blanking off failed! (%d)", ret); + return ret; + } + + return 0; +} + +#define ST7701_DEVICE(inst) \ + static const struct st7701_config st7701_config_##inst = { \ + .mipi_dsi = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \ + .backlight = GPIO_DT_SPEC_INST_GET_OR(inst, bl_gpios, {0}), \ + .data_lanes = DT_INST_PROP_BY_IDX(inst, data_lanes, 0), \ + .width = DT_INST_PROP(inst, width), \ + .height = DT_INST_PROP(inst, height), \ + .channel = DT_INST_REG_ADDR(inst), \ + .rotation = DT_INST_PROP(inst, rotation), \ + .hbp = DT_PROP(DT_INST_CHILD(inst, display_timings), hback_porch), \ + .hsync = DT_PROP(DT_INST_CHILD(inst, display_timings), hsync_len), \ + .hfp = DT_PROP(DT_INST_CHILD(inst, display_timings), hfront_porch), \ + .vbp = DT_PROP(DT_INST_CHILD(inst, display_timings), vback_porch), \ + .vsync = DT_PROP(DT_INST_CHILD(inst, display_timings), vsync_len), \ + .vfp = DT_PROP(DT_INST_CHILD(inst, display_timings), vfront_porch), \ + .gip_e0 = DT_INST_PROP_OR(inst, gip_e0, {}), \ + .gip_e1 = DT_INST_PROP_OR(inst, gip_e1, {}), \ + .gip_e2 = DT_INST_PROP_OR(inst, gip_e2, {}), \ + .gip_e3 = DT_INST_PROP_OR(inst, gip_e3, {}), \ + .gip_e4 = DT_INST_PROP_OR(inst, gip_e4, {}), \ + .gip_e5 = DT_INST_PROP_OR(inst, gip_e5, {}), \ + .gip_e6 = DT_INST_PROP_OR(inst, gip_e6, {}), \ + .gip_e7 = DT_INST_PROP_OR(inst, gip_e7, {}), \ + .gip_e8 = DT_INST_PROP_OR(inst, gip_e8, {}), \ + .gip_eb = DT_INST_PROP_OR(inst, gip_eb, {}), \ + .gip_ec = DT_INST_PROP_OR(inst, gip_ec, {}), \ + .gip_ed = DT_INST_PROP_OR(inst, gip_ed, {}), \ + .pvgamctrl = DT_INST_PROP_OR(inst, pvgamctrl, {}), \ + .nvgamctrl = DT_INST_PROP_OR(inst, nvgamctrl, {}), \ + }; \ + static struct st7701_data st7701_data_##inst = { \ + .dsi_pixel_format = DT_INST_PROP(inst, pixel_format), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, &st7701_init, NULL, &st7701_data_##inst, \ + &st7701_config_##inst, POST_KERNEL, \ + CONFIG_DISPLAY_ST7701_INIT_PRIORITY, &st7701_api); + +DT_INST_FOREACH_STATUS_OKAY(ST7701_DEVICE) diff --git a/drivers/display/display_st7701.h b/drivers/display/display_st7701.h new file mode 100644 index 0000000000000..3a910456b75a4 --- /dev/null +++ b/drivers/display/display_st7701.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ST7701_H_ +#define ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ST7701_H_ + +/** + * @name General parameters. + * @{ + */ + +/* Command2 BKx selection command */ +#define DSI_CMD2BKX_SEL 0xFF +#define DSI_CMD2BK1_SEL 0x11 +#define DSI_CMD2BK0_SEL 0x10 +#define DSI_CMD2BKX_SEL_NONE 0x00 + +/* Command2, BK0 commands */ +#define DSI_CMD2_BK0_PVGAMCTRL 0xB0 /* Positive Voltage Gamma Control */ +#define DSI_CMD2_BK0_NVGAMCTRL 0xB1 /* Negative Voltage Gamma Control */ +#define DSI_CMD2_BK0_LNESET 0xC0 /* Display Line setting */ +#define DSI_CMD2_BK0_PORCTRL 0xC1 /* Porch control */ +#define DSI_CMD2_BK0_INVSEL 0xC2 /* Inversion selection, Frame Rate Control */ + +/* Command2, BK1 commands */ +#define DSI_CMD2_BK1_VRHS 0xB0 /* Vop amplitude setting */ +#define DSI_CMD2_BK1_VCOM 0xB1 /* VCOM amplitude setting */ +#define DSI_CMD2_BK1_VGHSS 0xB2 /* VGH Voltage setting */ +#define DSI_CMD2_BK1_TESTCMD 0xB3 /* TEST Command Setting */ +#define DSI_CMD2_BK1_VGLS 0xB5 /* VGL Voltage setting */ +#define DSI_CMD2_BK1_PWCTLR1 0xB7 /* Power Control 1 */ +#define DSI_CMD2_BK1_PWCTLR2 0xB8 /* Power Control 2 */ +#define DSI_CMD2_BK1_SPD1 0xC1 /* Source pre_drive timing set1 */ +#define DSI_CMD2_BK1_SPD2 0xC2 /* Source EQ2 Setting */ +#define DSI_CMD2_BK1_MIPISET1 0xD0 /* MIPI Setting 1 */ + +#define ST7701_CMD_ID1 0xDA +#define ST7701_ID 0xFF + +/** + * @name MIPI DCS Write Control Display fields. + * @{ + */ + +/** Write Control Display: brightness control. */ +#define ST7701_WRCTRLD_BCTRL BIT(5) +/** Write Control Display: display dimming. */ +#define ST7701_WRCTRLD_DD BIT(3) +/** Write Control Display: backlight. */ +#define ST7701_WRCTRLD_BL BIT(2) + +/** Adaptive Brightness Control: off. */ +#define ST7701_WRCABC_OFF 0x00U +/** Adaptibe Brightness Control: user interface. */ +#define ST7701_WRCABC_UI 0x01U +/** Adaptibe Brightness Control: still picture. */ +#define ST7701_WRCABC_ST 0x02U +/** Adaptibe Brightness Control: moving image. */ +#define ST7701_WRCABC_MV 0x03U +/** @} */ + +#endif /* ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ST7701_H_ */ diff --git a/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi index 9809fe379ad49..a0f9cee3a3f47 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi @@ -14,6 +14,10 @@ /delete-node/ &agt3; /delete-node/ &agt4; /delete-node/ &agt5; +/delete-node/ ð +/delete-node/ &mdio; +#include + /delete-node/ &adc1; /delete-node/ &usbfs; /delete-node/ &usbfs_phy; diff --git a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi index ae50b0ddf5610..daeabd1e3f81f 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi @@ -536,6 +536,22 @@ clocks = <&pclkb 0 0>; status = "disabled"; }; + + eth: ethernet@40114100 { + compatible = "renesas,ra-ethernet"; + reg = <0x40114100 0xfc>; + interrupts = <51 12>; + local-mac-address = [00 11 22 33 44 55]; + phy-connection-type = "rmii"; + status = "disabled"; + }; + + mdio: mdio { + compatible = "renesas,ra-mdio"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; usbfs_phy: usbfs-phy { diff --git a/dts/bindings/display/sitronix,st7701.yaml b/dts/bindings/display/sitronix,st7701.yaml new file mode 100644 index 0000000000000..d17aff0dcf409 --- /dev/null +++ b/dts/bindings/display/sitronix,st7701.yaml @@ -0,0 +1,88 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +description: Sitronix ST7701 Panel + +compatible: "sitronix,st7701" + +include: [mipi-dsi-device.yaml, display-controller.yaml] + +properties: + reset-gpios: + type: phandle-array + description: | + The RESETn pin is asserted to disable the sensor causing a hard + reset. The sensor receives this as an active-low signal. + + bl-gpios: + type: phandle-array + description: | + The BLn pin is asserted to control the backlight of the panel. + The sensor receives this as an active-high signal. + + rotation: + type: int + default: 0 + enum: + - 0 + - 90 + - 180 + - 270 + description: | + Display rotation (CW) in degrees. Defaults to 0, display default. + + gip-e0: + type: uint8-array + description: GIP setting at address 0xE0. + + gip-e1: + type: uint8-array + description: GIP setting at address 0xE1. + + gip-e2: + type: uint8-array + description: GIP setting at address 0xE2. + + gip-e3: + type: uint8-array + description: GIP setting at address 0xE3. + + gip-e4: + type: uint8-array + description: GIP setting at address 0xE4. + + gip-e5: + type: uint8-array + description: GIP setting at address 0xE5. + + gip-e6: + type: uint8-array + description: GIP setting at address 0xE6. + + gip-e7: + type: uint8-array + description: GIP setting at address 0xE7. + + gip-e8: + type: uint8-array + description: GIP setting at address 0xE8. + + gip-eb: + type: uint8-array + description: GIP setting at address 0xEB. + + gip-ec: + type: uint8-array + description: GIP setting at address 0xEC. + + gip-ed: + type: uint8-array + description: GIP setting at address 0xED. + + pvgamctrl: + type: uint8-array + description: Positive voltage gamma control. + + nvgamctrl: + type: uint8-array + description: Negative voltage gamma control. diff --git a/soc/renesas/ra/ra6m5/sections.ld b/soc/renesas/ra/ra6m5/sections.ld index 1fe7db907a3d9..8f137924c13db 100644 --- a/soc/renesas/ra/ra6m5/sections.ld +++ b/soc/renesas/ra/ra6m5/sections.ld @@ -11,6 +11,8 @@ SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) *(.fsp_dtc_vector_table) } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_ofs), okay) + SECTION_PROLOGUE(.option_setting_ofs,,) { __OPTION_SETTING_OFS_Start = .; @@ -22,6 +24,10 @@ SECTION_PROLOGUE(.option_setting_ofs,,) __OPTION_SETTING_OFS_End = .; } GROUP_LINK_IN(OPTION_SETTING_OFS) = 0xFF +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_sas), okay) + SECTION_PROLOGUE(.option_setting_sas,,) { __OPTION_SETTING_SAS_Start = .; @@ -29,6 +35,10 @@ SECTION_PROLOGUE(.option_setting_sas,,) __OPTION_SETTING_SAS_End = .; } GROUP_LINK_IN(OPTION_SETTING_SAS) = 0xFF +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_s), okay) + SECTION_PROLOGUE(.option_setting_s,,) { __OPTION_SETTING_S_Start = .; @@ -69,3 +79,5 @@ SECTION_PROLOGUE(.option_setting_s,,) KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } GROUP_LINK_IN(OPTION_SETTING_S) = 0xFF + +#endif diff --git a/soc/renesas/ra/ra6m5/soc.c b/soc/renesas/ra/ra6m5/soc.c index 872b89421d305..b2819aed795dd 100644 --- a/soc/renesas/ra/ra6m5/soc.c +++ b/soc/renesas/ra/ra6m5/soc.c @@ -60,6 +60,9 @@ void soc_early_init_hook(void) R_CPSCU->ICUSARG = 0; R_CPSCU->ICUSARH = 0; R_CPSCU->ICUSARI = 0; + for (int i = 0; i < 16; i++) { + NVIC->ITNS[i] = 0; + } /* Enable protection using PRCR register. */ R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); diff --git a/tests/drivers/build_all/display/app.overlay b/tests/drivers/build_all/display/app.overlay index 1ea1ce4b34d8a..e41973d3c6b3a 100644 --- a/tests/drivers/build_all/display/app.overlay +++ b/tests/drivers/build_all/display/app.overlay @@ -249,6 +249,31 @@ height = <1280>; pixel-format = <0>; }; + + test_st7701: st7701@5 { + compatible = "sitronix,st7701"; + reg = <0x5>; + height = <800>; + width = <480>; + data-lanes = <2>; + pixel-format = <0>; + rotation = <0>; + pvgamctrl = [00 10 0E 02 03 0E 07 02 07 0A 12 27 37 00 0D 0E 10]; + nvgamctrl = [00 10 0E 03 03 0F 06 02 08 0A 13 26 36 00 0D 0E 10]; + display-timings { + compatible = "zephyr,panel-timing"; + hsync-active = <1>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + hback-porch = <40>; + hsync-len = <32>; + hfront-porch = <8>; + vback-porch = <6>; + vsync-len = <8>; + vfront-porch = <9>; + }; + }; }; test_spi: spi@33334444 {