diff --git a/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.conf b/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.conf index acee48b1..b0d99951 100644 --- a/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.conf +++ b/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.conf @@ -11,6 +11,9 @@ CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT=y CONFIG_LLEXT_STORAGE_WRITABLE=n +CONFIG_SHARED_MULTI_HEAP=y +CONFIG_HEAP_MEM_POOL_SIZE=2048 + CONFIG_FPU=y CONFIG_ICACHE=y CONFIG_DCACHE=y @@ -24,8 +27,12 @@ CONFIG_SHELL_STACK_SIZE=32768 CONFIG_MAIN_STACK_SIZE=32768 CONFIG_LLEXT_HEAP_SIZE=128 -#CONFIG_ADC=y -#CONFIG_PWM=y +CONFIG_ADC=y +CONFIG_PWM=y +CONFIG_DMA=y +CONFIG_MEMC=y +CONFIG_SPI_ASYNC=y +CONFIG_SPI_STM32_INTERRUPT=y CONFIG_NET_CORE_LOG_LEVEL_DBG=y @@ -78,3 +85,13 @@ CONFIG_MBEDTLS_HEAP_SIZE=60000 CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=7168 CONFIG_MBEDTLS_HASH_ALL_ENABLED=y CONFIG_MBEDTLS_CMAC=y + +CONFIG_VIDEO=y +CONFIG_VIDEO_LOG_LEVEL_DBG=y +CONFIG_VIDEO_STM32_DCMI=y +CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=3 +CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=614400 +CONFIG_VIDEO_BUFFER_POOL_ALIGN=32 +CONFIG_VIDEO_BUFFER_USE_SHARED_MULTI_HEAP=y +CONFIG_VIDEO_BUFFER_SMH_ATTRIBUTE=2 +CONFIG_FLASH=y diff --git a/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.overlay b/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.overlay index 88485a23..ba7e1684 100644 --- a/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.overlay +++ b/variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.overlay @@ -14,20 +14,253 @@ status = "okay"; }; +&i2c3 { + status = "okay"; + + gc2145: gc2145@3c { + compatible = "galaxycore,gc2145"; + reg = <0x3c>; + status = "okay"; + + reset-gpios = <&gpioe 3 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&gpiod 5 GPIO_ACTIVE_LOW>; + + port { + gc2145_ep_out: endpoint { + remote-endpoint = <&dcmi_ep_in>; + }; + }; + }; + + ov7670: ov7670@21 { + compatible = "ovti,ov7670"; + reg = <0x21>; + + reset-gpios = <&gpioe 3 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&gpiod 5 GPIO_ACTIVE_LOW>; + + port { + ov7670_ep_out: endpoint { + remote-endpoint = <&dcmi_ep_in>; + }; + }; + }; +}; + +&i2c1 { + status = "okay"; +}; + &i2c4 { status = "okay"; }; +&spi2 { + status = "okay"; + pinctrl-0 = <&spi2_sck_pi1 + &spi2_miso_pc2 &spi2_mosi_pc3>; + pinctrl-names = "default"; +}; + +&timers1 { + status = "okay"; + st,prescaler = <0>; + + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch1_pa8 &tim1_ch2_pj11>; + pinctrl-names = "default"; + }; +}; + +&timers3 { + status = "okay"; + st,prescaler = <100>; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch1_pc6 &tim3_ch2_pc7>; + pinctrl-names = "default"; + }; +}; + +&timers8 { + status = "okay"; + st,prescaler = <100>; + + pwm8: pwm { + status = "okay"; + pinctrl-0 = <&tim8_ch3n_ph15 &tim8_ch2_pj10 &tim8_ch2n_pj7>; + pinctrl-names = "default"; + }; +}; + +&timers12 { + status = "okay"; + st,prescaler = <100>; + + pwm12: pwm { + status = "okay"; + pinctrl-0 = <&tim12_ch1_ph6>; + pinctrl-names = "default"; + }; +}; + +&pwm1 { + /* Camera source clock */ + pwmclock: pwmclock { + status = "okay"; + compatible = "pwm-clock"; + clock-frequency = <0>; + #clock-cells = <1>; + pwms = <&pwm1 1 PWM_HZ(12000000) PWM_POLARITY_NORMAL>; + /* 12MHz for 7670, default is also 12MHz */ + }; +}; + &rng { status = "okay"; }; +&dmamux1 { + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + +&dcmi { + status = "okay"; + sensor = <&gc2145>; + /* sensor = <&ov7670>; */ + /* ext-sdram = <&sdram1>; */ + pinctrl-0 = <&dcmi_hsync_pa4 &dcmi_pixclk_pa6 &dcmi_vsync_pi5 + &dcmi_d0_ph9 &dcmi_d1_ph10 &dcmi_d2_ph11 &dcmi_d3_ph12 + &dcmi_d4_ph14 &dcmi_d5_pi4 &dcmi_d6_pi6 &dcmi_d7_pi7>; + pinctrl-names = "default"; + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pixelclk-active = <0>; + capture-rate = <1>; + dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | + STM32_DMA_MEM_INC | STM32_DMA_PERIPH_32BITS | STM32_DMA_MEM_32BITS | + STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_FULL>; //FULL for 7670, default FIFO_1_4 + + port { + dcmi_ep_in: endpoint { + remote-endpoint = <&gc2145_ep_out>; + //remote-endpoint = <&ov7670_ep_out>; + }; + }; +}; + + +&adc1 { + pinctrl-0 = <&adc1_inp12_pc2 + &adc1_inp13_pc3 + &adc1_inp18_pa4 + &adc1_inp3_pa6 + &adc1_inp0_pa0_c + &adc1_inp1_pa1_c>; + pinctrl-names = "default"; + st,adc-clock-source = "SYNC"; + st,adc-prescaler = <4>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + channel@c { + reg = <12>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; + channel@d { + reg = <13>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; + channel@12 { + reg = <18>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; + + /* PA0_C and PA1_C */ + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; +}; + +&adc3 { + pinctrl-0 = <&adc3_inp0_pc2_c + &adc3_inp1_pc3_c>; + pinctrl-names = "default"; + st,adc-clock-source = "SYNC"; + st,adc-prescaler = <4>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + }; +}; + / { chosen { + zephyr,camera = &dcmi; zephyr,console = &usart6; zephyr,shell-uart = &usart6; zephyr,cdc-acm-uart0 = &usart6; }; + + /* used to overcome problems with _C analog pins */ + gpioz: gpio@deadbeef { + compatible = "vnd,gpio"; + gpio-controller; + reg = <0xdeadbeef 0x1000>; + #gpio-cells = <0x2>; + status = "okay"; + }; }; / { @@ -59,29 +292,85 @@ / { zephyr,user { - digital-pin-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>, - <&gpiok 1 GPIO_ACTIVE_LOW>, - <&gpioj 11 GPIO_ACTIVE_LOW>, - <&gpiog 7 GPIO_ACTIVE_LOW>, - <&gpioc 7 GPIO_ACTIVE_LOW>, - <&gpioc 6 GPIO_ACTIVE_LOW>, - <&gpioa 8 GPIO_ACTIVE_LOW>, - <&gpioi 0 GPIO_ACTIVE_LOW>, - <&gpioc 3 GPIO_ACTIVE_LOW>, - <&gpioi 1 GPIO_ACTIVE_LOW>, - <&gpioc 2 GPIO_ACTIVE_LOW>, - <&gpioh 8 GPIO_ACTIVE_LOW>, - <&gpioh 7 GPIO_ACTIVE_LOW>, - <&gpioa 10 GPIO_ACTIVE_LOW>, - <&gpioa 9 GPIO_ACTIVE_LOW>, - <&gpiok 5 GPIO_ACTIVE_LOW>; // LEDR + digital-pin-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>, /* D0 */ + <&gpiok 1 GPIO_ACTIVE_LOW>, /* D1 */ + <&gpioj 11 GPIO_ACTIVE_LOW>, /* D2 */ + <&gpiog 7 GPIO_ACTIVE_LOW>, /* D3 */ + <&gpioc 7 GPIO_ACTIVE_LOW>, /* D4 */ + <&gpioc 6 GPIO_ACTIVE_LOW>, /* D5 */ + <&gpioa 8 GPIO_ACTIVE_LOW>, /* D6 */ + <&gpioi 0 GPIO_ACTIVE_LOW>, /* D7 */ + <&gpioc 3 GPIO_ACTIVE_LOW>, /* D8 */ + <&gpioi 1 GPIO_ACTIVE_LOW>, /* D9 */ + <&gpioc 2 GPIO_ACTIVE_LOW>, /* D10 */ + <&gpioh 8 GPIO_ACTIVE_LOW>, /* D11 */ + <&gpioh 7 GPIO_ACTIVE_LOW>, /* D12 */ + <&gpioa 10 GPIO_ACTIVE_LOW>, /* D13 */ + <&gpioa 9 GPIO_ACTIVE_LOW>, /* D14 */ + + <&gpioz 0 GPIO_ACTIVE_LOW>, /* A0 ADC2_INP0 */ + <&gpioz 1 GPIO_ACTIVE_LOW>, /* A1 ADC2_INP1 */ + <&gpioz 2 GPIO_ACTIVE_LOW>, /* A2 ADC3_INP0 */ + <&gpioz 3 GPIO_ACTIVE_LOW>, /* A3 ADC3_INP1 */ + <&gpioz 4 GPIO_ACTIVE_LOW>, /* A4 hack for duplicate PC_2 */ + <&gpioz 5 GPIO_ACTIVE_LOW>, /* A5 hack for duplicate PC_3 */ + /* <&gpioc 2 GPIO_ACTIVE_LOW>, A4 _ALT0? ADC1_INP12 */ + /* <&gpioc 3 GPIO_ACTIVE_LOW>, A5 _ALT0? ADC1_INP13 */ + <&gpioa 4 GPIO_ACTIVE_LOW>, /* A6 ADC1_INP18 */ + <&gpioa 6 GPIO_ACTIVE_LOW>, /* A7 ADC1_INP7 */ + + <&gpiok 5 GPIO_ACTIVE_LOW>, /* LEDR */ + <&gpiok 6 GPIO_ACTIVE_LOW>, /* LEDG */ + <&gpiok 7 GPIO_ACTIVE_LOW>; /* LEDB */ builtin-led-gpios = <&gpiok 5 GPIO_ACTIVE_LOW>, - <&gpiok 6 GPIO_ACTIVE_LOW>, - <&gpiok 7 GPIO_ACTIVE_LOW>; + <&gpiok 6 GPIO_ACTIVE_LOW>, + <&gpiok 7 GPIO_ACTIVE_LOW>; + + pwm-pin-gpios = <&gpioa 8 0>, + <&gpioc 6 0>, + <&gpioc 7 0>, + //<&gpiog 7 0>, + <&gpioj 11 0>, + //<&gpiok 1 0>, + <&gpioh 15 0>, + <&gpioj 7 0>, + <&gpioj 10 0>, + <&gpioh 6 0>; + + adc-pin-gpios = <&gpioz 0 0>, /* analog only */ + <&gpioz 1 0>, /* analog only */ + <&gpioz 2 0>, /* analog only */ + <&gpioz 3 0>, /* analog only */ + <&gpioc 2 0>, + <&gpioc 3 0>, + <&gpioa 4 0>, + <&gpioa 6 0>, + <&gpioz 4 0>, /* Hack for D19 */ + <&gpioz 5 0>; /* Hack for D20 */ serials = <&board_cdc_acm_uart>,<&usart6>, <&usart1>, <&uart4>; cdc-acm = <&board_cdc_acm_uart>; - i2cs = <&i2c4>; + i2cs = <&i2c3>, <&i2c1>, <&i2c4>; + spis = <&spi2>; + pwms = <&pwm1 1 PWM_HZ(12000000) PWM_POLARITY_NORMAL>, /* Camera */ + <&pwm3 1 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm3 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm1 2 PWM_HZ(5000) PWM_POLARITY_NORMAL>, + <&pwm8 3 PWM_HZ(500) PWM_POLARITY_INVERTED>, + <&pwm8 2 PWM_HZ(500) PWM_POLARITY_INVERTED>, + <&pwm8 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm12 1 PWM_HZ(500) PWM_POLARITY_NORMAL>; + + io-channels = <&adc1 0>, + <&adc1 1>, + <&adc3 0>, + <&adc3 1>, + <&adc1 12>, + <&adc1 13>, + <&adc1 18>, + <&adc1 3>, + <&adc1 12>, /* Hack for D19 */ + <&adc1 13>; /* Hack for D20 */ }; }; diff --git a/variants/arduino_portenta_h7_stm32h747xx_m7/pure_analog_pins.cpp b/variants/arduino_portenta_h7_stm32h747xx_m7/pure_analog_pins.cpp new file mode 100644 index 00000000..a6ba41b2 --- /dev/null +++ b/variants/arduino_portenta_h7_stm32h747xx_m7/pure_analog_pins.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "pure_analog_pins.h" + +#undef A0 +#undef A1 +#undef A2 +#undef A3 + +PureAnalogPin A0_PURE(0); +PureAnalogPin A1_PURE(1); +PureAnalogPin A2_PURE(2); +PureAnalogPin A3_PURE(3); + +int getAnalogReadResolution(); + +int analogRead(PureAnalogPin pin) { + return ::analogRead(A0 + pin.get()); +} diff --git a/variants/arduino_portenta_h7_stm32h747xx_m7/pure_analog_pins.h b/variants/arduino_portenta_h7_stm32h747xx_m7/pure_analog_pins.h new file mode 100644 index 00000000..9df13056 --- /dev/null +++ b/variants/arduino_portenta_h7_stm32h747xx_m7/pure_analog_pins.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _PURE_ANALOG_PINS_ +#define _PURE_ANALOG_PINS_ + +/****************************************************************************** + * INCLUDE + ******************************************************************************/ + +#include "Arduino.h" + +/****************************************************************************** + * PREPROCESSOR-MAGIC + ******************************************************************************/ + +#define PURE_ANALOG_AS_DIGITAL_ATTRIBUTE __attribute__ ((error("Can't use pins A0-A3 as digital"))) + +/****************************************************************************** + * TYPEDEF + ******************************************************************************/ + +class PureAnalogPin { +public: + PureAnalogPin(int _pin) : pin(_pin) {}; + int get() { + return pin; + }; + bool operator== (PureAnalogPin const & other) const { + return pin == other.pin; + } + //operator int() = delete; + __attribute__ ((error("Change me to a #define"))) operator int(); +private: + int pin; +}; + +extern PureAnalogPin A0_PURE; +extern PureAnalogPin A1_PURE; +extern PureAnalogPin A2_PURE; +extern PureAnalogPin A3_PURE; + +#define A0 A0_PURE +#define A1 A1_PURE +#define A2 A2_PURE +#define A3 A3_PURE + +/****************************************************************************** + * FUNCTION DECLARATION + ******************************************************************************/ + +void PURE_ANALOG_AS_DIGITAL_ATTRIBUTE pinMode (PureAnalogPin pin, PinMode mode); +PinStatus PURE_ANALOG_AS_DIGITAL_ATTRIBUTE digitalRead (PureAnalogPin pin); +void PURE_ANALOG_AS_DIGITAL_ATTRIBUTE digitalWrite(PureAnalogPin pin, PinStatus value); +int analogRead (PureAnalogPin pin); +void PURE_ANALOG_AS_DIGITAL_ATTRIBUTE analogWrite (PureAnalogPin pin, int value); + +#undef PURE_ANALOG_AS_DIGITAL_ATTRIBUTE + +#endif /* _PURE_ANALOG_PINS_ */ diff --git a/variants/arduino_portenta_h7_stm32h747xx_m7/variant.h b/variants/arduino_portenta_h7_stm32h747xx_m7/variant.h index 68c33a89..9c1abf2e 100644 --- a/variants/arduino_portenta_h7_stm32h747xx_m7/variant.h +++ b/variants/arduino_portenta_h7_stm32h747xx_m7/variant.h @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include "pure_analog_pins.h" // TODO: correctly handle these legacy defines #define MOSI 0