From 8f48b6acda2a90c05f264c9431de5f458515ddf1 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Tue, 14 Mar 2023 06:54:09 -0700 Subject: [PATCH] nxp:imxrt 1060/1170 bifurcation and restructuring imxrt:117x Reuse all but io_timer_hw_description and imxrt_pinirq.c imxrt:ADC & LPADC bifurcation and restructuring imxrt:hrt support Up to GPT6 nxp/rt117x:adc Corrected --- platforms/nuttx/src/px4/nxp/imxrt/hrt/hrt.c | 18 +- .../imxrt/include/px4_arch/hw_description.h | 761 ----------- .../px4_arch/io_timer_hw_description.h | 1186 ----------------- .../include/px4_arch/spi_hw_description.h | 140 -- .../src/px4/nxp/imxrt/io_pins/imxrt_pinirq.c | 14 +- .../src/px4/nxp/rt106x/include/px4_arch/adc.h | 12 +- .../rt106x/include/px4_arch/hw_description.h | 377 +++++- .../nxp/rt106x/include/px4_arch/io_timer.h | 143 +- .../px4_arch/io_timer_hw_description.h | 591 +++++++- .../include/px4_arch/spi_hw_description.h | 118 +- .../nuttx/src/px4/nxp/rt117x/CMakeLists.txt | 4 +- .../src/px4/nxp/rt117x/adc/CMakeLists.txt | 36 + .../nuttx/src/px4/nxp/rt117x/adc/adc.cpp | 248 ++++ .../src/px4/nxp/rt117x/include/px4_arch/adc.h | 12 +- .../rt117x/include/px4_arch/hw_description.h | 455 ++++++- .../px4_arch/io_timer_hw_description.h | 680 +++++++++- .../include/px4_arch/spi_hw_description.h | 112 +- .../src/px4/nxp/rt117x/io_pins/CMakeLists.txt | 44 + .../src/px4/nxp/rt117x/io_pins/imxrt_pinirq.c | 161 +++ 19 files changed, 2962 insertions(+), 2150 deletions(-) delete mode 100644 platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/hw_description.h delete mode 100644 platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer_hw_description.h delete mode 100644 platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h create mode 100644 platforms/nuttx/src/px4/nxp/rt117x/adc/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/nxp/rt117x/adc/adc.cpp create mode 100644 platforms/nuttx/src/px4/nxp/rt117x/io_pins/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/nxp/rt117x/io_pins/imxrt_pinirq.c diff --git a/platforms/nuttx/src/px4/nxp/imxrt/hrt/hrt.c b/platforms/nuttx/src/px4/nxp/imxrt/hrt/hrt.c index 7106a1814c..d44a1ee106 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/hrt/hrt.c +++ b/platforms/nuttx/src/px4/nxp/imxrt/hrt/hrt.c @@ -94,12 +94,28 @@ # define HRT_CLOCK_ALL() imxrt_clockall_gpt_bus() /* The Clock Gating macro for this GPT */ #elif HRT_TIMER == 2 # define HRT_CLOCK_ALL() imxrt_clockall_gpt2_bus() /* The Clock Gating macro for this GPT */ +#elif HRT_TIMER == 3 +# define HRT_CLOCK_ALL() imxrt_clockall_gpt3_bus() /* The Clock Gating macro for this GPT */ +#elif HRT_TIMER == 4 +# define HRT_CLOCK_ALL() imxrt_clockall_gpt4_bus() /* The Clock Gating macro for this GPT */ +#elif HRT_TIMER == 5 +# define HRT_CLOCK_ALL() imxrt_clockall_gpt5_bus() /* The Clock Gating macro for this GPT */ +#elif HRT_TIMER == 6 +# define HRT_CLOCK_ALL() imxrt_clockall_gpt6_bus() /* The Clock Gating macro for this GPT */ #endif #if HRT_TIMER == 1 && defined(CONFIG_IMXRT_GPT1) # error must not set CONFIG_IMXRT_GPT1=y and HRT_TIMER=1 #elif HRT_TIMER == 2 && defined(CONFIG_IMXRT_GPT2) # error must not set CONFIG_IMXRT_GPT2=y and HRT_TIMER=2 +#elif HRT_TIMER == 3 && defined(CONFIG_IMXRT_GPT3) +# error must not set CONFIG_IMXRT_GPT3=y and HRT_TIMER=3 +#elif HRT_TIMER == 4 && defined(CONFIG_IMXRT_GPT4) +# error must not set CONFIG_IMXRT_GPT4=y and HRT_TIMER=4 +#elif HRT_TIMER == 5 && defined(CONFIG_IMXRT_GPT5) +# error must not set CONFIG_IMXRT_GPT5=y and HRT_TIMER=5 +#elif HRT_TIMER == 6 && defined(CONFIG_IMXRT_GPT6) +# error must not set CONFIG_IMXRT_GPT6=y and HRT_TIMER=6 #endif /* @@ -165,7 +181,7 @@ # define STATUS_HRT CAT(GPT_SR_OF, HRT_TIMER_CHANNEL) /* OF Output Compare Flag */ # define OFIE_HRT CAT3(GPT_IR_OF, HRT_TIMER_CHANNEL,IE) /* Output Compare Interrupt Enable */ -#if (HRT_TIMER_CHANNEL > 1) || (HRT_TIMER_CHANNEL > 3) +#if (HRT_TIMER_CHANNEL < 1) || (HRT_TIMER_CHANNEL > 3) # error HRT_TIMER_CHANNEL must be a value between 1 and 3 #endif diff --git a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/hw_description.h b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/hw_description.h deleted file mode 100644 index 504b7b6011..0000000000 --- a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/hw_description.h +++ /dev/null @@ -1,761 +0,0 @@ -/**************************************************************************** - * - * Copyright (C) 2019 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#pragma once - - -#include - -#include "hardware/imxrt_flexpwm.h" - -#include - -#include -#if !defined(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) && !defined(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA) -# error "This code has only been validated with IMXRT1062/IMXRT1176. Make sure it is correct before using it on another board." -#endif - -/* - * PWM - */ - -namespace PWM -{ -enum FlexPWM { - FlexPWM1 = 0, - FlexPWM2, - FlexPWM3, - FlexPWM4, -}; - -enum FlexPWMModule { - PWM1_PWM_A = 0, - PWM1_PWM_B, - PWM1_PWM_X, - - PWM2_PWM_A, - PWM2_PWM_B, - PWM2_PWM_X, - - PWM3_PWM_A, - PWM3_PWM_B, - PWM3_PWM_X, - - PWM4_PWM_A, - PWM4_PWM_B, - PWM4_PWM_X, -}; - -enum FlexPWMSubmodule { - Submodule0 = 0, - Submodule1, - Submodule2, - Submodule3, -}; - -struct FlexPWMConfig { - FlexPWMModule module; - FlexPWMSubmodule submodule; -}; -} - -static inline constexpr uint32_t getFlexPWMBaseRegister(PWM::FlexPWM pwm) -{ - switch (pwm) { - case PWM::FlexPWM1: return IMXRT_FLEXPWM1_BASE; - - case PWM::FlexPWM2: return IMXRT_FLEXPWM2_BASE; - - case PWM::FlexPWM3: return IMXRT_FLEXPWM3_BASE; - - case PWM::FlexPWM4: return IMXRT_FLEXPWM4_BASE; - } - - return 0; -} - - -#ifdef CONFIG_ARCH_FAMILY_IMXRT117x - - -namespace IOMUX -{ -enum class Pad { - GPIO_EMC_B1_00 = 0, - GPIO_EMC_B1_01 = 1, - GPIO_EMC_B1_02 = 2, - GPIO_EMC_B1_03 = 3, - GPIO_EMC_B1_04 = 4, - GPIO_EMC_B1_05 = 5, - GPIO_EMC_B1_06 = 6, - GPIO_EMC_B1_07 = 7, - GPIO_EMC_B1_08 = 8, - GPIO_EMC_B1_09 = 9, - GPIO_EMC_B1_10 = 10, - GPIO_EMC_B1_11 = 11, - GPIO_EMC_B1_12 = 12, - GPIO_EMC_B1_13 = 13, - GPIO_EMC_B1_14 = 14, - GPIO_EMC_B1_15 = 15, - GPIO_EMC_B1_16 = 16, - GPIO_EMC_B1_17 = 17, - GPIO_EMC_B1_18 = 18, - GPIO_EMC_B1_19 = 19, - GPIO_EMC_B1_20 = 20, - GPIO_EMC_B1_21 = 21, - GPIO_EMC_B1_22 = 22, - GPIO_EMC_B1_23 = 23, - GPIO_EMC_B1_24 = 24, - GPIO_EMC_B1_25 = 25, - GPIO_EMC_B1_26 = 26, - GPIO_EMC_B1_27 = 27, - GPIO_EMC_B1_28 = 28, - GPIO_EMC_B1_29 = 29, - GPIO_EMC_B1_30 = 30, - GPIO_EMC_B1_31 = 31, - GPIO_EMC_B1_32 = 32, - GPIO_EMC_B1_33 = 33, - GPIO_EMC_B1_34 = 34, - GPIO_EMC_B1_35 = 35, - GPIO_EMC_B1_36 = 36, - GPIO_EMC_B1_37 = 37, - GPIO_EMC_B1_38 = 38, - GPIO_EMC_B1_39 = 39, - GPIO_EMC_B1_40 = 40, - GPIO_EMC_B1_41 = 41, - GPIO_EMC_B2_00 = 42, - GPIO_EMC_B2_01 = 43, - GPIO_EMC_B2_02 = 44, - GPIO_EMC_B2_03 = 45, - GPIO_EMC_B2_04 = 46, - GPIO_EMC_B2_05 = 47, - GPIO_EMC_B2_06 = 48, - GPIO_EMC_B2_07 = 49, - GPIO_EMC_B2_08 = 50, - GPIO_EMC_B2_09 = 51, - GPIO_EMC_B2_10 = 52, - GPIO_EMC_B2_11 = 53, - GPIO_EMC_B2_12 = 54, - GPIO_EMC_B2_13 = 55, - GPIO_EMC_B2_14 = 56, - GPIO_EMC_B2_15 = 57, - GPIO_EMC_B2_16 = 58, - GPIO_EMC_B2_17 = 59, - GPIO_EMC_B2_18 = 60, - GPIO_EMC_B2_19 = 61, - GPIO_EMC_B2_20 = 62, - GPIO_AD_00 = 63, - GPIO_AD_01 = 64, - GPIO_AD_02 = 65, - GPIO_AD_03 = 66, - GPIO_AD_04 = 67, - GPIO_AD_05 = 68, - GPIO_AD_06 = 69, - GPIO_AD_07 = 70, - GPIO_AD_08 = 71, - GPIO_AD_09 = 72, - GPIO_AD_10 = 73, - GPIO_AD_11 = 74, - GPIO_AD_12 = 75, - GPIO_AD_13 = 76, - GPIO_AD_14 = 77, - GPIO_AD_15 = 78, - GPIO_AD_16 = 79, - GPIO_AD_17 = 80, - GPIO_AD_18 = 81, - GPIO_AD_19 = 82, - GPIO_AD_20 = 83, - GPIO_AD_21 = 84, - GPIO_AD_22 = 85, - GPIO_AD_23 = 86, - GPIO_AD_24 = 87, - GPIO_AD_25 = 88, - GPIO_AD_26 = 89, - GPIO_AD_27 = 90, - GPIO_AD_28 = 91, - GPIO_AD_29 = 92, - GPIO_AD_30 = 93, - GPIO_AD_31 = 94, - GPIO_AD_32 = 95, - GPIO_AD_33 = 96, - GPIO_AD_34 = 97, - GPIO_AD_35 = 98, - GPIO_SD_B1_00 = 99, - GPIO_SD_B1_01 = 100, - GPIO_SD_B1_02 = 101, - GPIO_SD_B1_03 = 102, - GPIO_SD_B1_04 = 103, - GPIO_SD_B1_05 = 104, - GPIO_SD_B2_00 = 105, - GPIO_SD_B2_01 = 106, - GPIO_SD_B2_02 = 107, - GPIO_SD_B2_03 = 108, - GPIO_SD_B2_04 = 109, - GPIO_SD_B2_05 = 110, - GPIO_SD_B2_06 = 111, - GPIO_SD_B2_07 = 112, - GPIO_SD_B2_08 = 113, - GPIO_SD_B2_09 = 114, - GPIO_SD_B2_10 = 115, - GPIO_SD_B2_11 = 116, - GPIO_DISP_B1_00 = 117, - GPIO_DISP_B1_01 = 118, - GPIO_DISP_B1_02 = 119, - GPIO_DISP_B1_03 = 120, - GPIO_DISP_B1_04 = 121, - GPIO_DISP_B1_05 = 122, - GPIO_DISP_B1_06 = 123, - GPIO_DISP_B1_07 = 124, - GPIO_DISP_B1_08 = 125, - GPIO_DISP_B1_09 = 126, - GPIO_DISP_B1_10 = 127, - GPIO_DISP_B1_11 = 128, - GPIO_DISP_B2_00 = 129, - GPIO_DISP_B2_01 = 130, - GPIO_DISP_B2_02 = 131, - GPIO_DISP_B2_03 = 132, - GPIO_DISP_B2_04 = 133, - GPIO_DISP_B2_05 = 134, - GPIO_DISP_B2_06 = 135, - GPIO_DISP_B2_07 = 136, - GPIO_DISP_B2_08 = 137, - GPIO_DISP_B2_09 = 138, - GPIO_DISP_B2_10 = 139, - GPIO_DISP_B2_11 = 140, - GPIO_DISP_B2_12 = 141, - GPIO_DISP_B2_13 = 142, - GPIO_DISP_B2_14 = 143, - GPIO_DISP_B2_15 = 144, - WAKEUP = 145, - PMIC_ON_REQ = 146, - PMIC_STBY_REQ = 147, - GPIO_SNVS_00 = 148, - GPIO_SNVS_01 = 149, - GPIO_SNVS_02 = 150, - GPIO_SNVS_03 = 151, - GPIO_SNVS_04 = 152, - GPIO_SNVS_05 = 153, - GPIO_SNVS_06 = 154, - GPIO_SNVS_07 = 155, - GPIO_SNVS_08 = 156, - GPIO_SNVS_09 = 157, - GPIO_LPSR_00 = 158, - GPIO_LPSR_01 = 159, - GPIO_LPSR_02 = 160, - GPIO_LPSR_03 = 161, - GPIO_LPSR_04 = 162, - GPIO_LPSR_05 = 163, - GPIO_LPSR_06 = 164, - GPIO_LPSR_07 = 165, - GPIO_LPSR_08 = 166, - GPIO_LPSR_09 = 167, - GPIO_LPSR_10 = 168, - GPIO_LPSR_11 = 169, - GPIO_LPSR_12 = 170, - GPIO_LPSR_13 = 171, - GPIO_LPSR_14 = 172, - GPIO_LPSR_15 = 173 -}; - -} - -/* - * GPIO - */ - -namespace GPIO -{ -enum Port { - PortInvalid = 0, - Port1, - Port2, - Port3, - Port4, - Port5, - Port6, - Port7, - Port8, - Port9, - Port10, - Port11, - Port12, - Port13, -}; -enum Pin { - Pin0 = 0, - Pin1, - Pin2, - Pin3, - Pin4, - Pin5, - Pin6, - Pin7, - Pin8, - Pin9, - Pin10, - Pin11, - Pin12, - Pin13, - Pin14, - Pin15, - Pin16, - Pin17, - Pin18, - Pin19, - Pin20, - Pin21, - Pin22, - Pin23, - Pin24, - Pin25, - Pin26, - Pin27, - Pin28, - Pin29, - Pin30, - Pin31, -}; -struct GPIOPin { - Port port; - Pin pin; -}; -} - -static inline constexpr uint32_t getGPIOPort(GPIO::Port port) -{ - switch (port) { - case GPIO::Port1: return GPIO_PORT1; - - case GPIO::Port2: return GPIO_PORT2; - - case GPIO::Port3: return GPIO_PORT3; - - case GPIO::Port4: return GPIO_PORT4; - - case GPIO::Port5: return GPIO_PORT5; - - case GPIO::Port6: return GPIO_PORT6; - - case GPIO::Port7: return GPIO_PORT7; - - case GPIO::Port8: return GPIO_PORT8; - - case GPIO::Port9: return GPIO_PORT9; - - case GPIO::Port10: return GPIO_PORT10; - - case GPIO::Port11: return GPIO_PORT11; - - case GPIO::Port12: return GPIO_PORT12; - - case GPIO::Port13: return GPIO_PORT13; - - default: break; - } - - return 0; -} - -static inline constexpr uint32_t getGPIOPin(GPIO::Pin pin) -{ - switch (pin) { - case GPIO::Pin0: return GPIO_PIN0; - - case GPIO::Pin1: return GPIO_PIN1; - - case GPIO::Pin2: return GPIO_PIN2; - - case GPIO::Pin3: return GPIO_PIN3; - - case GPIO::Pin4: return GPIO_PIN4; - - case GPIO::Pin5: return GPIO_PIN5; - - case GPIO::Pin6: return GPIO_PIN6; - - case GPIO::Pin7: return GPIO_PIN7; - - case GPIO::Pin8: return GPIO_PIN8; - - case GPIO::Pin9: return GPIO_PIN9; - - case GPIO::Pin10: return GPIO_PIN10; - - case GPIO::Pin11: return GPIO_PIN11; - - case GPIO::Pin12: return GPIO_PIN12; - - case GPIO::Pin13: return GPIO_PIN13; - - case GPIO::Pin14: return GPIO_PIN14; - - case GPIO::Pin15: return GPIO_PIN15; - - case GPIO::Pin16: return GPIO_PIN16; - - case GPIO::Pin17: return GPIO_PIN17; - - case GPIO::Pin18: return GPIO_PIN18; - - case GPIO::Pin19: return GPIO_PIN19; - - case GPIO::Pin20: return GPIO_PIN20; - - case GPIO::Pin21: return GPIO_PIN21; - - case GPIO::Pin22: return GPIO_PIN22; - - case GPIO::Pin23: return GPIO_PIN23; - - case GPIO::Pin24: return GPIO_PIN24; - - case GPIO::Pin25: return GPIO_PIN25; - - case GPIO::Pin26: return GPIO_PIN26; - - case GPIO::Pin27: return GPIO_PIN27; - - case GPIO::Pin28: return GPIO_PIN28; - - case GPIO::Pin29: return GPIO_PIN29; - - case GPIO::Pin30: return GPIO_PIN30; - - case GPIO::Pin31: return GPIO_PIN31; - } - - return 0; -} - -#else - -namespace IOMUX -{ -enum class Pad { - GPIO_EMC_00 = 0, - GPIO_EMC_01 = 1, - GPIO_EMC_02 = 2, - GPIO_EMC_03 = 3, - GPIO_EMC_04 = 4, - GPIO_EMC_05 = 5, - GPIO_EMC_06 = 6, - GPIO_EMC_07 = 7, - GPIO_EMC_08 = 8, - GPIO_EMC_09 = 9, - GPIO_EMC_10 = 10, - GPIO_EMC_11 = 11, - GPIO_EMC_12 = 12, - GPIO_EMC_13 = 13, - GPIO_EMC_14 = 14, - GPIO_EMC_15 = 15, - GPIO_EMC_16 = 16, - GPIO_EMC_17 = 17, - GPIO_EMC_18 = 18, - GPIO_EMC_19 = 19, - GPIO_EMC_20 = 20, - GPIO_EMC_21 = 21, - GPIO_EMC_22 = 22, - GPIO_EMC_23 = 23, - GPIO_EMC_24 = 24, - GPIO_EMC_25 = 25, - GPIO_EMC_26 = 26, - GPIO_EMC_27 = 27, - GPIO_EMC_28 = 28, - GPIO_EMC_29 = 29, - GPIO_EMC_30 = 30, - GPIO_EMC_31 = 31, - GPIO_EMC_32 = 32, - GPIO_EMC_33 = 33, - GPIO_EMC_34 = 34, - GPIO_EMC_35 = 35, - GPIO_EMC_36 = 36, - GPIO_EMC_37 = 37, - GPIO_EMC_38 = 38, - GPIO_EMC_39 = 39, - GPIO_EMC_40 = 40, - GPIO_EMC_41 = 41, - GPIO_AD_B0_00 = 42, - GPIO_AD_B0_01 = 43, - GPIO_AD_B0_02 = 44, - GPIO_AD_B0_03 = 45, - GPIO_AD_B0_04 = 46, - GPIO_AD_B0_05 = 47, - GPIO_AD_B0_06 = 48, - GPIO_AD_B0_07 = 49, - GPIO_AD_B0_08 = 50, - GPIO_AD_B0_09 = 51, - GPIO_AD_B0_10 = 52, - GPIO_AD_B0_11 = 53, - GPIO_AD_B0_12 = 54, - GPIO_AD_B0_13 = 55, - GPIO_AD_B0_14 = 56, - GPIO_AD_B0_15 = 57, - GPIO_AD_B1_00 = 58, - GPIO_AD_B1_01 = 59, - GPIO_AD_B1_02 = 60, - GPIO_AD_B1_03 = 61, - GPIO_AD_B1_04 = 62, - GPIO_AD_B1_05 = 63, - GPIO_AD_B1_06 = 64, - GPIO_AD_B1_07 = 65, - GPIO_AD_B1_08 = 66, - GPIO_AD_B1_09 = 67, - GPIO_AD_B1_10 = 68, - GPIO_AD_B1_11 = 69, - GPIO_AD_B1_12 = 70, - GPIO_AD_B1_13 = 71, - GPIO_AD_B1_14 = 72, - GPIO_AD_B1_15 = 73, - GPIO_B0_00 = 74, - GPIO_B0_01 = 75, - GPIO_B0_02 = 76, - GPIO_B0_03 = 77, - GPIO_B0_04 = 78, - GPIO_B0_05 = 79, - GPIO_B0_06 = 80, - GPIO_B0_07 = 81, - GPIO_B0_08 = 82, - GPIO_B0_09 = 83, - GPIO_B0_10 = 84, - GPIO_B0_11 = 85, - GPIO_B0_12 = 86, - GPIO_B0_13 = 87, - GPIO_B0_14 = 88, - GPIO_B0_15 = 89, - GPIO_B1_00 = 90, - GPIO_B1_01 = 91, - GPIO_B1_02 = 92, - GPIO_B1_03 = 93, - GPIO_B1_04 = 94, - GPIO_B1_05 = 95, - GPIO_B1_06 = 96, - GPIO_B1_07 = 97, - GPIO_B1_08 = 98, - GPIO_B1_09 = 99, - GPIO_B1_10 = 100, - GPIO_B1_11 = 101, - GPIO_B1_12 = 102, - GPIO_B1_13 = 103, - GPIO_B1_14 = 104, - GPIO_B1_15 = 105, - GPIO_SD_B0_00 = 106, - GPIO_SD_B0_01 = 107, - GPIO_SD_B0_02 = 108, - GPIO_SD_B0_03 = 109, - GPIO_SD_B0_04 = 110, - GPIO_SD_B0_05 = 111, - GPIO_SD_B1_00 = 112, - GPIO_SD_B1_01 = 113, - GPIO_SD_B1_02 = 114, - GPIO_SD_B1_03 = 115, - GPIO_SD_B1_04 = 116, - GPIO_SD_B1_05 = 117, - GPIO_SD_B1_06 = 118, - GPIO_SD_B1_07 = 119, - GPIO_SD_B1_08 = 120, - GPIO_SD_B1_09 = 121, - GPIO_SD_B1_10 = 122, - GPIO_SD_B1_11 = 123, -}; - -} - -/* - * GPIO - */ - -namespace GPIO -{ -enum Port { - PortInvalid = 0, - Port1, - Port2, - Port3, - Port4, - Port5, -}; -enum Pin { - Pin0 = 0, - Pin1, - Pin2, - Pin3, - Pin4, - Pin5, - Pin6, - Pin7, - Pin8, - Pin9, - Pin10, - Pin11, - Pin12, - Pin13, - Pin14, - Pin15, - Pin16, - Pin17, - Pin18, - Pin19, - Pin20, - Pin21, - Pin22, - Pin23, - Pin24, - Pin25, - Pin26, - Pin27, - Pin28, - Pin29, - Pin30, - Pin31, -}; -struct GPIOPin { - Port port; - Pin pin; -}; -} - -static inline constexpr uint32_t getGPIOPort(GPIO::Port port) -{ - switch (port) { - case GPIO::Port1: return GPIO_PORT1; - - case GPIO::Port2: return GPIO_PORT2; - - case GPIO::Port3: return GPIO_PORT3; - - case GPIO::Port4: return GPIO_PORT4; - - case GPIO::Port5: return GPIO_PORT5; - - default: break; - } - - return 0; -} - -static inline constexpr uint32_t getGPIOPin(GPIO::Pin pin) -{ - switch (pin) { - case GPIO::Pin0: return GPIO_PIN0; - - case GPIO::Pin1: return GPIO_PIN1; - - case GPIO::Pin2: return GPIO_PIN2; - - case GPIO::Pin3: return GPIO_PIN3; - - case GPIO::Pin4: return GPIO_PIN4; - - case GPIO::Pin5: return GPIO_PIN5; - - case GPIO::Pin6: return GPIO_PIN6; - - case GPIO::Pin7: return GPIO_PIN7; - - case GPIO::Pin8: return GPIO_PIN8; - - case GPIO::Pin9: return GPIO_PIN9; - - case GPIO::Pin10: return GPIO_PIN10; - - case GPIO::Pin11: return GPIO_PIN11; - - case GPIO::Pin12: return GPIO_PIN12; - - case GPIO::Pin13: return GPIO_PIN13; - - case GPIO::Pin14: return GPIO_PIN14; - - case GPIO::Pin15: return GPIO_PIN15; - - case GPIO::Pin16: return GPIO_PIN16; - - case GPIO::Pin17: return GPIO_PIN17; - - case GPIO::Pin18: return GPIO_PIN18; - - case GPIO::Pin19: return GPIO_PIN19; - - case GPIO::Pin20: return GPIO_PIN20; - - case GPIO::Pin21: return GPIO_PIN21; - - case GPIO::Pin22: return GPIO_PIN22; - - case GPIO::Pin23: return GPIO_PIN23; - - case GPIO::Pin24: return GPIO_PIN24; - - case GPIO::Pin25: return GPIO_PIN25; - - case GPIO::Pin26: return GPIO_PIN26; - - case GPIO::Pin27: return GPIO_PIN27; - - case GPIO::Pin28: return GPIO_PIN28; - - case GPIO::Pin29: return GPIO_PIN29; - - case GPIO::Pin30: return GPIO_PIN30; - - case GPIO::Pin31: return GPIO_PIN31; - } - - return 0; -} - -#endif - -namespace SPI -{ - -enum class Bus { - LPSPI1 = 1, - LPSPI2, - LPSPI3, - LPSPI4, -#ifdef CONFIG_ARCH_FAMILY_IMXRT117x - LPSPI5, - LPSPI6, -#endif -}; - -using CS = GPIO::GPIOPin; ///< chip-select pin -using DRDY = GPIO::GPIOPin; ///< data ready pin - -struct bus_device_external_cfg_t { - CS cs_gpio; - DRDY drdy_gpio; -}; - -} // namespace SPI diff --git a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer_hw_description.h b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer_hw_description.h deleted file mode 100644 index 545c7587bf..0000000000 --- a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer_hw_description.h +++ /dev/null @@ -1,1186 +0,0 @@ -/**************************************************************************** - * - * Copyright (C) 2019 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#pragma once - - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#if !defined(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) && !defined(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA) -# error "This code has only been validated with IMXRT1062/IMXRT1176. Make sure it is correct before using it on another board." -#endif - - -static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t io_timers_conf[MAX_IO_TIMERS], - PWM::FlexPWMConfig pwm_config, IOMUX::Pad pad) -{ - timer_io_channels_t ret{}; - PWM::FlexPWM pwm{}; - - // FlexPWM IMXRT1176 Muxing Options -#ifdef CONFIG_ARCH_FAMILY_IMXRT117x - - switch (pwm_config.module) { - case PWM::PWM1_PWM_A: - pwm = PWM::FlexPWM1; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_23) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_23_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN23; - - } else if (pad == IOMUX::Pad::GPIO_AD_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_00_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN31; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_25) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_25_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN25; - - } else if (pad == IOMUX::Pad::GPIO_AD_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_02_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN1; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_27) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_27_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN27; - - } else if (pad == IOMUX::Pad::GPIO_AD_04) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_04_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN3; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_38) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_38_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN6; - - } - - break; - } - - break; - - case PWM::PWM1_PWM_B: - pwm = PWM::FlexPWM1; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_24) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_24_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN24; - - } else if (pad == IOMUX::Pad::GPIO_AD_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_01_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN0; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_26) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_26_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN26; - - } else if (pad == IOMUX::Pad::GPIO_AD_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_03_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN2; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_28) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_28_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN28; - - } else if (pad == IOMUX::Pad::GPIO_AD_05) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_05_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN4; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_39) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_39_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN7; - - } - - break; - } - - break; - - case PWM::PWM1_PWM_X: - pwm = PWM::FlexPWM1; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_AD_06) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_06_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN5; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_AD_07) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_07_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN6; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_AD_08) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_08_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN7; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_AD_09) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_09_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN8; - } - - break; - } - - break; - - - case PWM::PWM2_PWM_A: - pwm = PWM::FlexPWM2; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_06) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_06_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN6; - - } else if (pad == IOMUX::Pad::GPIO_AD_24) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_24_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN23; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_08) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_08_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN8; - - } else if (pad == IOMUX::Pad::GPIO_AD_26) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_26_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN25; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_10) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_10_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN10; - - } else if (pad == IOMUX::Pad::GPIO_AD_28) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_28_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN27; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_19) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_19_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN19; - - } - - break; - } - - break; - - case PWM::PWM2_PWM_B: - pwm = PWM::FlexPWM2; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_07) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_07_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN7; - - } else if (pad == IOMUX::Pad::GPIO_AD_25) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_25_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN24; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_09) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_09_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN9; - - } else if (pad == IOMUX::Pad::GPIO_AD_27) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_27_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN26; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_11) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_11_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN11; - - } else if (pad == IOMUX::Pad::GPIO_AD_29) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_29_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN28; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_20) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_20_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN20; - - } - - break; - } - - break; - - case PWM::PWM2_PWM_X: - pwm = PWM::FlexPWM2; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_AD_10) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_10_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN9; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_AD_11) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_11_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN10; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_AD_12) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_12_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN11; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_AD_13) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_13_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN12; - } - - break; - } - - break; - - - case PWM::PWM3_PWM_A: - pwm = PWM::FlexPWM3; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_29) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_29_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN29; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_00_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN10; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_31) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_31_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN31; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_02_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN12; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_33) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_33_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN1; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_04) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_04_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN14; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_21) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_21_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN21; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_06) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_06_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN16; - } - - break; - } - - break; - - case PWM::PWM3_PWM_B: - pwm = PWM::FlexPWM3; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_30) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_30_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN30; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_01_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN11; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_32) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_32_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN0; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_03_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN13; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_34) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_34_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN2; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_05) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_05_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN15; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_22) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_22_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN22; - - } else if (pad == IOMUX::Pad::GPIO_EMC_B2_07) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_07_INDEX); - ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN17; - } - - break; - } - - break; - - - case PWM::PWM3_PWM_X: - pwm = PWM::FlexPWM3; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_AD_14) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_14_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN13; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_AD_15) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_15_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN14; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_AD_16) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_16_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN15; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_AD_17) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_17_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN16; - } - - break; - } - - break; - - case PWM::PWM4_PWM_A: - pwm = PWM::FlexPWM4; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_00_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN0; - - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_02_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN2; - - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_04) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_04_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN4; - - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_17) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_17_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN17; - - } - - break; - } - - break; - - case PWM::PWM4_PWM_B: - pwm = PWM::FlexPWM4; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_B1_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_01_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN1; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_B1_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_03_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN3; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_B1_05) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_05_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN5; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_B1_18) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_18_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN18; - } - - break; - } - - break; - - - case PWM::PWM4_PWM_X: - pwm = PWM::FlexPWM4; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_AD_18) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_18_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN17; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_AD_19) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_19_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN18; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_AD_20) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_20_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN19; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_AD_21) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_21_INDEX); - ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN20; - } - - break; - } - - break; - } - - constexpr_assert(ret.gpio_out != 0, "Invalid PWM/Pad config"); - ret.gpio_out |= IOMUX_CMOS_OUTPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_HIGHSTRENGTH | IOMUX_SLEW_FAST; -#else - - switch (pwm_config.module) { - case PWM::PWM1_PWM_A: - pwm = PWM::FlexPWM1; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_23) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_23_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN23; - - } else if (pad == IOMUX::Pad::GPIO_SD_B0_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_00_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN12; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_25) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_25_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN25; - - } else if (pad == IOMUX::Pad::GPIO_SD_B0_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_02_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN14; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_27) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_27_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN27; - - } else if (pad == IOMUX::Pad::GPIO_SD_B0_04) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_04_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN16; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_38) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_38_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN24; - - } else if (pad == IOMUX::Pad::GPIO_SD_B1_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_00_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN0; - - } else if (pad == IOMUX::Pad::GPIO_AD_B0_10) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_10_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN10; - - } else if (pad == IOMUX::Pad::GPIO_EMC_12) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_12_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN12; - - } else if (pad == IOMUX::Pad::GPIO_B1_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_00_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN16; - } - - break; - } - - break; - - case PWM::PWM1_PWM_B: - pwm = PWM::FlexPWM1; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_24) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_24_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN24; - - } else if (pad == IOMUX::Pad::GPIO_SD_B0_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_01_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN13; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_26) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_26_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN26; - - } else if (pad == IOMUX::Pad::GPIO_SD_B0_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_03_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN15; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_28) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_28_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN28; - - } else if (pad == IOMUX::Pad::GPIO_SD_B0_05) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_05_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN17; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_39) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_39_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN25; - - } else if (pad == IOMUX::Pad::GPIO_SD_B1_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_01_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN1; - - } else if (pad == IOMUX::Pad::GPIO_AD_B0_11) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_11_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN11; - - } else if (pad == IOMUX::Pad::GPIO_EMC_13) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_13_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN13; - - } else if (pad == IOMUX::Pad::GPIO_B1_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_01_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN17; - } - - break; - } - - break; - - case PWM::PWM1_PWM_X: - pwm = PWM::FlexPWM1; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_AD_B0_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_02_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN2; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_AD_B0_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_03_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN3; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_AD_B0_12) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_12_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN12; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_AD_B0_13) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_13_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN13; - } - - break; - } - - break; - - - case PWM::PWM2_PWM_A: - pwm = PWM::FlexPWM2; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_B0_06) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_06_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN6; - - } else if (pad == IOMUX::Pad::GPIO_EMC_06) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_06_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN6; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_08) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_08_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN8; - - } else if (pad == IOMUX::Pad::GPIO_B0_08) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_08_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN8; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_10) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_10_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN10; - - } else if (pad == IOMUX::Pad::GPIO_B0_10) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_10_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN10; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_AD_B0_09) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_09_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN9; - - } else if (pad == IOMUX::Pad::GPIO_SD_B1_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_02_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN2; - - } else if (pad == IOMUX::Pad::GPIO_EMC_19) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_19_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN19; - - } else if (pad == IOMUX::Pad::GPIO_B1_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_02_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN18; - - } else if (pad == IOMUX::Pad::GPIO_AD_B0_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_00_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN0; - } - - break; - } - - break; - - case PWM::PWM2_PWM_B: - pwm = PWM::FlexPWM2; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_B0_07) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_07_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN6; - - } else if (pad == IOMUX::Pad::GPIO_EMC_07) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_07_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN6; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_09) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_09_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN8; - - } else if (pad == IOMUX::Pad::GPIO_B0_09) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_09_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN8; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_11) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_11_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN10; - - } else if (pad == IOMUX::Pad::GPIO_B0_11) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_11_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN10; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_AD_B0_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_01_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN1; - - } else if (pad == IOMUX::Pad::GPIO_SD_B1_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_03_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN3; - - } else if (pad == IOMUX::Pad::GPIO_EMC_20) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_20_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN20; - - } else if (pad == IOMUX::Pad::GPIO_B1_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_03_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN19; - } - - break; - } - - break; - - - case PWM::PWM3_PWM_A: - pwm = PWM::FlexPWM3; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_29) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_29_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN29; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_31) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_31_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN31; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_33) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_33_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN19; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_21) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_21_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN21; - } - - break; - } - - break; - - case PWM::PWM3_PWM_B: - pwm = PWM::FlexPWM3; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_30) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_30_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN30; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_32) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_32_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN18; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_34) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_34_INDEX); - ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN20; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_22) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_22_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN22; - } - - break; - } - - break; - - - case PWM::PWM4_PWM_A: - pwm = PWM::FlexPWM4; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_AD_B1_08) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B1_08_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN24; - - } else if (pad == IOMUX::Pad::GPIO_EMC_00) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_00_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN0; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_02) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_02_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN2; - - } else if (pad == IOMUX::Pad::GPIO_AD_B1_09) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B1_09_INDEX); - ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN25; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_04) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_04_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN4; - - } else if (pad == IOMUX::Pad::GPIO_B1_14) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_14_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN30; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_17) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_17_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN17; - - } else if (pad == IOMUX::Pad::GPIO_B1_15) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_15_INDEX); - ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN31; - } - - break; - } - - break; - - case PWM::PWM4_PWM_B: - pwm = PWM::FlexPWM4; - - switch (pwm_config.submodule) { - case PWM::Submodule0: - if (pad == IOMUX::Pad::GPIO_EMC_01) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_01_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN1; - } - - break; - - case PWM::Submodule1: - if (pad == IOMUX::Pad::GPIO_EMC_03) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_03_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN3; - } - - break; - - case PWM::Submodule2: - if (pad == IOMUX::Pad::GPIO_EMC_05) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_05_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN5; - } - - break; - - case PWM::Submodule3: - if (pad == IOMUX::Pad::GPIO_EMC_18) { - ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_18_INDEX); - ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN18; - } - - break; - } - - break; - } - - constexpr_assert(ret.gpio_out != 0, "Invalid PWM/Pad config"); - ret.gpio_out |= IOMUX_CMOS_OUTPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_50OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST; -#endif - - switch (pwm_config.module) { - case PWM::PWM1_PWM_A: - case PWM::PWM2_PWM_A: - case PWM::PWM3_PWM_A: - case PWM::PWM4_PWM_A: - ret.val_offset = PWMA_VAL; - break; - - case PWM::PWM1_PWM_B: - case PWM::PWM2_PWM_B: - case PWM::PWM3_PWM_B: - case PWM::PWM4_PWM_B: - ret.val_offset = PWMB_VAL; - break; - - case PWM::PWM1_PWM_X: - case PWM::PWM2_PWM_X: - case PWM::PWM3_PWM_X: - case PWM::PWM4_PWM_X: - ret.val_offset = PWMX_VAL; - break; - - default: - constexpr_assert(false, "not implemented"); - } - - switch (pwm_config.submodule) { - case PWM::Submodule0: - ret.sub_module = SM0; - ret.sub_module_bits = MCTRL_LDOK(1 << SM0); - break; - - case PWM::Submodule1: - ret.sub_module = SM1; - ret.sub_module_bits = MCTRL_LDOK(1 << SM1); - break; - - case PWM::Submodule2: - ret.sub_module = SM2; - ret.sub_module_bits = MCTRL_LDOK(1 << SM2); - break; - - case PWM::Submodule3: - ret.sub_module = SM3; - ret.sub_module_bits = MCTRL_LDOK(1 << SM3); - break; - } - - ret.gpio_in = 0; // TODO (not used yet) - - // find timer index - ret.timer_index = 0xff; - const uint32_t timer_base = getFlexPWMBaseRegister(pwm); - - for (int i = 0; i < MAX_IO_TIMERS; ++i) { - if (io_timers_conf[i].base == timer_base && io_timers_conf[i].submodle == ret.sub_module) { - ret.timer_index = i; - break; - } - } - - constexpr_assert(ret.timer_index != 0xff, "Timer not found"); - return ret; -} - -static inline constexpr io_timers_t initIOPWM(PWM::FlexPWM pwm, PWM::FlexPWMSubmodule sub) -{ - io_timers_t ret{}; - - ret.base = getFlexPWMBaseRegister(pwm); - ret.submodle = sub; - return ret; -} diff --git a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h deleted file mode 100644 index 0dda27e8b9..0000000000 --- a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** - * - * Copyright (C) 2020 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#pragma once - -#include -#include - -#if defined(CONFIG_SPI) - -#include - -//#define CS_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_UP_100K | IOMUX_DRIVE_33OHM | IOMUX_SPEED_LOW | IOMUX_SLEW_FAST) - -#define DRDY_IOMUX (IOMUX_PULL_UP | IOMUX_DRIVE_HIGHSTRENGTH) - -//#define GENERAL_OUTPUT_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST) - -static inline constexpr px4_spi_bus_device_t initSPIDevice(uint32_t devid, SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) -{ - px4_spi_bus_device_t ret{}; - ret.cs_gpio = getGPIOPort(cs_gpio.port) | getGPIOPin(cs_gpio.pin) | (GPIO_OUTPUT | GPIO_OUTPUT_ONE | CS_IOMUX); - - if (drdy_gpio.port != GPIO::PortInvalid) { - ret.drdy_gpio = getGPIOPort(drdy_gpio.port) | getGPIOPin(drdy_gpio.pin) | (GPIO_INPUT | DRDY_IOMUX); - } - - if (PX4_SPIDEVID_TYPE(devid) == 0) { // it's a PX4 device (internal or external) - ret.devid = PX4_SPIDEV_ID(PX4_SPI_DEVICE_ID, devid); - - } else { // it's a NuttX device (e.g. SPIDEV_FLASH(0)) - ret.devid = devid; - } - - ret.devtype_driver = PX4_SPI_DEV_ID(devid); - return ret; -} - -static inline constexpr px4_spi_bus_t initSPIBus(SPI::Bus bus, const px4_spi_bus_devices_t &devices, - GPIO::GPIOPin power_enable = {}) -{ - px4_spi_bus_t ret{}; - ret.requires_locking = false; - - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { - ret.devices[i] = devices.devices[i]; - - - if (ret.devices[i].cs_gpio != 0) { - if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { - int same_devices_count = 0; - - for (int j = 0; j < i; ++j) { - if (ret.devices[j].cs_gpio != 0) { - same_devices_count += (ret.devices[i].devid & 0xff) == (ret.devices[j].devid & 0xff); - } - } - - // increment the 2. LSB byte to allow multiple devices of the same type - ret.devices[i].devid |= same_devices_count << 8; - - } else { - // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) - ret.requires_locking = true; - } - } - } - - ret.bus = (int)bus; - ret.is_external = false; - - if (power_enable.port != GPIO::PortInvalid) { - ret.power_enable_gpio = getGPIOPort(power_enable.port) | getGPIOPin(power_enable.pin) | - (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GENERAL_OUTPUT_IOMUX); - } - - return ret; -} - -// just a wrapper since we cannot pass brace-enclosed initialized arrays directly as arguments -struct bus_device_external_cfg_array_t { - SPI::bus_device_external_cfg_t devices[SPI_BUS_MAX_DEVICES]; -}; - -static inline constexpr px4_spi_bus_t initSPIBusExternal(SPI::Bus bus, const bus_device_external_cfg_array_t &devices) -{ - px4_spi_bus_t ret{}; - - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { - if (devices.devices[i].cs_gpio.port == GPIO::PortInvalid) { - break; - } - - ret.devices[i] = initSPIDevice(i, devices.devices[i].cs_gpio, devices.devices[i].drdy_gpio); - } - - ret.bus = (int)bus; - ret.is_external = true; - ret.requires_locking = false; // external buses are never accessed by NuttX drivers - return ret; -} - -static inline constexpr SPI::bus_device_external_cfg_t initSPIConfigExternal(SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) -{ - SPI::bus_device_external_cfg_t ret{}; - ret.cs_gpio = cs_gpio; - ret.drdy_gpio = drdy_gpio; - return ret; -} -#endif // CONFIG_SPI diff --git a/platforms/nuttx/src/px4/nxp/imxrt/io_pins/imxrt_pinirq.c b/platforms/nuttx/src/px4/nxp/imxrt/io_pins/imxrt_pinirq.c index a993460f6f..8d89c6d452 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/io_pins/imxrt_pinirq.c +++ b/platforms/nuttx/src/px4/nxp/imxrt/io_pins/imxrt_pinirq.c @@ -47,14 +47,12 @@ typedef struct { int hi; } lh_t; -const lh_t port_to_irq[8] = { - {_IMXRT_GPIO1_0_15_BASE, _IMXRT_GPIO1_16_31_BASE}, - {_IMXRT_GPIO2_0_15_BASE, _IMXRT_GPIO2_16_31_BASE}, - {_IMXRT_GPIO3_0_15_BASE, _IMXRT_GPIO3_16_31_BASE}, - {_IMXRT_GPIO4_0_15_BASE, _IMXRT_GPIO4_16_31_BASE}, - {_IMXRT_GPIO5_0_15_BASE, _IMXRT_GPIO5_16_31_BASE}, - {_IMXRT_GPIO6_0_15_BASE, _IMXRT_GPIO6_16_31_BASE}, - {_IMXRT_GPIO13_BASE, _IMXRT_GPIO13_BASE}, //FIXME +const lh_t port_to_irq[9] = { + {_IMXRT_GPIO1_0_15_BASE, _IMXRT_GPIO1_16_31_BASE}, {_IMXRT_GPIO2_0_15_BASE, _IMXRT_GPIO2_16_31_BASE}, + {_IMXRT_GPIO3_0_15_BASE, _IMXRT_GPIO3_16_31_BASE}, {_IMXRT_GPIO4_0_15_BASE, _IMXRT_GPIO4_16_31_BASE}, + {_IMXRT_GPIO5_0_15_BASE, _IMXRT_GPIO5_16_31_BASE}, {_IMXRT_GPIO6_0_15_BASE, _IMXRT_GPIO6_16_31_BASE}, + {_IMXRT_GPIO7_0_15_BASE, _IMXRT_GPIO7_16_31_BASE}, {_IMXRT_GPIO8_0_15_BASE, _IMXRT_GPIO8_16_31_BASE}, + {_IMXRT_GPIO9_0_15_BASE, _IMXRT_GPIO9_16_31_BASE}, }; /**************************************************************************** diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/adc.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/adc.h index f9da7fb8f5..b2b4c60967 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/adc.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/adc.h @@ -32,4 +32,14 @@ ****************************************************************************/ #pragma once -#include "../../../imxrt/include/px4_arch/adc.h" +#include + +#if !defined(HW_REV_VER_ADC_BASE) +# define HW_REV_VER_ADC_BASE IMXRT_ADC1_BASE +#endif + +#if !defined(SYSTEM_ADC_BASE) +# define SYSTEM_ADC_BASE IMXRT_ADC1_BASE +#endif + +#include diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h index e7676690b9..d4aada2ffe 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h @@ -1,20 +1,20 @@ /**************************************************************************** * - * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * Copyright (C) 2019 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. + * used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -30,7 +30,368 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ + #pragma once -#include "../../../imxrt/include/px4_arch/hw_description.h" +#include + +#include "hardware/imxrt_flexpwm.h" + +#include + +#include +#ifndef CONFIG_ARCH_CHIP_MIMXRT1062DVL6A +# error "This code has only been validated with IMXRT1062. Make sure it is correct before using it on another board." +#endif + +/* + * PWM + */ + +namespace PWM +{ +enum FlexPWM { + FlexPWM1 = 0, + FlexPWM2, + FlexPWM3, + FlexPWM4, +}; + +enum FlexPWMModule { + PWM1_PWM_A = 0, + PWM1_PWM_B, + PWM1_PWM_X, + + PWM2_PWM_A, + PWM2_PWM_B, + + PWM3_PWM_A, + PWM3_PWM_B, + + PWM4_PWM_A, + PWM4_PWM_B, +}; + +enum FlexPWMSubmodule { + Submodule0 = 0, + Submodule1, + Submodule2, + Submodule3, +}; + +struct FlexPWMConfig { + FlexPWMModule module; + FlexPWMSubmodule submodule; +}; +} + +static inline constexpr uint32_t getFlexPWMBaseRegister(PWM::FlexPWM pwm) +{ + switch (pwm) { + case PWM::FlexPWM1: return IMXRT_FLEXPWM1_BASE; + + case PWM::FlexPWM2: return IMXRT_FLEXPWM2_BASE; + + case PWM::FlexPWM3: return IMXRT_FLEXPWM3_BASE; + + case PWM::FlexPWM4: return IMXRT_FLEXPWM4_BASE; + } + + return 0; +} + +namespace IOMUX +{ +enum class Pad { + GPIO_EMC_00 = 0, + GPIO_EMC_01 = 1, + GPIO_EMC_02 = 2, + GPIO_EMC_03 = 3, + GPIO_EMC_04 = 4, + GPIO_EMC_05 = 5, + GPIO_EMC_06 = 6, + GPIO_EMC_07 = 7, + GPIO_EMC_08 = 8, + GPIO_EMC_09 = 9, + GPIO_EMC_10 = 10, + GPIO_EMC_11 = 11, + GPIO_EMC_12 = 12, + GPIO_EMC_13 = 13, + GPIO_EMC_14 = 14, + GPIO_EMC_15 = 15, + GPIO_EMC_16 = 16, + GPIO_EMC_17 = 17, + GPIO_EMC_18 = 18, + GPIO_EMC_19 = 19, + GPIO_EMC_20 = 20, + GPIO_EMC_21 = 21, + GPIO_EMC_22 = 22, + GPIO_EMC_23 = 23, + GPIO_EMC_24 = 24, + GPIO_EMC_25 = 25, + GPIO_EMC_26 = 26, + GPIO_EMC_27 = 27, + GPIO_EMC_28 = 28, + GPIO_EMC_29 = 29, + GPIO_EMC_30 = 30, + GPIO_EMC_31 = 31, + GPIO_EMC_32 = 32, + GPIO_EMC_33 = 33, + GPIO_EMC_34 = 34, + GPIO_EMC_35 = 35, + GPIO_EMC_36 = 36, + GPIO_EMC_37 = 37, + GPIO_EMC_38 = 38, + GPIO_EMC_39 = 39, + GPIO_EMC_40 = 40, + GPIO_EMC_41 = 41, + GPIO_AD_B0_00 = 42, + GPIO_AD_B0_01 = 43, + GPIO_AD_B0_02 = 44, + GPIO_AD_B0_03 = 45, + GPIO_AD_B0_04 = 46, + GPIO_AD_B0_05 = 47, + GPIO_AD_B0_06 = 48, + GPIO_AD_B0_07 = 49, + GPIO_AD_B0_08 = 50, + GPIO_AD_B0_09 = 51, + GPIO_AD_B0_10 = 52, + GPIO_AD_B0_11 = 53, + GPIO_AD_B0_12 = 54, + GPIO_AD_B0_13 = 55, + GPIO_AD_B0_14 = 56, + GPIO_AD_B0_15 = 57, + GPIO_AD_B1_00 = 58, + GPIO_AD_B1_01 = 59, + GPIO_AD_B1_02 = 60, + GPIO_AD_B1_03 = 61, + GPIO_AD_B1_04 = 62, + GPIO_AD_B1_05 = 63, + GPIO_AD_B1_06 = 64, + GPIO_AD_B1_07 = 65, + GPIO_AD_B1_08 = 66, + GPIO_AD_B1_09 = 67, + GPIO_AD_B1_10 = 68, + GPIO_AD_B1_11 = 69, + GPIO_AD_B1_12 = 70, + GPIO_AD_B1_13 = 71, + GPIO_AD_B1_14 = 72, + GPIO_AD_B1_15 = 73, + GPIO_B0_00 = 74, + GPIO_B0_01 = 75, + GPIO_B0_02 = 76, + GPIO_B0_03 = 77, + GPIO_B0_04 = 78, + GPIO_B0_05 = 79, + GPIO_B0_06 = 80, + GPIO_B0_07 = 81, + GPIO_B0_08 = 82, + GPIO_B0_09 = 83, + GPIO_B0_10 = 84, + GPIO_B0_11 = 85, + GPIO_B0_12 = 86, + GPIO_B0_13 = 87, + GPIO_B0_14 = 88, + GPIO_B0_15 = 89, + GPIO_B1_00 = 90, + GPIO_B1_01 = 91, + GPIO_B1_02 = 92, + GPIO_B1_03 = 93, + GPIO_B1_04 = 94, + GPIO_B1_05 = 95, + GPIO_B1_06 = 96, + GPIO_B1_07 = 97, + GPIO_B1_08 = 98, + GPIO_B1_09 = 99, + GPIO_B1_10 = 100, + GPIO_B1_11 = 101, + GPIO_B1_12 = 102, + GPIO_B1_13 = 103, + GPIO_B1_14 = 104, + GPIO_B1_15 = 105, + GPIO_SD_B0_00 = 106, + GPIO_SD_B0_01 = 107, + GPIO_SD_B0_02 = 108, + GPIO_SD_B0_03 = 109, + GPIO_SD_B0_04 = 110, + GPIO_SD_B0_05 = 111, + GPIO_SD_B1_00 = 112, + GPIO_SD_B1_01 = 113, + GPIO_SD_B1_02 = 114, + GPIO_SD_B1_03 = 115, + GPIO_SD_B1_04 = 116, + GPIO_SD_B1_05 = 117, + GPIO_SD_B1_06 = 118, + GPIO_SD_B1_07 = 119, + GPIO_SD_B1_08 = 120, + GPIO_SD_B1_09 = 121, + GPIO_SD_B1_10 = 122, + GPIO_SD_B1_11 = 123, +}; + +} + +/* + * GPIO + */ + +namespace GPIO +{ +enum Port { + PortInvalid = 0, + Port1, + Port2, + Port3, + Port4, + Port5, +}; +enum Pin { + Pin0 = 0, + Pin1, + Pin2, + Pin3, + Pin4, + Pin5, + Pin6, + Pin7, + Pin8, + Pin9, + Pin10, + Pin11, + Pin12, + Pin13, + Pin14, + Pin15, + Pin16, + Pin17, + Pin18, + Pin19, + Pin20, + Pin21, + Pin22, + Pin23, + Pin24, + Pin25, + Pin26, + Pin27, + Pin28, + Pin29, + Pin30, + Pin31, +}; +struct GPIOPin { + Port port; + Pin pin; +}; +} + +static inline constexpr uint32_t getGPIOPort(GPIO::Port port) +{ + switch (port) { + case GPIO::Port1: return GPIO_PORT1; + + case GPIO::Port2: return GPIO_PORT2; + + case GPIO::Port3: return GPIO_PORT3; + + case GPIO::Port4: return GPIO_PORT4; + + case GPIO::Port5: return GPIO_PORT5; + + default: break; + } + + return 0; +} + +static inline constexpr uint32_t getGPIOPin(GPIO::Pin pin) +{ + switch (pin) { + case GPIO::Pin0: return GPIO_PIN0; + + case GPIO::Pin1: return GPIO_PIN1; + + case GPIO::Pin2: return GPIO_PIN2; + + case GPIO::Pin3: return GPIO_PIN3; + + case GPIO::Pin4: return GPIO_PIN4; + + case GPIO::Pin5: return GPIO_PIN5; + + case GPIO::Pin6: return GPIO_PIN6; + + case GPIO::Pin7: return GPIO_PIN7; + + case GPIO::Pin8: return GPIO_PIN8; + + case GPIO::Pin9: return GPIO_PIN9; + + case GPIO::Pin10: return GPIO_PIN10; + + case GPIO::Pin11: return GPIO_PIN11; + + case GPIO::Pin12: return GPIO_PIN12; + + case GPIO::Pin13: return GPIO_PIN13; + + case GPIO::Pin14: return GPIO_PIN14; + + case GPIO::Pin15: return GPIO_PIN15; + + case GPIO::Pin16: return GPIO_PIN16; + + case GPIO::Pin17: return GPIO_PIN17; + + case GPIO::Pin18: return GPIO_PIN18; + + case GPIO::Pin19: return GPIO_PIN19; + + case GPIO::Pin20: return GPIO_PIN20; + + case GPIO::Pin21: return GPIO_PIN21; + + case GPIO::Pin22: return GPIO_PIN22; + + case GPIO::Pin23: return GPIO_PIN23; + + case GPIO::Pin24: return GPIO_PIN24; + + case GPIO::Pin25: return GPIO_PIN25; + + case GPIO::Pin26: return GPIO_PIN26; + + case GPIO::Pin27: return GPIO_PIN27; + + case GPIO::Pin28: return GPIO_PIN28; + + case GPIO::Pin29: return GPIO_PIN29; + + case GPIO::Pin30: return GPIO_PIN30; + + case GPIO::Pin31: return GPIO_PIN31; + } + + return 0; +} + +namespace SPI +{ + +enum class Bus { + LPSPI1 = 1, + LPSPI2, + LPSPI3, + LPSPI4, +}; + +using CS = GPIO::GPIOPin; ///< chip-select pin +using DRDY = GPIO::GPIOPin; ///< data ready pin + +struct bus_device_external_cfg_t { + CS cs_gpio; + DRDY drdy_gpio; +}; + +} // namespace SPI diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer.h index 328ac3eddf..613ac1b197 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * Copyright (C) 2018 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,146 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ + +/** + * @file drv_io_timer.h + * + * imxrt-specific PWM output data. + */ +#include +#include +#include + +#include + #pragma once +__BEGIN_DECLS +/* configuration limits */ +#ifdef BOARD_NUM_IO_TIMERS +#define MAX_IO_TIMERS BOARD_NUM_IO_TIMERS +#else +#define MAX_IO_TIMERS 4 +#endif +#define MAX_TIMER_IO_CHANNELS 16 + +#define MAX_LED_TIMERS 2 +#define MAX_TIMER_LED_CHANNELS 6 + +#define IO_TIMER_ALL_MODES_CHANNELS 0 + +typedef enum io_timer_channel_mode_t { + IOTimerChanMode_NotUsed = 0, + IOTimerChanMode_PWMOut = 1, + IOTimerChanMode_PWMIn = 2, + IOTimerChanMode_Capture = 3, + IOTimerChanMode_OneShot = 4, + IOTimerChanMode_Trigger = 5, + IOTimerChanMode_Dshot = 6, + IOTimerChanMode_LED = 7, + IOTimerChanMode_PPS = 8, + IOTimerChanMode_Other = 9, + IOTimerChanModeSize +} io_timer_channel_mode_t; + +typedef uint16_t io_timer_channel_allocation_t; /* big enough to hold MAX_TIMER_IO_CHANNELS */ + +/* array of timers dedicated to PWM in and out and TBD capture use + *** Timers are driven from QTIMER3_OUT0 + *** In PWM mode the timer's prescaler is set to achieve a counter frequency of 1MHz + *** In OneShot mode the timer's prescaler is set to achieve a counter frequency of 8MHz + *** Other prescaler rates can be achieved by fore instance by setting the clock_freq = 1Mhz + *** the resulting PSC will be one and the timer will count at it's clock frequency. + */ +typedef struct io_timers_t { + uint32_t base; /* Base address of the timer */ + uint32_t submodle; /* Which Submodule */ + uint32_t clock_register; /* SIM_SCGCn */ + uint32_t clock_bit; /* SIM_SCGCn bit pos */ + uint32_t vectorno; /* IRQ number */ +} io_timers_t; + +typedef struct io_timers_channel_mapping_element_t { + uint32_t first_channel_index; + uint32_t channel_count; + uint32_t lowest_timer_channel; + uint32_t channel_count_including_gaps; +} io_timers_channel_mapping_element_t; + +/* mapping for each io_timers to timer_io_channels */ +typedef struct io_timers_channel_mapping_t { + io_timers_channel_mapping_element_t element[MAX_IO_TIMERS]; +} io_timers_channel_mapping_t; + +/* array of channels in logical order */ +typedef struct timer_io_channels_t { + uint32_t gpio_out; /* The timer valn_offset GPIO for PWM (this is the IOMUX Pad, e.g. PWM_IOMUX | GPIO_FLEXPWM2_PWMA00_2) */ + uint32_t gpio_in; /* The timer valn_offset GPIO for Capture */ + uint32_t gpio_portpin; /* The GPIO Port + Pin (e.g. GPIO_PORT2 | GPIO_PIN6) */ + uint8_t timer_index; /* 0 based index in the io_timers_t table */ + uint8_t val_offset; /* IMXRT_FLEXPWM_SM0VAL3_OFFSET or IMXRT_FLEXPWM_SM0VAL5_OFFSET */ + uint8_t sub_module; /* 0 based sub module offset */ + uint8_t sub_module_bits; /* LDOK and CLDOK bits */ + uint8_t timer_channel; /* Unused */ +} timer_io_channels_t; + +#define SM0 0 +#define SM1 1 +#define SM2 2 +#define SM3 3 + +#define PWMA_VAL IMXRT_FLEXPWM_SM0VAL3_OFFSET +#define PWMB_VAL IMXRT_FLEXPWM_SM0VAL5_OFFSET -#include "../../../imxrt/include/px4_arch/io_timer.h" +typedef void (*channel_handler_t)(void *context, const io_timers_t *timer, uint32_t chan_index, + const timer_io_channels_t *chan, + hrt_abstime isrs_time, uint16_t isrs_rcnt, + uint16_t capture); + + +/* supplied by board-specific code */ +__EXPORT extern const io_timers_t io_timers[MAX_IO_TIMERS]; +__EXPORT extern const io_timers_channel_mapping_t io_timers_channel_mapping; +__EXPORT extern const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS]; + +__EXPORT extern const io_timers_t led_pwm_timers[MAX_LED_TIMERS]; +__EXPORT extern const timer_io_channels_t led_pwm_channels[MAX_TIMER_LED_CHANNELS]; + +__EXPORT int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode, + channel_handler_t channel_handler, void *context); + +__EXPORT int io_timer_init_timer(unsigned timer, io_timer_channel_mode_t mode); + +__EXPORT int io_timer_set_pwm_rate(unsigned timer, unsigned rate); +__EXPORT int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, + io_timer_channel_allocation_t masks); +__EXPORT uint16_t io_channel_get_ccr(unsigned channel); +__EXPORT int io_timer_set_ccr(unsigned channel, uint16_t value); +__EXPORT uint32_t io_timer_get_group(unsigned timer); +__EXPORT int io_timer_validate_channel_index(unsigned channel); +__EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t mode); +__EXPORT int io_timer_unallocate_channel(unsigned channel); +__EXPORT int io_timer_get_channel_mode(unsigned channel); +__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode); +__EXPORT extern void io_timer_trigger(unsigned channel_mask); + +/** + * Reserve a timer + * @return 0 on success (if not used yet, or already set to the mode) + */ +__EXPORT int io_timer_allocate_timer(unsigned timer, io_timer_channel_mode_t mode); + +__EXPORT int io_timer_unallocate_timer(unsigned timer); + +/** + * Returns the pin configuration for a specific channel, to be used as GPIO output. + * 0 is returned if the channel is not valid. + */ +__EXPORT uint32_t io_timer_channel_get_gpio_output(unsigned channel); +/** + * Returns the pin configuration for a specific channel, to be used as PWM input. + * 0 is returned if the channel is not valid. + */ +__EXPORT uint32_t io_timer_channel_get_as_pwm_input(unsigned channel); + +__END_DECLS diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h index 3d4b6417df..e371b6de83 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h @@ -1,20 +1,20 @@ /**************************************************************************** * - * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * Copyright (C) 2019 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. + * used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -30,7 +30,582 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ + #pragma once -#include "../../../imxrt/include/px4_arch/io_timer_hw_description.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#ifndef CONFIG_ARCH_CHIP_MIMXRT1062DVL6A +# error "This code has only been validated with IMXRT1062. Make sure it is correct before using it on another board." +#endif + + +static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t io_timers_conf[MAX_IO_TIMERS], + PWM::FlexPWMConfig pwm_config, IOMUX::Pad pad) +{ + timer_io_channels_t ret{}; + PWM::FlexPWM pwm{}; + + // FlexPWM Muxing Options + switch (pwm_config.module) { + case PWM::PWM1_PWM_A: + pwm = PWM::FlexPWM1; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_23) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_23_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN23; + + } else if (pad == IOMUX::Pad::GPIO_SD_B0_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_00_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN12; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_25) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_25_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN25; + + } else if (pad == IOMUX::Pad::GPIO_SD_B0_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_02_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN14; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_27) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_27_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN27; + + } else if (pad == IOMUX::Pad::GPIO_SD_B0_04) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_04_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN16; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_38) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_38_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN24; + + } else if (pad == IOMUX::Pad::GPIO_SD_B1_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_00_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN0; + + } else if (pad == IOMUX::Pad::GPIO_AD_B0_10) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_10_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN10; + + } else if (pad == IOMUX::Pad::GPIO_EMC_12) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_12_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN12; + + } else if (pad == IOMUX::Pad::GPIO_B1_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_00_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN16; + } + + break; + } + + break; + + case PWM::PWM1_PWM_B: + pwm = PWM::FlexPWM1; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_24) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_24_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN24; + + } else if (pad == IOMUX::Pad::GPIO_SD_B0_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_01_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN13; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_26) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_26_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN26; + + } else if (pad == IOMUX::Pad::GPIO_SD_B0_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_03_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN15; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_28) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_28_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN28; + + } else if (pad == IOMUX::Pad::GPIO_SD_B0_05) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_05_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN17; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_39) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_39_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN25; + + } else if (pad == IOMUX::Pad::GPIO_SD_B1_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_01_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN1; + + } else if (pad == IOMUX::Pad::GPIO_AD_B0_11) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_11_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN11; + + } else if (pad == IOMUX::Pad::GPIO_EMC_13) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_13_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN13; + + } else if (pad == IOMUX::Pad::GPIO_B1_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_01_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN17; + } + + break; + } + + break; + + case PWM::PWM1_PWM_X: + pwm = PWM::FlexPWM1; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_AD_B0_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_02_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN2; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_AD_B0_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_03_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN3; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_AD_B0_12) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_12_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN12; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_AD_B0_13) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_13_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN13; + } + + break; + } + + break; + + + case PWM::PWM2_PWM_A: + pwm = PWM::FlexPWM2; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_B0_06) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_06_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN6; + + } else if (pad == IOMUX::Pad::GPIO_EMC_06) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_06_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN6; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_08) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_08_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN8; + + } else if (pad == IOMUX::Pad::GPIO_B0_08) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_08_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN8; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_10) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_10_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN10; + + } else if (pad == IOMUX::Pad::GPIO_B0_10) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_10_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN10; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_AD_B0_09) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_09_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN9; + + } else if (pad == IOMUX::Pad::GPIO_SD_B1_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_02_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN2; + + } else if (pad == IOMUX::Pad::GPIO_EMC_19) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_19_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN19; + + } else if (pad == IOMUX::Pad::GPIO_B1_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_02_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN18; + + } else if (pad == IOMUX::Pad::GPIO_AD_B0_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_00_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN0; + } + + break; + } + + break; + + case PWM::PWM2_PWM_B: + pwm = PWM::FlexPWM2; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_B0_07) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_07_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN6; + + } else if (pad == IOMUX::Pad::GPIO_EMC_07) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_07_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN6; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_09) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_09_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN8; + + } else if (pad == IOMUX::Pad::GPIO_B0_09) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_09_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN8; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_11) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_11_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN10; + + } else if (pad == IOMUX::Pad::GPIO_B0_11) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B0_11_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN10; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_AD_B0_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_01_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN1; + + } else if (pad == IOMUX::Pad::GPIO_SD_B1_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B1_03_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN3; + + } else if (pad == IOMUX::Pad::GPIO_EMC_20) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_20_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN20; + + } else if (pad == IOMUX::Pad::GPIO_B1_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_03_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN19; + } + + break; + } + + break; + + + case PWM::PWM3_PWM_A: + pwm = PWM::FlexPWM3; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_29) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_29_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN29; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_31) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_31_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN31; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_33) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_33_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN19; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_21) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_21_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN21; + } + + break; + } + + break; + + case PWM::PWM3_PWM_B: + pwm = PWM::FlexPWM3; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_30) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_30_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN30; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_32) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_32_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN18; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_34) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_34_INDEX); + ret.gpio_portpin = GPIO_PORT3 | GPIO_PIN20; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_22) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_22_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN22; + } + + break; + } + + break; + + + case PWM::PWM4_PWM_A: + pwm = PWM::FlexPWM4; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_AD_B1_08) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B1_08_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN24; + + } else if (pad == IOMUX::Pad::GPIO_EMC_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_00_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN0; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_02_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN2; + + } else if (pad == IOMUX::Pad::GPIO_AD_B1_09) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B1_09_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN25; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_04) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_04_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN4; + + } else if (pad == IOMUX::Pad::GPIO_B1_14) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_14_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN30; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_17) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_17_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN17; + + } else if (pad == IOMUX::Pad::GPIO_B1_15) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_15_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN31; + } + + break; + } + + break; + + case PWM::PWM4_PWM_B: + pwm = PWM::FlexPWM4; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_01_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN1; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_03_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN3; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_05) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_05_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN5; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_18) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_18_INDEX); + ret.gpio_portpin = GPIO_PORT4 | GPIO_PIN18; + } + + break; + } + + break; + } + + constexpr_assert(ret.gpio_out != 0, "Invalid PWM/Pad config"); + ret.gpio_out |= IOMUX_CMOS_OUTPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_50OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST; + + switch (pwm_config.module) { + case PWM::PWM1_PWM_A: + case PWM::PWM2_PWM_A: + case PWM::PWM3_PWM_A: + case PWM::PWM4_PWM_A: + ret.val_offset = PWMA_VAL; + break; + + case PWM::PWM1_PWM_B: + case PWM::PWM2_PWM_B: + case PWM::PWM3_PWM_B: + case PWM::PWM4_PWM_B: + ret.val_offset = PWMB_VAL; + break; + + default: + constexpr_assert(false, "not implemented"); + } + + switch (pwm_config.submodule) { + case PWM::Submodule0: + ret.sub_module = SM0; + ret.sub_module_bits = MCTRL_LDOK(1 << SM0); + break; + + case PWM::Submodule1: + ret.sub_module = SM1; + ret.sub_module_bits = MCTRL_LDOK(1 << SM1); + break; + + case PWM::Submodule2: + ret.sub_module = SM2; + ret.sub_module_bits = MCTRL_LDOK(1 << SM2); + break; + + case PWM::Submodule3: + ret.sub_module = SM3; + ret.sub_module_bits = MCTRL_LDOK(1 << SM3); + break; + } + + ret.gpio_in = 0; // TODO (not used yet) + + // find timer index + ret.timer_index = 0xff; + const uint32_t timer_base = getFlexPWMBaseRegister(pwm); + + for (int i = 0; i < MAX_IO_TIMERS; ++i) { + if (io_timers_conf[i].base == timer_base && io_timers_conf[i].submodle == ret.sub_module) { + ret.timer_index = i; + break; + } + } + + constexpr_assert(ret.timer_index != 0xff, "Timer not found"); + + return ret; +} + +static inline constexpr io_timers_t initIOPWM(PWM::FlexPWM pwm, PWM::FlexPWMSubmodule sub) +{ + io_timers_t ret{}; + + ret.base = getFlexPWMBaseRegister(pwm); + ret.submodle = sub; + return ret; +} diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h index b736695d85..de0c30247d 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h @@ -1,20 +1,20 @@ /**************************************************************************** * - * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * Copyright (C) 2020 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. + * used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -30,11 +30,113 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ + #pragma once +#include +#include + #if defined(CONFIG_SPI) -#include "../../../imxrt/include/px4_arch/spi_hw_description.h" +#include + +#define CS_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_UP_100K | IOMUX_DRIVE_33OHM | IOMUX_SPEED_LOW | IOMUX_SLEW_FAST) + +#define DRDY_IOMUX (IOMUX_SCHMITT_TRIGGER | IOMUX_PULL_UP_47K | IOMUX_DRIVE_HIZ) + +#define GENERAL_OUTPUT_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST) + +static inline constexpr px4_spi_bus_device_t initSPIDevice(uint32_t devid, SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) +{ + px4_spi_bus_device_t ret{}; + ret.cs_gpio = getGPIOPort(cs_gpio.port) | getGPIOPin(cs_gpio.pin) | (GPIO_OUTPUT | GPIO_OUTPUT_ONE | CS_IOMUX); + + if (drdy_gpio.port != GPIO::PortInvalid) { + ret.drdy_gpio = getGPIOPort(drdy_gpio.port) | getGPIOPin(drdy_gpio.pin) | (GPIO_INPUT | DRDY_IOMUX); + } + + if (PX4_SPIDEVID_TYPE(devid) == 0) { // it's a PX4 device (internal or external) + ret.devid = PX4_SPIDEV_ID(PX4_SPI_DEVICE_ID, devid); + + } else { // it's a NuttX device (e.g. SPIDEV_FLASH(0)) + ret.devid = devid; + } + + ret.devtype_driver = PX4_SPI_DEV_ID(devid); + return ret; +} + +static inline constexpr px4_spi_bus_t initSPIBus(SPI::Bus bus, const px4_spi_bus_devices_t &devices, + GPIO::GPIOPin power_enable = {}) +{ + px4_spi_bus_t ret{}; + ret.requires_locking = false; + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + ret.devices[i] = devices.devices[i]; + + + if (ret.devices[i].cs_gpio != 0) { + if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + int same_devices_count = 0; + + for (int j = 0; j < i; ++j) { + if (ret.devices[j].cs_gpio != 0) { + same_devices_count += (ret.devices[i].devid & 0xff) == (ret.devices[j].devid & 0xff); + } + } + + // increment the 2. LSB byte to allow multiple devices of the same type + ret.devices[i].devid |= same_devices_count << 8; + + } else { + // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) + ret.requires_locking = true; + } + } + } + + ret.bus = (int)bus; + ret.is_external = false; + + if (power_enable.port != GPIO::PortInvalid) { + ret.power_enable_gpio = getGPIOPort(power_enable.port) | getGPIOPin(power_enable.pin) | + (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GENERAL_OUTPUT_IOMUX); + } + + return ret; +} + +// just a wrapper since we cannot pass brace-enclosed initialized arrays directly as arguments +struct bus_device_external_cfg_array_t { + SPI::bus_device_external_cfg_t devices[SPI_BUS_MAX_DEVICES]; +}; + +static inline constexpr px4_spi_bus_t initSPIBusExternal(SPI::Bus bus, const bus_device_external_cfg_array_t &devices) +{ + px4_spi_bus_t ret{}; + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + if (devices.devices[i].cs_gpio.port == GPIO::PortInvalid) { + break; + } + + ret.devices[i] = initSPIDevice(i, devices.devices[i].cs_gpio, devices.devices[i].drdy_gpio); + } + + ret.bus = (int)bus; + ret.is_external = true; + ret.requires_locking = false; // external buses are never accessed by NuttX drivers + return ret; +} + +static inline constexpr SPI::bus_device_external_cfg_t initSPIConfigExternal(SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) +{ + SPI::bus_device_external_cfg_t ret{}; + ret.cs_gpio = cs_gpio; + ret.drdy_gpio = drdy_gpio; + return ret; +} constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS]) { diff --git a/platforms/nuttx/src/px4/nxp/rt117x/CMakeLists.txt b/platforms/nuttx/src/px4/nxp/rt117x/CMakeLists.txt index 8f14a4cde5..91224642dc 100644 --- a/platforms/nuttx/src/px4/nxp/rt117x/CMakeLists.txt +++ b/platforms/nuttx/src/px4/nxp/rt117x/CMakeLists.txt @@ -32,13 +32,13 @@ ############################################################################ -#add_subdirectory(../imxrt/adc adc) +add_subdirectory(adc) add_subdirectory(../imxrt/board_critmon board_critmon) add_subdirectory(../imxrt/board_hw_info board_hw_info) add_subdirectory(../imxrt/board_reset board_reset) #add_subdirectory(../imxrt/dshot dshot) add_subdirectory(../imxrt/hrt hrt) add_subdirectory(../imxrt/led_pwm led_pwm) -add_subdirectory(../imxrt/io_pins io_pins) +add_subdirectory(io_pins) #add_subdirectory(../imxrt/tone_alarm tone_alarm) add_subdirectory(../imxrt/version version) diff --git a/platforms/nuttx/src/px4/nxp/rt117x/adc/CMakeLists.txt b/platforms/nuttx/src/px4/nxp/rt117x/adc/CMakeLists.txt new file mode 100644 index 0000000000..9f0d432ba0 --- /dev/null +++ b/platforms/nuttx/src/px4/nxp/rt117x/adc/CMakeLists.txt @@ -0,0 +1,36 @@ +############################################################################ +# +# Copyright (c) 2023 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(arch_adc + adc.cpp +) diff --git a/platforms/nuttx/src/px4/nxp/rt117x/adc/adc.cpp b/platforms/nuttx/src/px4/nxp/rt117x/adc/adc.cpp new file mode 100644 index 0000000000..273821849e --- /dev/null +++ b/platforms/nuttx/src/px4/nxp/rt117x/adc/adc.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** + * + * Copyright (C) 2023 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file adc.cpp + * + * Driver for the imxrt ADC. + * + * This is a low-rate driver, designed for sampling things like voltages + * and so forth. It avoids the gross complexity of the NuttX ADC driver. + */ + +#include +#include +#include +#include +#include + +#include +#include + +typedef uint32_t adc_chan_t; +#define ADC_TOTAL_CHANNELS 16 + +#define _REG(_addr) (*(volatile uint32_t *)(_addr)) + +/* ADC register accessors */ + +#define REG(base_address, _reg) _REG((base_address) + (_reg)) + +#define rVERID(base_address) REG(base_address, IMXRT_LPADC_VERID_OFFSET) /* Version ID Register */ +#define rPARAM(base_address) REG(base_address, IMXRT_LPADC_PARAM_OFFSET) /* Parameter Register */ +#define rCTRL(base_address) REG(base_address, IMXRT_LPADC_CTRL_OFFSET) /* LPADC Control Register */ +#define rSTAT(base_address) REG(base_address, IMXRT_LPADC_STAT_OFFSET) /* LPADC Status Register */ +#define rIE(base_address) REG(base_address, IMXRT_LPADC_IE_OFFSET) /* Interrupt Enable Register */ +#define rDE(base_address) REG(base_address, IMXRT_LPADC_DE_OFFSET) /* DMA Enable Register */ +#define rCFG(base_address) REG(base_address, IMXRT_LPADC_CFG_OFFSET) /* LPADC Configuration Register */ +#define rPAUSE(base_address) REG(base_address, IMXRT_LPADC_PAUSE_OFFSET) /* LPADC Pause Register */ +#define rFCTRL(base_address) REG(base_address, IMXRT_LPADC_FCTRL_OFFSET) /* LPADC FIFO Control Register */ +#define rSWTRIG(base_address) REG(base_address, IMXRT_LPADC_SWTRIG_OFFSET) /* Software Trigger Register */ +#define rCMDL1(base_address) REG(base_address, IMXRT_LPADC_CMDL1_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH1(base_address) REG(base_address, IMXRT_LPADC_CMDH1_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL2(base_address) REG(base_address, IMXRT_LPADC_CMDL2_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH2(base_address) REG(base_address, IMXRT_LPADC_CMDH2_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL3(base_address) REG(base_address, IMXRT_LPADC_CMDL3_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH3(base_address) REG(base_address, IMXRT_LPADC_CMDH3_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL4(base_address) REG(base_address, IMXRT_LPADC_CMDL4_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH4(base_address) REG(base_address, IMXRT_LPADC_CMDH4_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL5(base_address) REG(base_address, IMXRT_LPADC_CMDL5_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH5(base_address) REG(base_address, IMXRT_LPADC_CMDH5_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL6(base_address) REG(base_address, IMXRT_LPADC_CMDL6_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH6(base_address) REG(base_address, IMXRT_LPADC_CMDH6_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL7(base_address) REG(base_address, IMXRT_LPADC_CMDL7_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH7(base_address) REG(base_address, IMXRT_LPADC_CMDH7_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL8(base_address) REG(base_address, IMXRT_LPADC_CMDL8_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH8(base_address) REG(base_address, IMXRT_LPADC_CMDH8_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL9(base_address) REG(base_address, IMXRT_LPADC_CMDL9_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH9(base_address) REG(base_address, IMXRT_LPADC_CMDH9_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL10(base_address) REG(base_address, IMXRT_LPADC_CMDL10_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH10(base_address) REG(base_address, IMXRT_LPADC_CMDH10_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL11(base_address) REG(base_address, IMXRT_LPADC_CMDL11_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH11(base_address) REG(base_address, IMXRT_LPADC_CMDH11_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL12(base_address) REG(base_address, IMXRT_LPADC_CMDL12_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH12(base_address) REG(base_address, IMXRT_LPADC_CMDH12_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL13(base_address) REG(base_address, IMXRT_LPADC_CMDL13_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH13(base_address) REG(base_address, IMXRT_LPADC_CMDH13_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL14(base_address) REG(base_address, IMXRT_LPADC_CMDL14_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH14(base_address) REG(base_address, IMXRT_LPADC_CMDH14_OFFSET) /* LPADC Command High Buffer Register */ +#define rCMDL15(base_address) REG(base_address, IMXRT_LPADC_CMDL15_OFFSET) /* LPADC Command Low Buffer Register */ +#define rCMDH15(base_address) REG(base_address, IMXRT_LPADC_CMDH15_OFFSET) /* LPADC Command High Buffer Register */ +#define rRESFIFO(base_address) REG(base_address, IMXRT_LPADC_RESFIFO_OFFSET) /* LPADC Data Result FIFO Register */ +#define rTCTRL0(base_address) REG(base_address, IMXRT_LPADC_TCTRL0_OFFSET) /* Trigger Control Register */ +#define rTCTRL1(base_address) REG(base_address, IMXRT_LPADC_TCTRL1_OFFSET) /* Trigger Control Register */ +#define rTCTRL2(base_address) REG(base_address, IMXRT_LPADC_TCTRL2_OFFSET) /* Trigger Control Register */ +#define rTCTRL3(base_address) REG(base_address, IMXRT_LPADC_TCTRL3_OFFSET) /* Trigger Control Register */ +#define rTCTRL4(base_address) REG(base_address, IMXRT_LPADC_TCTRL4_OFFSET) /* Trigger Control Register */ +#define rTCTRL5(base_address) REG(base_address, IMXRT_LPADC_TCTRL5_OFFSET) /* Trigger Control Register */ +#define rTCTRL6(base_address) REG(base_address, IMXRT_LPADC_TCTRL6_OFFSET) /* Trigger Control Register */ +#define rTCTRL7(base_address) REG(base_address, IMXRT_LPADC_TCTRL7_OFFSET) /* Trigger Control Register */ +#define rCV1(base_address) REG(base_address, IMXRT_LPADC_CV1_OFFSET) /* Compare Value Register */ +#define rCV2(base_address) REG(base_address, IMXRT_LPADC_CV2_OFFSET) /* Compare Value Register */ +#define rCV3(base_address) REG(base_address, IMXRT_LPADC_CV3_OFFSET) /* Compare Value Register */ +#define rCV4(base_address) REG(base_address, IMXRT_LPADC_CV4_OFFSET) /* Compare Value Register */ + +int px4_arch_adc_init(uint32_t base_address) +{ + static bool once = false; + + if (!once) { + + once = true; + + /* Input is ADCx_CLK_ROOT_SYS_PLL2_CLK with devide by 6. + * 528 Mhz / 6 = 88 Mhz. + */ + + + if (base_address == IMXRT_LPADC1_BASE) { + imxrt_clockall_adc1(); + + } else if (base_address == IMXRT_LPADC2_BASE) { + imxrt_clockall_adc2(); + } + + + irqstate_t flags = px4_enter_critical_section(); + rCTRL(base_address) |= IMXRT_LPADC_CTRL_RST; + rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_RST; + rCTRL(base_address) |= IMXRT_LPADC_CTRL_RSTFIFO; + rCFG(base_address) = IMXRT_LPADC_CFG_REFSEL_REFSEL_0 | IMXRT_LPADC_CFG_PWREN | IMXRT_LPADC_CFG_PWRSEL_PWRSEL_3 | + IMXRT_LPADC_CFG_PUDLY(128); + rCTRL(base_address) = IMXRT_LPADC_CTRL_ADCEN; + + px4_leave_critical_section(flags); + + /* Read ADC1 vtemp_sensor_plus */ + + rCMDL1(base_address) = IMXRT_LPADC_CMDL1_ADCH_ADCH_7; + + rCMDH1(base_address) = IMXRT_LPADC_CMDH1_STS_STS_7 | IMXRT_LPADC_CMDH1_AVGS_AVGS_0; + rTCTRL0(base_address) = IMXRT_LPADC_TCTRL0_TCMD_TCMD_1; + rSTAT(base_address) = IMXRT_LPADC_STAT_FOF; + + /* kick off a sample and wait for it to complete */ + hrt_abstime now = hrt_absolute_time(); + + rSWTRIG(base_address) = IMXRT_LPADC_SWTRIG_SWT0; + + while (!(rSTAT(base_address) & IMXRT_LPADC_STAT_RDY)) { + + /* don't wait for more than 100us, since that means something broke - + * should reset here if we see this + */ + + if ((hrt_absolute_time() - now) > 100) { + rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN; + return -4; + } + } + + int32_t r = (rRESFIFO(base_address) & IMXRT_LPADC_RESFIFO_D_MASK) >> 3; + UNUSED(r); + rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN; + } // once + + return 0; +} + +void px4_arch_adc_uninit(uint32_t base_address) +{ + rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN; + + if (base_address == IMXRT_LPADC1_BASE) { + imxrt_clockoff_adc1(); + + } else if (base_address == IMXRT_LPADC2_BASE) { + imxrt_clockoff_adc2(); + } +} + +uint32_t px4_arch_adc_sample(uint32_t base_address, unsigned channel) +{ + + uint32_t absel = (channel & 1) ? IMXRT_LPADC_CMDL1_ABSEL : 0; + channel >>= 1; + + irqstate_t flags = px4_enter_critical_section(); + + /* clear any previous results */ + + rCTRL(base_address) |= IMXRT_LPADC_CTRL_RSTFIFO; + + rCMDL1(base_address) = absel | (channel & IMXRT_LPADC_CMDL1_ADCH_MASK); + rCMDH1(base_address) = IMXRT_LPADC_CMDH1_STS_STS_7 | IMXRT_LPADC_CMDH1_AVGS_AVGS_0; + rTCTRL0(base_address) = IMXRT_LPADC_TCTRL0_TCMD_TCMD_1; + rSTAT(base_address) = IMXRT_LPADC_STAT_FOF; + rCTRL(base_address) = IMXRT_LPADC_CTRL_ADCEN; + + up_udelay(1); + rSWTRIG(base_address) = IMXRT_LPADC_SWTRIG_SWT0; + + /* wait for the conversion to complete */ + hrt_abstime now = hrt_absolute_time(); + + while (!(rSTAT(base_address) & IMXRT_LPADC_STAT_RDY)) { + /* don't wait for more than 30us, since that means something broke + * should reset here if we see this + */ + if ((hrt_absolute_time() - now) > 30) { + rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN; + px4_leave_critical_section(flags); + return UINT32_MAX; + } + } + + /* read the result and clear COCO0 */ + + uint32_t result = (rRESFIFO(base_address) & IMXRT_LPADC_RESFIFO_D_MASK) >> 3; + rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN; + px4_leave_critical_section(flags); + + return result; +} + +float px4_arch_adc_reference_v() +{ + return BOARD_ADC_POS_REF_V; +} + +uint32_t px4_arch_adc_temp_sensor_mask() +{ + return 0; +} + +uint32_t px4_arch_adc_dn_fullcount(void) +{ + return 1 << 12; // 12 bit ADC +} diff --git a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/adc.h b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/adc.h index f9da7fb8f5..d43ba990e1 100644 --- a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/adc.h +++ b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/adc.h @@ -32,4 +32,14 @@ ****************************************************************************/ #pragma once -#include "../../../imxrt/include/px4_arch/adc.h" +#include + +#if !defined(HW_REV_VER_ADC_BASE) +# define HW_REV_VER_ADC_BASE IMXRT_LPADC1_BASE +#endif + +#if !defined(SYSTEM_ADC_BASE) +# define SYSTEM_ADC_BASE IMXRT_LPADC1_BASE +#endif + +#include diff --git a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/hw_description.h b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/hw_description.h index e7676690b9..71a492b161 100644 --- a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/hw_description.h @@ -1,20 +1,20 @@ /**************************************************************************** * - * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * Copyright (C) 2023 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. + * used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -30,7 +30,446 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ + #pragma once -#include "../../../imxrt/include/px4_arch/hw_description.h" +#include + +#include "hardware/imxrt_flexpwm.h" + +#include + +#include +#if !defined(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA) +# error "This code has only been validated with IMXRT1176. Make sure it is correct before using it on another board." +#endif + +/* + * PWM + */ + +namespace PWM +{ +enum FlexPWM { + FlexPWM1 = 0, + FlexPWM2, + FlexPWM3, + FlexPWM4, +}; + +enum FlexPWMModule { + PWM1_PWM_A = 0, + PWM1_PWM_B, + PWM1_PWM_X, + + PWM2_PWM_A, + PWM2_PWM_B, + PWM2_PWM_X, + + PWM3_PWM_A, + PWM3_PWM_B, + PWM3_PWM_X, + + PWM4_PWM_A, + PWM4_PWM_B, + PWM4_PWM_X, +}; + +enum FlexPWMSubmodule { + Submodule0 = 0, + Submodule1, + Submodule2, + Submodule3, +}; + +struct FlexPWMConfig { + FlexPWMModule module; + FlexPWMSubmodule submodule; +}; +} + +static inline constexpr uint32_t getFlexPWMBaseRegister(PWM::FlexPWM pwm) +{ + switch (pwm) { + case PWM::FlexPWM1: return IMXRT_FLEXPWM1_BASE; + + case PWM::FlexPWM2: return IMXRT_FLEXPWM2_BASE; + + case PWM::FlexPWM3: return IMXRT_FLEXPWM3_BASE; + + case PWM::FlexPWM4: return IMXRT_FLEXPWM4_BASE; + } + + return 0; +} +namespace IOMUX +{ +enum class Pad { + GPIO_EMC_B1_00 = 0, + GPIO_EMC_B1_01 = 1, + GPIO_EMC_B1_02 = 2, + GPIO_EMC_B1_03 = 3, + GPIO_EMC_B1_04 = 4, + GPIO_EMC_B1_05 = 5, + GPIO_EMC_B1_06 = 6, + GPIO_EMC_B1_07 = 7, + GPIO_EMC_B1_08 = 8, + GPIO_EMC_B1_09 = 9, + GPIO_EMC_B1_10 = 10, + GPIO_EMC_B1_11 = 11, + GPIO_EMC_B1_12 = 12, + GPIO_EMC_B1_13 = 13, + GPIO_EMC_B1_14 = 14, + GPIO_EMC_B1_15 = 15, + GPIO_EMC_B1_16 = 16, + GPIO_EMC_B1_17 = 17, + GPIO_EMC_B1_18 = 18, + GPIO_EMC_B1_19 = 19, + GPIO_EMC_B1_20 = 20, + GPIO_EMC_B1_21 = 21, + GPIO_EMC_B1_22 = 22, + GPIO_EMC_B1_23 = 23, + GPIO_EMC_B1_24 = 24, + GPIO_EMC_B1_25 = 25, + GPIO_EMC_B1_26 = 26, + GPIO_EMC_B1_27 = 27, + GPIO_EMC_B1_28 = 28, + GPIO_EMC_B1_29 = 29, + GPIO_EMC_B1_30 = 30, + GPIO_EMC_B1_31 = 31, + GPIO_EMC_B1_32 = 32, + GPIO_EMC_B1_33 = 33, + GPIO_EMC_B1_34 = 34, + GPIO_EMC_B1_35 = 35, + GPIO_EMC_B1_36 = 36, + GPIO_EMC_B1_37 = 37, + GPIO_EMC_B1_38 = 38, + GPIO_EMC_B1_39 = 39, + GPIO_EMC_B1_40 = 40, + GPIO_EMC_B1_41 = 41, + GPIO_EMC_B2_00 = 42, + GPIO_EMC_B2_01 = 43, + GPIO_EMC_B2_02 = 44, + GPIO_EMC_B2_03 = 45, + GPIO_EMC_B2_04 = 46, + GPIO_EMC_B2_05 = 47, + GPIO_EMC_B2_06 = 48, + GPIO_EMC_B2_07 = 49, + GPIO_EMC_B2_08 = 50, + GPIO_EMC_B2_09 = 51, + GPIO_EMC_B2_10 = 52, + GPIO_EMC_B2_11 = 53, + GPIO_EMC_B2_12 = 54, + GPIO_EMC_B2_13 = 55, + GPIO_EMC_B2_14 = 56, + GPIO_EMC_B2_15 = 57, + GPIO_EMC_B2_16 = 58, + GPIO_EMC_B2_17 = 59, + GPIO_EMC_B2_18 = 60, + GPIO_EMC_B2_19 = 61, + GPIO_EMC_B2_20 = 62, + GPIO_AD_00 = 63, + GPIO_AD_01 = 64, + GPIO_AD_02 = 65, + GPIO_AD_03 = 66, + GPIO_AD_04 = 67, + GPIO_AD_05 = 68, + GPIO_AD_06 = 69, + GPIO_AD_07 = 70, + GPIO_AD_08 = 71, + GPIO_AD_09 = 72, + GPIO_AD_10 = 73, + GPIO_AD_11 = 74, + GPIO_AD_12 = 75, + GPIO_AD_13 = 76, + GPIO_AD_14 = 77, + GPIO_AD_15 = 78, + GPIO_AD_16 = 79, + GPIO_AD_17 = 80, + GPIO_AD_18 = 81, + GPIO_AD_19 = 82, + GPIO_AD_20 = 83, + GPIO_AD_21 = 84, + GPIO_AD_22 = 85, + GPIO_AD_23 = 86, + GPIO_AD_24 = 87, + GPIO_AD_25 = 88, + GPIO_AD_26 = 89, + GPIO_AD_27 = 90, + GPIO_AD_28 = 91, + GPIO_AD_29 = 92, + GPIO_AD_30 = 93, + GPIO_AD_31 = 94, + GPIO_AD_32 = 95, + GPIO_AD_33 = 96, + GPIO_AD_34 = 97, + GPIO_AD_35 = 98, + GPIO_SD_B1_00 = 99, + GPIO_SD_B1_01 = 100, + GPIO_SD_B1_02 = 101, + GPIO_SD_B1_03 = 102, + GPIO_SD_B1_04 = 103, + GPIO_SD_B1_05 = 104, + GPIO_SD_B2_00 = 105, + GPIO_SD_B2_01 = 106, + GPIO_SD_B2_02 = 107, + GPIO_SD_B2_03 = 108, + GPIO_SD_B2_04 = 109, + GPIO_SD_B2_05 = 110, + GPIO_SD_B2_06 = 111, + GPIO_SD_B2_07 = 112, + GPIO_SD_B2_08 = 113, + GPIO_SD_B2_09 = 114, + GPIO_SD_B2_10 = 115, + GPIO_SD_B2_11 = 116, + GPIO_DISP_B1_00 = 117, + GPIO_DISP_B1_01 = 118, + GPIO_DISP_B1_02 = 119, + GPIO_DISP_B1_03 = 120, + GPIO_DISP_B1_04 = 121, + GPIO_DISP_B1_05 = 122, + GPIO_DISP_B1_06 = 123, + GPIO_DISP_B1_07 = 124, + GPIO_DISP_B1_08 = 125, + GPIO_DISP_B1_09 = 126, + GPIO_DISP_B1_10 = 127, + GPIO_DISP_B1_11 = 128, + GPIO_DISP_B2_00 = 129, + GPIO_DISP_B2_01 = 130, + GPIO_DISP_B2_02 = 131, + GPIO_DISP_B2_03 = 132, + GPIO_DISP_B2_04 = 133, + GPIO_DISP_B2_05 = 134, + GPIO_DISP_B2_06 = 135, + GPIO_DISP_B2_07 = 136, + GPIO_DISP_B2_08 = 137, + GPIO_DISP_B2_09 = 138, + GPIO_DISP_B2_10 = 139, + GPIO_DISP_B2_11 = 140, + GPIO_DISP_B2_12 = 141, + GPIO_DISP_B2_13 = 142, + GPIO_DISP_B2_14 = 143, + GPIO_DISP_B2_15 = 144, + WAKEUP = 145, + PMIC_ON_REQ = 146, + PMIC_STBY_REQ = 147, + GPIO_SNVS_00 = 148, + GPIO_SNVS_01 = 149, + GPIO_SNVS_02 = 150, + GPIO_SNVS_03 = 151, + GPIO_SNVS_04 = 152, + GPIO_SNVS_05 = 153, + GPIO_SNVS_06 = 154, + GPIO_SNVS_07 = 155, + GPIO_SNVS_08 = 156, + GPIO_SNVS_09 = 157, + GPIO_LPSR_00 = 158, + GPIO_LPSR_01 = 159, + GPIO_LPSR_02 = 160, + GPIO_LPSR_03 = 161, + GPIO_LPSR_04 = 162, + GPIO_LPSR_05 = 163, + GPIO_LPSR_06 = 164, + GPIO_LPSR_07 = 165, + GPIO_LPSR_08 = 166, + GPIO_LPSR_09 = 167, + GPIO_LPSR_10 = 168, + GPIO_LPSR_11 = 169, + GPIO_LPSR_12 = 170, + GPIO_LPSR_13 = 171, + GPIO_LPSR_14 = 172, + GPIO_LPSR_15 = 173 +}; + +} + +/* + * GPIO + */ + +namespace GPIO +{ +enum Port { + PortInvalid = 0, + Port1, + Port2, + Port3, + Port4, + Port5, + Port6, + Port7, + Port8, + Port9, + Port10, + Port11, + Port12, + Port13, +}; +enum Pin { + Pin0 = 0, + Pin1, + Pin2, + Pin3, + Pin4, + Pin5, + Pin6, + Pin7, + Pin8, + Pin9, + Pin10, + Pin11, + Pin12, + Pin13, + Pin14, + Pin15, + Pin16, + Pin17, + Pin18, + Pin19, + Pin20, + Pin21, + Pin22, + Pin23, + Pin24, + Pin25, + Pin26, + Pin27, + Pin28, + Pin29, + Pin30, + Pin31, +}; +struct GPIOPin { + Port port; + Pin pin; +}; +} + +static inline constexpr uint32_t getGPIOPort(GPIO::Port port) +{ + switch (port) { + case GPIO::Port1: return GPIO_PORT1; + + case GPIO::Port2: return GPIO_PORT2; + + case GPIO::Port3: return GPIO_PORT3; + + case GPIO::Port4: return GPIO_PORT4; + + case GPIO::Port5: return GPIO_PORT5; + + case GPIO::Port6: return GPIO_PORT6; + + case GPIO::Port7: return GPIO_PORT7; + + case GPIO::Port8: return GPIO_PORT8; + + case GPIO::Port9: return GPIO_PORT9; + + case GPIO::Port10: return GPIO_PORT10; + + case GPIO::Port11: return GPIO_PORT11; + + case GPIO::Port12: return GPIO_PORT12; + + case GPIO::Port13: return GPIO_PORT13; + + default: break; + } + + return 0; +} + +static inline constexpr uint32_t getGPIOPin(GPIO::Pin pin) +{ + switch (pin) { + case GPIO::Pin0: return GPIO_PIN0; + + case GPIO::Pin1: return GPIO_PIN1; + + case GPIO::Pin2: return GPIO_PIN2; + + case GPIO::Pin3: return GPIO_PIN3; + + case GPIO::Pin4: return GPIO_PIN4; + + case GPIO::Pin5: return GPIO_PIN5; + + case GPIO::Pin6: return GPIO_PIN6; + + case GPIO::Pin7: return GPIO_PIN7; + + case GPIO::Pin8: return GPIO_PIN8; + + case GPIO::Pin9: return GPIO_PIN9; + + case GPIO::Pin10: return GPIO_PIN10; + + case GPIO::Pin11: return GPIO_PIN11; + + case GPIO::Pin12: return GPIO_PIN12; + + case GPIO::Pin13: return GPIO_PIN13; + + case GPIO::Pin14: return GPIO_PIN14; + + case GPIO::Pin15: return GPIO_PIN15; + + case GPIO::Pin16: return GPIO_PIN16; + + case GPIO::Pin17: return GPIO_PIN17; + + case GPIO::Pin18: return GPIO_PIN18; + + case GPIO::Pin19: return GPIO_PIN19; + + case GPIO::Pin20: return GPIO_PIN20; + + case GPIO::Pin21: return GPIO_PIN21; + + case GPIO::Pin22: return GPIO_PIN22; + + case GPIO::Pin23: return GPIO_PIN23; + + case GPIO::Pin24: return GPIO_PIN24; + + case GPIO::Pin25: return GPIO_PIN25; + + case GPIO::Pin26: return GPIO_PIN26; + + case GPIO::Pin27: return GPIO_PIN27; + + case GPIO::Pin28: return GPIO_PIN28; + + case GPIO::Pin29: return GPIO_PIN29; + + case GPIO::Pin30: return GPIO_PIN30; + + case GPIO::Pin31: return GPIO_PIN31; + } + + return 0; +} + +namespace SPI +{ + +enum class Bus { + LPSPI1 = 1, + LPSPI2, + LPSPI3, + LPSPI4, + LPSPI5, + LPSPI6, +}; + +using CS = GPIO::GPIOPin; ///< chip-select pin +using DRDY = GPIO::GPIOPin; ///< data ready pin + +struct bus_device_external_cfg_t { + CS cs_gpio; + DRDY drdy_gpio; +}; + +} // namespace SPI diff --git a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/io_timer_hw_description.h b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/io_timer_hw_description.h index 3d4b6417df..438045b0ad 100644 --- a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/io_timer_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/io_timer_hw_description.h @@ -1,20 +1,20 @@ /**************************************************************************** * - * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * Copyright (C) 2019 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. + * used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -30,7 +30,671 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ + #pragma once -#include "../../../imxrt/include/px4_arch/io_timer_hw_description.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#if !defined(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA) +# error "This code has only been validated with IMXRT1176. Make sure it is correct before using it on another board." +#endif + + +static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t io_timers_conf[MAX_IO_TIMERS], + PWM::FlexPWMConfig pwm_config, IOMUX::Pad pad) +{ + timer_io_channels_t ret{}; + PWM::FlexPWM pwm {}; + + // FlexPWM Muxing Options + switch (pwm_config.module) { + case PWM::PWM1_PWM_A: + pwm = PWM::FlexPWM1; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_23) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_23_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN23; + + } else if (pad == IOMUX::Pad::GPIO_AD_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_00_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN31; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_25) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_25_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN25; + + } else if (pad == IOMUX::Pad::GPIO_AD_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_02_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN1; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_27) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_27_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN27; + + } else if (pad == IOMUX::Pad::GPIO_AD_04) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_04_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN3; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_38) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_38_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN6; + + } + + break; + } + + break; + + case PWM::PWM1_PWM_B: + pwm = PWM::FlexPWM1; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_24) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_24_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN24; + + } else if (pad == IOMUX::Pad::GPIO_AD_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_01_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN0; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_26) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_26_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN26; + + } else if (pad == IOMUX::Pad::GPIO_AD_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_03_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN2; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_28) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_28_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN28; + + } else if (pad == IOMUX::Pad::GPIO_AD_05) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_05_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN4; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_39) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_39_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN7; + + } + + break; + } + + break; + + case PWM::PWM1_PWM_X: + pwm = PWM::FlexPWM1; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_AD_06) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_06_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN5; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_AD_07) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_07_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN6; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_AD_08) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_08_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN7; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_AD_09) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_09_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN8; + } + + break; + } + + break; + + + case PWM::PWM2_PWM_A: + pwm = PWM::FlexPWM2; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_06) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_06_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN6; + + } else if (pad == IOMUX::Pad::GPIO_AD_24) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_24_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN23; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_08) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_08_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN8; + + } else if (pad == IOMUX::Pad::GPIO_AD_26) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_26_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN25; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_10) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_10_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN10; + + } else if (pad == IOMUX::Pad::GPIO_AD_28) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_28_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN27; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_19) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_19_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN19; + + } + + break; + } + + break; + + case PWM::PWM2_PWM_B: + pwm = PWM::FlexPWM2; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_07) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_07_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN7; + + } else if (pad == IOMUX::Pad::GPIO_AD_25) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_25_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN24; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_09) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_09_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN9; + + } else if (pad == IOMUX::Pad::GPIO_AD_27) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_27_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN26; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_11) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_11_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN11; + + } else if (pad == IOMUX::Pad::GPIO_AD_29) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_29_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN28; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_20) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_20_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN20; + + } + + break; + } + + break; + + case PWM::PWM2_PWM_X: + pwm = PWM::FlexPWM2; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_AD_10) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_10_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN9; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_AD_11) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_11_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN10; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_AD_12) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_12_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN11; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_AD_13) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_13_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN12; + } + + break; + } + + break; + + + case PWM::PWM3_PWM_A: + pwm = PWM::FlexPWM3; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_29) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_29_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN29; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_00_INDEX); + ret.gpio_portpin = GPIO_PORT2 | GPIO_PIN10; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_31) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_31_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN31; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_02_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN12; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_33) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_33_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN1; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_04) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_04_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN14; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_21) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_21_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN21; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_06) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_06_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN16; + } + + break; + } + + break; + + case PWM::PWM3_PWM_B: + pwm = PWM::FlexPWM3; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_30) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_30_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN30; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_01_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN11; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_32) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_32_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN0; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_03_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN13; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_34) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_34_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN2; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_05) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_05_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN15; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_22) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_22_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN22; + + } else if (pad == IOMUX::Pad::GPIO_EMC_B2_07) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B2_07_INDEX); + ret.gpio_portpin = GPIO_PORT8 | GPIO_PIN17; + } + + break; + } + + break; + + + case PWM::PWM3_PWM_X: + pwm = PWM::FlexPWM3; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_AD_14) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_14_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN13; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_AD_15) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_15_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN14; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_AD_16) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_16_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN15; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_AD_17) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_17_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN16; + } + + break; + } + + break; + + case PWM::PWM4_PWM_A: + pwm = PWM::FlexPWM4; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_00) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_00_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN0; + + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_02) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_02_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN2; + + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_04) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_04_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN4; + + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_17) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_17_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN17; + + } + + break; + } + + break; + + case PWM::PWM4_PWM_B: + pwm = PWM::FlexPWM4; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_EMC_B1_01) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_01_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN1; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_EMC_B1_03) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_03_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN3; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_EMC_B1_05) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_05_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN5; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_EMC_B1_18) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_B1_18_INDEX); + ret.gpio_portpin = GPIO_PORT1 | GPIO_PIN18; + } + + break; + } + + break; + + + case PWM::PWM4_PWM_X: + pwm = PWM::FlexPWM4; + + switch (pwm_config.submodule) { + case PWM::Submodule0: + if (pad == IOMUX::Pad::GPIO_AD_18) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_18_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN17; + } + + break; + + case PWM::Submodule1: + if (pad == IOMUX::Pad::GPIO_AD_19) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_19_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN18; + } + + break; + + case PWM::Submodule2: + if (pad == IOMUX::Pad::GPIO_AD_20) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_20_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN19; + } + + break; + + case PWM::Submodule3: + if (pad == IOMUX::Pad::GPIO_AD_21) { + ret.gpio_out = GPIO_PERIPH | GPIO_ALT11 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_21_INDEX); + ret.gpio_portpin = GPIO_PORT9 | GPIO_PIN20; + } + + break; + } + + break; + } + + constexpr_assert(ret.gpio_out != 0, "Invalid PWM/Pad config"); + ret.gpio_out |= IOMUX_CMOS_OUTPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_HIGHSTRENGTH | IOMUX_SLEW_FAST; + + switch (pwm_config.module) { + case PWM::PWM1_PWM_A: + case PWM::PWM2_PWM_A: + case PWM::PWM3_PWM_A: + case PWM::PWM4_PWM_A: + ret.val_offset = PWMA_VAL; + break; + + case PWM::PWM1_PWM_B: + case PWM::PWM2_PWM_B: + case PWM::PWM3_PWM_B: + case PWM::PWM4_PWM_B: + ret.val_offset = PWMB_VAL; + break; + + case PWM::PWM1_PWM_X: + case PWM::PWM2_PWM_X: + case PWM::PWM3_PWM_X: + case PWM::PWM4_PWM_X: + ret.val_offset = PWMX_VAL; + break; + + default: + constexpr_assert(false, "not implemented"); + } + + switch (pwm_config.submodule) { + case PWM::Submodule0: + ret.sub_module = SM0; + ret.sub_module_bits = MCTRL_LDOK(1 << SM0); + break; + + case PWM::Submodule1: + ret.sub_module = SM1; + ret.sub_module_bits = MCTRL_LDOK(1 << SM1); + break; + + case PWM::Submodule2: + ret.sub_module = SM2; + ret.sub_module_bits = MCTRL_LDOK(1 << SM2); + break; + + case PWM::Submodule3: + ret.sub_module = SM3; + ret.sub_module_bits = MCTRL_LDOK(1 << SM3); + break; + } + + ret.gpio_in = 0; // TODO (not used yet) + + // find timer index + ret.timer_index = 0xff; + const uint32_t timer_base = getFlexPWMBaseRegister(pwm); + + for (int i = 0; i < MAX_IO_TIMERS; ++i) { + if (io_timers_conf[i].base == timer_base && io_timers_conf[i].submodle == ret.sub_module) { + ret.timer_index = i; + break; + } + } + + constexpr_assert(ret.timer_index != 0xff, "Timer not found"); + + return ret; +} + +static inline constexpr io_timers_t initIOPWM(PWM::FlexPWM pwm, PWM::FlexPWMSubmodule sub) +{ + io_timers_t ret{}; + + ret.base = getFlexPWMBaseRegister(pwm); + ret.submodle = sub; + return ret; +} diff --git a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/spi_hw_description.h index b736695d85..f8573c32f5 100644 --- a/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/spi_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt117x/include/px4_arch/spi_hw_description.h @@ -1,20 +1,20 @@ /**************************************************************************** * - * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * Copyright (C) 2020 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. + * used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -30,11 +30,107 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ + #pragma once +#include +#include + #if defined(CONFIG_SPI) -#include "../../../imxrt/include/px4_arch/spi_hw_description.h" +#include + +static inline constexpr px4_spi_bus_device_t initSPIDevice(uint32_t devid, SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) +{ + px4_spi_bus_device_t ret{}; + ret.cs_gpio = getGPIOPort(cs_gpio.port) | getGPIOPin(cs_gpio.pin) | (GPIO_OUTPUT | GPIO_OUTPUT_ONE | CS_IOMUX); + + if (drdy_gpio.port != GPIO::PortInvalid) { + ret.drdy_gpio = getGPIOPort(drdy_gpio.port) | getGPIOPin(drdy_gpio.pin) | (GPIO_INPUT | DRDY_IOMUX); + } + + if (PX4_SPIDEVID_TYPE(devid) == 0) { // it's a PX4 device (internal or external) + ret.devid = PX4_SPIDEV_ID(PX4_SPI_DEVICE_ID, devid); + + } else { // it's a NuttX device (e.g. SPIDEV_FLASH(0)) + ret.devid = devid; + } + + ret.devtype_driver = PX4_SPI_DEV_ID(devid); + return ret; +} + +static inline constexpr px4_spi_bus_t initSPIBus(SPI::Bus bus, const px4_spi_bus_devices_t &devices, + GPIO::GPIOPin power_enable = {}) +{ + px4_spi_bus_t ret{}; + ret.requires_locking = false; + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + ret.devices[i] = devices.devices[i]; + + + if (ret.devices[i].cs_gpio != 0) { + if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + int same_devices_count = 0; + + for (int j = 0; j < i; ++j) { + if (ret.devices[j].cs_gpio != 0) { + same_devices_count += (ret.devices[i].devid & 0xff) == (ret.devices[j].devid & 0xff); + } + } + + // increment the 2. LSB byte to allow multiple devices of the same type + ret.devices[i].devid |= same_devices_count << 8; + + } else { + // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) + ret.requires_locking = true; + } + } + } + + ret.bus = (int)bus; + ret.is_external = false; + + if (power_enable.port != GPIO::PortInvalid) { + ret.power_enable_gpio = getGPIOPort(power_enable.port) | getGPIOPin(power_enable.pin) | + (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GENERAL_OUTPUT_IOMUX); + } + + return ret; +} + +// just a wrapper since we cannot pass brace-enclosed initialized arrays directly as arguments +struct bus_device_external_cfg_array_t { + SPI::bus_device_external_cfg_t devices[SPI_BUS_MAX_DEVICES]; +}; + +static inline constexpr px4_spi_bus_t initSPIBusExternal(SPI::Bus bus, const bus_device_external_cfg_array_t &devices) +{ + px4_spi_bus_t ret{}; + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + if (devices.devices[i].cs_gpio.port == GPIO::PortInvalid) { + break; + } + + ret.devices[i] = initSPIDevice(i, devices.devices[i].cs_gpio, devices.devices[i].drdy_gpio); + } + + ret.bus = (int)bus; + ret.is_external = true; + ret.requires_locking = false; // external buses are never accessed by NuttX drivers + return ret; +} + +static inline constexpr SPI::bus_device_external_cfg_t initSPIConfigExternal(SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) +{ + SPI::bus_device_external_cfg_t ret{}; + ret.cs_gpio = cs_gpio; + ret.drdy_gpio = drdy_gpio; + return ret; +} constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS]) { diff --git a/platforms/nuttx/src/px4/nxp/rt117x/io_pins/CMakeLists.txt b/platforms/nuttx/src/px4/nxp/rt117x/io_pins/CMakeLists.txt new file mode 100644 index 0000000000..3ddf7ac38a --- /dev/null +++ b/platforms/nuttx/src/px4/nxp/rt117x/io_pins/CMakeLists.txt @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2015-2019 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_compile_options( + -Wno-unused-function + ) # TODO: remove once io_timer_handlerX are used + +px4_add_library(arch_io_pins + ../../imxrt/io_pins/io_timer.c + ../../imxrt/io_pins/pwm_servo.c + ../../imxrt/io_pins/pwm_trigger.c + ../../imxrt/io_pins/input_capture.c + imxrt_pinirq.c +) diff --git a/platforms/nuttx/src/px4/nxp/rt117x/io_pins/imxrt_pinirq.c b/platforms/nuttx/src/px4/nxp/rt117x/io_pins/imxrt_pinirq.c new file mode 100644 index 0000000000..e1bf45040b --- /dev/null +++ b/platforms/nuttx/src/px4/nxp/rt117x/io_pins/imxrt_pinirq.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include + +#include + +#include "chip.h" +#include "imxrt_irq.h" +#include "hardware/imxrt_gpio.h" + +typedef struct { + int low; + int hi; +} lh_t; + + +const lh_t port_to_irq[13] = { + {_IMXRT_GPIO1_0_15_BASE, _IMXRT_GPIO1_16_31_BASE}, + {_IMXRT_GPIO2_0_15_BASE, _IMXRT_GPIO2_16_31_BASE}, + {_IMXRT_GPIO3_0_15_BASE, _IMXRT_GPIO3_16_31_BASE}, + {_IMXRT_GPIO4_0_15_BASE, _IMXRT_GPIO4_16_31_BASE}, + {_IMXRT_GPIO5_0_15_BASE, _IMXRT_GPIO5_16_31_BASE}, + {_IMXRT_GPIO6_0_15_BASE, _IMXRT_GPIO6_16_31_BASE}, + {0, 0}, // GPIO7 Not on CM7 + {0, 0}, // GPIO8 Not on CM7 + {0, 0}, // GPIO9 Not on CM7 + {0, 0}, // GPIO10 Not on CM7 + {0, 0}, // GPIO11 Not on CM7 + {0, 0}, // GPIO12 Not on CM7 + {_IMXRT_GPIO13_BASE, _IMXRT_GPIO13_BASE}, +}; + +static bool imxrt_pin_irq_valid(gpio_pinset_t pinset) +{ + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + lh_t irqlh = port_to_irq[port]; + return (irqlh.low != 0 && irqlh.hi != 0); +} +/**************************************************************************** + * Name: imxrt_pin_irqattach + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Input Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - func: when non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +static int imxrt_pin_irqattach(gpio_pinset_t pinset, xcpt_t func, void *arg) +{ + int rv = -EINVAL; + volatile int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + volatile int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + volatile int irq; + lh_t irqlh = port_to_irq[port]; + + if (irqlh.low != 0 && irqlh.hi != 0) { + rv = OK; + irq = (pin < 16) ? irqlh.low : irqlh.hi; + irq += pin % 16; + irq_attach(irq, func, arg); + up_enable_irq(irq); + } + + return rv; +} + +/**************************************************************************** + * Name: imxrt_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Input Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ +#if defined(CONFIG_IMXRT_GPIO_IRQ) +int imxrt_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg) +{ + int ret = -ENOSYS; + + if (imxrt_pin_irq_valid(pinset)) { + if (func == NULL) { + imxrt_gpioirq_disable(pinset); + pinset &= ~GPIO_INTCFG_MASK; + ret = imxrt_config_gpio(pinset); + + } else { + + pinset &= ~GPIO_INTCFG_MASK; + + if (risingedge & fallingedge) { + pinset |= GPIO_INTBOTH_EDGES; + + } else if (risingedge) { + pinset |= GPIO_INT_RISINGEDGE; + + } else if (fallingedge) { + pinset |= GPIO_INT_FALLINGEDGE; + } + + imxrt_gpioirq_configure(pinset); + ret = imxrt_pin_irqattach(pinset, func, arg); + } + } + + return ret; +} +#endif /* CONFIG_IMXRT_GPIO_IRQ */