From 4b40e19e20a53350f8ede71c3393959b93f63fdb Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Mon, 2 Oct 2023 07:50:43 -0700 Subject: [PATCH] nxp_fmurt1170-v1:Add bootloader nxp_fmurt1170-v1:bootloader removed ADC nxp_fmurt1170-v1:bootloader base bootloader script off of script.ld nxp_fmurt1170-v1:add _bootdelay_signature & change entry from 0x30000000 to 0x30040000 fmurt1170-v1:hw_config Bootloader has to have 12 bytes --- boards/nxp/fmurt1170-v1/bootloader.px4board | 3 + .../extras/nxp_fmurt1170-v1_bootloader.bin | Bin 0 -> 78632 bytes boards/nxp/fmurt1170-v1/firmware.prototype | 2 +- .../nuttx-config/bootloader/defconfig | 111 ++++++++++ .../nuttx-config/scripts/bootloader_script.ld | 195 ++++++++++++++++++ .../nuttx-config/scripts/ocram-script.ld | 10 +- .../nuttx-config/scripts/script.ld | 10 +- boards/nxp/fmurt1170-v1/src/CMakeLists.txt | 93 +++++---- boards/nxp/fmurt1170-v1/src/bootloader_main.c | 61 ++++++ boards/nxp/fmurt1170-v1/src/hw_config.h | 130 ++++++++++++ .../src/imxrt_flexspi_nor_flash.c | 15 ++ boards/nxp/fmurt1170-v1/src/imxrt_romapi.h | 1 + boards/nxp/fmurt1170-v1/src/init.c | 20 +- 13 files changed, 605 insertions(+), 46 deletions(-) create mode 100644 boards/nxp/fmurt1170-v1/bootloader.px4board create mode 100755 boards/nxp/fmurt1170-v1/extras/nxp_fmurt1170-v1_bootloader.bin create mode 100644 boards/nxp/fmurt1170-v1/nuttx-config/bootloader/defconfig create mode 100644 boards/nxp/fmurt1170-v1/nuttx-config/scripts/bootloader_script.ld create mode 100644 boards/nxp/fmurt1170-v1/src/bootloader_main.c create mode 100644 boards/nxp/fmurt1170-v1/src/hw_config.h diff --git a/boards/nxp/fmurt1170-v1/bootloader.px4board b/boards/nxp/fmurt1170-v1/bootloader.px4board new file mode 100644 index 000000000000..19b6e662be69 --- /dev/null +++ b/boards/nxp/fmurt1170-v1/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/nxp/fmurt1170-v1/extras/nxp_fmurt1170-v1_bootloader.bin b/boards/nxp/fmurt1170-v1/extras/nxp_fmurt1170-v1_bootloader.bin new file mode 100755 index 0000000000000000000000000000000000000000..a6903819581298dae3ccfad5af6f08f61cdeed69 GIT binary patch literal 78632 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 z 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 literal 0 HcmV?d00001 diff --git a/boards/nxp/fmurt1170-v1/firmware.prototype b/boards/nxp/fmurt1170-v1/firmware.prototype index d6de226d59dd..1795a4a1d172 100644 --- a/boards/nxp/fmurt1170-v1/firmware.prototype +++ b/boards/nxp/fmurt1170-v1/firmware.prototype @@ -1,5 +1,5 @@ { - "board_id": 31, + "board_id": 35, "magic": "PX4FWv1", "description": "Firmware for the NXPFMURT1170v1 board", "image": "", diff --git a/boards/nxp/fmurt1170-v1/nuttx-config/bootloader/defconfig b/boards/nxp/fmurt1170-v1/nuttx-config/bootloader/defconfig new file mode 100644 index 000000000000..94010646dfd5 --- /dev/null +++ b/boards/nxp/fmurt1170-v1/nuttx-config/bootloader/defconfig @@ -0,0 +1,111 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_SPI_EXCHANGE is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/nxp/fmurt1170-v1/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1176DVMAA=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RAMVECTORS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_ITCM=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_BOOTLOADER_FIXUP=y +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_FORCE_ALIGNMENT=y +CONFIG_BOARD_INITTHREAD_PRIORITY=254 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=104926 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_CDCACM=y +CONFIG_CDCACM_BULKIN_REQLEN=96 +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x001d +CONFIG_CDCACM_PRODUCTSTR="PX4 BL FMURT1170 v1.x" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x1FC9 +CONFIG_CDCACM_VENDORSTR="NXP SEMICONDUCTORS" +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEBUG_USAGEFAULT=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_EDMA=y +CONFIG_IMXRT_EDMA_EDBG=y +CONFIG_IMXRT_EDMA_ELINK=y +CONFIG_IMXRT_EDMA_NTCD=64 +CONFIG_IMXRT_FLEXSPI2=y +CONFIG_IMXRT_LPUART8=y +CONFIG_IMXRT_SNVS_LPSRTC=y +CONFIG_IMXRT_USBDEV=y +CONFIG_INIT_ENTRYPOINT="bootloader_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_LPUART8_BAUD=57600 +CONFIG_LPUART8_IFLOWCONTROL=y +CONFIG_LPUART8_OFLOWCONTROL=y +CONFIG_LPUART8_RXBUFSIZE=600 +CONFIG_LPUART8_RXDMA=y +CONFIG_LPUART8_TXBUFSIZE=1500 +CONFIG_LPUART8_TXDMA=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=1835008 +CONFIG_RAM_START=0x20240000 +CONFIG_RAW_BINARY=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_SYSTEMTICK_HOOK=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_DMA=y +CONFIG_USBDEV_DUALSPEED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/nxp/fmurt1170-v1/nuttx-config/scripts/bootloader_script.ld b/boards/nxp/fmurt1170-v1/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 000000000000..3eed03aa5050 --- /dev/null +++ b/boards/nxp/fmurt1170-v1/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,195 @@ +/**************************************************************************** + * boards/arm/imxrt/imxrt1170-evk/scripts/flash.ld + * + * 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 */ + + /* Reallocate + * Final Configuration is + * No DTCM + * 512k OCRAM M7 (FlexRAM) (2038:0000-203f:ffff) + * 128k OCRAMM7 FlexRAM ECC (2036:0000-2037:ffff) + * 64k OCRAM2 ECC parity (2035:0000-2035:ffff) + * 64k OCRAM1 ECC parity (2034:0000-2034:ffff) + * 512k FlexRAM OCRAM2 (202C:0000-2033:ffff) + * 512k FlexRAM OCRAM1 (2024:0000-202B:ffff) + * 256k System OCRAM M4 (2020:0000-2023:ffff) + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x30000000, LENGTH = 128K + sram (rwx) : ORIGIN = 0x20240000, LENGTH = 2M-256k-512k + 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) +EXTERN(board_get_manifest) +EXTERN(_bootdelay_signature) + +ENTRY(__start) + +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 + + .vectors : + { + KEEP(*(.vectors)) + *(.text .text.__start) + } >flash + + .itcmfunc : + { + . = ALIGN(8); + _sitcmfuncs = ABSOLUTE(.); + FILL(0xFF) + . = 0x40 ; + . = ALIGN(8); + _eitcmfuncs = ABSOLUTE(.); + } > itcm AT > flash + + _fitcmfuncs = LOADADDR(.itcmfunc); + + /* The RAM vector table (if present) should lie at the beginning of SRAM */ + + .ram_vectors (COPY) : { + *(.ram_vectors) + } > dtcm + + .text : ALIGN(4) + { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + . = ALIGN(4096); + _etext = ABSOLUTE(.); + _srodata = ABSOLUTE(.); + *(.rodata .rodata.*) + . = ALIGN(4096); + _erodata = ABSOLUTE(.); + } > flash + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(.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); + _sdtcm = ORIGIN(dtcm); + _edtcm = ORIGIN(dtcm) + LENGTH(dtcm); +} diff --git a/boards/nxp/fmurt1170-v1/nuttx-config/scripts/ocram-script.ld b/boards/nxp/fmurt1170-v1/nuttx-config/scripts/ocram-script.ld index d5976cc9d445..e5440265592c 100644 --- a/boards/nxp/fmurt1170-v1/nuttx-config/scripts/ocram-script.ld +++ b/boards/nxp/fmurt1170-v1/nuttx-config/scripts/ocram-script.ld @@ -64,7 +64,7 @@ MEMORY { - flash (rx) : ORIGIN = 0x30000000, LENGTH = 7M + flash (rx) : ORIGIN = 0x30040000, LENGTH = 7M-256K flashxip (rx) : ORIGIN = 0x30700000, LENGTH = 1M /* Vectors @ boot+ivt OCRAM2 Flex RAM Boot IVT */ sram (rwx) : ORIGIN = 0x20240000 + 40K, LENGTH = 512K + 256K + 128K - (32K + 8K) @@ -78,6 +78,7 @@ EXTERN(g_flash_config) EXTERN(g_image_vector_table) EXTERN(g_boot_data) EXTERN(g_dcd_data) +EXTERN(_bootdelay_signature) ENTRY(_stext) @@ -222,6 +223,13 @@ SECTIONS { _stext = ABSOLUTE(.); *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; *(.text .text.*) _etext = ABSOLUTE(.); diff --git a/boards/nxp/fmurt1170-v1/nuttx-config/scripts/script.ld b/boards/nxp/fmurt1170-v1/nuttx-config/scripts/script.ld index 7ac88335a5cf..993d64d0b7c8 100644 --- a/boards/nxp/fmurt1170-v1/nuttx-config/scripts/script.ld +++ b/boards/nxp/fmurt1170-v1/nuttx-config/scripts/script.ld @@ -34,7 +34,7 @@ MEMORY { - flash (rx) : ORIGIN = 0x30000000, LENGTH = 3M /* We have 64M but we do not want to wait to program it all */ + flash (rx) : ORIGIN = 0x30020000, LENGTH = 4M-128K /* We have 64M but we do not want to wait to program it all */ sram (rwx) : ORIGIN = 0x20240000, LENGTH = 2M-256k-512k itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 256K /* TODO FlexRAM partition */ dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 256K @@ -46,6 +46,7 @@ EXTERN(g_flash_config) EXTERN(g_image_vector_table) EXTERN(g_boot_data) EXTERN(board_get_manifest) +EXTERN(_bootdelay_signature) ENTRY(__start) @@ -98,6 +99,13 @@ SECTIONS { _stext = ABSOLUTE(.); *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; *(.text .text.*) *(.fixup) *(.gnu.warning) diff --git a/boards/nxp/fmurt1170-v1/src/CMakeLists.txt b/boards/nxp/fmurt1170-v1/src/CMakeLists.txt index 3a633b91ee84..cd9d6fb6b277 100644 --- a/boards/nxp/fmurt1170-v1/src/CMakeLists.txt +++ b/boards/nxp/fmurt1170-v1/src/CMakeLists.txt @@ -1,6 +1,6 @@ ############################################################################ # -# Copyright (c) 2016, 2019 PX4 Development Team. All rights reserved. +# Copyright (c) 2016, 2019, 2023 PX4 Development Team. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -30,40 +30,63 @@ # POSSIBILITY OF SUCH DAMAGE. # ############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_compile_definitions(BOOTLOADER) + add_library(drivers_board + bootloader_main.c + init.c + usb.c + imxrt_romapi.c + imxrt_flexspi_nor_boot.c + imxrt_flexspi_nor_flash.c + imxrt_clockconfig.c + timer_config.cpp + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer #gpio + arch_io_pins # iotimer + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) -if(CONFIG_IMXRT1170_FLEXSPI_FRAM) - list(APPEND SRCS - imxrt_flexspi_fram.c - ) -endif() +else() + if(CONFIG_IMXRT1170_FLEXSPI_FRAM) + list(APPEND SRCS + imxrt_flexspi_fram.c + ) + endif() -px4_add_library(drivers_board - autoleds.c - automount.c - #can.c - i2c.cpp - init.c - led.c - manifest.c - mtd.cpp - sdhc.c - spi.cpp - timer_config.cpp - usb.c - imxrt_romapi.c - imxrt_flexspi_fram.c - imxrt_flexspi_nor_boot.c - imxrt_flexspi_nor_flash.c - imxrt_clockconfig.c - ${SRCS} -) + px4_add_library(drivers_board + autoleds.c + automount.c + #can.c + i2c.cpp + init.c + led.c + manifest.c + mtd.cpp + sdhc.c + spi.cpp + timer_config.cpp + usb.c + imxrt_romapi.c + imxrt_flexspi_fram.c + imxrt_flexspi_nor_boot.c + imxrt_flexspi_nor_flash.c + imxrt_clockconfig.c + ${SRCS} + ) -target_link_libraries(drivers_board - PRIVATE - arch_board_hw_info - arch_spi - drivers__led # drv_led_start - nuttx_arch # sdio - nuttx_drivers # sdio - px4_layer -) + target_link_libraries(drivers_board + PRIVATE + arch_board_hw_info + arch_spi + drivers__led # drv_led_start + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer + ) +endif() diff --git a/boards/nxp/fmurt1170-v1/src/bootloader_main.c b/boards/nxp/fmurt1170-v1/src/bootloader_main.c new file mode 100644 index 000000000000..04008aa2ffaf --- /dev/null +++ b/boards/nxp/fmurt1170-v1/src/bootloader_main.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * + * Copyright (c) 2023 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * FMU-specific early startup code for bootloader +*/ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/nxp/fmurt1170-v1/src/hw_config.h b/boards/nxp/fmurt1170-v1/src/hw_config.h new file mode 100644 index 000000000000..19611e379cb6 --- /dev/null +++ b/boards/nxp/fmurt1170-v1/src/hw_config.h @@ -0,0 +1,130 @@ +/* + * hw_config.h + * + * Created on: May 17, 2015 + * Author: david_s5 + */ + +#ifndef HW_CONFIG_H_ +#define HW_CONFIG_H_ + +/**************************************************************************** + * 10-8--2016: + * To simplify the ripple effect on the tools, we will be using + * /dev/serial/by-id/PX4 to locate PX4 devices. Therefore + * moving forward all Bootloaders must contain the prefix "PX4 BL " + * in the USBDEVICESTRING + * This Change will be made in an upcoming BL release + ****************************************************************************/ +/* + * Define usage to configure a bootloader + * + * + * Constant example Usage + * APP_LOAD_ADDRESS 0x08004000 - The address in Linker Script, where the app fw is org-ed + * BOOTLOADER_DELAY 5000 - Ms to wait while under USB pwr or bootloader request + * BOARD_FMUV2 + * INTERFACE_USB 1 - (Optional) Scan and use the USB interface for bootloading + * INTERFACE_USART 1 - (Optional) Scan and use the Serial interface for bootloading + * USBDEVICESTRING "PX4 BL FMU v2.x" - USB id string + * USBPRODUCTID 0x0011 - PID Should match defconfig + * BOOT_DELAY_ADDRESS 0x000001a0 - (Optional) From the linker script from Linker Script to get a custom + * delay provided by an APP FW + * BOARD_TYPE 9 - Must match .prototype boad_id + * _FLASH_KBYTES (*(uint16_t *)0x1fff7a22) - Run time flash size detection + * BOARD_FLASH_SECTORS ((_FLASH_KBYTES == 0x400) ? 11 : 23) - Run time determine the physical last sector + * BOARD_FLASH_SECTORS 11 - Hard coded zero based last sector + * BOARD_FLASH_SIZE (_FLASH_KBYTES*1024)- Total Flash size of device, determined at run time. + * (1024 * 1024) - Hard coded Total Flash of device - The bootloader and app reserved will be deducted + * programmatically + * + * BOARD_FIRST_FLASH_SECTOR_TO_ERASE 2 - Optional sectors index in the flash_sectors table (F4 only), to begin erasing. + * This is to allow sectors to be reserved for app fw usage. That will NOT be erased + * during a FW upgrade. + * The default is 0, and selects the first sector to be erased, as the 0th entry in the + * flash_sectors table. Which is the second physical sector of FLASH in the device. + * The first physical sector of FLASH is used by the bootloader, and is not defined + * in the table. + * + * APP_RESERVATION_SIZE (BOARD_FIRST_FLASH_SECTOR_TO_ERASE * 16 * 1024) - Number of bytes reserved by the APP FW. This number plus + * BOOTLOADER_RESERVATION_SIZE will be deducted from + * BOARD_FLASH_SIZE to determine the size of the App FW + * and hence the address space of FLASH to erase and program. + * USBMFGSTRING "PX4 AP" - Optional USB MFG string (default is '3D Robotics' if not defined.) + * SERIAL_BREAK_DETECT_DISABLED - Optional prevent break selection on Serial port from entering or staying in BL + * + * * Other defines are somewhat self explanatory. + */ + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 + +#define APP_LOAD_ADDRESS 0x30020000 +#define APP_VECTOR_OFFSET 0x2000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" + +//#define USE_VBUS_PULL_DOWN +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,1500000" +#define BOOT_DELAY_ADDRESS 0x3003b540 +#define BOARD_TYPE 35 +// The board has a 64 Mb part with 16384, 4K secors, but we artificialy limit it to 4 Mb +// as 1024, 4K sectors +#define BOARD_FLASH_SECTORS 1024 // Really (16384) +#define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 32 // We resreve 128K for the bootloader +#define BOARD_FLASH_SIZE (4 * 1024 * 1024) + +#define OSC_FREQ 24 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN // GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +/* + * Uncommenting this allows to force the bootloader through + * a PWM output pin. As this can accidentally initialize + * an ESC prematurely, it is not recommended. This feature + * has not been used and hence defaults now to off. + * + * # define BOARD_FORCE_BL_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN14) + * # define BOARD_FORCE_BL_PIN_IN (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11) + * + * # define BOARD_POWER_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4) + * # define BOARD_POWER_ON 1 + * # define BOARD_POWER_OFF 0 + * # undef BOARD_POWER_PIN_RELEASE // Leave pin enabling Power - un comment to release (disable power) + * +*/ + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +#if !defined(APP_RESERVATION_SIZE) +# define APP_RESERVATION_SIZE 0 +#endif + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#endif /* HW_CONFIG_H_ */ diff --git a/boards/nxp/fmurt1170-v1/src/imxrt_flexspi_nor_flash.c b/boards/nxp/fmurt1170-v1/src/imxrt_flexspi_nor_flash.c index 42680165dbeb..515b81ca879e 100644 --- a/boards/nxp/fmurt1170-v1/src/imxrt_flexspi_nor_flash.c +++ b/boards/nxp/fmurt1170-v1/src/imxrt_flexspi_nor_flash.c @@ -109,14 +109,29 @@ const struct flexspi_nor_config_s g_flash_fast_config = { [0 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, DUMMY_DDR, FLEXSPI_8PAD, 0x04),//0xb3048b20, [0 + 2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP_EXE, FLEXSPI_1PAD, 0x00), //0xa704, + /* 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_EXE, FLEXSPI_1PAD, 0x00), + /* Write enable SPI *///06h [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP_EXE, FLEXSPI_1PAD, 0x00),//0x00000406, + /* Write enable OPI SPI *///06h + [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_EXE, FLEXSPI_1PAD, 0x00), + /*Write Configuration Register 2 =01, Enable OPI DDR mode*/ //72H +32bit address + CR20x00000000 = 0x01 [4 * 6 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x72, CMD_SDR, FLEXSPI_1PAD, 0x00),//0x04000472, [4 * 6 + 1] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x00),//0x04000400, [4 * 6 + 2] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, WRITE_SDR, FLEXSPI_1PAD, 0x01),//0x20010400, + /*Page program*/ + [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x12, CMD_DDR, FLEXSPI_8PAD, 0xED),//0x87ed8712, + [4 * 9 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, WRITE_DDR, FLEXSPI_8PAD, 0x04),//0xa3048b20, }, }, .pageSize = 256u, diff --git a/boards/nxp/fmurt1170-v1/src/imxrt_romapi.h b/boards/nxp/fmurt1170-v1/src/imxrt_romapi.h index cdc3018b6bd2..52b354c2d193 100644 --- a/boards/nxp/fmurt1170-v1/src/imxrt_romapi.h +++ b/boards/nxp/fmurt1170-v1/src/imxrt_romapi.h @@ -60,6 +60,7 @@ typedef struct _flexspi_xfer { extern "C" { #endif +extern struct flexspi_nor_config_s g_bootConfig; /*! * @brief ROM API init diff --git a/boards/nxp/fmurt1170-v1/src/init.c b/boards/nxp/fmurt1170-v1/src/init.c index 2eaab8bc8bd9..8774fa566dcd 100644 --- a/boards/nxp/fmurt1170-v1/src/init.c +++ b/boards/nxp/fmurt1170-v1/src/init.c @@ -170,21 +170,23 @@ __EXPORT void board_on_reset(int status) * Description: * ****************************************************************************/ +struct flexspi_nor_config_s g_bootConfig; + locate_code(".ramfunc") void imxrt_octl_flash_initialize(void) { const uint32_t instance = 1; - volatile struct flexspi_nor_config_s bootConfig; - memcpy((struct flexspi_nor_config_s *)&bootConfig, &g_flash_fast_config, + memcpy((struct flexspi_nor_config_s *)&g_bootConfig, &g_flash_fast_config, sizeof(struct flexspi_nor_config_s)); - bootConfig.memConfig.tag = FLEXSPI_CFG_BLK_TAG; + g_bootConfig.memConfig.tag = FLEXSPI_CFG_BLK_TAG; ROM_API_Init(); - ROM_FLEXSPI_NorFlash_Init(instance, (struct flexspi_nor_config_s *)&bootConfig); + ROM_FLEXSPI_NorFlash_Init(instance, (struct flexspi_nor_config_s *)&g_bootConfig); + ROM_FLEXSPI_NorFlash_ClearCache(1); ARM_DSB(); ARM_ISB(); @@ -345,10 +347,12 @@ __EXPORT void imxrt_boardinitialize(void) * any failure to indicate the nature of the failure. * ****************************************************************************/ -volatile bool g_debug_loop_on_fault = true; - __EXPORT int board_app_initialize(uintptr_t arg) { + int ret = OK; + +#if !defined(BOOTLOADER) + VDD_3V3_SD_CARD_EN(true); VDD_5V_PERIPH_EN(true); VDD_5V_HIPOWER_EN(true); @@ -374,8 +378,6 @@ __EXPORT int board_app_initialize(uintptr_t arg) px4_arch_gpiowrite(GPIO_HW_VER_REV_DRIVE, 1); VDD_3V3_SENSORS4_EN(true); - int ret = OK; - /* Need hrt running before using the ADC */ px4_platform_init(); @@ -486,5 +488,7 @@ __EXPORT int board_app_initialize(uintptr_t arg) imxrt_caninitialize(3); #endif +#endif /* !defined(BOOTLOADER) */ + return ret; }