diff --git a/cores/arduino/zephyrCommon.cpp b/cores/arduino/zephyrCommon.cpp index 4dd834cf..3263d8d2 100644 --- a/cores/arduino/zephyrCommon.cpp +++ b/cores/arduino/zephyrCommon.cpp @@ -140,6 +140,29 @@ const struct pwm_dt_spec arduino_pwm[] = { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), pwms, PWM_DT_SPEC) }; /* pwm-pins node provides a mapping digital pin numbers to pwm channels */ +#if 1 +static const struct gpio_dt_spec arduino_pwm_pins[] = {DT_FOREACH_PROP_ELEM_SEP( + DT_PATH(zephyr_user), pwm_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))}; + +size_t pwm_pin_index(pin_size_t pinNumber) { + printk("pwm_pin_index: %u: ", pinNumber); + if (pinNumber >= ARRAY_SIZE(arduino_pins)) { + return (size_t)-1; + } + printk("(%p %u):", arduino_pins[pinNumber].port, arduino_pins[pinNumber].pin); + for(size_t i=0; i<ARRAY_SIZE(arduino_pwm_pins); i++) { + printk(" [%p,%u]", arduino_pwm_pins[i].port, arduino_pwm_pins[i].pin); + if ((arduino_pwm_pins[i].port == arduino_pins[pinNumber].port) && (arduino_pwm_pins[i].pin == arduino_pins[pinNumber].pin)) { + printk("\n"); + return i; + } + } + printk("\n"); + return (size_t)-1; +} + + +#else const pin_size_t arduino_pwm_pins[] = { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), pwm_pin_gpios, PWM_PINS) }; @@ -151,7 +174,7 @@ size_t pwm_pin_index(pin_size_t pinNumber) { } return (size_t)-1; } - +#endif #endif //CONFIG_PWM #ifdef CONFIG_ADC @@ -293,12 +316,13 @@ void delay(unsigned long ms) { k_sleep(K_MSEC(ms)); } void delayMicroseconds(unsigned int us) { k_sleep(K_USEC(us)); } unsigned long micros(void) { + #ifdef CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER - return k_cyc_to_us_floor32(k_cycle_get_64()); + return k_cyc_to_us_floor32(k_cycle_get_64()); #else - return k_cyc_to_us_floor32(k_cycle_get_32()); -#endif - } + return k_cyc_to_us_floor32(k_cycle_get_32()); +#endif +} unsigned long millis(void) { return k_uptime_get_32(); } diff --git a/loader/boards/arduino_portenta_h7_m7.conf b/loader/boards/arduino_portenta_h7_m7.conf index acee48b1..567c7e2f 100644 --- a/loader/boards/arduino_portenta_h7_m7.conf +++ b/loader/boards/arduino_portenta_h7_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,15 @@ 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_VIDEO_GC2145=y +CONFIG_FLASH=y diff --git a/loader/boards/arduino_portenta_h7_m7.overlay b/loader/boards/arduino_portenta_h7_m7.overlay index d5f0aea8..19654b02 100644 --- a/loader/boards/arduino_portenta_h7_m7.overlay +++ b/loader/boards/arduino_portenta_h7_m7.overlay @@ -21,20 +21,243 @@ status = "okay"; }; +&i2c3 { + status = "okay"; + gc2145: gc2145@3c { + compatible = "galaxycore,gc2145"; + reg = <0x3c>; + //ov7670: ov7670@21 { + // compatible = "ovti,ov7670"; + // reg = <0x21>; + reset-gpios = <&gpioe 3 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&gpiod 5 GPIO_ACTIVE_LOW>; + + port { + gc2145_ep_out: endpoint { + //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 { + /* Use the pwmclock node to start the clock generation */ + 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 = <ADC_ACQ_TIME_MAX>; + zephyr,resolution = <16>; + }; + channel@d { + reg = <13>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>; + zephyr,resolution = <16>; + }; + channel@12 { + reg = <18>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>; + zephyr,resolution = <16>; + }; + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>; + 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 = <ADC_ACQ_TIME_MAX>; + zephyr,resolution = <16>; + }; + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>; + 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 = <ADC_ACQ_TIME_MAX>; + zephyr,resolution = <16>; + }; + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>; + 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"; + }; + }; / { @@ -66,29 +289,272 @@ / { 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 0>, /* D0 */ + <&gpiok 1 0>, /* D1 */ + <&gpioj 11 0>, /* D2 */ + <&gpiog 7 0>, /* D3 */ + <&gpioc 7 0>, /* D4 */ + <&gpioc 6 0>, /* D5 */ + <&gpioa 8 0>, /* D6 */ + <&gpioi 0 0>, /* D7 */ + <&gpioc 3 0>, /* D8 */ + <&gpioi 1 0>, /* D9 */ + <&gpioc 2 0>, /* D10 */ + <&gpioh 8 0>, /* D11 */ + <&gpioh 7 0>, /* D12 */ + <&gpioa 10 0>, /* D13 */ + <&gpioa 9 0>, /* D14 */ + + <&gpioz 0 0>, /* A0 ADC2_INP0 */ + <&gpioz 1 0>, /* A1 ADC2_INP1 */ + <&gpioz 2 0>, /* A2 ADC3_INP0 */ + <&gpioz 3 0>, /* A3 ADC3_INP1 */ + <&gpioz 4 0>, /* A4 hack for duplicate PC_2 */ + <&gpioz 5 0>, /* A5 hack for duplicate PC_3 */ + /* <&gpioc 2 0>, A4 _ALT0? ADC1_INP12 */ + /* <&gpioc 3 0>, A5 _ALT0? ADC1_INP13 */ + <&gpioa 4 0>, /* A6 ADC1_INP18 */ + <&gpioa 6 0>, /* A7 ADC1_INP7 */ + + + <&gpiok 5 GPIO_ACTIVE_LOW>, // LEDR + <&gpiok 6 GPIO_ACTIVE_LOW>, // LEDG + <&gpiok 7 GPIO_ACTIVE_LOW>, // LEDB + + <&gpioa 0 0>, + /* <&gpioa 1 0>, */ + /* <&gpioa 2 0>, */ + /* <&gpioa 3 0>, */ + /* D21 <&gpioa 4 0>, */ + /* <&gpioa 5 0>, */ + /* D22 <&gpioa 6 0>, */ + /* <&gpioa 7 0>, */ + /* D6 <&gpioa 8 0>, */ + /* D14<&gpioa 9 0>, */ + /* D13 <&gpioa 10 0>, */ + <&gpioa 11 0>, + <&gpioa 12 0>, + <&gpioa 13 0>, + <&gpioa 14 0>, + /* <&gpioa 15 0>, */ + /* <&gpiob 0 0>, */ + /* <&gpiob 1 0>, */ + <&gpiob 2 0>, + <&gpiob 3 0>, + <&gpiob 4 0>, + /* <&gpiob 5 0>, */ + <&gpiob 6 0>, + <&gpiob 7 0>, + <&gpiob 8 0>, + <&gpiob 9 0>, + /* <&gpiob 10 0>, */ + /* <&gpiob 11 0>, */ + /* <&gpiob 12 0>, */ + /* <&gpiob 13 0>, */ + <&gpiob 14 0>, + <&gpiob 15 0>, + /* <&gpioc 0 0>, */ + /* <&gpioc 1 0>, */ + /* D10 <&gpioc 2 0>, */ + /* D8 <&gpioc 3 0>, */ + /* <&gpioc 4 0>, */ + /* <&gpioc 5 0>, */ + /* D5<&gpioc 6 0>, */ + /* D4<&gpioc 7 0>, */ + /* <&gpioc 8 0>, */ + /* <&gpioc 9 0>, */ + /* <&gpioc 10 0>, */ + /* <&gpioc 11 0>, */ + /* <&gpioc 12 0>, */ + <&gpioc 13 0>, + /* <&gpioc 14 0>, */ + <&gpioc 15 0>, + /* <&gpiod 0 0>, */ + /* <&gpiod 1 0>, */ + /* <&gpiod 2 0>, */ + <&gpiod 3 0>, + <&gpiod 4 0>, + <&gpiod 5 0>, + <&gpiod 6 0>, + <&gpiod 7 0>, + /* <&gpiod 8 0>, */ + /* <&gpiod 9 0>, */ + /* <&gpiod 10 0>, */ + /* <&gpiod 11 0>, */ + /* <&gpiod 12 0>, */ + /* <&gpiod 13 0>, */ + /* <&gpiod 14 0>, */ + /* <&gpiod 15 0>, */ + /* <&gpioe 0 0>, */ + /* <&gpioe 1 0>, */ + <&gpioe 2 0>, + <&gpioe 3 0>, + /* <&gpioe 4 0>, */ + /* <&gpioe 5 0>, */ + /* <&gpioe 6 0>, */ + /* <&gpioe 7 0>, */ + /* <&gpioe 8 0>, */ + /* <&gpioe 9 0>, */ + /* <&gpioe 10 0>, */ + /* <&gpioe 11 0>, */ + /* <&gpioe 12 0>, */ + /* <&gpioe 13 0>, */ + /* <&gpioe 14 0>, */ + /* <&gpioe 15 0>, */ + /* <&gpiof 0 0>, */ + /* <&gpiof 1 0>, */ + /* <&gpiof 2 0>, */ + /* <&gpiof 3 0>, */ + /* <&gpiof 4 0>, */ + /* <&gpiof 5 0>, */ + /* <&gpiof 6 0>, */ + /* <&gpiof 7 0>, */ + /* <&gpiof 8 0>, */ + /* <&gpiof 9 0>, */ + /* <&gpiof 10 0>, */ + /* <&gpiof 11 0>, */ + /* <&gpiof 12 0>, */ + /* <&gpiof 13 0>, */ + /* <&gpiof 14 0>, */ + /* <&gpiof 15 0>, */ + /* <&gpiog 0 0>, */ + /* <&gpiog 1 0>, */ + /* <&gpiog 2 0>, */ + <&gpiog 3 0>, + /* <&gpiog 4 0>, */ + /* <&gpiog 5 0>, */ + /* <&gpiog 6 0>, */ + /* D3 <&gpiog 7 0>, */ + /* <&gpiog 8 0>, */ + <&gpiog 9 0>, + <&gpiog 10 0>, + /* <&gpiog 11 0>, */ + /* <&gpiog 12 0>, */ + /* <&gpiog 13 0>, */ + <&gpiog 14 0>, + /* <&gpiog 15 0>, */ + /* <&gpioh 0 0>, */ + /* <&gpioh 1 0>, */ + /* <&gpioh 2 0>, */ + /* <&gpioh 3 0>, */ + /* <&gpioh 4 0>, */ + /* <&gpioh 5 0>, */ + <&gpioh 6 0>, + /* D12 <&gpioh 7 0>, */ + /* D11 <&gpioh 8 0>, */ + <&gpioh 9 0>, + <&gpioh 10 0>, + <&gpioh 11 0>, + <&gpioh 12 0>, + <&gpioh 13 0>, + <&gpioh 14 0>, + /* D0 <&gpioh 15 0>, */ + /* D7 <&gpioi 0 0>, */ + /* D9<&gpioi 1 0>, */ + <&gpioi 2 0>, + <&gpioi 3 0>, + <&gpioi 4 0>, + <&gpioi 5 0>, + <&gpioi 6 0>, + <&gpioi 7 0>, + <&gpioi 8 0>, + <&gpioi 9 0>, + <&gpioi 10 0>, + /* <&gpioi 11 0>, */ + /* <&gpioi 12 0>, */ + <&gpioi 13 0>, + <&gpioi 14 0>, + <&gpioi 15 0>, + /* <&gpioj 0 0>, */ + /* <&gpioj 1 0>, */ + /* <&gpioj 2 0>, */ + /* <&gpioj 3 0>, */ + /* <&gpioj 4 0>, */ + /* <&gpioj 5 0>, */ + <&gpioj 6 0>, + <&gpioj 7 0>, + <&gpioj 8 0>, + <&gpioj 9 0>, + <&gpioj 10 0>; + /* D2 <&gpioj 11 0>, */ + /* <&gpioj 12 0>, */ + /* <&gpioj 13 0>, */ + /* <&gpioj 14 0>, */ + /* <&gpioj 15 0>, */ + /* <&gpiok 0 0>, */ + /* D1 <&gpiok 1 0>; */ + + /* <&gpiok 2 0>, */ + /* <&gpiok 3 0>, */ + /* <&gpiok 4 0>; */ + + /* commented out for now to allow LEDs to work + /* LEDR <&gpiok 5 0>, */ + /* LEDG <&gpiok 6 0>, */ + /* LEDB <&gpiok 7 0>; */ + + 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>; + port-pin-gpios = <&gpioa 0 0>, + <&gpiob 0 0>, + <&gpioc 0 0>, + <&gpiod 0 0>, + <&gpioe 0 0>, + <&gpiof 0 0>, + <&gpiog 0 0>, + <&gpioh 0 0>, + <&gpioi 0 0>, + <&gpioj 0 0>, + <&gpiok 0 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 = <&cdc_acm_uart0>,<&usart6>, <&usart1>, <&uart4>; cdc-acm = <&cdc_acm_uart0>; - i2cs = <&i2c4>; + i2cs = <&i2c3>, <&i2c1>, <&i2c4>; + spis = <&spi2>; + pwms = <&pwm1 1 PWM_HZ(12000000) PWM_POLARITY_NORMAL>, //12mhz default + <&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/loader/fixups.c b/loader/fixups.c index aca88c15..34934642 100644 --- a/loader/fixups.c +++ b/loader/fixups.c @@ -39,7 +39,7 @@ SYS_INIT(disable_bootloader_mpu, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAU SYS_INIT(disable_mpu_rasr_xn, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif -#if defined(CONFIG_BOARD_ARDUINO_GIGA_R1) && defined(CONFIG_VIDEO) +#if (defined(CONFIG_BOARD_ARDUINO_GIGA_R1) || defined(CONFIG_BOARD_ARDUINO_PORTENTA_H7)) && defined(CONFIG_VIDEO) #include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/clock_control.h> diff --git a/variants/arduino_portenta_h7/PinNames.cpp b/variants/arduino_portenta_h7/PinNames.cpp new file mode 100644 index 00000000..57676699 --- /dev/null +++ b/variants/arduino_portenta_h7/PinNames.cpp @@ -0,0 +1,103 @@ +#include <Arduino.h> +#include "zephyrInternal.h" +#include "PinNames.h" + +// duplicate of one in zephyr common +static const struct gpio_dt_spec arduino_pins[] = { DT_FOREACH_PROP_ELEM_SEP( + DT_PATH(zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, )) }; + +static const struct gpio_dt_spec arduino_ports[] = { DT_FOREACH_PROP_ELEM_SEP( + DT_PATH(zephyr_user), port_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, )) }; + + +void pinMode(PinName pinNumber, PinMode mode) { + // See if the pinName maps to a real pin number if so use the pin number version + int pin_index = PinNameToIndex(pinNumber); + if (pin_index != -1) { + // this will grab any settings out of the device tree. + pinMode((pin_size_t)pin_index, mode); + return; + } + + if (pinNumber & DUAL_PAD) return; + + if (mode == INPUT) { // input mode + gpio_pin_configure(arduino_ports[pinNumber >> 4].port, pinNumber & 0xf, + GPIO_INPUT | GPIO_ACTIVE_HIGH); + } else if (mode == INPUT_PULLUP) { // input with internal pull-up + gpio_pin_configure(arduino_ports[pinNumber >> 4].port, pinNumber & 0xf, + GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_HIGH); + } else if (mode == INPUT_PULLDOWN) { // input with internal pull-down + gpio_pin_configure(arduino_ports[pinNumber >> 4].port, pinNumber & 0xf, + GPIO_INPUT | GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH); + } else if (mode == OUTPUT) { // output mode + gpio_pin_configure(arduino_ports[pinNumber >> 4].port, pinNumber & 0xf, + GPIO_OUTPUT_LOW | GPIO_ACTIVE_HIGH); + } +} + +void digitalWrite(PinName pinNumber, PinStatus status) { + if (pinNumber & DUAL_PAD) return; + gpio_pin_set(arduino_ports[pinNumber >> 4].port, pinNumber & 0xf, status); +} + + +PinStatus digitalRead(PinName pinNumber) { + if (pinNumber & DUAL_PAD) return LOW; + return (gpio_pin_get(arduino_ports[pinNumber >> 4].port, pinNumber & 0xf) == 1) ? HIGH : LOW; +} + +int analogRead(PinName pinNumber) { + // Not sure what to do here, does anyone do something like: + // analogRead(PA_0c); or analogRead(PC2_ALT0)? + // first pass only support ones on pins. + if (pinNumber & DUAL_PAD) { + switch (pinNumber & 0xf) { + case 0: return analogRead(A0); + case 1: return analogRead(A1); + case 2: return analogRead(A2); + case 3: return analogRead(A3); + default: return -1; + } + + } + int pin_index = PinNameToIndex(pinNumber); + if (pin_index != -1) { + return analogRead(pin_index); + } + return -1; +} + + +void analogWrite(PinName pinNumber, int value) { + // first pass only support ones on pins. + if (pinNumber & DUAL_PAD) return; + int pin_index = PinNameToIndex(pinNumber); + if (pin_index != -1) { + analogWrite(pin_index, value); + } +} + + + +int PinNameToIndex(PinName P) { + if (P & DUAL_PAD) return -1; + for (size_t i = 0; i < ARRAY_SIZE(arduino_pins); i++) { + if ((arduino_ports[P >> 4].port == arduino_pins[i].port) && ((P & 0xf) == arduino_pins[i].pin)) { + return i; + } + } + return -1; +} + +PinName digitalPinToPinName(pin_size_t P) { + if (P < ARRAY_SIZE(arduino_pins)) { + // Convert the pins port into an index into our port's list + for (uint8_t port_index = 0; port_index < ARRAY_SIZE(arduino_ports); port_index++) { + if (arduino_pins[P].port == arduino_ports[port_index].port) { + return (PinName)((port_index << 4) | arduino_pins[P].pin); + } + } + } + return PinName::NC; +} diff --git a/variants/arduino_portenta_h7/PinNames.h b/variants/arduino_portenta_h7/PinNames.h new file mode 100644 index 00000000..826ac0fa --- /dev/null +++ b/variants/arduino_portenta_h7/PinNames.h @@ -0,0 +1,320 @@ + +#ifndef ZEPHYR_PINNAMES_H +#define ZEPHYR_PINNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DUAL_PAD 0x800 + +typedef enum { + PA_0 = 0x00, + PA_1 = 0x01, + PA_2 = 0x02, + PA_3 = 0x03, + PA_4 = 0x04, + PA_5 = 0x05, + PA_6 = 0x06, + PA_7 = 0x07, + PA_8 = 0x08, + PA_9 = 0x09, + PA_10 = 0x0A, + PA_11 = 0x0B, + PA_12 = 0x0C, + PA_13 = 0x0D, + PA_14 = 0x0E, + PA_15 = 0x0F, + PB_0 = 0x10, + PB_1 = 0x11, + PB_2 = 0x12, + PB_3 = 0x13, + PB_4 = 0x14, + PB_5 = 0x15, + PB_6 = 0x16, + PB_7 = 0x17, + PB_8 = 0x18, + PB_9 = 0x19, + PB_10 = 0x1A, + PB_11 = 0x1B, + PB_12 = 0x1C, + PB_13 = 0x1D, + PB_14 = 0x1E, + PB_15 = 0x1F, + PC_0 = 0x20, + PC_1 = 0x21, + PC_2 = 0x22, + PC_3 = 0x23, + PC_4 = 0x24, + PC_5 = 0x25, + PC_6 = 0x26, + PC_7 = 0x27, + PC_8 = 0x28, + PC_9 = 0x29, + PC_10 = 0x2A, + PC_11 = 0x2B, + PC_12 = 0x2C, + PC_13 = 0x2D, + PC_14 = 0x2E, + PC_15 = 0x2F, + PD_0 = 0x30, + PD_1 = 0x31, + PD_2 = 0x32, + PD_3 = 0x33, + PD_4 = 0x34, + PD_5 = 0x35, + PD_6 = 0x36, + PD_7 = 0x37, + PD_8 = 0x38, + PD_9 = 0x39, + PD_10 = 0x3A, + PD_11 = 0x3B, + PD_12 = 0x3C, + PD_13 = 0x3D, + PD_14 = 0x3E, + PD_15 = 0x3F, + PE_0 = 0x40, + PE_1 = 0x41, + PE_2 = 0x42, + PE_3 = 0x43, + PE_4 = 0x44, + PE_5 = 0x45, + PE_6 = 0x46, + PE_7 = 0x47, + PE_8 = 0x48, + PE_9 = 0x49, + PE_10 = 0x4A, + PE_11 = 0x4B, + PE_12 = 0x4C, + PE_13 = 0x4D, + PE_14 = 0x4E, + PE_15 = 0x4F, + PF_0 = 0x50, + PF_1 = 0x51, + PF_2 = 0x52, + PF_3 = 0x53, + PF_4 = 0x54, + PF_5 = 0x55, + PF_6 = 0x56, + PF_7 = 0x57, + PF_8 = 0x58, + PF_9 = 0x59, + PF_10 = 0x5A, + PF_11 = 0x5B, + PF_12 = 0x5C, + PF_13 = 0x5D, + PF_14 = 0x5E, + PF_15 = 0x5F, + PG_0 = 0x60, + PG_1 = 0x61, + PG_2 = 0x62, + PG_3 = 0x63, + PG_4 = 0x64, + PG_5 = 0x65, + PG_6 = 0x66, + PG_7 = 0x67, + PG_8 = 0x68, + PG_9 = 0x69, + PG_10 = 0x6A, + PG_11 = 0x6B, + PG_12 = 0x6C, + PG_13 = 0x6D, + PG_14 = 0x6E, + PG_15 = 0x6F, + PH_0 = 0x70, + PH_1 = 0x71, + PH_2 = 0x72, + PH_3 = 0x73, + PH_4 = 0x74, + PH_5 = 0x75, + PH_6 = 0x76, + PH_7 = 0x77, + PH_8 = 0x78, + PH_9 = 0x79, + PH_10 = 0x7A, + PH_11 = 0x7B, + PH_12 = 0x7C, + PH_13 = 0x7D, + PH_14 = 0x7E, + PH_15 = 0x7F, + PI_0 = 0x80, + PI_1 = 0x81, + PI_2 = 0x82, + PI_3 = 0x83, + PI_4 = 0x84, + PI_5 = 0x85, + PI_6 = 0x86, + PI_7 = 0x87, + PI_8 = 0x88, + PI_9 = 0x89, + PI_10 = 0x8A, + PI_11 = 0x8B, + PI_12 = 0x8C, + PI_13 = 0x8D, + PI_14 = 0x8E, + PI_15 = 0x8F, + PJ_0 = 0x90, + PJ_1 = 0x91, + PJ_2 = 0x92, + PJ_3 = 0x93, + PJ_4 = 0x94, + PJ_5 = 0x95, + PJ_6 = 0x96, + PJ_7 = 0x97, + PJ_8 = 0x98, + PJ_9 = 0x99, + PJ_10 = 0x9A, + PJ_11 = 0x9B, + PJ_12 = 0x9C, + PJ_13 = 0x9D, + PJ_14 = 0x9E, + PJ_15 = 0x9F, + PK_0 = 0xA0, + PK_1 = 0xA1, + PK_2 = 0xA2, + PK_3 = 0xA3, + PK_4 = 0xA4, + PK_5 = 0xA5, + PK_6 = 0xA6, + PK_7 = 0xA7, + + // Lets add the Analog only pins, will name them like the schematic, but number like + PA_0C = 0X00 | DUAL_PAD, + PA_1C = 0X01 | DUAL_PAD, + PC_2C = 0X02 | DUAL_PAD, + PC_3C = 0X03 | DUAL_PAD, + + + WL_REG_ON = PJ_1, + WL_HOST_WAKE = PJ_5, + WL_SDIO_0 = PC_8, + WL_SDIO_1 = PC_9, + WL_SDIO_2 = PC_10, + WL_SDIO_3 = PC_11, + WL_SDIO_CMD = PD_2, + WL_SDIO_CLK = PC_12, + + /**** ADC internal channels ****/ + + ADC_TEMP = 0xF0, // Internal pin virtual value + ADC_VREF = 0xF1, // Internal pin virtual value + ADC_VBAT = 0xF2, // Internal pin virtual value + + //Led mappings + LED_RED = PK_5, //Red + LED_GREEN = PK_6, //Green + LED_BLUE = PK_7, //Blue + + CYBSP_BT_UART_RX = PF_6, + CYBSP_BT_UART_TX = PA_15, + CYBSP_BT_UART_RTS = PF_8, + CYBSP_BT_UART_CTS = PF_9, + + CYBSP_BT_POWER = PJ_12, + CYBSP_BT_HOST_WAKE = PJ_13, + CYBSP_BT_DEVICE_WAKE = PJ_14, + + /**** QSPI FLASH pins ****/ + QSPI_FLASH1_IO0 = PD_11, + QSPI_FLASH1_IO1 = PD_12, + QSPI_FLASH1_IO2 = PF_7, + QSPI_FLASH1_IO3 = PD_13, + QSPI_FLASH1_SCK = PF_10, + QSPI_FLASH1_CSN = PG_6, + + /**** USB FS pins ****/ + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, + USB_OTG_FS_ID = PA_10, + USB_OTG_FS_SOF = PA_8, + USB_OTG_FS_VBUS = PA_9, + + /**** USB HS pins ****/ + USB_OTG_HS_DM = PB_14, + USB_OTG_HS_DP = PB_15, + USB_OTG_HS_ID = PB_12, + USB_OTG_HS_SOF = PA_4, + USB_OTG_HS_ULPI_CK = PA_5, + USB_OTG_HS_ULPI_D0 = PA_3, + USB_OTG_HS_ULPI_D1 = PB_0, + USB_OTG_HS_ULPI_D2 = PB_1, + USB_OTG_HS_ULPI_D3 = PB_10, + USB_OTG_HS_ULPI_D4 = PB_11, + USB_OTG_HS_ULPI_D5 = PB_12, + USB_OTG_HS_ULPI_D6 = PB_13, + USB_OTG_HS_ULPI_D7 = PB_5, + USB_OTG_HS_ULPI_DIR = PC_2, + USB_OTG_HS_ULPI_NXT = PC_3, + USB_OTG_HS_ULPI_STP = PC_0, + USB_OTG_HS_VBUS = PB_13, + + /**** ETHERNET pins ****/ + ETH_MDC = PC_1, + ETH_MDIO = PA_2, + ETH_CRS_DV = PA_7, + ETH_REF_CLK = PA_1, + ETH_RXD0 = PC_4, + ETH_RXD1 = PC_5, + ETH_RX_CLK = PA_1, + ETH_TXD0 = PG_13, + ETH_TXD1 = PG_12, + ETH_TX_EN = PG_11, + + /**** OSCILLATOR pins ****/ + RCC_OSC32_IN = PC_14, + RCC_OSC32_OUT = PC_15, + RCC_OSC_IN = PH_0, + RCC_OSC_OUT = PH_1, + + /**** DEBUG pins ****/ + SYS_JTCK_SWCLK = PA_14, + SYS_JTDI = PA_15, + SYS_JTDO_SWO = PB_3, + SYS_JTMS_SWDIO = PA_13, + SYS_JTRST = PB_4, + SYS_PVD_IN = PB_7, + SYS_TRACECLK = PE_2, + SYS_TRACED0 = PE_3, + SYS_TRACED0_ALT0 = PC_1, + SYS_TRACED0_ALT1 = PG_13, + SYS_TRACED1 = PE_4, + SYS_TRACED1_ALT0 = PC_8, + SYS_TRACED1_ALT1 = PG_14, + SYS_TRACED2 = PE_5, + SYS_TRACED2_ALT0 = PD_2, + SYS_TRACED3 = PE_6, + SYS_TRACED3_ALT0 = PC_12, + SYS_TRGIO = PC_7, + SYS_WKUP0 = PA_0, + SYS_WKUP1 = PA_2, + SYS_WKUP2 = PC_13, + SYS_WKUP5 = PC_1, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +// Standardized LED and button names +#define LED1 LED_RED +#define LED2 LED_GREEN +#define LED3 LED_BLUE +#define BUTTON1 PC_13 + + + +#ifdef __cplusplus + +} + +// overloads - only cpp as c does not allow overloads of functions +void pinMode(PinName pinNumber, PinMode mode); +void digitalWrite(PinName pinNumber, PinStatus status); +int PinNameToIndex(PinName P); +PinName digitalPinToPinName(pin_size_t P); +PinStatus digitalRead(PinName pinNumber); +int analogRead(PinName pinNumber); +void analogWrite(PinName pinNumber, int value); + +#endif + +#endif diff --git a/variants/arduino_portenta_h7/pure_analog_pins.cpp b/variants/arduino_portenta_h7/pure_analog_pins.cpp new file mode 100644 index 00000000..83548487 --- /dev/null +++ b/variants/arduino_portenta_h7/pure_analog_pins.cpp @@ -0,0 +1,17 @@ +#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/pure_analog_pins.h b/variants/arduino_portenta_h7/pure_analog_pins.h new file mode 100644 index 00000000..b949a069 --- /dev/null +++ b/variants/arduino_portenta_h7/pure_analog_pins.h @@ -0,0 +1,57 @@ +#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/variant.h b/variants/arduino_portenta_h7/variant.h index 68c33a89..336ffa3d 100644 --- a/variants/arduino_portenta_h7/variant.h +++ b/variants/arduino_portenta_h7/variant.h @@ -3,6 +3,8 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include "pure_analog_pins.h" +#include "PinNames.h" // TODO: correctly handle these legacy defines #define MOSI 0