Initial IMXRT1170-EVK support

RT7 Boot from debugger now

RT7 Version OCOTP GUID/Rev Fix

RT7 I2C & SPI Partly working

RT7 Add FRAM support

Co-authored-by: David Sidrane <david.sidrane@nscdg.com>

nxp_imxrt1170-evk:Finish 1170 iomux versioning

nxp_imxrt1170-evk:Use FMUM1170 GPIO for PWM

nxp_imxrt1170-evk:Add to CI

nxp_imxrt1170-evk:Move to 192.168.0 network

nxp_imxrt1170-evk:Use LPADC

nxp_imxrt1170-evk:Entry is start

nxp_imxrt1170-evk:Correct Manifest

nxp_imxrt1170-evk:Correct USB VBUS Detect

nxp_imxrt1170-evk:Work twords FMURT1170
This commit is contained in:
Peter van der Perk
2023-10-25 04:05:13 -07:00
committed by David Sidrane
co-authored by David Sidrane
parent aa786db9e3
commit 7005e14e8e
54 changed files with 7580 additions and 22 deletions
@@ -345,6 +345,7 @@ typedef enum PX4_SOC_ARCH_ID_t {
PX4_SOC_ARCH_ID_NXPS32K146 = 0x0007,
PX4_SOC_ARCH_ID_NXPS32K344 = 0x0008,
PX4_SOC_ARCH_ID_NXPIMXRT1176 = 0x0009,
PX4_SOC_ARCH_ID_EAGLE = 0x1001,
PX4_SOC_ARCH_ID_QURT = 0x1002,
+3
View File
@@ -139,6 +139,9 @@ function(px4_os_determine_build_chip)
elseif(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "rt106x")
elseif(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "rt117x")
elseif(CONFIG_ARCH_CHIP_S32K146)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "s32k14x")
@@ -187,7 +187,7 @@ static void mavlink_usb_check(void *arg)
if (param1 == 1) {
// 1: Reboot autopilot
px4_reboot_request(false, 0);
//px4_reboot_request(false, 0);
} else if (param1 == 2) {
// 2: Shutdown autopilot
@@ -197,7 +197,7 @@ static void mavlink_usb_check(void *arg)
} else if (param1 == 3) {
// 3: Reboot autopilot and keep it in the bootloader until upgraded.
px4_reboot_request(true, 0);
//px4_reboot_request(true, 0);
}
}
}
@@ -136,6 +136,7 @@ static int dn_to_ordinal(uint16_t dn)
static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc_channel)
{
int rv = -EIO;
const unsigned int samples = 16;
/*
* Step one is there resistors?
@@ -158,6 +159,7 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
imxrt_config_gpio(PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio_sense));
up_udelay(100); /* About 10 TC assuming 485 K */
/* Read Drive lines while sense are driven low */
@@ -170,7 +172,6 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
imxrt_gpio_write(PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio_sense), 1);
up_udelay(100); /* About 10 TC assuming 485 K */
/* Read Drive lines while sense are driven high */
int high = imxrt_gpio_read(PX4_MAKE_GPIO_INPUT(gpio_drive));
@@ -192,7 +193,6 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
if ((high ^ low) && low == 0) {
/* Yes - Fire up the ADC (it has once control) */
if (px4_arch_adc_init(HW_REV_VER_ADC_BASE) == OK) {
/* Read the value */
@@ -221,12 +221,14 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
/* Turn the drive lines to digital outputs High */
imxrt_config_gpio(gpio_drive);
return rv;
}
static int determine_hw_info(int *revision, int *version)
{
int dn;
int rv = read_id_dn(&dn, GPIO_HW_REV_DRIVE, GPIO_HW_REV_SENSE, ADC_HW_REV_SENSE_CHANNEL);
@@ -41,8 +41,8 @@
#include <px4_platform_common/constexpr_util.h>
#include <board_config.h>
#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."
#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
/*
@@ -65,12 +65,15 @@ enum FlexPWMModule {
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 {
@@ -101,6 +104,361 @@ static inline constexpr uint32_t getFlexPWMBaseRegister(PWM::FlexPWM pwm)
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 {
@@ -376,6 +734,8 @@ static inline constexpr uint32_t getGPIOPin(GPIO::Pin pin)
return 0;
}
#endif
namespace SPI
{
@@ -384,6 +744,10 @@ enum class Bus {
LPSPI2,
LPSPI3,
LPSPI4,
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
LPSPI5,
LPSPI6,
#endif
};
using CS = GPIO::GPIOPin; ///< chip-select pin
@@ -119,6 +119,7 @@ typedef struct timer_io_channels_t {
#define PWMA_VAL IMXRT_FLEXPWM_SM0VAL3_OFFSET
#define PWMB_VAL IMXRT_FLEXPWM_SM0VAL5_OFFSET
#define PWMX_VAL IMXRT_FLEXPWM_SM0VAL0_OFFSET //FIXME
typedef void (*channel_handler_t)(void *context, const io_timers_t *timer, uint32_t chan_index,
@@ -47,8 +47,8 @@
#include <hardware/imxrt_pinmux.h>
#include <board_config.h>
#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."
#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
@@ -58,7 +58,575 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
timer_io_channels_t ret{};
PWM::FlexPWM pwm{};
// FlexPWM Muxing Options
// 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;
@@ -541,6 +1109,7 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
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:
@@ -557,6 +1126,13 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
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");
}
@@ -597,7 +1173,6 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t
}
constexpr_assert(ret.timer_index != 0xff, "Timer not found");
return ret;
}
@@ -40,11 +40,11 @@
#include <imxrt_gpio.h>
#define CS_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_UP_100K | IOMUX_DRIVE_33OHM | IOMUX_SPEED_LOW | IOMUX_SLEW_FAST)
//#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 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)
//#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 = {})
{
@@ -47,16 +47,14 @@ typedef struct {
int hi;
} lh_t;
const lh_t port_to_irq[9] = {
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_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},
{_IMXRT_GPIO13_BASE, _IMXRT_GPIO13_BASE}, //FIXME
};
/****************************************************************************
@@ -283,7 +283,7 @@ uint32_t io_timer_channel_get_gpio_output(unsigned channel)
}
return timer_io_channels[channel].gpio_portpin | (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP
| IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST);
| IOMUX_SLEW_FAST);
return 0;
}
@@ -42,7 +42,11 @@
#include <stdio.h>
#include <string.h>
#include <arm_internal.h>
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
#include <hardware/rt117x/imxrt117x_ocotp.h>
#else
#include <hardware/imxrt_ocotp.h>
#endif
#define CPU_UUID_BYTE_FORMAT_ORDER {3, 2, 1, 0, 7, 6, 5, 4}
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00ff0000) >> 8) | (((x) & 0x0000ff00) << 8) | ((x) << 24))
@@ -89,9 +93,13 @@ void board_get_uuid32(uuid_uint32_t uuid_words)
* word [0] word[1]
* SJC_CHALL[63:32] [31:00]
*/
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
uuid_words[0] = getreg32(IMXRT_OCOTP_FUSE(0x10));
uuid_words[1] = getreg32(IMXRT_OCOTP_FUSE(0x11));
#else
uuid_words[0] = getreg32(IMXRT_OCOTP_CFG1);
uuid_words[1] = getreg32(IMXRT_OCOTP_CFG0);
#endif
}
int board_get_uuid32_formated(char *format_buffer, int size,
@@ -39,10 +39,46 @@
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/defines.h>
#include <chip.h>
#include <hardware/imxrt_usb_analog.h>
#include "arm_internal.h"
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
# include <hardware/rt117x/imxrt117x_ocotp.h>
# include <hardware/rt117x/imxrt117x_anadig.h>
#else
# include <chip.h>
# include <hardware/imxrt_usb_analog.h>
#endif
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
#define CHIP_TAG "i.MX RT11?0 r??"
#define CHIP_TAG_LEN sizeof(CHIP_TAG)-1
#define SI_REV(n) ((n & 0x7000000) >> 24)
#define DIFPROG_TYPE(n) ((n & 0xF000) >> 12)
#define DIFPROG_REV_MAJOR(n) ((n & 0xF0) >> 4)
#define DIFPROG_REV_MINOR(n) ((n & 0xF))
int board_mcu_version(char *rev, const char **revstr, const char **errata)
{
uint32_t info = getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG);
static char chip[sizeof(CHIP_TAG)] = CHIP_TAG;
*revstr = chip;
chip[CHIP_TAG_LEN - 6] = '0' + DIFPROG_TYPE(info);
chip[CHIP_TAG_LEN - 2] = 'A' + (DIFPROG_REV_MAJOR(info) - 10);
chip[CHIP_TAG_LEN - 1] = '0' + DIFPROG_REV_MINOR(info);
*rev = '0' + SI_REV(getreg32(IMXRT_OCOTP_FUSE(18)));
if (errata) {
*errata = NULL;
}
return 0;
}
#else
#define DIGPROG_MINOR_SHIFT 0
#define DIGPROG_MINOR_MASK (0xff << DIGPROG_MINOR_SHIFT)
@@ -74,3 +110,5 @@ int board_mcu_version(char *rev, const char **revstr, const char **errata)
return 0;
}
#endif
@@ -0,0 +1,44 @@
############################################################################
#
# 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.
#
############################################################################
#add_subdirectory(../imxrt/adc 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(../imxrt/tone_alarm tone_alarm)
add_subdirectory(../imxrt/version version)
@@ -0,0 +1,35 @@
/****************************************************************************
*
* 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 "../../../imxrt/include/px4_arch/adc.h"
@@ -0,0 +1,36 @@
/****************************************************************************
*
* 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 "../../../imxrt/include/px4_arch/hw_description.h"
@@ -0,0 +1,35 @@
/****************************************************************************
*
* 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 "../../../imxrt/include/px4_arch/i2c_hw_description.h"
@@ -0,0 +1,36 @@
/****************************************************************************
*
* 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 "../../../imxrt/include/px4_arch/io_timer.h"
@@ -0,0 +1,36 @@
/****************************************************************************
*
* 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 "../../../imxrt/include/px4_arch/io_timer_hw_description.h"
@@ -0,0 +1,108 @@
/****************************************************************************
*
* 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 "../../../nxp_common/include/px4_arch/micro_hal.h"
__BEGIN_DECLS
#define PX4_SOC_ARCH_ID PX4_SOC_ARCH_ID_NXPIMXRT1176
#// Fixme: using ??
#define PX4_BBSRAM_SIZE 2048
#define PX4_BBSRAM_GETDESC_IOCTL 0
#define PX4_NUMBER_I2C_BUSES 2 //FIXME
#define GPIO_OUTPUT_SET GPIO_OUTPUT_ONE
#define GPIO_OUTPUT_CLEAR GPIO_OUTPUT_ZERO
#include <chip.h>
#include <imxrt_lpspi.h>
#include <imxrt_lpi2c.h>
#include <imxrt_iomuxc.h>
//# include <imxrt_uid.h> todo:Upsteam UID access
/* imxrt defines the 64 bit UUID as
*
* OCOTP 0x410 bits 31:0
* OCOTP 0x420 bits 63:32
*
* PX4 uses the words in bigendian order MSB to LSB
* word [0] [1]
* bits 63-32, 31-00,
*/
#define PX4_CPU_UUID_BYTE_LENGTH 8
#define PX4_CPU_UUID_WORD32_LENGTH (PX4_CPU_UUID_BYTE_LENGTH/sizeof(uint32_t))
/* The mfguid will be an array of bytes with
* MSD @ index 0 - LSD @ index PX4_CPU_MFGUID_BYTE_LENGTH-1
*
* It will be converted to a string with the MSD on left and LSD on the right most position.
*/
#define PX4_CPU_MFGUID_BYTE_LENGTH PX4_CPU_UUID_BYTE_LENGTH
/* define common formating across all commands */
#define PX4_CPU_UUID_WORD32_FORMAT "%08x"
#define PX4_CPU_UUID_WORD32_SEPARATOR ":"
#define PX4_CPU_UUID_WORD32_UNIQUE_H 0 /* Least significant digits change the most (die wafer,X,Y */
#define PX4_CPU_UUID_WORD32_UNIQUE_M 1 /* Most significant digits change the least (lot#) */
/* Separator nnn:nnn:nnnn 2 char per byte term */
#define PX4_CPU_UUID_WORD32_FORMAT_SIZE (PX4_CPU_UUID_WORD32_LENGTH-1+(2*PX4_CPU_UUID_BYTE_LENGTH)+1)
#define PX4_CPU_MFGUID_FORMAT_SIZE ((2*PX4_CPU_MFGUID_BYTE_LENGTH)+1)
/* bus_num is 1 based on imx and must be translated from the legacy one based */
#define PX4_BUS_OFFSET 0 /* imxrt buses are 1 based no adjustment needed */
#define px4_spibus_initialize(bus_num_1based) imxrt_lpspibus_initialize(PX4_BUS_NUMBER_FROM_PX4(bus_num_1based))
#define px4_i2cbus_initialize(bus_num_1based) imxrt_i2cbus_initialize(PX4_BUS_NUMBER_FROM_PX4(bus_num_1based))
#define px4_i2cbus_uninitialize(pdev) imxrt_i2cbus_uninitialize(pdev)
#define px4_arch_configgpio(pinset) imxrt_config_gpio(pinset)
#define px4_arch_unconfiggpio(pinset)
#define px4_arch_gpioread(pinset) imxrt_gpio_read(pinset)
#define px4_arch_gpiowrite(pinset, value) imxrt_gpio_write(pinset, value)
int imxrt_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, bool event, xcpt_t func, void *arg);
#define px4_arch_gpiosetevent(pinset,r,f,e,fp,a) imxrt_gpiosetevent(pinset,r,f,e,fp,a)
#define PX4_MAKE_GPIO_INPUT(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT ))
#define PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_SLEW_FAST))
#define PX4_MAKE_GPIO_OUTPUT_SET(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT | GPIO_OUTPUT_ONE | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_SLEW_FAST))
__END_DECLS
@@ -0,0 +1,43 @@
/****************************************************************************
*
* 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
#if defined(CONFIG_SPI)
#include "../../../imxrt/include/px4_arch/spi_hw_description.h"
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS])
{
return true;
}
#endif // CONFIG_SPI