Add support for NXP MR-VMU-Tropic board (#25845)
Container build / Set Tags and Variables (push) Has been cancelled
Container build / Build Container (amd64) (push) Has been cancelled
Container build / Build Container (arm64) (push) Has been cancelled
Container build / Deploy To Registry (push) Has been cancelled
Build all targets / Scan for Board Targets (push) Has been cancelled
Build all targets / Build [${{ matrix.runner }}][${{ matrix.group }}] (push) Has been cancelled
Build all targets / Upload Artifacts (push) Has been cancelled
Checks / build (NO_NINJA_BUILD=1 px4_fmu-v5_default) (push) Has been cancelled
Checks / build (NO_NINJA_BUILD=1 px4_sitl_default) (push) Has been cancelled
Checks / build (check_format) (push) Has been cancelled
Checks / build (check_newlines) (push) Has been cancelled
Checks / build (module_documentation) (push) Has been cancelled
Checks / build (px4_fmu-v2_default stack_check) (push) Has been cancelled
Checks / build (px4_sitl_allyes) (push) Has been cancelled
Checks / build (shellcheck_all) (push) Has been cancelled
Checks / build (tests) (push) Has been cancelled
Checks / build (tests_coverage) (push) Has been cancelled
Checks / build (validate_module_configs) (push) Has been cancelled
Clang Tidy / build (push) Has been cancelled
MacOS build / build (px4_fmu-v5_default) (push) Has been cancelled
MacOS build / build (px4_sitl) (push) Has been cancelled
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Has been cancelled
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Has been cancelled
EKF Update Change Indicator / unit_tests (push) Has been cancelled
Failsafe Simulator Build / build (failsafe_web) (push) Has been cancelled
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Has been cancelled
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Has been cancelled
FLASH usage analysis / Publish Results (push) Has been cancelled
ITCM check / Checking nxp_mr-tropic (push) Has been cancelled
ITCM check / Checking nxp_tropic-community (push) Has been cancelled
ITCM check / Checking px4_fmu-v5x (push) Has been cancelled
ITCM check / Checking px4_fmu-v6xrt (push) Has been cancelled
MAVROS Mission Tests / build (map[mission:MC_mission_box vehicle:iris]) (push) Has been cancelled
MAVROS Offboard Tests / build (map[test_file:mavros_posix_tests_offboard_posctl.test vehicle:iris]) (push) Has been cancelled
Nuttx Target with extra env config / build (px4_fmu-v5_default) (push) Has been cancelled
Python CI Checks / build (push) Has been cancelled
ROS Integration Tests / build (push) Has been cancelled
ROS Translation Node Tests / Build and test (map[ros_version:humble ubuntu:jammy]) (push) Has been cancelled
ROS Translation Node Tests / Build and test (map[ros_version:jazzy ubuntu:noble]) (push) Has been cancelled
SITL Tests / Testing PX4 tailsitter (push) Has been cancelled
SITL Tests / Testing PX4 iris (push) Has been cancelled
SITL Tests / Testing PX4 standard_vtol (push) Has been cancelled
Handle stale issues and PRs / stale (push) Has been cancelled

* rt106x: Use platform SPI hal layer

* rt106x: Add romapi support and reboot to isp/bootloader

* bootloader: imxrt_common: Add rt106x support

* NXP MR-Tropic initial commit

* Add missing file for mr-tropic bootloader

* nxp-mr-tropic:Bootloader Alow Assertion debugging & Keep Ram Vectors

* nxp-mr-tropic: Firmware Boot from bootloader

* nxp-mr-tropic:Add Bootloader bin file

* mr-tropic: Update config and linker

Fixes enet issues with write-back and some code cleanup.
Furthermore increase NOR LittleFS to 256kB to reflect on linker

* Update NuttX

* mr-tropic: fix itcm apping and add mr-tropic to itcm check

---------

Co-authored-by: David Sidrane <David.Sidrane@NscDg.com>
This commit is contained in:
Peter van der Perk
2025-11-05 17:48:26 +01:00
committed by GitHub
parent 5f0d222e1b
commit 1250563ed1
55 changed files with 5972 additions and 30 deletions
@@ -157,8 +157,13 @@
#if BOARD_NUMBER_BRICKS == 0
/* allow SITL to disable all bricks */
#elif BOARD_NUMBER_BRICKS == 1
# define BOARD_BATT_V_LIST {ADC_BATTERY_VOLTAGE_CHANNEL}
# define BOARD_BATT_I_LIST {ADC_BATTERY_CURRENT_CHANNEL}
# if defined(BOARD_NUMBER_DIGITAL_BRICKS)
# define BOARD_BATT_V_LIST {-1}
# define BOARD_BATT_I_LIST {-1}
# else
# define BOARD_BATT_V_LIST {ADC_BATTERY_VOLTAGE_CHANNEL}
# define BOARD_BATT_I_LIST {ADC_BATTERY_CURRENT_CHANNEL}
# endif
# define BOARD_BRICK_VALID_LIST {BOARD_ADC_BRICK_VALID}
#elif BOARD_NUMBER_BRICKS == 2
# if defined(BOARD_NUMBER_DIGITAL_BRICKS)
+3
View File
@@ -507,6 +507,9 @@ if(NOT NUTTX_DIR MATCHES "external")
if(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A)
set(DEBUG_DEVICE "MIMXRT1062XXX6A")
set(DEBUG_SVD_FILE "MIMXRT1062.xml")
elseif(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A)
set(DEBUG_DEVICE "MIMXRT1064XXX6A")
set(DEBUG_SVD_FILE "MIMXRT1064.xml")
elseif(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA)
set(DEBUG_DEVICE "MIMXRT1176DVMAA")
set(DEBUG_SVD_FILE "MIMXRT1176_cm7.xml")
+3
View File
@@ -158,6 +158,9 @@ function(px4_os_determine_build_chip)
elseif(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "rt106x")
elseif(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "rt106x")
elseif(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "rt117x")
@@ -9,9 +9,19 @@
#include "hw_config.h"
#include <px4_arch/imxrt_flexspi_nor_flash.h>
#include <px4_arch/imxrt_romapi.h>
#include <hardware/rt117x/imxrt117x_ocotp.h>
#include <hardware/rt117x/imxrt117x_anadig.h>
#include <hardware/rt117x/imxrt117x_snvs.h>
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
# include <hardware/rt117x/imxrt117x_ocotp.h>
# include <hardware/rt117x/imxrt117x_anadig.h>
# include <hardware/rt117x/imxrt117x_snvs.h>
#else
# include <chip.h>
# include <hardware/imxrt_usb_analog.h>
# include <hardware/imxrt_snvs.h>
# include <hardware/imxrt_ocotp.h>
# include "hardware/imxrt_ccm.h"
# include "imxrt_periphclks.h"
# define SNVS_LPCR_GPR_Z_DIS (1 << 24) /* Bit 24: General Purpose Registers Zeroization Disable */
#endif
#include <hardware/imxrt_usb_analog.h>
#include "imxrt_clockconfig.h"
@@ -30,14 +40,31 @@
#define APP_SIZE_MAX (BOARD_FLASH_SIZE - (BOOTLOADER_RESERVATION_SIZE + APP_RESERVATION_SIZE))
#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))
#elif defined(CONFIG_ARCH_FAMILY_IMXRT106x)
#define CHIP_TAG "i.MX RT10?? r?.?"
#define DIGPROG_MINOR_SHIFT 0
#define DIGPROG_MINOR_MASK (0xff << DIGPROG_MINOR_SHIFT)
#define DIGPROG_MINOR(info) (((info) & DIGPROG_MINOR_MASK) >> DIGPROG_MINOR_SHIFT)
#define DIGPROG_MAJOR_LOWER_SHIFT 8
#define DIGPROG_MAJOR_LOWER_MASK (0xff << DIGPROG_MAJOR_LOWER_SHIFT)
#define DIGPROG_MAJOR_LOWER(info) (((info) & DIGPROG_MAJOR_LOWER_MASK) >> DIGPROG_MAJOR_LOWER_SHIFT)
#define DIGPROG_MAJOR_UPPER_SHIFT 16
#define DIGPROG_MAJOR_UPPER_MASK (0xff << DIGPROG_MAJOR_UPPER_SHIFT)
#define DIGPROG_MAJOR_UPPER(info) (((info) & DIGPROG_MAJOR_UPPER_MASK) >> DIGPROG_MAJOR_UPPER_SHIFT)
#endif
#define CHIP_TAG_LEN sizeof(CHIP_TAG)-1
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
#define FLASH_BASE IMXRT_FLEXSPI1_CIPHER_BASE
#elif defined(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A)
#define FLASH_BASE IMXRT_FLEX2CIPHER_BASE
#endif
/* context passed to cinit */
#if INTERFACE_USART
@@ -287,6 +314,27 @@ board_deinit(void)
px4_arch_configgpio(MK_GPIO_INPUT(BOARD_PIN_LED_BOOTLOADER));
#endif
#ifdef CONFIG_ARCH_FAMILY_IMXRT106x
// Restore CCM registers to ROM state
putreg32(0x00000001, IMXRT_CCM_CACRR);
putreg32(0x000A8200, IMXRT_CCM_CBCDR);
putreg32(0x06490B03, IMXRT_CCM_CSCDR1);
putreg32(0x75AE8104, IMXRT_CCM_CBCMR);
putreg32(0x67930001, IMXRT_CCM_CSCMR1);
imxrt_clockoff_lpuart3();
imxrt_clockoff_usboh3();
imxrt_clockoff_timer3();
imxrt_clockoff_xbar1();
imxrt_clockoff_xbar3();
up_disable_icache();
up_disable_dcache();
#endif
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
const uint32_t dnfw[] = {
CCM_CR_M7,
CCM_CR_BUS,
@@ -309,6 +357,8 @@ board_deinit(void)
putreg32(CCM_CR_CTRL_OFF, IMXRT_CCM_CR_CTRL(i));
}
}
#endif
}
inline void arch_systic_init(void)
@@ -365,7 +415,7 @@ ssize_t arch_flash_write(uintptr_t address, const void *buffer, size_t buflen)
j++;
}
uintptr_t offset = ((uintptr_t) address) - IMXRT_FLEXSPI1_CIPHER_BASE;
uintptr_t offset = ((uintptr_t) address) - FLASH_BASE;
volatile uint32_t status = ROM_FLEXSPI_NorFlash_ProgramPage(1, pConfig, offset, (const uint32_t *)buffer);
up_invalidate_dcache((uintptr_t)address,
@@ -400,7 +450,7 @@ flash_func_sector_size(unsigned sector)
ssize_t up_progmem_ispageerased(unsigned sector)
{
const uint32_t bytes_per_sector = flash_func_sector_size(sector);
uint32_t *address = (uint32_t *)(IMXRT_FLEXSPI1_CIPHER_BASE + (sector * bytes_per_sector));
uint32_t *address = (uint32_t *)(FLASH_BASE + (sector * bytes_per_sector));
const uint32_t uint32_per_sector = bytes_per_sector / sizeof(*address);
int blank = 0; /* Assume it is Bank */
@@ -437,9 +487,9 @@ flash_func_erase_sector(unsigned sector, bool force)
struct flexspi_nor_config_s *pConfig = &g_bootConfig;
const uint32_t bytes_per_sector = flash_func_sector_size(sector);
uint32_t *address = (uint32_t *)(IMXRT_FLEXSPI1_CIPHER_BASE + (sector * bytes_per_sector));
uint32_t *address = (uint32_t *)(FLASH_BASE + (sector * bytes_per_sector));
uintptr_t offset = ((uintptr_t) address) - IMXRT_FLEXSPI1_CIPHER_BASE;
uintptr_t offset = ((uintptr_t) address) - FLASH_BASE;
irqstate_t flags;
flags = enter_critical_section();
volatile uint32_t status = ROM_FLEXSPI_NorFlash_Erase(1, pConfig, (uintptr_t) offset, bytes_per_sector);
@@ -473,6 +523,8 @@ flash_func_read_otp(uintptr_t address)
return 0;
}
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
uint32_t get_mcu_id(void)
{
// ??? is DEBUGMCU get able
@@ -499,6 +551,36 @@ int get_mcu_desc(int max, uint8_t *revstr)
return strp - revstr;
}
#elif defined(CONFIG_ARCH_FAMILY_IMXRT106x)
uint32_t get_mcu_id(void)
{
return getreg32(IMXRT_OCOTP_UNIQUE_ID_LSB);
}
int get_mcu_desc(int max, uint8_t *revstr)
{
uint32_t info = getreg32(IMXRT_USB_ANALOG_DIGPROG);
// CHIP_TAG "i.MX RT10?? r?.?"
static uint8_t chip[sizeof(CHIP_TAG) + 1] = CHIP_TAG;
chip[CHIP_TAG_LEN - 1] = '0' + DIGPROG_MINOR(info);
chip[CHIP_TAG_LEN - 3] = '1' + DIGPROG_MAJOR_LOWER(info);
chip[CHIP_TAG_LEN - 6] = getreg32(0x401F867C) == 0x10 ? '4' : '2';
chip[CHIP_TAG_LEN - 7] = DIGPROG_MAJOR_UPPER(info) == 0x6a ? '5' : '6';
uint8_t *endp = &revstr[max - 1];
uint8_t *strp = revstr;
uint8_t *des = chip;
while (strp < endp && *des) {
*strp++ = *des++;
}
return strp - revstr;
}
#endif
int check_silicon(void)
{
@@ -717,6 +799,7 @@ bootloader_main(void)
* Returns - 0 if connected.
*
************************************************************************************/
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
#undef IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT
#define USB1_VBUS_DET_STAT_OFFSET 0xd0
#define IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT (IMXRT_USBPHY1_BASE + USB1_VBUS_DET_STAT_OFFSET)
@@ -727,6 +810,17 @@ bootloader_main(void)
try_boot = false;
}
#elif defined(CONFIG_ARCH_FAMILY_IMXRT106x)
#undef IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT
#define IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT (IMXRT_ANATOP_BASE + IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT_OFFSET)
if ((getreg32(IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT) & USB_ANALOG_USB_VBUS_DETECT_STAT_VBUS_VALID) != 0) {
usb_connected = true;
/* don't try booting before we set up the bootloader */
try_boot = false;
}
#endif
#endif
#if INTERFACE_USART
@@ -0,0 +1,34 @@
############################################################################
#
# 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.
#
############################################################################
add_subdirectory(../imxrt_common arch_bootloader)
@@ -35,9 +35,7 @@ px4_add_library(arch_board_reset
board_reset.cpp
)
if (CONFIG_ARCH_FAMILY_IMXRT117x)
target_link_libraries(arch_board_reset PRIVATE arch_board_romapi)
endif()
# up_systemreset
if (NOT DEFINED CONFIG_BUILD_FLAT)
@@ -45,6 +45,12 @@
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
#include <hardware/rt117x/imxrt117x_snvs.h>
#elif defined CONFIG_ARCH_FAMILY_IMXRT106x
# include <hardware/imxrt_snvs.h>
# define SNVS_LPCR_GPR_Z_DIS (1 << 24) /* Bit 24: General Purpose Registers Zeroization Disable */
#endif
#ifdef BOARD_HAS_ISP_BOOTLOADER
#include <px4_arch/imxrt_flexspi_nor_flash.h>
#include <px4_arch/imxrt_romapi.h>
#endif
@@ -59,13 +65,9 @@
static int board_reset_enter_bootloader()
{
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
uint32_t regvalue = BOOT_RTC_SIGNATURE;
modifyreg32(IMXRT_SNVS_LPCR, 0, SNVS_LPCR_GPR_Z_DIS);
putreg32(regvalue, PX4_IMXRT_RTC_REBOOT_REG_ADDRESS);
#elif defined(BOARD_HAS_TEENSY_BOOTLOADER)
asm("BKPT #251"); /* Enter Teensy MKL02 bootloader */
#endif
return OK;
}
@@ -75,15 +77,16 @@ int board_reset(int status)
board_reset_enter_bootloader();
}
#if defined(BOARD_HAS_ISP_BOOTLOADER)
else if (status == REBOOT_TO_ISP) {
#ifdef BOARD_HAS_TEENSY_BOOTLOADER
asm("BKPT #251"); /* Enter Teensy MKL02 bootloader */
#elif defined(BOARD_HAS_ISP_BOOTLOADER)
uint32_t arg = 0xeb100000;
ROM_API_Init();
ROM_RunBootloader(&arg);
#endif
}
#endif
#if defined(BOARD_HAS_ON_RESET)
board_on_reset(status);
@@ -138,18 +138,33 @@
(FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \
FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
#ifdef CONFIG_ARCH_FAMILY_IMXRT106x
//!@brief Definitions for FlexSPI Serial Clock Frequency
typedef enum _FlexSpiSerialClockFreq {
kFlexSpiSerialClk_30MHz = 1,
kFlexSpiSerialClk_50MHz = 2,
kFlexSpiSerialClk_60MHz = 3,
kFlexSpiSerialClk_75MHz = 4,
kFlexSpiSerialClk_80MHz = 5,
kFlexSpiSerialClk_100MHz = 6,
kFlexSpiSerialClk_120MHz = 7,
kFlexSpiSerialClk_133MHz = 8,
kFlexSpiSerialClk_166MHz = 9,
} flexspi_serial_clk_freq_t;
#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x)
//!@brief Definitions for FlexSPI Serial Clock Frequency
typedef enum _FlexSpiSerialClockFreq {
kFlexSpiSerialClk_30MHz = 1,
kFlexSpiSerialClk_50MHz = 2,
kFlexSpiSerialClk_60MHz = 3,
kFlexSpiSerialClk_80MHz = 4,
kFlexSpiSerialClk_100MHz = 5,
kFlexSpiSerialClk_100MHz = 5,
kFlexSpiSerialClk_120MHz = 6,
kFlexSpiSerialClk_133MHz = 7,
kFlexSpiSerialClk_166MHz = 8,
kFlexSpiSerialClk_200MHz = 9,
} flexspi_serial_clk_freq_t;
#endif
//!@brief FlexSPI clock configuration type
enum {
@@ -239,7 +239,9 @@ status_t ROM_FLEXSPI_NorFlash_Erase(uint32_t instance, flexspi_nor_config_t *con
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout
*/
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
status_t ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t start);
#endif
/*!
* @brief Erase one block specified by address
@@ -259,7 +261,9 @@ status_t ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance, flexspi_nor_config_
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout
*/
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
status_t ROM_FLEXSPI_NorFlash_EraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t start);
#endif
/*!
* @brief Erase all the Serial NOR devices connected on FLEXSPI.
@@ -342,10 +346,12 @@ status_t ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance,
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout Device timeout.
*/
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
status_t ROM_FLEXSPI_NorFlash_WaitBusy(uint32_t instance,
flexspi_nor_config_t *config,
bool isParallelMode,
uint32_t address);
#endif
/*@}*/
/*!
@@ -52,8 +52,29 @@ typedef union _standard_version {
#endif
} standard_version_t;
#ifdef CONFIG_ARCH_FAMILY_IMXRT106x
/*!
* @brief Interface for the ROM FLEXSPI NOR flash driver.
* @brief Interface for the IMXRT106X ROM FLEXSPI NOR flash driver.
*/
typedef struct {
uint32_t version;
status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*page_program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dst_addr, const uint32_t *src);
status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
void (*clear_cache)(uint32_t instance);
status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
} flexspi_nor_driver_interface_t;
#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x)
/*!
* @brief Interface for the IMXRT117X ROM FLEXSPI NOR flash driver.
*/
typedef struct {
uint32_t version;
@@ -73,6 +94,33 @@ typedef struct {
const uint32_t reserved1[2]; /*!< Reserved */
} flexspi_nor_driver_interface_t;
#endif
#ifdef CONFIG_ARCH_FAMILY_IMXRT106x
/*!
* @brief Root of the bootloader api tree.
*
* An instance of this struct resides in read-only memory in the bootloader. It
* provides a user application access to APIs exported by the bootloader.
*
* @note The order of existing fields must not be changed.
*/
typedef struct {
const uint32_t version; //!< Bootloader version number
const char *copyright; //!< Bootloader Copyright
void (*runBootloader)(void *arg); //!< Function to start the bootloader executing
const uint32_t *reserved0; //!< Reserved
const flexspi_nor_driver_interface_t *flexSpiNorDriver; //!< FlexSPI NOR Flash API
const uint32_t *reserved1; //!< Reserved
const uint32_t *unused_rtwdogDriver;
const uint32_t *unused_wdogDriver;
const uint32_t *reserved2;
} bootloader_api_entry_t;
#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x)
/*!
* @brief Root of the bootloader api tree.
*
@@ -89,6 +137,8 @@ typedef struct {
const uint32_t reserved[8]; /*!< Reserved */
} bootloader_api_entry_t;
#endif
/*******************************************************************************
* Variables
******************************************************************************/
@@ -104,6 +154,9 @@ static bootloader_api_entry_t *g_bootloaderTree = NULL;
locate_code(".ramfunc")
void ROM_API_Init(void)
{
#ifdef CONFIG_ARCH_FAMILY_IMXRT106x
g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0020001cU);
#else
if ((getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG) & ANADIG_MISC_MISC_DIFPROG_CHIPID(0x10U)) != 0U) {
g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0021001cU);
@@ -111,6 +164,8 @@ void ROM_API_Init(void)
} else {
g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0020001cU);
}
#endif
}
/*!
@@ -193,6 +248,8 @@ status_t ROM_FLEXSPI_NorFlash_Erase(uint32_t instance, flexspi_nor_config_t *con
return g_bootloaderTree->flexSpiNorDriver->erase(instance, config, start, length);
}
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
/*!
* @brief Erase one sector specified by address.
*
@@ -219,6 +276,8 @@ status_t ROM_FLEXSPI_NorFlash_EraseBlock(uint32_t instance, flexspi_nor_config_t
return g_bootloaderTree->flexSpiNorDriver->erase_block(instance, config, start);
}
#endif
/*! @brief Erase all the Serial NOR devices connected on FLEXSPI. */
locate_code(".ramfunc")
status_t ROM_FLEXSPI_NorFlash_EraseAll(uint32_t instance, flexspi_nor_config_t *config)
@@ -242,6 +301,19 @@ status_t ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance,
return g_bootloaderTree->flexSpiNorDriver->update_lut(instance, seqIndex, lutBase, seqNumber);
}
#ifdef CONFIG_ARCH_FAMILY_IMXRT106x
/*! @brief Software reset for the FLEXSPI logic. */
locate_code(".ramfunc")
void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance)
{
g_bootloaderTree->flexSpiNorDriver->clear_cache(instance);
}
#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x)
/*! @brief Software reset for the FLEXSPI logic. */
locate_code(".ramfunc")
void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance)
@@ -259,6 +331,9 @@ void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance)
MISRA_CAST(clearCacheCommand_t, clearCacheCommand, uint32_t, clearCacheFunctionAddress);
(void)clearCacheCommand(instance);
}
#endif
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
/*! @brief Wait until device is idle*/
locate_code(".ramfunc")
@@ -269,3 +344,5 @@ status_t ROM_FLEXSPI_NorFlash_WaitBusy(uint32_t instance,
{
return g_bootloaderTree->flexSpiNorDriver->wait_busy(instance, config, isParallelMode, address);
}
#endif
@@ -90,7 +90,7 @@ int board_mcu_version(char *rev, const char **revstr, const char **errata)
#define DIGPROG_MAJOR_UPPER_MASK (0xff << DIGPROG_MAJOR_UPPER_SHIFT)
#define DIGPROG_MAJOR_UPPER(info) (((info) & DIGPROG_MAJOR_UPPER_MASK) >> DIGPROG_MAJOR_UPPER_SHIFT)
// 876543210
#define CHIP_TAG "i.MX RT10?2 r?.?"
#define CHIP_TAG "i.MX RT10?? r?.?"
#define CHIP_TAG_LEN sizeof(CHIP_TAG)-1
int board_mcu_version(char *rev, const char **revstr, const char **errata)
@@ -100,6 +100,7 @@ int board_mcu_version(char *rev, const char **revstr, const char **errata)
chip[CHIP_TAG_LEN - 1] = '0' + DIGPROG_MINOR(info);
chip[CHIP_TAG_LEN - 3] = '1' + DIGPROG_MAJOR_LOWER(info);
chip[CHIP_TAG_LEN - 6] = getreg32(0x401F867C) == 0x10 ? '4' : '2';
chip[CHIP_TAG_LEN - 7] = DIGPROG_MAJOR_UPPER(info) == 0x6a ? '5' : '6';
*revstr = chip;
*rev = '0' + DIGPROG_MINOR(info);
@@ -36,11 +36,13 @@ 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/romapi romapi)
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)
add_subdirectory(../imxrt/spi spi)
add_subdirectory(px4io_serial)
@@ -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_MIMXRT1064DVL6A)
# error "This code has only been validated with IMXRT1062 and IMXRT1064. Make sure it is correct before using it on another board."
#endif
/*
@@ -0,0 +1,36 @@
/****************************************************************************
*
* Copyright (c) 2024 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/imxrt_flexspi_nor_flash.h"
@@ -0,0 +1,36 @@
/****************************************************************************
*
* Copyright (c) 2024 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/imxrt_romapi.h"
@@ -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_MIMXRT1064DVL6A)
# error "This code has only been validated with IMXRT1062 and IMXRT1064. Make sure it is correct before using it on another board."
#endif
@@ -46,6 +46,58 @@
#define GENERAL_OUTPUT_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST)
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS])
{
const bool nuttx_enabled_spi_buses[] = {
#ifdef CONFIG_IMXRT_LPSPI1
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI2
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI3
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI4
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI5
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI6
true,
#else
false,
#endif
};
for (unsigned i = 0; i < sizeof(nuttx_enabled_spi_buses) / sizeof(nuttx_enabled_spi_buses[0]); ++i) {
bool found_bus = false;
for (int j = 0; j < SPI_BUS_MAX_BUS_ITEMS; ++j) {
if (spi_busses_conf[j].bus == (int)i + 1) {
found_bus = true;
}
}
// Either the bus is enabled in NuttX and configured in spi_busses_conf, or disabled and not configured
constexpr_assert(found_bus == nuttx_enabled_spi_buses[i], "SPI bus config mismatch (CONFIG_STM32H7_SPIx)");
}
return false;
}
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{};
@@ -138,8 +190,57 @@ static inline constexpr SPI::bus_device_external_cfg_t initSPIConfigExternal(SPI
return ret;
}
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS])
struct px4_spi_bus_array_t {
px4_spi_bus_t item[SPI_BUS_MAX_BUS_ITEMS];
};
#if defined(BOARD_HAS_HW_SPLIT_VERSIONING)
static inline constexpr px4_spi_bus_all_hw_t initSPIFmumID(hw_fmun_id_t hw_fmun_id,
const px4_spi_bus_array_t &bus_items)
{
return true;
px4_spi_bus_all_hw_t ret{};
for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) {
ret.buses[i] = bus_items.item[i];
}
ret.board_hw_fmun_id = hw_fmun_id;
return ret;
}
#else
static inline constexpr px4_spi_bus_all_hw_t initSPIHWVersion(int hw_version_revision,
const px4_spi_bus_array_t &bus_items)
{
px4_spi_bus_all_hw_t ret{};
for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) {
ret.buses[i] = bus_items.item[i];
}
ret.board_hw_version_revision = hw_version_revision;
return ret;
}
#endif
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_buses_conf[SPI_BUS_MAX_BUS_ITEMS]);
constexpr bool validateSPIConfig(const px4_spi_bus_all_hw_t spi_buses_conf[BOARD_NUM_SPI_CFG_HW_VERSIONS])
{
for (int ver = 0; ver < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++ver) {
validateSPIConfig(spi_buses_conf[ver].buses);
}
for (int ver = 1; ver < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++ver) {
for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) {
const bool equal_power_enable_gpio = spi_buses_conf[ver].buses[i].power_enable_gpio == spi_buses_conf[ver -
1].buses[i].power_enable_gpio;
// currently board_control_spi_sensors_power_configgpio() depends on that - this restriction can be removed
// by ensuring board_control_spi_sensors_power_configgpio() is called after the hw version is determined
// and SPI config is initialized.
constexpr_assert(equal_power_enable_gpio, "All HW versions must define the same power enable GPIO");
}
}
return false;
}
#endif // CONFIG_SPI