From 5b2311ef2dca2ae4e026acac87915c7ab35d535a Mon Sep 17 00:00:00 2001 From: Royyan Zahir Date: Tue, 22 Sep 2026 17:05:55 +0400 Subject: [PATCH] boards/arm/imxrt: add the Holybro Pixhawk 6X-RT A MIMXRT1176 flight controller built to the Pixhawk FMUv6X-RT standard, so the port also covers the NXP MR-VMU-RT1176. Board data comes from PX4, which already carries it as a NuttX board config: the clock tree, the LPUART1 pinmux, and the Macronix octal flash configuration block the boot ROM reads at offset 0x400. The board ships with the PX4 bootloader in the first 128 KB of QSPI, so the image links at 0x30020000 and is loaded by it rather than written to the flash base. The console is CDC/ACM as on teensy-4.x, so a USB cable is the only thing needed to run NuttX here. Signed-off-by: Royyan Zahir --- .../arm/imxrt/boards/fmu-v6xrt/index.rst | 115 ++++ .../imxrt/boards/fmu-v6xrt/pixhawk6x-rt.png | Bin 0 -> 139898 bytes boards/Kconfig | 13 + boards/arm/imxrt/fmu-v6xrt/CMakeLists.txt | 30 + boards/arm/imxrt/fmu-v6xrt/Kconfig | 38 ++ .../arm/imxrt/fmu-v6xrt/configs/nsh/defconfig | 56 ++ boards/arm/imxrt/fmu-v6xrt/include/board.h | 588 ++++++++++++++++++ boards/arm/imxrt/fmu-v6xrt/scripts/Make.defs | 49 ++ .../imxrt/fmu-v6xrt/scripts/flash-ocram.ld | 188 ++++++ boards/arm/imxrt/fmu-v6xrt/scripts/flash.ld | 152 +++++ .../imxrt/fmu-v6xrt/scripts/kernel-space.ld | 106 ++++ boards/arm/imxrt/fmu-v6xrt/scripts/memory.ld | 72 +++ .../arm/imxrt/fmu-v6xrt/scripts/user-space.ld | 122 ++++ boards/arm/imxrt/fmu-v6xrt/src/CMakeLists.txt | 33 + boards/arm/imxrt/fmu-v6xrt/src/Makefile | 34 + boards/arm/imxrt/fmu-v6xrt/src/fmu-v6xrt.h | 341 ++++++++++ boards/arm/imxrt/fmu-v6xrt/src/imxrt_boot.c | 135 ++++ .../arm/imxrt/fmu-v6xrt/src/imxrt_bringup.c | 299 +++++++++ .../imxrt/fmu-v6xrt/src/imxrt_clockconfig.c | 506 +++++++++++++++ .../fmu-v6xrt/src/imxrt_flexspi_nor_boot.c | 55 ++ .../fmu-v6xrt/src/imxrt_flexspi_nor_boot.h | 165 +++++ .../fmu-v6xrt/src/imxrt_flexspi_nor_flash.c | 178 ++++++ .../fmu-v6xrt/src/imxrt_flexspi_nor_flash.h | 359 +++++++++++ 23 files changed, 3634 insertions(+) create mode 100644 Documentation/platforms/arm/imxrt/boards/fmu-v6xrt/index.rst create mode 100644 Documentation/platforms/arm/imxrt/boards/fmu-v6xrt/pixhawk6x-rt.png create mode 100644 boards/arm/imxrt/fmu-v6xrt/CMakeLists.txt create mode 100644 boards/arm/imxrt/fmu-v6xrt/Kconfig create mode 100644 boards/arm/imxrt/fmu-v6xrt/configs/nsh/defconfig create mode 100644 boards/arm/imxrt/fmu-v6xrt/include/board.h create mode 100644 boards/arm/imxrt/fmu-v6xrt/scripts/Make.defs create mode 100644 boards/arm/imxrt/fmu-v6xrt/scripts/flash-ocram.ld create mode 100644 boards/arm/imxrt/fmu-v6xrt/scripts/flash.ld create mode 100644 boards/arm/imxrt/fmu-v6xrt/scripts/kernel-space.ld create mode 100644 boards/arm/imxrt/fmu-v6xrt/scripts/memory.ld create mode 100644 boards/arm/imxrt/fmu-v6xrt/scripts/user-space.ld create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/CMakeLists.txt create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/Makefile create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/fmu-v6xrt.h create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/imxrt_boot.c create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/imxrt_bringup.c create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/imxrt_clockconfig.c create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.c create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.h create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.c create mode 100644 boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.h diff --git a/Documentation/platforms/arm/imxrt/boards/fmu-v6xrt/index.rst b/Documentation/platforms/arm/imxrt/boards/fmu-v6xrt/index.rst new file mode 100644 index 00000000000..f4af42f85a4 --- /dev/null +++ b/Documentation/platforms/arm/imxrt/boards/fmu-v6xrt/index.rst @@ -0,0 +1,115 @@ +===================== +Holybro Pixhawk 6X-RT +===================== + +.. tags:: chip:imxrt, chip:imxrt1176, vendor:holybro + +.. figure:: pixhawk6x-rt.png + :scale: 50 % + :align: center + :alt: The Holybro Pixhawk 6X-RT flight controller + + Holybro Pixhawk 6X-RT + +The `Pixhawk 6X-RT `_ +is a flight controller from Holybro built to the Pixhawk FMUv6X-RT open +standard, using the i.MX RT1176 crossover MCU. This board port targets that +standard, so it also covers the +`NXP MR-VMU-RT1176 `_. + +Features +======== + +* MIMXRT1176DVMAA, Cortex-M7 and Cortex-M4. This port clocks the M7 at 996 MHz +* 64 MB external QSPI flash, 2 MB RAM +* CAAM cryptographic accelerator with a hardware entropy source +* STM32F100 IO co-processor +* USB-C device connector +* 2 CAN buses, 100BASE-TX Ethernet, 16 PWM outputs +* Three IMUs on a vibration isolation system, two BMP388 barometers, BMM150 magnetometer +* microSD socket + +Supported in NuttX: the CAAM entropy source through ``/dev/random`` and +``/dev/urandom``, LPUART, USB device and the FlexSPI boot path. + +.. warning:: + + The sensors, CAN, Ethernet and PWM outputs listed above are board features + with no NuttX drivers in this port. Only the peripherals named as supported + are wired up. + +Buttons and LEDs +================ + +The board has no user buttons reachable from NuttX in this port. Its status +LEDs are driven by the flight stack rather than by board logic, and are not +used to signal NuttX state. + +Serial Console +============== + +LPUART1 is on the DEBUG connector at 57600 baud. + +========== ================ ================ +Pin Signal Notes +========== ================ ================ +DEBUG TX GPIO_DISP_B1_02 LPUART1_TX, ALT9 +DEBUG RX GPIO_DISP_B1_03 LPUART1_RX, ALT9 +========== ================ ================ + +The ``nsh`` configuration uses the USB CDC/ACM console instead, so the DEBUG +connector is optional and a USB-C cable is enough. + +Flash Layout +============ + +The board ships with the PX4 bootloader programmed at the base of QSPI flash. +It occupies the first 128 KB and starts the application at ``0x30020000``. +NuttX links to that address and is loaded by the bootloader rather than written +to the flash base. + +=========== ============= ========================== +Address Size Contents +=========== ============= ========================== +0x30000000 128 KB PX4 bootloader, as shipped +0x30020000 4 MB - 128 KB NuttX +=========== ============= ========================== + +.. warning:: + + Writing to the flash base removes the bootloader, and with it the ability to + load firmware over USB. Recovering from that needs SWD. + +Power Supply +============ + +The board is powered over USB-C for bench use, or from the vehicle power +module in flight. Nothing in this port manages power. + +Installation +============ + +The toolchain is the same as for every i.MX RT board; see +:doc:`the platform page <../../index>`. + +Flashing needs ``px_uploader.py`` from the PX4 source tree. The bootloader +enumerates as a USB CDC/ACM device for roughly five seconds after reset, so +start the uploader first and then reset the board: + +.. code-block:: console + + $ python Tools/px_mkfw.py --prototype firmware.prototype --image nuttx.bin > nuttx.px4 + $ python Tools/px_uploader.py --port "/dev/serial/by-id/*PX4*" nuttx.px4 + +The uploader expects a ``.px4`` container rather than a raw binary. + +Configurations +============== + +nsh +--- + +The basic NuttShell configuration. The console is USB CDC/ACM, so the shell +appears on the same connector used for flashing, at ``/dev/ttyACM0`` on the +host. ``/dev/random`` and ``/dev/urandom`` are backed by the CAAM hardware +entropy source. diff --git a/Documentation/platforms/arm/imxrt/boards/fmu-v6xrt/pixhawk6x-rt.png b/Documentation/platforms/arm/imxrt/boards/fmu-v6xrt/pixhawk6x-rt.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b569663a0becaca19b82a48570b9e0ec81b5c8 GIT binary patch literal 139898 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

04IpdxhC@iOk*&jt*aHQEy0b^^ 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

Y?%W!tq44<&i&fTV&9-Hmh% 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 + * David Sidrane + * + * 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 NuttX 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. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_IMXRT_FMU_V6XRT_INCLUDE_BOARD_H +#define __BOARDS_ARM_IMXRT_FMU_V6XRT_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking *****************************************************************/ + +/* The ARM PLL is 996MHz; see imxrt_clockconfig.c for the dividers. */ + +#define BOARD_CPU_FREQUENCY 996000000 +#define IMXRT_IPG_PODF_DIVIDER 5 +#define BOARD_GPT_FREQUENCY 24000000 +#define BOARD_XTAL_FREQUENCY 24000000 +#define BOARD_FLEXIO_PREQ 108000000 + +/* SDIO *********************************************************************/ + +/* Pin drive characteristics - drive strength in particular may need tuning + * for specific boards. + */ + +/* GPIO_SD_B1_02 */ + +#define PIN_USDHC1_D0 (GPIO_USDHC1_DATA0_1 | IOMUX_USDHC1_DATAX_DEFAULT) + +/* GPIO_SD_B1_03 */ + +#define PIN_USDHC1_D1 (GPIO_USDHC1_DATA1_1 | IOMUX_USDHC1_DATAX_DEFAULT) + +/* GPIO_SD_B1_04 */ + +#define PIN_USDHC1_D2 (GPIO_USDHC1_DATA2_1 | IOMUX_USDHC1_DATAX_DEFAULT) + +/* GPIO_SD_B1_05 */ + +#define PIN_USDHC1_D3 (GPIO_USDHC1_DATA3_1 | IOMUX_USDHC1_DATAX_DEFAULT) + +/* GPIO_SD_B1_01 */ + +#define PIN_USDHC1_DCLK (GPIO_USDHC1_CLK_1 | IOMUX_USDHC1_CLK_DEFAULT) + +/* GPIO_SD_B1_00 */ + +#define PIN_USDHC1_CMD (GPIO_USDHC1_CMD_1 | IOMUX_USDHC1_CMD_DEFAULT) + +/* GPIO_AD_32 */ + +#define PIN_USDHC1_CD (GPIO_USDHC1_CD_2 | IOMUX_USDHC1_CLK_DEFAULT) + +/* 386 KHz for initial inquiry stuff */ + +#define BOARD_USDHC_IDMODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV256 +#define BOARD_USDHC_IDMODE_DIVISOR USDHC_SYSCTL_DVS_DIV(2) + +/* 24.8MHz for other modes */ + +#define BOARD_USDHC_MMCMODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 +#define BOARD_USDHC_MMCMODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) + +#define BOARD_USDHC_SD1MODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 +#define BOARD_USDHC_SD1MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) + +#define BOARD_USDHC_SD4MODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 +#define BOARD_USDHC_SD4MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) + +/* LED definitions **********************************************************/ + +/* The px4 fmu-v6x board has numerous LEDs but only three, LED_GREEN a Green + * LED_BLUE a Blue LED and LED_RED a Red LED, that can be controlled by + * software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in + * any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/imxrt_autoleds.c. The LEDs encode OS events as + * follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ ---- + */ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* PIO Disambiguation *******************************************************/ + +/* LPUARTs + * + * We pull down CTS so that if nothing is connected, conde will not block. + */ +#define IOMUX_UART_CTS_DEFAULT (IOMUX_PULL_DOWN | IOMUX_DRIVE_HIGHSTRENGTH | IOMUX_SLEW_SLOW) +#define IOMUX_UART_BOARD_DEFAULT (IOMUX_PULL_NONE | IOMUX_DRIVE_HIGHSTRENGTH | IOMUX_SLEW_FAST) + +/* Debug */ + +/* UART1_RX_DEBUG GPIO_DISP_B1_03 */ + +#define GPIO_LPUART1_RX (GPIO_LPUART1_RX_2|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART1_TX_DEBUG GPIO_DISP_B1_02 */ + +#define GPIO_LPUART1_TX (GPIO_LPUART1_TX_2|IOMUX_UART_BOARD_DEFAULT) + +/* GPS 1 */ + +/* UART3_RX_GPS1 GPIO_AD_31 */ + +#define GPIO_LPUART3_RX (GPIO_LPUART3_RX_1|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART3_TX_GPS1 GPIO_AD_30 */ + +#define GPIO_LPUART3_TX (GPIO_LPUART3_TX_1|IOMUX_UART_DEFAULT) + +/* Telem 1 */ + +/* UART4_CTS_TELEM1 GPIO_DISP_B1_05 */ + +#define GPIO_LPUART4_CTS (GPIO_LPUART4_CTS_1|IOMUX_UART_CTS_DEFAULT|PADMUX_SION) + +/* UART4_RTS_TELEM1 GPIO_DISP_B1_07 GPIO4 Pin 28 */ + +#define GPIO_LPUART4_RTS (GPIO_PORT4 | GPIO_PIN28 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_UART_DEFAULT) + +/* UART4_RX_TELEM1 GPIO_DISP_B1_04 */ + +#define GPIO_LPUART4_RX (GPIO_LPUART4_RX_1|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART4_TX_TELEM1 GPIO_DISP_B1_06 */ + +#define GPIO_LPUART4_TX (GPIO_LPUART4_TX_1|IOMUX_UART_BOARD_DEFAULT) + +/* GPS 2 */ + +/* UART5_RX_GPS2 GPIO_AD_29 */ + +#define GPIO_LPUART5_RX (GPIO_LPUART5_RX_1|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART5_TX_GPS2 GPIO_AD_28 */ + +#define GPIO_LPUART5_TX (GPIO_LPUART5_TX_1|IOMUX_UART_DEFAULT) + +/* PX4IO */ + +/* UART6_RX_FROM_IO__NC GPIO_EMC_B1_41 */ + +#define GPIO_LPUART6_RX (GPIO_LPUART6_RX_1|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART6_TX_TO_IO__RC_INPUT GPIO_EMC_B1_40 */ + +#define GPIO_LPUART6_TX (GPIO_LPUART6_TX_1|IOMUX_UART_DEFAULT) + +/* Telem 2 */ + +/* UART8_CTS_TELEM2 GPIO_AD_04 */ + +#define GPIO_LPUART8_CTS (GPIO_LPUART8_CTS_1|IOMUX_UART_CTS_DEFAULT|PADMUX_SION) + +/* UART8_RTS_TELEM2 GPIO_AD_05 GPIO3 Pin 4 */ + +#define GPIO_LPUART8_RTS (GPIO_PORT3 | GPIO_PIN4 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_UART_DEFAULT) + +/* UART8_RX_TELEM2 GPIO_AD_03 */ + +#define GPIO_LPUART8_RX (GPIO_LPUART8_RX_2|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART8_TX_TELEM2 GPIO_AD_02 */ + +#define GPIO_LPUART8_TX (GPIO_LPUART8_TX_2|IOMUX_UART_BOARD_DEFAULT) + +/* Telem 3 */ + +/* UART10_CTS_TELEM3 GPIO_AD_34 */ + +#define GPIO_LPUART10_CTS (GPIO_LPUART10_CTS_1|IOMUX_UART_CTS_DEFAULT|PADMUX_SION) + +/* UART10_RTS_TELEM3 GPIO_AD_35 GPIO4 Pin 2 */ + +#define GPIO_LPUART10_RTS (GPIO_PORT4 | GPIO_PIN2 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_UART_DEFAULT) + +/* UART10_RX_TELEM3 GPIO_AD_33 */ + +#define GPIO_LPUART10_RX (GPIO_LPUART10_RX_2|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART10_TX_TELEM3 GPIO_AD_15 */ + +#define GPIO_LPUART10_TX (GPIO_LPUART10_TX_1|IOMUX_UART_BOARD_DEFAULT) + +/* Ext 2 */ + +/* No DMA Support at this time for lack of DMA1, DMAMUX1 support */ + +/* UART11_RX_EXTERNAL2 GPIO_LPSR_05 */ + +#define GPIO_LPUART11_RX (GPIO_LPUART11_RX_2|IOMUX_UART_DEFAULT|PADMUX_SION) + +/* UART11_TX_EXTERNAL2 GPIO_LPSR_04 */ + +#define GPIO_LPUART11_TX (GPIO_LPUART11_TX_2|IOMUX_UART_DEFAULT) + +/* CAN + * + * CAN1 is routed to transceiver. + * CAN2 is routed to transceiver. + * CAN3 is routed to transceiver. + */ + +#define FLEXCAN_IOMUX (IOMUX_PULL_UP | IOMUX_SLEW_FAST) + +/* GPIO_AD_06 */ + +#define GPIO_FLEXCAN1_TX (GPIO_FLEXCAN1_TX_1 | FLEXCAN_IOMUX) + +/* GPIO_AD_07 */ + +#define GPIO_FLEXCAN1_RX (GPIO_FLEXCAN1_RX_1 | FLEXCAN_IOMUX) + +/* GPIO_AD_00 */ + +#define GPIO_FLEXCAN2_TX (GPIO_FLEXCAN2_TX_1 | FLEXCAN_IOMUX) + +/* GPIO_AD_01 */ + +#define GPIO_FLEXCAN2_RX (GPIO_FLEXCAN2_RX_1 | FLEXCAN_IOMUX) + +/* GPIO_LPSR_00 */ + +#define GPIO_FLEXCAN3_TX (GPIO_FLEXCAN3_TX_1 | FLEXCAN_IOMUX) + +/* GPIO_LPSR_01 */ + +#define GPIO_FLEXCAN3_RX (GPIO_FLEXCAN3_RX_1 | FLEXCAN_IOMUX) + +/* LPSPI */ + +/* SPI1_MISO_SENSOR1 GPIO_EMC_B2_03 */ + +#define GPIO_LPSPI1_MISO (GPIO_LPSPI1_SDI_2|IOMUX_LPSPI_DEFAULT) + +/* SPI1_MOSI_SENSOR1 GPIO_EMC_B2_02 */ + +#define GPIO_LPSPI1_MOSI (GPIO_LPSPI1_SDO_2|IOMUX_LPSPI_DEFAULT) + +/* SPI1_SCK_SENSOR1 GPIO_EMC_B2_00 */ + +#define GPIO_LPSPI1_SCK (GPIO_LPSPI1_SCK_2|IOMUX_LPSPI_DEFAULT) + +/* SPI2_MISO_SENSOR2 GPIO_AD_27 */ + +#define GPIO_LPSPI2_MISO (GPIO_LPSPI2_SDI_1|IOMUX_LPSPI_DEFAULT) + +/* SPI2_MOSI_SENSOR2 GPIO_AD_26 */ + +#define GPIO_LPSPI2_MOSI (GPIO_LPSPI2_SDO_1|IOMUX_LPSPI_DEFAULT) + +/* SPI2_SCK_SENSOR2 GPIO_AD_24 */ + +#define GPIO_LPSPI2_SCK (GPIO_LPSPI2_SCK_1|IOMUX_LPSPI_DEFAULT) + +/* SPI3_MISO_SENSOR3 GPIO_EMC_B2_07 */ + +#define GPIO_LPSPI3_MISO (GPIO_LPSPI3_SDI_1|IOMUX_LPSPI_DEFAULT) + +/* SPI3_MOSI_SENSOR3 GPIO_EMC_B2_06 */ + +#define GPIO_LPSPI3_MOSI (GPIO_LPSPI3_SDO_1|IOMUX_LPSPI_DEFAULT) + +/* SPI3_SCK_SENSOR3 GPIO_EMC_B2_04 */ + +#define GPIO_LPSPI3_SCK (GPIO_LPSPI3_SCK_1|IOMUX_LPSPI_DEFAULT) + +/* SPI4 Not connected to anything */ + +/* LPSPI6 No DMA Support at this time for lack of DMA1, DMAMUX1 support */ + +/* SPI6_MISO_EXTERNAL1 GPIO_LPSR_12 */ + +#define GPIO_LPSPI6_MISO (GPIO_LPSPI6_SDI_1|IOMUX_LPSPI_DEFAULT) + +/* SPI6_MOSI_EXTERNAL1 GPIO_LPSR_11 */ + +#define GPIO_LPSPI6_MOSI (GPIO_LPSPI6_SDO_1|IOMUX_LPSPI_DEFAULT) + +/* SPI6_SCK_EXTERNAL1 GPIO_LPSR_10 */ + +#define GPIO_LPSPI6_SCK (GPIO_LPSPI6_SCK_1|IOMUX_LPSPI_DEFAULT) + +/* LPI2Cs */ + +/* I2C1_SCL_GPS1 GPIO_AD_08 GPIO_GPIO3_IO07 */ + +#define GPIO_LPI2C1_SCL_RESET (GPIO_PORT3 | GPIO_PIN7 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* I2C1_SDA_GPS1 GPIO_AD_09 GPIO_GPIO3_IO08 */ + +#define GPIO_LPI2C1_SDA_RESET (GPIO_PORT3 | GPIO_PIN8 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* I2C1_SCL_GPS1 GPIO_AD_08 */ + +#define GPIO_LPI2C1_SCL (GPIO_LPI2C1_SCL_2|IOMUX_LPI2C_DEFAULT) + +/* I2C1_SDA_GPS1 GPIO_AD_09 */ + +#define GPIO_LPI2C1_SDA (GPIO_LPI2C1_SDA_2|IOMUX_LPI2C_DEFAULT) + +/* I2C2_SCL_GPS2 GPIO_AD_18 GPIO_GPIO3_IO17 */ + +#define GPIO_LPI2C2_SCL_RESET (GPIO_PORT3 | GPIO_PIN17 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* I2C2_SDA_GPS2 GPIO_AD_19 GPIO_GPIO3_IO18 */ + +#define GPIO_LPI2C2_SDA_RESET (GPIO_PORT3 | GPIO_PIN18 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* I2C2_SCL_GPS2 GPIO_AD_18 */ + +#define GPIO_LPI2C2_SCL (GPIO_LPI2C2_SCL_2|IOMUX_LPI2C_DEFAULT) + +/* I2C2_SDA_GPS2 GPIO_AD_19 */ + +#define GPIO_LPI2C2_SDA (GPIO_LPI2C2_SDA_2|IOMUX_LPI2C_DEFAULT) + +/* I2C3_SCL_FMU GPIO_DISP_B2_10 GPIO_GPIO5_IO11_1 */ + +#define GPIO_LPI2C3_SCL_RESET (GPIO_PORT5 | GPIO_PIN11 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* I2C3_SDA_FMU GPIO_DISP_B2_11 GPIO_GPIO5_IO12_1 */ + +#define GPIO_LPI2C3_SDA_RESET (GPIO_PORT5 | GPIO_PIN12 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* I2C3_SCL_FMU GPIO_DISP_B2_10 */ + +#define GPIO_LPI2C3_SCL (GPIO_LPI2C3_SCL_2|IOMUX_LPI2C_DEFAULT) + +/* I2C3_SDA_FMU GPIO_DISP_B2_11 */ + +#define GPIO_LPI2C3_SDA (GPIO_LPI2C3_SDA_2|IOMUX_LPI2C_DEFAULT) + +/* I2C6_SCL_EXTERNAL2 GPIO_LPSR_07 GPIO_GPIO6_IO07_1 */ + +#define GPIO_LPI2C6_SCL_RESET (GPIO_PORT6 | GPIO_PIN7 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* I2C6_SDA_EXTERNAL2 GPIO_LPSR_06 GPIO_GPIO6_IO06_1 */ + +#define GPIO_LPI2C6_SDA_RESET (GPIO_PORT6 | GPIO_PIN6 | GPIO_OUTPUT | GPIO_OUTPUT_ONE) + +/* LPI2C6 No DMA Support at this time for lack of DMA1, DMAMUX1 support */ + +/* I2C6_SCL_EXTERNAL2 GPIO_LPSR_07 */ + +#define GPIO_LPI2C6_SCL (GPIO_LPI2C6_SCL_1|IOMUX_LPI2C_DEFAULT) + +/* I2C6_SDA_EXTERNAL2 GPIO_LPSR_06 */ + +#define GPIO_LPI2C6_SDA (GPIO_LPI2C6_SDA_1|IOMUX_LPI2C_DEFAULT) + +/* ETH Disambiguation *******************************************************/ + +/* This is the ENET_1G interface. */ + +/* Compile time selection */ +#if defined(CONFIG_ETH0_PHY_TJA1103) +# define BOARD_PHY_ADDR (18) +#endif +#if defined(CONFIG_ETH0_PHY_LAN8742A) +# define BOARD_PHY_ADDR (0) +#endif + +/* Run time selection see mii.h */ + +#define BOARD_ETH0_PHY_LIST \ + { \ + "LAN8742A", \ + MII_PHYID1_LAN8742A, \ + MII_PHYID2_LAN8742A, \ + MII_LAN8740_SCSR, \ + 0, \ + 0xffff, \ + MII_LAN8720_SPSCR_10MBPS, \ + MII_LAN8720_SPSCR_100MBPS, \ + MII_LAN8720_SPSCR_DUPLEX, \ + 22, \ + }, \ + { \ + "TJA1103", \ + MII_PHYID1_TJA1103, \ + MII_PHYID2_TJA1103, \ + 0xffff, \ + 18, \ + 0xffff, \ + 0, \ + MII_LAN8720_SPSCR_100MBPS, \ + MII_LAN8720_SPSCR_DUPLEX, \ + 45, \ + }, \ + +/* GPIO_DISP_B1_09 */ + +#define GPIO_ENET2_TX_DATA00 (GPIO_ENET_1G_TX_DATA0_1|IOMUX_ENET_DATA_DEFAULT) + +/* GPIO_DISP_B1_08 */ + +#define GPIO_ENET2_TX_DATA01 (GPIO_ENET_1G_TX_DATA1_1|IOMUX_ENET_DATA_DEFAULT) + +/* GPIO_EMC_B2_15 */ + +#define GPIO_ENET2_RX_DATA00 (GPIO_ENET_1G_RX_DATA0_2|IOMUX_ENET_DATA_DEFAULT) + +/* GPIO_EMC_B2_16 */ + +#define GPIO_ENET2_RX_DATA01 (GPIO_ENET_1G_RX_DATA1_2|IOMUX_ENET_DATA_DEFAULT) + +/* GPIO_EMC_B2_20 */ + +#define GPIO_ENET2_MDIO (GPIO_ENET_1G_MDIO_1|IOMUX_ENET_MDIO_DEFAULT) + +/* GPIO_EMC_B2_19 */ + +#define GPIO_ENET2_MDC (GPIO_ENET_1G_MDC_1|IOMUX_ENET_MDC_DEFAULT) + +/* GPIO_DISP_B1_00 */ + +#define GPIO_ENET2_RX_EN (GPIO_ENET_1G_RX_EN_1|IOMUX_ENET_EN_DEFAULT) + +/* GPIO_DISP_B1_01 */ + +#define GPIO_ENET2_RX_ER (GPIO_ENET_RX_ER_1|IOMUX_ENET_RXERR_DEFAULT) + +/* GPIO_DISP_B1_11 */ + +#define GPIO_ENET2_TX_CLK (GPIO_ENET_1G_REF_CLK_1|IOMUX_ENET_TX_CLK_DEFAULT) + +/* GPIO_DISP_B1_10 */ + +#define GPIO_ENET2_TX_EN (GPIO_ENET_1G_TX_EN_1|IOMUX_ENET_EN_DEFAULT) + +/* Board provides GPIO or other Hardware for signaling to timing analyzer */ + +#if defined(CONFIG_BOARD_USE_PROBES) +#define PROBE_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_SLEW_FAST) +# define PROBE_N(n) (1<<((n)-1)) +# define PROBE_1 /* GPIO_EMC_B1_23 */ (GPIO_PORT1 | GPIO_PIN23 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_2 /* GPIO_EMC_B1_25 */ (GPIO_PORT1 | GPIO_PIN25 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_3 /* GPIO_EMC_B1_27 */ (GPIO_PORT1 | GPIO_PIN27 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_4 /* GPIO_EMC_B1_06 */ (GPIO_PORT1 | GPIO_PIN6 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_5 /* GPIO_EMC_B1_08 */ (GPIO_PORT1 | GPIO_PIN8 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_6 /* GPIO_EMC_B1_10 */ (GPIO_PORT1 | GPIO_PIN10 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_7 /* GPIO_EMC_B1_19 */ (GPIO_PORT1 | GPIO_PIN19 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_8 /* GPIO_EMC_B1_29 */ (GPIO_PORT1 | GPIO_PIN29 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_9 /* GPIO_EMC_B1_31 */ (GPIO_PORT1 | GPIO_PIN31 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_10 /* GPIO_EMC_B1_21 */ (GPIO_PORT1 | GPIO_PIN21 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_11 /* GPIO_EMC_B1_00 */ (GPIO_PORT1 | GPIO_PIN0 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) +# define PROBE_12 /* GPIO_EMC_B1_02 */ (GPIO_PORT1 | GPIO_PIN2 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | PROBE_IOMUX) + +# define PROBE_INIT(mask) \ + do { \ + if ((mask)& PROBE_N(1)) { imxrt_config_gpio(PROBE_1); } \ + if ((mask)& PROBE_N(2)) { imxrt_config_gpio(PROBE_2); } \ + if ((mask)& PROBE_N(3)) { imxrt_config_gpio(PROBE_3); } \ + if ((mask)& PROBE_N(4)) { imxrt_config_gpio(PROBE_4); } \ + if ((mask)& PROBE_N(5)) { imxrt_config_gpio(PROBE_5); } \ + if ((mask)& PROBE_N(6)) { imxrt_config_gpio(PROBE_6); } \ + if ((mask)& PROBE_N(7)) { imxrt_config_gpio(PROBE_7); } \ + if ((mask)& PROBE_N(8)) { imxrt_config_gpio(PROBE_8); } \ + if ((mask)& PROBE_N(9)) { imxrt_config_gpio(PROBE_9); } \ + if ((mask)& PROBE_N(10)) { imxrt_config_gpio(PROBE_10); } \ + if ((mask)& PROBE_N(11)) { imxrt_config_gpio(PROBE_11); } \ + if ((mask)& PROBE_N(12)) { imxrt_config_gpio(PROBE_12); } \ + } while(0) + +# define PROBE(n,s) do {imxrt_gpio_write(PROBE_##n,(s));}while(0) +# define PROBE_MARK(n) PROBE(n,false);PROBE(n,true) +#else +# define PROBE_INIT(mask) +# define PROBE(n,s) +# define PROBE_MARK(n) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_IMXRT_FMU_V6XRT_INCLUDE_BOARD_H */ diff --git a/boards/arm/imxrt/fmu-v6xrt/scripts/Make.defs b/boards/arm/imxrt/fmu-v6xrt/scripts/Make.defs new file mode 100644 index 00000000000..fa147466fff --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/scripts/Make.defs @@ -0,0 +1,49 @@ +############################################################################ +# boards/arm/imxrt/fmu-v6xrt/scripts/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs + +ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y) + LDSCRIPT = flash.ld +else ifeq ($(CONFIG_BOOT_RUNFROMISRAM),y) + LDSCRIPT = flash-ocram.ld +endif + +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +# Loadable module definitions + +CMODULEFLAGS = $(CFLAGS) -mlong-calls # --target1-abs + +LDMODULEFLAGS = -r -e module_initialize +LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) diff --git a/boards/arm/imxrt/fmu-v6xrt/scripts/flash-ocram.ld b/boards/arm/imxrt/fmu-v6xrt/scripts/flash-ocram.ld new file mode 100644 index 00000000000..a3b10c27dd5 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/scripts/flash-ocram.ld @@ -0,0 +1,188 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/scripts/flash-ocram.ld + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Specify the memory areas */ + +/* The fmu-v6xrt has 8MiB of QSPI FLASH beginning at address, + * 0x0060:0000, Upto 512Kb of DTCM RAM beginning at 0x2000:0000, and 1MiB OCRAM + * beginning at 0x2020:0000. Neither DTCM or SDRAM are used in this + * configuration. + * + * The default flexram setting on the iMXRT 1064 is + * 256Kib to OCRRAM, 128Kib ITCM and 128Kib DTCM. + * This can be changed by using a dcd by minipulating + * IOMUX GPR16 and GPR17. + * The configuration we will use is 384Kib to OCRRAM, 0Kib ITCM and + * 128Kib DTCM. + * + * This is the OCRAM inker script. + * The NXP ROM bootloader will move the FLASH image to OCRAM. + * We must reserve 32K for the bootloader' OCRAM usage from the OCRAM Size + * and an additional 8K for the ivt_s which is IVT_SIZE(8K) This 40K can be + * reused once the application is running. + * + * 0x2020:A000 to 0x202d:ffff - The application Image's vector table + * 0x2020:8000 to 0x2020:A000 - IVT + * 0x2020:0000 to 0x2020:7fff - NXP ROM bootloader. + * + * We artificially split the FLASH to allow locating sections that we do not + * want loaded inoto OCRAM. This is to save on OCRAM where the speen of the + * code does not matter. + * + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x30000000, LENGTH = 3M + flashxip (rx) : ORIGIN = 0x30300000, LENGTH = 1M + /* Vectors @ boot+ivt OCRAM2 Flex RAM Boot IVT */ + sram (rwx) : ORIGIN = 0x20240000, LENGTH = 512K /* TODO OCRAM2*/ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 0K + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 0 +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +EXTERN(g_flash_config) +EXTERN(g_image_vector_table) +EXTERN(g_boot_data) +EXTERN(g_dcd_data) + +ENTRY(_stext) + +SECTIONS +{ + /* Image Vector Table and Boot Data for booting from external flash */ + + .boot_hdr : ALIGN(4) + { + FILL(0xff) + __boot_hdr_start__ = ABSOLUTE(.) ; + KEEP(*(.boot_hdr.conf)) + . = 0x1000 ; + KEEP(*(.boot_hdr.ivt)) + . = 0x1020 ; + KEEP(*(.boot_hdr.boot_data)) + . = 0x1030 ; + KEEP(*(.boot_hdr.dcd_data)) + __boot_hdr_end__ = ABSOLUTE(.) ; + . = 0x2000 ; + } > flash + + /* Catch all the section we want not in OCRAM so that the *(.text .text.*) in flash does not */ + + .flashxip : ALIGN(4) + { + FILL(0xff) + + /* Order matters */ + + imxrt_start.o(.text) + imxrt_boot.o(.text) + + *(.slow_memory) + *(.rodata .rodata.*) + KEEP(*(__param*)) + *(.fixup) + *(.gnu.warning) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + + } > flashxip + + .text : + { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + _etext = ABSOLUTE(.); + } > sram AT > flash + + .init_section : + { + _sinit = ABSOLUTE(.); + *(.init_array .init_array.*) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : + { + *(.ARM.extab*) + } > sram AT > flash + + .ARM.exidx : + { + __exidx_start = ABSOLUTE(.); + *(.ARM.exidx*) + __exidx_end = ABSOLUTE(.); + } > sram AT > flash + + _eronly = ABSOLUTE(.); + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + .ramfunc ALIGN(4): + { + _sramfuncs = ABSOLUTE(.); + *(.ramfunc .ramfunc.*) + _eramfuncs = ABSOLUTE(.); + } > sram AT > flash + + _framfuncs = LOADADDR(.ramfunc); + + .bss : + { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/arm/imxrt/fmu-v6xrt/scripts/flash.ld b/boards/arm/imxrt/fmu-v6xrt/scripts/flash.ld new file mode 100644 index 00000000000..6e40c634ea4 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/scripts/flash.ld @@ -0,0 +1,152 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/scripts/flash.ld + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Specify the memory areas */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x30020000, LENGTH = 4M-128K /* loaded by the PX4 bootloader */ + sram (rwx) : ORIGIN = 0x20240000, LENGTH = 1024K /* OCRAM1 + OCRAM2*/ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 256K /* TODO FlexRAM partition */ + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 256K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +EXTERN(g_flash_config) +EXTERN(g_image_vector_table) +EXTERN(g_boot_data) + +ENTRY(_stext) + +SECTIONS +{ + /* Image Vector Table and Boot Data for booting from external flash */ + + .boot_hdr : ALIGN(4) + { + FILL(0xff) + . = 0x400 ; + __boot_hdr_start__ = ABSOLUTE(.) ; + KEEP(*(.boot_hdr.conf)) + . = 0x1000 ; + KEEP(*(.boot_hdr.ivt)) + . = 0x1020 ; + KEEP(*(.boot_hdr.boot_data)) + . = 0x1030 ; + KEEP(*(.boot_hdr.dcd_data)) + __boot_hdr_end__ = ABSOLUTE(.) ; + . = 0x2000 ; + } >flash + + /* The RAM vector table (if present) should lie at the beginning of SRAM */ + + .ram_vectors : { + *(.ram_vectors) + } > sram + + .text : ALIGN(4) + { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + .init_section : + { + _sinit = ABSOLUTE(.); + *(.init_array .init_array.*) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : + { + *(.ARM.extab*) + } > flash + + .ARM.exidx : + { + __exidx_start = ABSOLUTE(.); + *(.ARM.exidx*) + __exidx_end = ABSOLUTE(.); + } > flash + + _eronly = ABSOLUTE(.); + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + .ramfunc ALIGN(4): + { + _sramfuncs = ABSOLUTE(.); + *(.ramfunc .ramfunc.*) + _eramfuncs = ABSOLUTE(.); + } > sram AT > flash + + _framfuncs = LOADADDR(.ramfunc); + + .bss : + { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + _boot_loadaddr = ORIGIN(flash); + _boot_size = LENGTH(flash); + _ram_size = LENGTH(sram); +} diff --git a/boards/arm/imxrt/fmu-v6xrt/scripts/kernel-space.ld b/boards/arm/imxrt/fmu-v6xrt/scripts/kernel-space.ld new file mode 100644 index 00000000000..c65ce0efdcc --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/scripts/kernel-space.ld @@ -0,0 +1,106 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/scripts/kernel-space.ld + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* NOTE: This depends on the memory.ld script having been included prior to + * this script. + */ + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +SECTIONS +{ + .text : + { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > kflash + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > kflash + + .ARM.extab : + { + *(.ARM.extab*) + } > kflash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : + { + *(.ARM.exidx*) + } > kflash + + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > kocram AT > kflash + + .bss : + { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > kocram + + /* Stabs debugging sections */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/arm/imxrt/fmu-v6xrt/scripts/memory.ld b/boards/arm/imxrt/fmu-v6xrt/scripts/memory.ld new file mode 100644 index 00000000000..968e0e421b8 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/scripts/memory.ld @@ -0,0 +1,72 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/scripts/memory.ld + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* The i.MXRT1064-EVK has 8MiB of Hyper FLASH beginning at address, + * 0x0060:0000, Up to 512Kb of DTCM RAM beginning at 0x2000:0000, and 1MiB OCRAM + * beginning at 0x2020:0000. Neither DTCM or SDRAM are used in this + * configuration. + * + * The user and kernel space partitions will be spanned with a single + * region of size 2**n bytes. As a consequence, as the partitions increase + * in size, the alignment requirement also increases. The sizes below give + * the largest possible user address spaces (but leave far too much for the + * OS). + * + * The solution to this wasted memory is to (1) use more than one region to + * span the user spaces, or (2) poke holes in a larger region (via sub- + * regions) to trim it to fit better. + * + * A detailed memory map for the 512KB SRAM region is as follows: + * + * 0x2020 0000: Kernel .data region. Typical size: 0.1KB + * ------ ---- Kernel .bss region. Typical size: 1.8KB + * 0x2020 0800: Kernel IDLE thread stack (approximate). Size is + * determined by CONFIG_IDLETHREAD_STACKSIZE and + * adjustments for alignment. Typical is 1KB. + * ------ ---- Padded to 4KB + * 0x2040 0000: User .data region. Size is variable. + * ------- ---- User .bss region Size is variable. + * 0x2042 0000: Beginning of kernel heap. Size determined by + * CONFIG_MM_KERNEL_HEAPSIZE. + * ------ ---- Beginning of user heap. Can vary with other settings. + * 0x2080 0000: End+1 of mappable OCRAM + */ + +/* Specify the memory areas */ + +MEMORY +{ + /* 16MiB of QSPI */ + + kflash (rx) : ORIGIN = 0x30000000, LENGTH = 1M + uflash (rx) : ORIGIN = 0x30200000, LENGTH = 1M + flash (rx) : ORIGIN = 0x30400000, LENGTH = 14M + + /* 1MiB of OCRAM */ + + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 256K + kocram (rwx) : ORIGIN = 0x20240000, LENGTH = 512K + uocram (rwx) : ORIGIN = 0x20280000, LENGTH = 512K +} + + + _ram_size = LENGTH(kocram) + LENGTH(uocram); \ No newline at end of file diff --git a/boards/arm/imxrt/fmu-v6xrt/scripts/user-space.ld b/boards/arm/imxrt/fmu-v6xrt/scripts/user-space.ld new file mode 100644 index 00000000000..bf11418dcdb --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/scripts/user-space.ld @@ -0,0 +1,122 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/scripts/user-space.ld + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* NOTE: This depends on the memory.ld script having been included prior to + * this script. + */ + +/* Make sure that the critical memory management functions are in user-space. + * the user heap memory manager will reside in user-space but be usable both + * by kernel- and user-space code + */ + +EXTERN(umm_initialize) +EXTERN(umm_addregion) +EXTERN(umm_trysemaphore) +EXTERN(umm_givesemaphore) + +EXTERN(malloc) +EXTERN(realloc) +EXTERN(zalloc) +EXTERN(free) + +OUTPUT_ARCH(arm) +SECTIONS +{ + .userspace : + { + *(.userspace) + } > uflash + + .text : + { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > uflash + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > uflash + + .ARM.extab : + { + *(.ARM.extab*) + } > uflash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : + { + *(.ARM.exidx*) + } > uflash + + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > uocram AT > uflash + + .bss : + { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > uocram + + /* Stabs debugging sections */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/arm/imxrt/fmu-v6xrt/src/CMakeLists.txt b/boards/arm/imxrt/fmu-v6xrt/src/CMakeLists.txt new file mode 100644 index 00000000000..22596a36b9c --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/CMakeLists.txt @@ -0,0 +1,33 @@ +# ############################################################################## +# boards/arm/imxrt/fmu-v6xrt/src/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +set(SRCS imxrt_boot.c imxrt_flexspi_nor_boot.c imxrt_flexspi_nor_flash.c + imxrt_clockconfig.c imxrt_bringup.c) + +target_sources(board PRIVATE ${SRCS}) + +if(CONFIG_BOOT_RUNFROMFLASH) + set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash.ld") +elseif(CONFIG_BOOT_RUNFROMISRAM) + set_property(GLOBAL PROPERTY LD_SCRIPT + "${NUTTX_BOARD_DIR}/scripts/flash-ocram.ld") +endif() diff --git a/boards/arm/imxrt/fmu-v6xrt/src/Makefile b/boards/arm/imxrt/fmu-v6xrt/src/Makefile new file mode 100644 index 00000000000..f11b15bd63a --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# boards/arm/imxrt/fmu-v6xrt/src/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +CSRCS = imxrt_boot.c imxrt_flexspi_nor_boot.c imxrt_flexspi_nor_flash.c +CSRCS += imxrt_clockconfig.c + +ifeq ($(CONFIG_BOARDCTL),y) +CSRCS += imxrt_bringup.c +else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y) +CSRCS += imxrt_bringup.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/imxrt/fmu-v6xrt/src/fmu-v6xrt.h b/boards/arm/imxrt/fmu-v6xrt/src/fmu-v6xrt.h new file mode 100644 index 00000000000..09e2401339b --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/fmu-v6xrt.h @@ -0,0 +1,341 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/fmu-v6xrt.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +#ifndef __BOARDS_ARM_IMXRT_FMU_V6XRT_SRC_FMU_V6XRT_H +#define __BOARDS_ARM_IMXRT_FMU_V6XRT_SRC_FMU_V6XRT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "imxrt_gpio.h" +#include "imxrt_iomuxc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Touchscreen definitions **************************************************/ + +/* The i.MX RT1170 EVK has a connector (J48) for RK055AHD091-CTG or + * RK055IQH091-CTG LCDs. The RK055AHD091-CTG comes with the GT911 + * touchscreen driver chip integrated. GT911 is connected to the LPI2C5 bus. + */ + +/* LPI2C address of the GT911 touchscreen driver chip */ + +#define GT911_I2C_ADDRESS 0x5d + +/* i.MX RT 1176 GPIO Pin Definitions ****************************************/ + +/* LEDs */ + +/* There are five LED status indicators located on the EVK Board. + * The functions of these LEDs include: + * + * - Main Power Supply (D16) + * Green: DC 5V main supply is normal. + * Red: J43 input voltage is over 5.6V. + * Off: The board is not powered. + * - Reset LED - Red (D7) + * - OpenSDA LED - Red (D5) + * - USER LED 1 - Green (D6) + * - USER LED 2 - Red (D34) + * + * Only two LEDs, D6 & D34, are under software control. + */ + +#define GPIO_LED1 (GPIO_OUTPUT | IOMUX_LED_DEFAULT | GPIO_OUTPUT_ZERO | \ + GPIO_PORT3 | GPIO_PIN3) /* GPIO_AD_04 */ +#define GPIO_LED2 (GPIO_OUTPUT | IOMUX_LED_DEFAULT | GPIO_OUTPUT_ZERO | \ + GPIO_PORT3 | GPIO_PIN25) /* GPIO_AD_26 */ + +#define LED_DRIVER_PATH "/dev/userleds" + +/* Buttons ******************************************************************/ + +/* The IMXRT1170-EVK board has seven (sets of) switches or buttons: + * + * - External boot configuration switches (SW1) + * - External boot configuration switches (SW2) + * - MCU reset button (SW3) + * - System Reset Button / POR_BUTTON (SW4) + * - 5V power switch (SW5) + * - CPU ONOFF Button (SW6) + * - CPU Wakeup Button / USER_BUTTON (SW7) + * + * Only one button, SW7, can be used for user input. + */ + +#define GPIO_SW7 (GPIO_INTERRUPT | GPIO_INTBOTH_EDGES | \ + IOMUX_SW_DEFAULT | GPIO_PORT13 | \ + GPIO_PIN0) /* WAKEUP */ + +#define GPIO_SW7_INT (_IMXRT_GPIO13_BASE+0) + +/* LCD Backlight */ + +#define GPIO_LCD_BL (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GPIO_PORT3 | \ + GPIO_PIN30 | IOMUX_LCD_BL_DEFAULT) /* GPIO_AD_30 */ + +/* 10/100 Mbps Ethernet & Gigabit Ethernet */ + +/* 10/100 Mbps Ethernet Interrupt: GPIO_AD_12 + * Gigabit Ethernet Interrupt: GPIO_DISP_B2_12 + * + * This pin has a week pull-up within the PHY, is open-drain, and requires + * an external 1k ohm pull-up resistor (present on the EVK). A falling + * edge then indicates a change in state of the PHY. + */ + +#define GPIO_ENET_INT (IOMUX_ENET_INT_DEFAULT | GPIO_OUTPUT | \ + GPIO_PORT3 | GPIO_PIN11) /* GPIO_AD_12 */ +#define GPIO_ENET_IRQ IMXRT_IRQ_GPIO3_0_15 + +#define GPIO_ENET1G_INT (IOMUX_ENET_INT_DEFAULT | \ + GPIO_PORT5 | GPIO_PIN13) /* GPIO_DISP_B2_12 */ +#define GPIO_ENET1G_IRQ IMXRT_IRQ_GPIO5_13 + +/* 10/100 Mbps Ethernet Reset: GPIO_LPSR_12 + * Gigabit Ethernet Reset: GPIO_DISP_B2_13 + * + * The #RST uses inverted logic. The initial value of zero will put the + * PHY into the reset state. + */ + +#define GPIO_ENET_RST (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | \ + GPIO_PORT6 | GPIO_PIN12 | \ + IOMUX_ENET_RST_DEFAULT) /* GPIO_LPSR_12 */ + +#define GPIO_ENET1G_RST (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | \ + GPIO_PORT5 | GPIO_PIN14 | \ + IOMUX_ENET_RST_DEFAULT) /* GPIO_DISP_B2_13 */ + +/* LPSPI1 CS: GPIO_AD_29 */ + +#define IOMUX_LPSPI1_CS (IOMUX_SLEW_FAST | IOMUX_DRIVE_HIGHSTRENGTH | \ + IOMUX_PULL_UP) +#define GPIO_LPSPI1_CS (GPIO_OUTPUT | GPIO_OUTPUT_ONE | \ + GPIO_PORT3 | GPIO_PIN28 | \ + IOMUX_LPSPI1_CS) /* GPIO_AD_29 */ + +/* LPSPI6 CS: GPIO_LPSR_09 */ + +#define IOMUX_LPSPI6_CS (IOMUX_SLEW_FAST | IOMUX_DRIVE_HIGHSTRENGTH | \ + IOMUX_PULL_UP) +#define GPIO_LPSPI6_CS (GPIO_OUTPUT | GPIO_OUTPUT_ONE | \ + GPIO_PORT6 | GPIO_PIN9 | \ + IOMUX_LPSPI6_CS) /* GPIO_LPSR_09 */ + +/* Touchscreen + * + * Interrupt line: GPIO_AD_00 + * + * The interrupt line coming from the GT911 touchscreen driver IC. + * The touchscreen driver is integrated into the optional RK055AHD091-CTG LCD + * panel and it's connected to the LPI2C5 bus. + * + * Reset line: GPIO_AD_01 + * + * The reset line is active low. + */ + +#define GPIO_GT911_INTR IMXRT_IRQ_GPIO2_31 /* GPIO_AD_00 */ + +#define IOMUX_GT911_RST (IOMUX_PULL_NONE | IOMUX_CMOS_OUTPUT | \ + IOMUX_DRIVE_40OHM | IOMUX_SPEED_MEDIUM | \ + IOMUX_SLEW_SLOW) +#define GPIO_GT911_CTRST_N (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | \ + GPIO_PORT3 | GPIO_PIN0 | \ + IOMUX_GT911_RST) /* GPIO_AD_01 */ + +/* Test Pins ****************************************************************/ + +#define BOARD_NGPIOIN 0 /* Amount of GPIO Input pins */ +#define BOARD_NGPIOOUT 4 /* Amount of GPIO Output pins */ +#define BOARD_NGPIOINT 0 /* Amount of GPIO Input w/ Interruption pins */ + +#define GPIO_GOUT1 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT5 | GPIO_PIN12) /* GPIO_DISP_B2_11 */ + +#define GPIO_GOUT2 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT5 | GPIO_PIN11) /* GPIO_DISP_B2_10 */ + +#define GPIO_GOUT3 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT5 | GPIO_PIN13) /* GPIO_DISP_B2_12 */ + +#define GPIO_GOUT4 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT3 | GPIO_PIN3) /* GPIO_AD_04 */ + +/* USB OTG1 ID Pin: GPIO_AD_09 + * USB OTG2 ID Pin: GPIO_AD_08 + */ + +#define GPIO_USBOTG1_ID (GPIO_USB_OTG1_ID_1 | IOMUX_USBOTG_ID_DEFAULT) /* GPIO_AD_09 */ +#define GPIO_USBOTG2_ID (GPIO_USB_OTG2_ID_1 | IOMUX_USBOTG_ID_DEFAULT) /* GPIO_AD_08 */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: imxrt_bringup + * + * Description: + * Bring up board features + * + ****************************************************************************/ + +#if defined(CONFIG_BOARDCTL) || defined(CONFIG_BOARD_LATE_INITIALIZE) +int imxrt_bringup(void); +#endif + +/**************************************************************************** + * Name: imxrt_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the i.MXRT1050 EVK. + * + ****************************************************************************/ + +void imxrt_spidev_initialize(void); + +/**************************************************************************** + * Name: imxrt_mmcsd_spi_initialize + * + * Description: + * Initialize SPI-based SD card and card detect thread. + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD_SPI +int imxrt_mmcsd_spi_initialize(int minor) +#endif + +/**************************************************************************** + * Name: imxrt_autoled_initialize + * + * Description: + * Initialize NuttX-controlled LED logic + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_LEDS +void imxrt_autoled_initialize(void); +#endif + +/**************************************************************************** + * Name: imxrt_gpio_initialize + * + * Description: + * Initialize GPIO drivers for use with /apps/examples/gpio + * + ****************************************************************************/ + +#ifdef CONFIG_DEV_GPIO +int imxrt_gpio_initialize(void); +#endif + +/**************************************************************************** + * Name: imxrt_can_setup + * + * Description: + * Initialize CAN and register the CAN device + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_FLEXCAN +int imxrt_can_setup(void); +#endif + +/**************************************************************************** + * Name: imxrt_adc_initialize + * + * Description: + * Initialize ADC drivers + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_ADC +int imxrt_adc_initialize(void); +#endif + +/**************************************************************************** + * Name: imxrt_ft5x06_register + * + * Description: + * Initialize ft5x06 IC touchscreen driver + * + ****************************************************************************/ + +#ifdef CONFIG_INPUT_FT5X06 +int imxrt_ft5x06_register(void); +#endif + +/**************************************************************************** + * Name: imxrt_backlight + * + * Description: + * Initialize the backlight pins of the LCD and turn it ON + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_LCD +void imxrt_lcd_initialize(void); +#endif + +#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) +int imxrt_usbhost_initialize(void); +#endif + +#ifdef CONFIG_IMXRT1170_FLEXSPI_NOR +int imxrt_flexspi_nor_initialize(void); +#endif + +#ifdef CONFIG_IMXRT1170_FLEXSPI_FRAM +int imxrt_flexspi_fram_initialize(void); +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_IMXRT_FMU_V6XRT_SRC_FMU_V6XRT_H */ diff --git a/boards/arm/imxrt/fmu-v6xrt/src/imxrt_boot.c b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_boot.c new file mode 100644 index 00000000000..ad3135f0de7 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_boot.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/imxrt_boot.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "imxrt_start.h" +#include "fmu-v6xrt.h" +#include "arm_internal.h" +#include "imxrt_flexspi_nor_boot.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_ocram_initialize + * + * Description: + * Called off reset vector to reconfigure the flexRAM + * and finish the FLASH to RAM Copy. + * + ****************************************************************************/ + +void imxrt_ocram_initialize(void) +{ + const uint32_t *src; + uint32_t *dest; + uint32_t regval; + + /* Reallocate 128K of Flex RAM from ITCM to OCRAM + * Final Configuration is + * 128 DTCM + * + * 128 FlexRAM OCRAM (202C:0000-202D:ffff) + * 256 FlexRAM OCRAM (2028:0000-202B:ffff) + * 512 System OCRAM2 (2020:0000-2027:ffff) + * */ + + putreg32(0xaa555555, IMXRT_IOMUXC_GPR_GPR17); + regval = getreg32(IMXRT_IOMUXC_GPR_GPR16); + putreg32(regval | GPR_GPR16_FLEXRAM_BANK_CFG_SEL, IMXRT_IOMUXC_GPR_GPR16); + + src = (uint32_t *) (LOCATE_IN_SRC(g_boot_data.start) + g_boot_data.size); + dest = (uint32_t *) (g_boot_data.start + g_boot_data.size); + + while (dest < (uint32_t *) &_etext) + { + *dest++ = *src++; + } +} + +/**************************************************************************** + * Name: imxrt_flexram_partition + * + * Description: + * Sets FlexRAM partitioning + * + ****************************************************************************/ + +void imxrt_flexram_partition(void) +{ +} + +/**************************************************************************** + * Name: imxrt_boardinitialize + * + * Description: + * All i.MX RT architectures must provide the following entry point. This + * entry point is called early in the initialization -- after clocking and + * memory have been configured but before caches have been enabled and + * before any devices have been initialized. + * + ****************************************************************************/ + +void imxrt_boardinitialize(void) +{ + /* Configure on-board LEDs if LED support has been selected. */ + +#ifdef CONFIG_ARCH_LEDS + imxrt_autoled_initialize(); +#endif +} + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional + * initialization call will be performed in the boot-up sequence to a + * function called board_late_initialize(). board_late_initialize() will + * be called immediately after up_intitialize() is called and just before + * the initial application is started. This additional initialization + * phase may be used, for example, to initialize board-specific device + * drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + /* Perform board initialization */ + + imxrt_bringup(); +} +#endif /* CONFIG_BOARD_LATE_INITIALIZE */ diff --git a/boards/arm/imxrt/fmu-v6xrt/src/imxrt_bringup.c b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_bringup.c new file mode 100644 index 00000000000..c8aaed2b7ea --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_bringup.c @@ -0,0 +1,299 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/imxrt_bringup.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_IMXRT_USDHC +# include "imxrt_usdhc.h" +#endif + +#ifdef CONFIG_USBMONITOR +# include +#endif + +#ifdef CONFIG_PL2303 +# include +#endif + +#include "imxrt_enet.h" +#include "fmu-v6xrt.h" + +#include /* Must always be included last */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Checking needed by MMC/SDCard */ + +#ifdef CONFIG_NSH_MMCSDMINOR +# define MMCSD_MINOR CONFIG_NSH_MMCSDMINOR +#else +# define MMCSD_MINOR 0 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#if defined(CONFIG_I2C_DRIVER) && defined(CONFIG_IMXRT_LPI2C) +static void imxrt_i2c_register(int bus) +{ + struct i2c_master_s *i2c; + int ret; + + i2c = imxrt_i2cbus_initialize(bus); + if (i2c == NULL) + { + i2cerr("ERROR: Failed to get I2C%d interface\n", bus); + } + else + { + ret = i2c_register(i2c, bus); + if (ret < 0) + { + i2cerr("ERROR: Failed to register I2C%d driver: %d\n", bus, ret); + imxrt_i2cbus_uninitialize(i2c); + } + } +} +#endif + +#ifdef CONFIG_IMXRT_USDHC +static int nsh_sdmmc_initialize(void) +{ + struct sdio_dev_s *sdmmc; + int ret = 0; + + /* Get an instance of the SDIO interface */ + + sdmmc = imxrt_usdhc_initialize(0); + if (!sdmmc) + { + syslog(LOG_ERR, "ERROR: Failed to initialize SD/MMC\n"); + } + else + { + /* Bind the SDIO interface to the MMC/SD driver */ + + ret = mmcsd_slotinitialize(0, sdmmc); + if (ret != OK) + { + syslog(LOG_ERR, + "ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", + ret); + } + + imxrt_usdhc_set_sdio_card_isr(sdmmc, NULL, NULL); + } + + return OK; +} +#else +# define nsh_sdmmc_initialize() (OK) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_bringup + * + * Description: + * Bring up board features + * + ****************************************************************************/ + +int imxrt_bringup(void) +{ + int ret; + + /* If we got here then perhaps not all initialization was successful, but + * at least enough succeeded to bring-up NSH with perhaps reduced + * capabilities. + */ + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to mount procfs at /proc: %d\n", ret); + } +#endif + +#if defined(CONFIG_I2C_DRIVER) && defined(CONFIG_IMXRT_LPI2C5) + imxrt_i2c_register(5); +#endif + +#ifdef CONFIG_IMXRT_USDHC + /* Initialize SDHC-base MMC/SD card support */ + + nsh_sdmmc_initialize(); +#endif + +#ifdef CONFIG_IMXRT_LPSPI + imxrt_spidev_initialize(); +#endif + +#ifdef CONFIG_MMCSD_SPI + /* Initialize SPI-based MMC/SD card support */ + + ret = imxrt_mmcsd_spi_initialize(MMCSD_MINOR); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to initialize SD slot %d: %d\n", ret); + } +#endif + +#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) + ret = imxrt_usbhost_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to start USB host services: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_USBMONITOR + /* Start the USB Monitor */ + + ret = usbmonitor_start(); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to start USB monitor: %d\n", ret); + } +#endif + +#if defined(CONFIG_IMXRT_ENET) && defined(CONFIG_NETDEV_LATEINIT) + ret = imxrt_netinitialize(0); +#endif + +#ifdef CONFIG_IMXRT_FLEXCAN + ret = imxrt_can_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: imxrt_can_setup() failed: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_DEV_GPIO + /* Initialize the GPIO driver */ + + ret = imxrt_gpio_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_IMXRT_ADC + /* Initialize ADC and register the ADC driver. */ + + ret = imxrt_adc_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: imxrt_adc_initialize() failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_INPUT_FT5X06 + /* Initialize the FT5X06 touchscreen driver */ + + ret = imxrt_ft5x06_register(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: imxrt_ft5x06_register() failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_IMXRT_LCD + /* Initialize the backlight pin and turn it to ON. */ + + imxrt_lcd_initialize(); +#endif + +#ifdef CONFIG_INPUT_BUTTONS + /* Register the BUTTON driver */ + + ret = btn_lower_initialize("/dev/buttons"); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret); + return ret; + } +#endif /* CONFIG_INPUT_BUTTONS */ + +#ifdef CONFIG_VIDEO_FB + /* Initialize and register the framebuffer driver */ + + ret = fb_register(0, 0); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_PL2303 + usbdev_serialinitialize(0); +#endif + +#ifdef CONFIG_IMXRT1170_FLEXSPI_NOR + ret = imxrt_flexspi_nor_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: imxrt_flexspi_nor_initialize failed: %d\n", ret); + } +#endif /* CONFIG_IMXRT1170_FLEXSPI_NOR */ + +#ifdef CONFIG_IMXRT1170_FLEXSPI_FRAM + ret = imxrt_flexspi_fram_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: imxrt_flexspi_nor_initialize failed: %d\n", ret); + } +#endif /* CONFIG_IMXRT1170_FLEXSPI_FRAM */ + + UNUSED(ret); + return OK; +} diff --git a/boards/arm/imxrt/fmu-v6xrt/src/imxrt_clockconfig.c b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_clockconfig.c new file mode 100644 index 00000000000..730ee18dc16 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_clockconfig.c @@ -0,0 +1,506 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/imxrt_clockconfig.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "imxrt_clockconfig.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Each FMU-V6XRT board must provide the following initialized structure. + * This is needed to establish the initial board clocking. + */ + +const struct clock_configuration_s g_initial_clkconfig = +{ + .ccm = + { + .m7_clk_root = + { + .enable = 1, + .div = 1, + .mux = M7_CLK_ROOT_PLL_ARM_CLK, + }, + .m4_clk_root = + { + .enable = 1, + .div = 1, + .mux = M4_CLK_ROOT_SYS_PLL3_PFD3, + }, + .bus_clk_root = + { + .enable = 1, + .div = 2, + .mux = BUS_CLK_ROOT_SYS_PLL3_CLK, + }, + .bus_lpsr_clk_root = + { + .enable = 1, + .div = 3, + .mux = BUS_LPSR_CLK_ROOT_SYS_PLL3_CLK, + }, + .semc_clk_root = + { + .enable = 0, + .div = 3, + .mux = SEMC_CLK_ROOT_SYS_PLL2_PFD1, + }, + .cssys_clk_root = + { + .enable = 1, + .div = 1, + .mux = CSSYS_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .cstrace_clk_root = + { + .enable = 1, + .div = 4, + .mux = CSTRACE_CLK_ROOT_SYS_PLL2_CLK, + }, + .m4_systick_clk_root = + { + .enable = 1, + .div = 1, + .mux = M4_SYSTICK_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .m7_systick_clk_root = + { + .enable = 1, + .div = 240, + .mux = M7_SYSTICK_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .adc1_clk_root = + { + .enable = 1, + .div = 6, + .mux = ADC1_CLK_ROOT_SYS_PLL2_CLK, + }, + .adc2_clk_root = + { + .enable = 1, + .div = 6, + .mux = ADC2_CLK_ROOT_SYS_PLL2_CLK, + }, + .acmp_clk_root = + { + .enable = 1, + .div = 1, + .mux = ACMP_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .flexio1_clk_root = /* 432 / 4 = 108Mhz */ + { + .enable = 1, + .div = 4, + .mux = FLEXIO1_CLK_ROOT_SYS_PLL2_PFD3, + }, + .flexio2_clk_root = + { + .enable = 1, + .div = 1, + .mux = FLEXIO2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .gpt1_clk_root = + { + .enable = 1, + .div = 1, + .mux = GPT1_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .gpt2_clk_root = + { + .enable = 1, + .div = 1, + .mux = GPT2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .gpt3_clk_root = + { + .enable = 1, + .div = 1, + .mux = GPT3_CLK_ROOT_OSC_24M, + }, + .gpt4_clk_root = + { + .enable = 1, + .div = 1, + .mux = GPT4_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .gpt5_clk_root = + { + .enable = 1, + .div = 1, + .mux = GPT5_CLK_ROOT_OSC_24M, + }, + .gpt6_clk_root = + { + .enable = 1, + .div = 1, + .mux = GPT6_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .flexspi1_clk_root = + { + .enable = 1, + .div = 4, + .mux = FLEXSPI1_CLK_ROOT_SYS_PLL2_CLK, + }, + .flexspi2_clk_root = + { + .enable = 1, + .div = 1, + .mux = FLEXSPI2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .can1_clk_root = /* 240 / 3 = 80Mhz */ + { + .enable = 1, + .div = 3, + .mux = CAN1_CLK_ROOT_SYS_PLL3_DIV2, + }, + .can2_clk_root = /* 240 / 3 = 80Mhz */ + { + .enable = 1, + .div = 3, + .mux = CAN2_CLK_ROOT_SYS_PLL3_DIV2, + }, + .can3_clk_root = /* 480 / 6 = 80Mhz */ + { + .enable = 1, + .div = 6, + .mux = CAN3_CLK_ROOT_SYS_PLL3_CLK, + }, + .lpuart1_clk_root = /* 528 / 22 = 24Mhz */ + { + .enable = 1, + .div = 22, + .mux = LPUART1_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpuart3_clk_root = /* 528 / 11 = 48Mhz */ + { + .enable = 1, + .div = 11, + .mux = LPUART3_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpuart4_clk_root = /* 528 / 11 = 48Mhz */ + { + .enable = 1, + .div = 11, + .mux = LPUART4_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpuart5_clk_root = /* 528 / 11 = 48Mhz */ + { + .enable = 1, + .div = 11, + .mux = LPUART5_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpuart6_clk_root = /* 528 / 11 = 48Mhz */ + { + .enable = 1, + .div = 11, + .mux = LPUART6_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpuart8_clk_root = /* 528 / 11 = 48Mhz */ + { + .enable = 1, + .div = 11, + .mux = LPUART8_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpuart10_clk_root = /* 528 / 11 = 48Mhz */ + { + .enable = 1, + .div = 11, + .mux = LPUART10_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpuart11_clk_root = /* 480 / 10 = 48Mhz */ + { + .enable = 1, + .div = 10, + .mux = LPUART11_CLK_ROOT_SYS_PLL3_CLK, + }, + .lpi2c1_clk_root = /* 528 / 22 = 24Mhz */ + { + .enable = 1, + .div = 22, + .mux = LPI2C1_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpi2c2_clk_root = /* 528 / 22 = 24Mhz */ + { + .enable = 1, + .div = 22, + .mux = LPI2C2_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpi2c3_clk_root = /* 528 / 22 = 24Mhz */ + { + .enable = 1, + .div = 22, + .mux = LPI2C3_CLK_ROOT_SYS_PLL2_CLK, + }, + .lpi2c6_clk_root = /* 480 / 20 = 24Mhz */ + { + .enable = 1, + .div = 20, + .mux = LPI2C6_CLK_ROOT_SYS_PLL3_CLK, + }, + .lpspi1_clk_root = /* 200 / 2 = 100Mhz */ + { + .enable = 1, + .div = 2, + .mux = LPSPI1_CLK_ROOT_SYS_PLL1_DIV5, + }, + .lpspi2_clk_root = /* 200 / 2 = 100Mhz */ + { + .enable = 1, + .div = 2, + .mux = LPSPI2_CLK_ROOT_SYS_PLL1_DIV5, + }, + .lpspi3_clk_root = /* 200 / 2 = 100Mhz */ + { + .enable = 1, + .div = 2, + .mux = LPSPI3_CLK_ROOT_SYS_PLL1_DIV5, + }, + .lpspi6_clk_root = /* 200 / 2 = 100Mhz */ + { + .enable = 1, + .div = 2, + .mux = LPSPI6_CLK_ROOT_SYS_PLL1_DIV5, + }, + .emv1_clk_root = + { + .enable = 0, + .div = 1, + .mux = EMV1_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .emv2_clk_root = + { + .enable = 0, + .div = 1, + .mux = EMV2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .enet1_clk_root = + { + .enable = 0, + .div = 10, + .mux = ENET1_CLK_ROOT_SYS_PLL1_DIV2, + }, + .enet2_clk_root = + { + .enable = 0, + .div = 10, + .mux = ENET2_CLK_ROOT_SYS_PLL1_DIV2, + }, + .enet_qos_clk_root = + { + .enable = 0, + .div = 1, + .mux = ENET_QOS_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .enet_25m_clk_root = + { + .enable = 1, + .div = 1, + .mux = ENET_25M_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .enet_timer1_clk_root = + { + .enable = 0, + .div = 1, + .mux = ENET_TIMER1_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .enet_timer2_clk_root = + { + .enable = 0, + .div = 1, + .mux = ENET_TIMER2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .enet_timer3_clk_root = + { + .enable = 0, + .div = 1, + .mux = ENET_TIMER3_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .usdhc1_clk_root = + { + .enable = 1, + .div = 2, + .mux = USDHC1_CLK_ROOT_SYS_PLL2_PFD2, + }, + .usdhc2_clk_root = + { + .enable = 0, + .div = 1, + .mux = USDHC2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .asrc_clk_root = + { + .enable = 0, + .div = 1, + .mux = ASRC_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .mqs_clk_root = + { + .enable = 0, + .div = 1, + .mux = MQS_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .mic_clk_root = + { + .enable = 0, + .div = 1, + .mux = MIC_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .spdif_clk_root = + { + .enable = 0, + .div = 1, + .mux = SPDIF_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .sai1_clk_root = + { + .enable = 0, + .div = 1, + .mux = SAI1_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .sai2_clk_root = + { + .enable = 0, + .div = 1, + .mux = SAI2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .sai3_clk_root = + { + .enable = 0, + .div = 1, + .mux = SAI3_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .sai4_clk_root = + { + .enable = 0, + .div = 1, + .mux = SAI4_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .gc355_clk_root = + { + .enable = 0, + .div = 2, + .mux = GC355_CLK_ROOT_VIDEO_PLL_CLK, + }, + .lcdif_clk_root = + { + .enable = 0, + .div = 1, + .mux = LCDIF_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .lcdifv2_clk_root = + { + .enable = 0, + .div = 1, + .mux = LCDIFV2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .mipi_ref_clk_root = + { + .enable = 0, + .div = 1, + .mux = MIPI_REF_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .mipi_esc_clk_root = + { + .enable = 0, + .div = 1, + .mux = MIPI_ESC_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .csi2_clk_root = + { + .enable = 0, + .div = 1, + .mux = CSI2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .csi2_esc_clk_root = + { + .enable = 0, + .div = 1, + .mux = CSI2_ESC_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .csi2_ui_clk_root = + { + .enable = 0, + .div = 1, + .mux = CSI2_UI_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .csi_clk_root = + { + .enable = 0, + .div = 1, + .mux = CSI_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .cko1_clk_root = + { + .enable = 0, + .div = 1, + .mux = CKO1_CLK_ROOT_OSC_RC_48M_DIV2, + }, + .cko2_clk_root = + { + .enable = 0, + .div = 1, + .mux = CKO2_CLK_ROOT_OSC_RC_48M_DIV2, + }, + }, + .arm_pll = + { + /* ARM_PLL = Fin * (loop_div / (2 * post_div)), so 166 / 4 here. */ + + .post_div = 0, /* 0 = /2, 1 = /4, 2 = /8, 3 = /1 */ + .loop_div = 166, /* ARM_PLL = 996 MHz */ + }, + .sys_pll1 = + { + .enable = 1, + .div = 41, + .num = 178956970, + .denom = 268435455, + }, + .sys_pll2 = + { + .mfd = 268435455, + .ss_enable = 0, + .pfd0 = 27, /* (528 * 18) / 27 = 352 MHz */ + .pfd1 = 16, /* (528 * 18) / 16 = 594 MHz */ + .pfd2 = 24, /* (528 * 18) / 24 = 396 MHz */ + .pfd3 = 22, /* (528 * 18) / 22 = 216 MHz */ + }, + .sys_pll3 = + { + .pfd0 = 13, /* (480 * 18) / 13 = 8640/13 = 664.62 MHz */ + .pfd1 = 17, /* (480 * 18) / 17 = 8640/17 = 508.24 MHz */ + .pfd2 = 32, /* (480 * 18) / 32 = 270 MHz */ + .pfd3 = 22, /* (480 * 18) / 22 = 8640/20 = 392.73 MHz */ + } +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.c b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.c new file mode 100644 index 00000000000..56a16cae551 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "imxrt_flexspi_nor_boot.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +locate_data(".boot_hdr.ivt") +const struct ivt_s g_image_vector_table = +{ + IVT_HEADER, /* IVT Header */ + IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ + IVT_RSVD, /* Reserved = 0 */ + (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ + (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ + (uint32_t)IMAG_VECTOR_TABLE, /* Pointer to IVT Self (absolute address */ + (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ + IVT_RSVD /* Reserved = 0 */ +}; + +locate_data(".boot_hdr.boot_data") +const struct boot_data_s g_boot_data = +{ + IMAGE_DEST, /* boot start location */ + (IMAGE_DEST_END - IMAGE_DEST), /* size */ + PLUGIN_FLAG, /* Plugin flag */ + 0xffffffff /* empty - extra data word */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.h b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.h new file mode 100644 index 00000000000..d433c1f32f2 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.h @@ -0,0 +1,165 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_boot.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_PX4_FMU_V6XRT_SRC_IMXRT_FLEXSPI_NOR_BOOT_H +#define __BOARDS_PX4_FMU_V6XRT_SRC_IMXRT_FLEXSPI_NOR_BOOT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IVT Data */ + +#define IVT_MAJOR_VERSION 0x4 +#define IVT_MAJOR_VERSION_SHIFT 0x4 +#define IVT_MAJOR_VERSION_MASK 0xf +#define IVT_MINOR_VERSION 0x1 +#define IVT_MINOR_VERSION_SHIFT 0x0 +#define IVT_MINOR_VERSION_MASK 0xf + +#define IVT_VERSION(major, minor) \ + ((((major) & IVT_MAJOR_VERSION_MASK) << IVT_MAJOR_VERSION_SHIFT) | \ + (((minor) & IVT_MINOR_VERSION_MASK) << IVT_MINOR_VERSION_SHIFT)) + +#define IVT_TAG_HEADER (0xd1) /* Image Vector Table */ +#define IVT_SIZE 0x2000 +#define IVT_PAR IVT_VERSION(IVT_MAJOR_VERSION, IVT_MINOR_VERSION) + +#define IVT_HEADER (IVT_TAG_HEADER | (IVT_SIZE << 8) | (IVT_PAR << 24)) +#define IVT_RSVD (uint32_t)(0x00000000) + +/* DCD Data */ + +#define DCD_TAG_HEADER (0xd2) +#define DCD_TAG_HEADER_SHIFT (24) +#define DCD_VERSION (0x40) +#define DCD_ARRAY_SIZE 1 + +#define FLASH_BASE 0x30000000 +/* The part holds 64M, but programming all of it costs more time than the + * image needs. + */ + +#define FLASH_END FLASH_BASE + (3 * (1024 * 1024)) + +/* This has to account for the memory configuration the bootloader + * leaves behind. + */ + +#define ROM_BOOTLOADER_OCRAM_RES 0x8000 +#define OCRAM_BASE (0x20200000 + ROM_BOOTLOADER_OCRAM_RES) +#define OCRAM_END (OCRAM_BASE + (512 * 1024) + (256 * 1024) - ROM_BOOTLOADER_OCRAM_RES) + +#define SCLK 1 +#if defined(CONFIG_BOOT_RUNFROMFLASH) +# define IMAGE_DEST FLASH_BASE +# define IMAGE_DEST_END FLASH_END +# define IMAGE_DEST_OFFSET 0 +#else +# define IMAGE_DEST OCRAM_BASE +# define IMAGE_DEST_END OCRAM_END +# define IMAGE_DEST_OFFSET IVT_SIZE +#endif + +#define LOCATE_IN_DEST(x) (((uint32_t)(x)) - FLASH_BASE + IMAGE_DEST) +#define LOCATE_IN_SRC(x) (((uint32_t)(x)) - IMAGE_DEST + FLASH_BASE) + +#define DCD_ADDRESS 0 +#define BOOT_DATA_ADDRESS LOCATE_IN_DEST(&g_boot_data) +#define CSF_ADDRESS 0 +#define PLUGIN_FLAG (uint32_t)0 + +/* Located in Destination Memory */ + +#define IMAGE_ENTRY_ADDRESS ((uint32_t)&_vectors) +#define IMAG_VECTOR_TABLE LOCATE_IN_DEST(&g_image_vector_table) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* IVT Data */ + +struct ivt_s +{ + /* Header with tag #HAB_TAG_IVT, length and HAB version fields + * (see data) + */ + + uint32_t hdr; + + /* Absolute address of the first instruction to execute from the + * image + */ + + uint32_t entry; + + /* Reserved in this version of HAB: should be NULL. */ + + uint32_t reserved1; + + /* Absolute address of the image DCD: may be NULL. */ + + uint32_t dcd; + + /* Absolute address of the Boot Data: may be NULL, but not interpreted + * any further by HAB + */ + + uint32_t boot_data; + + /* Absolute address of the IVT. */ + + uint32_t self; + + /* Absolute address of the image CSF. */ + + uint32_t csf; + + /* Reserved in this version of HAB: should be zero. */ + + uint32_t reserved2; +}; + +/* Boot Data */ + +struct boot_data_s +{ + uint32_t start; /* boot start location */ + uint32_t size; /* size */ + uint32_t plugin; /* plugin flag - 1 if downloaded application is plugin */ + uint32_t placeholder; /* placeholder to make even 0x10 size */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct boot_data_s g_boot_data; +extern const uint8_t g_dcd_data[]; +extern const void * const _vectors[]; + +#endif /* __BOARDS_PX4_FMU_V6XRT_SRC_IMXRT_FLEXSPI_NOR_BOOT_H */ diff --git a/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.c b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.c new file mode 100644 index 00000000000..01802cc0930 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.c @@ -0,0 +1,178 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http: + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "imxrt_flexspi_nor_flash.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +locate_data(".boot_hdr.conf") +const struct flexspi_nor_config_s g_flash_config = +{ + .mem_config = + { +#if !defined(CONFIG_BOARD_BOOTLOADER_INVALID_FCB) + .tag = FLEXSPI_CFG_BLK_TAG, +#else + .tag = 0xffffffffl, +#endif + .version = FLEXSPI_CFG_BLK_VERSION, + .read_sample_clksrc = FLASH_READ_SAMPLE_CLK_LOOPBACK_INTERNELLY, + .cs_hold_time = 1, + .cs_setup_time = 1, + .device_mode_cfg_enable = 1, + .device_mode_type = DEVICE_CONFIG_CMD_TYPE_GENERIC, + .wait_time_cfg_commands = 1, + .controller_misc_option = + (1u << FLEXSPIMISC_OFFSET_SAFECONFIG_FREQ_EN), + .device_type = FLEXSPI_DEVICE_TYPE_SERIAL_NOR, + .sflash_pad_type = SERIAL_FLASH_1PAD, + .serial_clk_freq = FLEXSPI_SERIAL_CLKFREQ_30MHz, + .sflash_a1size = 64ul * 1024u * 1024u, + .data_valid_time = + { + [0] = 0, + }, + .busy_offset = 0u, + .busybit_polarity = 0u, + .lookup_table = + { + /* Read Dedicated 3Byte Address Read(0x03), 24bit address */ + + [0 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x03, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + [0 + 1] = FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x04, + STOP, FLEXSPI_1PAD, 0), + }, + }, + .page_size = 256u, + .sector_size = 4u * 1024u, + .blocksize = 64u * 1024u, + .is_uniform_blocksize = false, + .ipcmd_serial_clkfreq = 1, + .serial_nor_type = 2, + .reserve2[0] = 0x7008200, +}; + +const struct flexspi_nor_config_s g_flash_fast_config = +{ + .mem_config = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .read_sample_clksrc = FLASH_READ_SAMPLE_CLK_EXT_INPUT_FROM_DQSPAD, + .cs_hold_time = 1, + .cs_setup_time = 1, + .device_mode_cfg_enable = 1, + .device_mode_type = DEVICE_CONFIG_CMD_TYPE_SPI2XPI, + .wait_time_cfg_commands = 1, + .device_mode_seq = + { + .seq_num = 1, + .seq_id = 6, /* See Lookup table for more details */ + .reserved = 0, + }, + .device_mode_arg = 2, /* Enable OPI DDR mode */ + .controller_misc_option = + (1u << FLEXSPIMISC_OFFSET_SAFECONFIG_FREQ_EN) | + (1u << FLEXSPIMISC_OFFSET_DDR_MODE_EN), + .device_type = FLEXSPI_DEVICE_TYPE_SERIAL_NOR, + .sflash_pad_type = SERIAL_FLASH_8PADS, + .serial_clk_freq = FLEXSPI_SERIAL_CLKFREQ_200MHz, + .sflash_a1size = 64ul * 1024u * 1024u, + .data_valid_time = + { + [0] = 0, + }, + .busy_offset = 0u, + .busybit_polarity = 0u, + .lookup_table = + { + /* Read. Macronix wants 20 dummy cycles at 200MHz, and the + * operand is 2N in DDR mode, hence 0x28. + */ + + [0 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xee, + CMD_DDR, FLEXSPI_8PAD, 0x11), + [0 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, + DUMMY_DDR, FLEXSPI_8PAD, 0x28), + [0 + 2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, + STOP, FLEXSPI_1PAD, 0x00), + + /* Read status */ + + [4 * 2 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x05, + CMD_DDR, FLEXSPI_8PAD, 0xfa), + [4 * 2 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, + DUMMY_DDR, FLEXSPI_8PAD, 0x04), + [4 * 2 + 2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, + STOP, FLEXSPI_1PAD, 0x00), + + /* Write enable SPI */ + + [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, + STOP, FLEXSPI_1PAD, 0x00), + + /* Write enable OPI SPI */ + + [4 * 4 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x06, + CMD_DDR, FLEXSPI_8PAD, 0xf9), + + /* Erase sector */ + + [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x21, + CMD_DDR, FLEXSPI_8PAD, 0xde), + [4 * 5 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, + STOP, FLEXSPI_1PAD, 0x00), + + /* Write Configuration Register 2 =01, Enable OPI DDR mode */ + + [4 * 6 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x72, + CMD_SDR, FLEXSPI_1PAD, 0x00), + [4 * 6 + 1] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, + CMD_SDR, FLEXSPI_1PAD, 0x00), + [4 * 6 + 2] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, + WRITE_SDR, FLEXSPI_1PAD, 0x01), + + /* Page program */ + + [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x12, + CMD_DDR, FLEXSPI_8PAD, 0xed), + [4 * 9 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, + WRITE_DDR, FLEXSPI_8PAD, 0x04), + }, + }, + .page_size = 256u, + .sector_size = 4u * 1024u, + .blocksize = 64u * 1024u, + .is_uniform_blocksize = false, + .ipcmd_serial_clkfreq = 1, + .serial_nor_type = 2, + .reserve2[0] = 0x7008200, +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.h b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.h new file mode 100644 index 00000000000..4abd98e0bd8 --- /dev/null +++ b/boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.h @@ -0,0 +1,359 @@ +/**************************************************************************** + * boards/arm/imxrt/fmu-v6xrt/src/imxrt_flexspi_nor_flash.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_IMXRT_FMU_V6XRT_SRC_IMXRT_FLEXSPI_NOR_FLASH_H +#define __BOARDS_ARM_IMXRT_FMU_V6XRT_SRC_IMXRT_FLEXSPI_NOR_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* FLEXSPI memory config block related definitions */ + +#define FLEXSPI_CFG_BLK_TAG (0x42464346ul) +#define FLEXSPI_CFG_BLK_VERSION (0x56010400ul) +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ + +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related definitions */ + +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0a +#define LEARN_DDR 0x2a +#define DATSZ_SDR 0x0b +#define DATSZ_DDR 0x2b +#define DUMMY_SDR 0x0c +#define DUMMY_DDR 0x2c +#define DUMMY_RWDS_SDR 0x0d +#define DUMMY_RWDS_DDR 0x2d +#define JMP_ON_CS 0x1f +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_OPERAND0_MASK (0xffu) +#define FLEXSPI_LUT_OPERAND0_SHIFT (0U) +#define FLEXSPI_LUT_OPERAND0(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_OPERAND0_SHIFT)) & \ + FLEXSPI_LUT_OPERAND0_MASK) +#define FLEXSPI_LUT_NUM_PADS0_MASK (0x300u) +#define FLEXSPI_LUT_NUM_PADS0_SHIFT (8u) +#define FLEXSPI_LUT_NUM_PADS0(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS0_SHIFT)) & \ + FLEXSPI_LUT_NUM_PADS0_MASK) +#define FLEXSPI_LUT_OPCODE0_MASK (0xfc00u) +#define FLEXSPI_LUT_OPCODE0_SHIFT (10u) +#define FLEXSPI_LUT_OPCODE0(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_OPCODE0_SHIFT)) & \ + FLEXSPI_LUT_OPCODE0_MASK) +#define FLEXSPI_LUT_OPERAND1_MASK (0xff0000u) +#define FLEXSPI_LUT_OPERAND1_SHIFT (16U) +#define FLEXSPI_LUT_OPERAND1(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_OPERAND1_SHIFT)) & \ + FLEXSPI_LUT_OPERAND1_MASK) +#define FLEXSPI_LUT_NUM_PADS1_MASK (0x3000000u) +#define FLEXSPI_LUT_NUM_PADS1_SHIFT (24u) +#define FLEXSPI_LUT_NUM_PADS1(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS1_SHIFT)) & \ + FLEXSPI_LUT_NUM_PADS1_MASK) +#define FLEXSPI_LUT_OPCODE1_MASK (0xfc000000u) +#define FLEXSPI_LUT_OPCODE1_SHIFT (26u) +#define FLEXSPI_LUT_OPCODE1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPCODE1_SHIFT)) & \ + FLEXSPI_LUT_OPCODE1_MASK) + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (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)) + +/* */ + +#define NOR_CMD_INDEX_READ CMD_INDEX_READ +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE +#define NOR_CMD_INDEX_ERASESECTOR 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE +#define NOR_CMD_INDEX_CHIPERASE 5 +#define NOR_CMD_INDEX_DUMMY 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 + +/* READ LUT sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ + +/* Read Status LUT sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS CMD_LUT_SEQ_IDX_READSTATUS + +/* 2 Read status DPI/QPI/OPI sequence id in LUT stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 2 + +/* 3 Write Enable sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE CMD_LUT_SEQ_IDX_WRITEENABLE + +/* 4 Write Enable DPI/QPI/OPI sequence id in LUT stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI 4 + +/* 5 Erase Sector sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 + +/* 8 Erase Block sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 + +/* 9 Program sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM CMD_LUT_SEQ_IDX_WRITE + +/* 11 Chip Erase sequence in lookupTable id stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 + +/* 13 Read SFDP sequence in lookupTable id stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 + +/* 14 Restore 0-4-4/0-8-8 mode sequence id in LUT stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD 14 + +/* 15 Exit 0-4-4/0-8-8 mode sequence id in LUT stored in config blobk */ + +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD 15 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Definitions for FlexSPI Serial Clock Frequency */ + +enum flexspi_serial_clkfreq_e +{ + FLEXSPI_SERIAL_CLKFREQ_30MHz = 1, + FLEXSPI_SERIAL_CLKFREQ_50MHz = 2, + FLEXSPI_SERIAL_CLKFREQ_60MHz = 3, + FLEXSPI_SERIAL_CLKFREQ_75MHz = 4, + FLEXSPI_SERIAL_CLKFREQ_80MHz = 5, + FLEXSPI_SERIAL_CLKFREQ_100MHz = 6, + FLEXSPI_SERIAL_CLKFREQ_133MHz = 7, + FLEXSPI_SERIAL_CLKFREQ_166MHz = 8, + FLEXSPI_SERIAL_CLKFREQ_200MHz = 9, +}; + +/* FlexSPI clock configuration type */ + +enum flexspi_serial_clockmode_e +{ + FLEXSPI_CLKMODE_SDR, + FLEXSPI_CLKMODE_DDR, +}; + +/* FlexSPI Read Sample Clock Source definition */ + +enum flash_read_sample_clk_e +{ + FLASH_READ_SAMPLE_CLK_LOOPBACK_INTERNELLY = 0, + FLASH_READ_SAMPLE_CLK_LOOPBACK_FROM_DQSPAD = 1, + FLASH_READ_SAMPLE_CLK_LOOPBACK_FROM_SCKPAD = 2, + FLASH_READ_SAMPLE_CLK_EXT_INPUT_FROM_DQSPAD = 3, +}; + +/* Misc feature bit definitions */ + +enum flash_misc_feature_e +{ + FLEXSPIMISC_OFFSET_DIFFCLKEN = 0, /* Bit for Differential clock enable */ + FLEXSPIMISC_OFFSET_CK2EN = 1, /* Bit for CK2 enable */ + FLEXSPIMISC_OFFSET_PARALLELEN = 2, /* Bit for Parallel mode enable */ + FLEXSPIMISC_OFFSET_WORD_ADDRESSABLE_EN = 3, /* Bit for Word Addressable enable */ + FLEXSPIMISC_OFFSET_SAFECONFIG_FREQ_EN = 4, /* Bit for Safe Configuration Frequency enable */ + FLEXSPIMISC_OFFSET_PAD_SETTING_OVERRIDE_EN = 5, /* Bit for Pad setting override enable */ + FLEXSPIMISC_OFFSET_DDR_MODE_EN = 6, /* Bit for DDR clock configuration indication. */ +}; + +/* Flash Type Definition */ + +enum flash_flash_type_e +{ + FLEXSPI_DEVICE_TYPE_SERIAL_NOR = 1, /* Flash devices are Serial NOR */ + FLEXSPI_DEVICE_TYPE_SERIAL_NAND = 2, /* Flash devices are Serial NAND */ + FLEXSPI_DEVICE_TYPE_SERIAL_RAM = 3, /* Flash devices are Serial RAM/HyperFLASH */ + FLEXSPI_DEVICE_TYPE_MCP_NOR_NAND = 0x12, /* Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND */ + FLEXSPI_DEVICE_TYPE_MCP_NOR_RAM = 0x13, /* Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs */ +}; + +/* Flash Pad Definitions */ + +enum flash_flash_pad_e +{ + SERIAL_FLASH_1PAD = 1, + SERIAL_FLASH_2PADS = 2, + SERIAL_FLASH_4PADS = 4, + SERIAL_FLASH_8PADS = 8, +}; + +/* Flash Configuration Command Type */ + +enum flash_config_cmd_e +{ + DEVICE_CONFIG_CMD_TYPE_GENERIC, /* Generic command, for example: configure dummy cycles, drive strength, etc */ + DEVICE_CONFIG_CMD_TYPE_QUADENABLE, /* Quad Enable command */ + DEVICE_CONFIG_CMD_TYPE_SPI2XPI, /* Switch from SPI to DPI/QPI/OPI mode */ + DEVICE_CONFIG_CMD_TYPE_XPI2SPI, /* Switch from DPI/QPI/OPI to SPI mode */ + DEVICE_CONFIG_CMD_TYPE_SPI2NO_CMD, /* Switch to 0-4-4/0-8-8 mode */ + DEVICE_CONFIG_CMD_TYPE_RESET, /* Reset device command */ +}; + +/* FlexSPI LUT Sequence structure */ + +struct flexspi_lut_seq_s +{ + uint8_t seq_num; /* Sequence Number, valid number: 1-16 */ + uint8_t seq_id; /* Sequence Index, valid number: 0-15 */ + uint16_t reserved; +}; + +/* FlexSPI Memory Configuration Block */ + +struct flexspi_mem_config_s +{ + uint32_t tag; + uint32_t version; + uint32_t reserved0; + uint8_t read_sample_clksrc; + uint8_t cs_hold_time; + uint8_t cs_setup_time; + uint8_t column_address_width; /* [0x00f-0x00f] Column Address with, for + * HyperBus protocol, it is fixed to 3, + * For Serial NAND, need to refer to + * datasheet + */ + uint8_t device_mode_cfg_enable; + uint8_t device_mode_type; + uint16_t wait_time_cfg_commands; + struct flexspi_lut_seq_s device_mode_seq; + uint32_t device_mode_arg; + uint8_t config_cmd_enable; + uint8_t config_mode_type[3]; + struct flexspi_lut_seq_s config_cmd_seqs[3]; + uint32_t reserved1; + uint32_t config_cmd_args[3]; + uint32_t reserved2; + uint32_t controller_misc_option; + uint8_t device_type; + uint8_t sflash_pad_type; + uint8_t serial_clk_freq; + uint8_t lut_custom_seq_enable; + uint32_t reserved3[2]; + uint32_t sflash_a1size; + uint32_t sflash_a2size; + uint32_t sflash_b1size; + uint32_t sflash_b2size; + uint32_t cspad_setting_override; + uint32_t sclkpad_setting_override; + uint32_t datapad_setting_override; + uint32_t dqspad_setting_override; + uint32_t timeout_in_ms; + uint32_t command_interval; + uint16_t data_valid_time[2]; + uint16_t busy_offset; + uint16_t busybit_polarity; + uint32_t lookup_table[64]; + struct flexspi_lut_seq_s lut_customseq[12]; + uint32_t reserved4[4]; +}; + +/* Serial NOR configuration block */ + +struct flexspi_nor_config_s +{ + struct flexspi_mem_config_s mem_config; /* Common memory configuration info + * via FlexSPI + */ + + uint32_t page_size; /* Page size of Serial NOR */ + uint32_t sector_size; /* Sector size of Serial NOR */ + uint8_t ipcmd_serial_clkfreq; /* Clock frequency for IP command */ + uint8_t is_uniform_blocksize; /* Sector/Block size is the same */ + uint8_t reserved0[2]; /* Reserved for future use */ + uint8_t serial_nor_type; /* Serial NOR Flash type: 0/1/2/3 */ + uint8_t need_exit_nocmdmode; /* Need to exit NoCmd mode before + * other IP command + */ + + uint8_t halfclk_for_nonreadcmd; /* Half the Serial Clock for non-read + * command: true/false + */ + + uint8_t need_restore_nocmdmode; /* Need to Restore NoCmd mode after IP + * command execution + */ + + uint32_t blocksize; /* Block size */ + uint32_t reserve2[11]; /* Reserved for future use */ +}; + +#endif /* __BOARDS_ARM_IMXRT_FMU_V6XRT_SRC_IMXRT_FLEXSPI_NOR_FLASH_H */