mirror of https://github.com/wolfSSL/wolfBoot.git
885 lines
38 KiB
C
885 lines
38 KiB
C
/* imx-rt.c
|
||
*
|
||
* Custom HAL implementation. Defines the
|
||
* functions used by wolfboot for a specific target.
|
||
*
|
||
* Copyright (C) 2021 wolfSSL Inc.
|
||
*
|
||
* This file is part of wolfBoot.
|
||
*
|
||
* wolfBoot is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* wolfBoot is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||
*/
|
||
|
||
#include <stdint.h>
|
||
#include <target.h>
|
||
#include "image.h"
|
||
#include "printf.h"
|
||
#include "fsl_common.h"
|
||
#include "fsl_iomuxc.h"
|
||
#include "fsl_nor_flash.h"
|
||
#include "fsl_flexspi.h"
|
||
#ifdef DEBUG_UART
|
||
#include "fsl_lpuart.h"
|
||
#endif
|
||
|
||
#ifdef CPU_MIMXRT1062DVL6A
|
||
#include "evkmimxrt1060_flexspi_nor_config.h"
|
||
#define USE_GET_CONFIG
|
||
#endif
|
||
#ifdef CPU_MIMXRT1042XJM5B
|
||
#include "evkmimxrt1040_flexspi_nor_config.h"
|
||
#endif
|
||
#ifdef CPU_MIMXRT1052DVJ6B
|
||
#include "evkbimxrt1050_flexspi_nor_config.h"
|
||
#endif
|
||
#ifdef CPU_MIMXRT1064DVL6A
|
||
#include "evkmimxrt1064_flexspi_nor_config.h"
|
||
#define USE_GET_CONFIG
|
||
#endif
|
||
|
||
#include "xip/fsl_flexspi_nor_boot.h"
|
||
|
||
/* #define DEBUG_EXT_FLASH */
|
||
/* #define TEST_FLASH */
|
||
|
||
#ifdef TEST_FLASH
|
||
static int test_flash(void);
|
||
#endif
|
||
|
||
|
||
#ifdef __WOLFBOOT
|
||
|
||
/** Built-in ROM API for bootloaders **/
|
||
|
||
typedef void rtwdog_config_t;
|
||
typedef void wdog_config_t;
|
||
|
||
/* Watchdog structures */
|
||
typedef struct {
|
||
void (*RTWDOG_GetDefaultConfig)(rtwdog_config_t *config);
|
||
void (*RTWDOG_Init)(RTWDOG_Type *base, const rtwdog_config_t *config);
|
||
void (*RTWDOG_Deinit)(RTWDOG_Type *base);
|
||
void (*RTWDOG_Enable)(RTWDOG_Type *base);
|
||
void (*RTWDOG_Disable)(RTWDOG_Type *base);
|
||
void (*RTWDOG_EnableInterrupts)(RTWDOG_Type *base, uint32_t mask);
|
||
void (*RTWDOG_DisableInterrupts)(RTWDOG_Type *base, uint32_t mask);
|
||
uint32_t (*RTWDOG_GetStatusFlags)(RTWDOG_Type *base);
|
||
void (*RTWDOG_ClearStatusFlags)(RTWDOG_Type *base, uint32_t mask);
|
||
void (*RTWDOG_SetTimeoutValue)(RTWDOG_Type *base, uint16_t timeoutCount);
|
||
void (*RTWDOG_SetWindowValue)(RTWDOG_Type *base, uint16_t windowValue);
|
||
void (*RTWDOG_Unlock)(RTWDOG_Type *base);
|
||
void (*RTWDOG_Refresh)(RTWDOG_Type *base);
|
||
uint16_t (*RTWDOG_GetCounterValue)(RTWDOG_Type *base);
|
||
} rtwdog_driver_interface_t;
|
||
|
||
typedef struct {
|
||
void (*WDOG_GetDefaultConfig)(wdog_config_t *config);
|
||
void (*WDOG_Init)(WDOG_Type *base, const wdog_config_t *config);
|
||
void (*WDOG_Deinit)(WDOG_Type *base);
|
||
void (*WDOG_Enable)(WDOG_Type *base);
|
||
void (*WDOG_Disable)(WDOG_Type *base);
|
||
void (*WDOG_EnableInterrupts)(WDOG_Type *base, uint16_t mask);
|
||
uint16_t (*WDOG_GetStatusFlags)(WDOG_Type *base);
|
||
void (*WDOG_ClearInterruptStatus)(WDOG_Type *base, uint16_t mask);
|
||
void (*WDOG_SetTimeoutValue)(WDOG_Type *base, uint16_t timeoutCount);
|
||
void (*WDOG_SetInterrputTimeoutValue)(WDOG_Type *base, uint16_t timeoutCount);
|
||
void (*WDOG_DisablePowerDownEnable)(WDOG_Type *base);
|
||
void (*WDOG_Refresh)(WDOG_Type *base);
|
||
} wdog_driver_interface_t;
|
||
|
||
/* Flex SPI op */
|
||
typedef enum _FlexSPIOperationType {
|
||
kFlexSpiOperation_Command,
|
||
kFlexSpiOperation_Config,
|
||
kFlexSpiOperation_Write,
|
||
kFlexSpiOperation_Read,
|
||
kFlexSpiOperation_End = kFlexSpiOperation_Read,
|
||
} flexspi_operation_t;
|
||
|
||
/* FLEX SPI Xfer */
|
||
typedef struct _FlexSpiXfer {
|
||
flexspi_operation_t operation;
|
||
uint32_t baseAddress;
|
||
uint32_t seqId;
|
||
uint32_t seqNum;
|
||
bool isParallelModeEnable;
|
||
uint32_t *txBuffer;
|
||
uint32_t txSize;
|
||
uint32_t *rxBuffer;
|
||
uint32_t rxSize;
|
||
} flexspi_xfer_t;
|
||
|
||
/* Serial NOR config option */
|
||
typedef struct _serial_nor_config_option {
|
||
union {
|
||
struct {
|
||
uint32_t max_freq : 4; /* Maximum supported Frequency */
|
||
uint32_t misc_mode : 4; /* miscellaneous mode */
|
||
uint32_t quad_mode_setting : 4; /* Quad mode setting */
|
||
uint32_t cmd_pads : 4; /* Command pads */
|
||
uint32_t query_pads : 4; /* SFDP read pads */
|
||
uint32_t device_type : 4; /* Device type */
|
||
uint32_t option_size : 4; /* Option size, in terms of uint32_t, size = (option_size + 1) * 4 */
|
||
uint32_t tag : 4; /* Tag, must be 0x0E */
|
||
} B;
|
||
uint32_t U;
|
||
} option0;
|
||
union {
|
||
struct {
|
||
uint32_t dummy_cycles : 8; /* Dummy cycles before read */
|
||
uint32_t reserved0 : 8; /* Reserved for future use */
|
||
uint32_t pinmux_group : 4; /* The pinmux group selection */
|
||
uint32_t reserved1 : 8; /* Reserved for future use */
|
||
uint32_t flash_connection : 4; /* Flash connection option: 0 - Single Flash connected to port A */
|
||
} B;
|
||
uint32_t U;
|
||
} option1;
|
||
} serial_nor_config_option_t;
|
||
|
||
/* NOR flash API */
|
||
typedef struct {
|
||
uint32_t version;
|
||
status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
|
||
status_t (*program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t
|
||
dst_addr, const uint32_t *src);
|
||
status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
|
||
status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start,
|
||
uint32_t lengthInBytes);
|
||
status_t (*read)(
|
||
uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t addr,
|
||
uint32_t lengthInBytes);
|
||
void (*clear_cache)(uint32_t instance);
|
||
status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
|
||
status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t
|
||
*lutBase, uint32_t seqNumber);
|
||
status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config,
|
||
serial_nor_config_option_t *option);
|
||
} flexspi_nor_driver_interface_t;
|
||
|
||
|
||
/* Root pointer */
|
||
typedef struct {
|
||
const uint32_t version; /* Bootloader version number */
|
||
const char *copyright; /* Bootloader Copyright */
|
||
void (*runBootloader)(void *arg); /* Function to start the bootloader executing */
|
||
const uint32_t *reserved0; /* Reserved */
|
||
const flexspi_nor_driver_interface_t *flexSpiNorDriver; /* FlexSPI NOR Flash API */
|
||
const uint32_t *reserved1; /* Reserved */
|
||
const rtwdog_driver_interface_t *rtwdogDriver;
|
||
const wdog_driver_interface_t *wdogDriver;
|
||
const uint32_t *reserved2;
|
||
} bootloader_api_entry_t;
|
||
|
||
bootloader_api_entry_t *g_bootloaderTree;
|
||
#ifdef USE_GET_CONFIG
|
||
flexspi_nor_config_t flexspi_config;
|
||
#define FLEXSPI_CONFIG &flexspi_config
|
||
#else
|
||
#define FLEXSPI_CONFIG (flexspi_nor_config_t*)&qspiflash_config
|
||
#endif
|
||
|
||
|
||
/* FlexSPI LUT Sequence Instruction index offset */
|
||
#define LUT_SEQ_INS_0_1 (0x00U)
|
||
#define LUT_SEQ_INS_2_3 (0x01U)
|
||
#define LUT_SEQ_INS_4_5 (0x02U)
|
||
#define LUT_SEQ_INS_6_7 (0x03U)
|
||
|
||
/* FlexSPI LUT Sequence index offset (NOR) */
|
||
#define LUT_SEQ_IDX_0 (0x00U) /* Read command */
|
||
#define LUT_SEQ_IDX_1 (0x04U) /* Read Status command */
|
||
#define LUT_SEQ_IDX_2 (0x08U) /* RESERVED */
|
||
#define LUT_SEQ_IDX_3 (0x0CU) /* Write Enable command */
|
||
#define LUT_SEQ_IDX_4 (0x10U) /* RESERVED - Custom QE Enable */
|
||
#define LUT_SEQ_IDX_5 (0x14U) /* Erase Sector command */
|
||
#define LUT_SEQ_IDX_6 (0x18U) /* RESERVED */
|
||
#define LUT_SEQ_IDX_7 (0x1CU) /* RESERVED */
|
||
#define LUT_SEQ_IDX_8 (0x20U) /* RESERVED */
|
||
#define LUT_SEQ_IDX_9 (0x24U) /* Page Program command */
|
||
#define LUT_SEQ_IDX_10 (0x28U) /* RESERVED */
|
||
#define LUT_SEQ_IDX_11 (0x2CU) /* Full Chip Erase */
|
||
#define LUT_SEQ_IDX_12 (0x30U) /* RESERVED */
|
||
#define LUT_SEQ_IDX_13 (0x34U) /* SFDP */
|
||
#define LUT_SEQ_IDX_14 (0x38U) /* RESERVED */
|
||
#define LUT_SEQ_IDX_15 (0x3CU) /* Dummy */
|
||
|
||
/** Flash configuration in the .flash_config section of flash **/
|
||
#ifdef CPU_MIMXRT1064DVL6A
|
||
#define CONFIG_FLASH_SIZE (4 * 1024 * 1024) /* 4MBytes */
|
||
#define CONFIG_FLASH_PAGE_SIZE 256UL /* 256Bytes */
|
||
#define CONFIG_FLASH_SECTOR_SIZE (4 * 1024) /* 4KBytes */
|
||
#define CONFIG_FLASH_BLOCK_SIZE (64 * 1024) /* 64KBytes */
|
||
#define CONFIG_FLASH_UNIFORM_BLOCKSIZE false
|
||
#define CONFIG_SERIAL_CLK_FREQ kFlexSpiSerialClk_100MHz
|
||
const flexspi_nor_config_t __attribute__((section(".flash_config"))) qspiflash_config = {
|
||
.memConfig =
|
||
{
|
||
.tag = FLEXSPI_CFG_BLK_TAG,
|
||
.version = FLEXSPI_CFG_BLK_VERSION,
|
||
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
|
||
.csHoldTime = 3u,
|
||
.csSetupTime = 3u,
|
||
.sflashPadType = kSerialFlash_4Pads,
|
||
.serialClkFreq = CONFIG_SERIAL_CLK_FREQ,
|
||
.sflashA1Size = CONFIG_FLASH_SIZE,
|
||
.lookupTable = {
|
||
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
|
||
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
|
||
},
|
||
},
|
||
.pageSize = CONFIG_FLASH_PAGE_SIZE,
|
||
.sectorSize = CONFIG_FLASH_SECTOR_SIZE,
|
||
.blockSize = CONFIG_FLASH_BLOCK_SIZE,
|
||
.isUniformBlockSize = CONFIG_FLASH_UNIFORM_BLOCKSIZE,
|
||
};
|
||
#endif
|
||
|
||
|
||
/** Flash configuration in the .flash_config section of flash **/
|
||
#ifdef CPU_MIMXRT1062DVL6A
|
||
#define CONFIG_FLASH_SIZE (8 * 1024 * 1024) /* 8MBytes */
|
||
#define CONFIG_FLASH_PAGE_SIZE 256UL /* 256Bytes */
|
||
#define CONFIG_FLASH_SECTOR_SIZE (4 * 1024) /* 4KBytes */
|
||
#define CONFIG_FLASH_BLOCK_SIZE (64 * 1024) /* 64KBytes */
|
||
#define CONFIG_FLASH_UNIFORM_BLOCKSIZE false
|
||
#define CONFIG_SERIAL_CLK_FREQ kFlexSpiSerialClk_100MHz
|
||
const flexspi_nor_config_t __attribute__((section(".flash_config"))) qspiflash_config = {
|
||
.memConfig =
|
||
{
|
||
.tag = FLEXSPI_CFG_BLK_TAG,
|
||
.version = FLEXSPI_CFG_BLK_VERSION,
|
||
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
|
||
.csHoldTime = 3u,
|
||
.csSetupTime = 3u,
|
||
.sflashPadType = kSerialFlash_4Pads,
|
||
.serialClkFreq = CONFIG_SERIAL_CLK_FREQ,
|
||
.sflashA1Size = CONFIG_FLASH_SIZE,
|
||
.lookupTable = {
|
||
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
|
||
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
|
||
},
|
||
},
|
||
.pageSize = CONFIG_FLASH_PAGE_SIZE,
|
||
.sectorSize = CONFIG_FLASH_SECTOR_SIZE,
|
||
.blockSize = CONFIG_FLASH_BLOCK_SIZE,
|
||
.isUniformBlockSize = CONFIG_FLASH_UNIFORM_BLOCKSIZE,
|
||
};
|
||
#endif
|
||
|
||
|
||
/** Flash configuration in the .flash_config section of flash **/
|
||
#if defined(CPU_MIMXRT1042XJM5B) || defined(CPU_MIMXRT1052DVJ6B)
|
||
|
||
#ifdef CONFIG_FLASH_W25Q64JV
|
||
/* Winbond W25Q64JV */
|
||
#define WRITE_STATUS_CMD 0x31
|
||
#define QE_ENABLE 0x02 /* S9 */
|
||
#elif defined(CONFIG_FLASH_IS25WP064A)
|
||
/* ISSI IS25WP064A (on EVKB with rework see AN12183) */
|
||
#define WRITE_STATUS_CMD 0x1
|
||
#define QE_ENABLE 0x40 /* S6 */
|
||
#elif !defined(CONFIG_HYPERFLASH)
|
||
/* Hyperflash - Default on RT1050-EVKB */
|
||
#define CONFIG_HYPERFLASH
|
||
#endif
|
||
|
||
#ifdef CONFIG_HYPERFLASH
|
||
#define CONFIG_FLASH_SIZE (64 * 1024 * 1024) /* 64MBytes */
|
||
#define CONFIG_FLASH_PAGE_SIZE 512UL /* 512Bytes */
|
||
#define CONFIG_FLASH_SECTOR_SIZE (256 * 1024) /* 256KBytes */
|
||
#define CONFIG_FLASH_BLOCK_SIZE (256 * 1024) /* 256KBytes */
|
||
#define CONFIG_FLASH_UNIFORM_BLOCKSIZE true
|
||
#define CONFIG_SERIAL_CLK_FREQ kFlexSpiSerialClk_133MHz
|
||
|
||
const flexspi_nor_config_t __attribute__((section(".flash_config"))) qspiflash_config = {
|
||
.memConfig = {
|
||
.tag = FLEXSPI_CFG_BLK_TAG,
|
||
.version = FLEXSPI_CFG_BLK_VERSION,
|
||
.readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
|
||
.csHoldTime = 3u,
|
||
.csSetupTime = 3u,
|
||
.columnAddressWidth = 3u,
|
||
/* Enable DDR mode, Word-addressable, Safe configuration, Differential clock */
|
||
.controllerMiscOption =
|
||
(1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) |
|
||
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable),
|
||
.deviceType = kFlexSpiDeviceType_SerialNOR,
|
||
.sflashPadType = kSerialFlash_8Pads,
|
||
.serialClkFreq = CONFIG_SERIAL_CLK_FREQ,
|
||
.lutCustomSeqEnable = 0x1,
|
||
.sflashA1Size = CONFIG_FLASH_SIZE,
|
||
.dataValidTime = {15u, 0u},
|
||
.busyOffset = 15u,
|
||
.busyBitPolarity = 1u,
|
||
.lookupTable = {
|
||
/* Read LUTs */
|
||
[0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18),
|
||
[1] = FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_DDR, FLEXSPI_8PAD, 0x0C),
|
||
[2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),
|
||
|
||
/* Read Status LUTs - 0 */
|
||
[4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 1 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 1 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 1 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x70),
|
||
|
||
/* Read Status LUTs - 1 */
|
||
[4 * 2 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18),
|
||
[4 * 2 + 1] = FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_RWDS_DDR, FLEXSPI_8PAD, 0x0B),
|
||
[4 * 2 + 2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x4, STOP, FLEXSPI_1PAD, 0x0),
|
||
|
||
/* Write Enable LUTs - 0 */
|
||
[4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 3 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 3 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 3 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
|
||
/* Write Enable LUTs - 1 */
|
||
[4 * 4 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 4 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x55),
|
||
[4 * 4 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x02),
|
||
[4 * 4 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x55),
|
||
|
||
/* Erase Sector LUTs - 0 */
|
||
[4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 5 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 5 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 5 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x80),
|
||
|
||
/* Erase Sector LUTs - 1 */
|
||
[4 * 6 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 6 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 6 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 6 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
|
||
/* Erase Sector LUTs - 2 */
|
||
[4 * 7 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 7 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x55),
|
||
[4 * 7 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x02),
|
||
[4 * 7 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x55),
|
||
|
||
/* Erase Sector LUTs - 3 */
|
||
[4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, RADDR_DDR, FLEXSPI_8PAD, 0x18),
|
||
[4 * 8 + 1] = FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 8 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x30, STOP, FLEXSPI_1PAD, 0x0),
|
||
|
||
/* Page Program LUTs - 0 */
|
||
[4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 9 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 9 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 9 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xA0),
|
||
|
||
/* Page Program LUTs - 1 */
|
||
[4 * 10 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, RADDR_DDR, FLEXSPI_8PAD, 0x18),
|
||
[4 * 10 + 1] = FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, WRITE_DDR, FLEXSPI_8PAD, 0x80),
|
||
|
||
/* Erase Chip LUTs - 0 */
|
||
[4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 11 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 11 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 11 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x80),
|
||
|
||
/* Erase Chip LUTs - 1 */
|
||
[4 * 12 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 12 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 12 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 12 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
|
||
/* Erase Chip LUTs - 2 */
|
||
[4 * 13 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 13 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x55),
|
||
[4 * 13 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x02),
|
||
[4 * 13 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x55),
|
||
|
||
/* Erase Chip LUTs - 3 */
|
||
[4 * 14 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x0),
|
||
[4 * 14 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0xAA),
|
||
[4 * 14 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x05),
|
||
[4 * 14 + 3] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x0, CMD_DDR, FLEXSPI_8PAD, 0x10),
|
||
},
|
||
/* LUT customized sequence */
|
||
.lutCustomSeq = {
|
||
{.seqNum = 0, .seqId = 0, .reserved = 0},
|
||
{.seqNum = 2, .seqId = 1, .reserved = 0},
|
||
{.seqNum = 2, .seqId = 3, .reserved = 0},
|
||
{.seqNum = 4, .seqId = 5, .reserved = 0},
|
||
{.seqNum = 2, .seqId = 9, .reserved = 0},
|
||
{.seqNum = 4, .seqId = 11, .reserved = 0}
|
||
},
|
||
},
|
||
.pageSize = CONFIG_FLASH_PAGE_SIZE,
|
||
.sectorSize = CONFIG_FLASH_SECTOR_SIZE,
|
||
.ipcmdSerialClkFreq = 1u,
|
||
.serialNorType = 1u,
|
||
.blockSize = CONFIG_FLASH_BLOCK_SIZE,
|
||
.isUniformBlockSize = CONFIG_FLASH_UNIFORM_BLOCKSIZE,
|
||
};
|
||
#else /* QSPI */
|
||
|
||
#define CONFIG_FLASH_SIZE (8 * 1024 * 1024) /* 8MBytes */
|
||
#define CONFIG_FLASH_PAGE_SIZE 256UL /* 256Bytes */
|
||
#define CONFIG_FLASH_SECTOR_SIZE (4 * 1024) /* 4Bytes */
|
||
#define CONFIG_FLASH_BLOCK_SIZE (64 * 1024) /* 64KBytes */
|
||
#define CONFIG_FLASH_UNIFORM_BLOCKSIZE false
|
||
#define CONFIG_SERIAL_CLK_FREQ kFlexSpiSerialClk_100MHz
|
||
#define CONFIG_FLASH_ADDR_WIDTH 24u /* Width of flash addresses (either 24 or 32) */
|
||
#define CONFIG_FLASH_QE_ENABLE 1
|
||
|
||
/* Note: By default the RT1050-EVKB uses HyperFlex.
|
||
* To use QSPI flash a rework is required. See AN12183
|
||
*/
|
||
|
||
/* QSPI boot header */
|
||
/* Credit to: https://community.nxp.com/t5/i-MX-RT/RT1050-Debugging-with-QSPI-flash-on-secondary-pinmux/m-p/934745 */
|
||
const flexspi_nor_config_t __attribute__((section(".flash_config"))) qspiflash_config = {
|
||
.memConfig = {
|
||
.tag = FLEXSPI_CFG_BLK_TAG,
|
||
.version = FLEXSPI_CFG_BLK_VERSION,
|
||
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
|
||
.deviceType = kFlexSpiDeviceType_SerialNOR,
|
||
.sflashPadType = kSerialFlash_4Pads,
|
||
.serialClkFreq = CONFIG_SERIAL_CLK_FREQ,
|
||
.sflashA1Size = CONFIG_FLASH_SIZE,
|
||
.csHoldTime = 3,
|
||
.csSetupTime = 3,
|
||
.controllerMiscOption = (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable),
|
||
.columnAddressWidth = 0,
|
||
.waitTimeCfgCommands = 0, /* 0=use read status (or #*100us) wait instead */
|
||
#if CONFIG_FLASH_QE_ENABLE == 1
|
||
.deviceModeCfgEnable = 1,
|
||
.deviceModeType = kDeviceConfigCmdType_QuadEnable,
|
||
.deviceModeSeq.seqNum = 2, /* issue 2 commands starting at index 3 */
|
||
.deviceModeSeq.seqId = 3, /* issue write enable and write status */
|
||
.deviceModeArg = QE_ENABLE,
|
||
#endif
|
||
.lutCustomSeqEnable = 0,
|
||
.dataValidTime = {16u, 16u},
|
||
.busyOffset = 0, /* WIP/Busy bit=0 (read status busy bit offset */
|
||
.busyBitPolarity = 0, /* 0 – Busy bit=1 (device is busy) */
|
||
.lookupTable = {
|
||
#if 0 /* disabled for now, causes issue with page program */
|
||
/* Quad Input/output read sequence - with optimized XIP support */
|
||
[LUT_SEQ_IDX_0 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0xEB,
|
||
RADDR_SDR, FLEXSPI_4PAD, CONFIG_FLASH_ADDR_WIDTH),
|
||
[LUT_SEQ_IDX_0 + LUT_SEQ_INS_2_3] = FLEXSPI_LUT_SEQ(
|
||
MODE8_SDR, FLEXSPI_4PAD, 0xA0 /* continuous read mode - 2 dummy cycles */,
|
||
DUMMY_SDR, FLEXSPI_4PAD, 0x04 /* 4 dummy cycles (6 total) */ ),
|
||
[LUT_SEQ_IDX_0 + LUT_SEQ_INS_4_5] = FLEXSPI_LUT_SEQ(
|
||
READ_SDR, FLEXSPI_4PAD, 0x04 /* any non-zero value */,
|
||
JMP_ON_CS, FLEXSPI_1PAD, 0x01),
|
||
#else
|
||
/* Quad Input/output read sequence */
|
||
[LUT_SEQ_IDX_0 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0xEB,
|
||
RADDR_SDR, FLEXSPI_4PAD, CONFIG_FLASH_ADDR_WIDTH),
|
||
[LUT_SEQ_IDX_0 + LUT_SEQ_INS_2_3] = FLEXSPI_LUT_SEQ(
|
||
DUMMY_SDR, FLEXSPI_4PAD, 0x06 /* 6 dummy cycles */,
|
||
READ_SDR, FLEXSPI_4PAD, 0x04 /* any non-zero value */ ),
|
||
#endif
|
||
/* Read Status */
|
||
[LUT_SEQ_IDX_1 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0x05,
|
||
READ_SDR, FLEXSPI_1PAD, 0x04 /* Read 4 bytes */ ),
|
||
/* Write Enable */
|
||
[LUT_SEQ_IDX_3 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0x06,
|
||
STOP, FLEXSPI_1PAD, 0x00),
|
||
/* Write Status - Custom LUT (QE Enable) */
|
||
[LUT_SEQ_IDX_4 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, WRITE_STATUS_CMD,
|
||
WRITE_SDR, FLEXSPI_1PAD, 0x01 /* Write 1 byte */ ),
|
||
/* Erase Sector */
|
||
[LUT_SEQ_IDX_5 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0x20 /* Sector Erase, 1-bit */,
|
||
RADDR_SDR, FLEXSPI_1PAD, CONFIG_FLASH_ADDR_WIDTH),
|
||
/* Erase Block - Custom LUT */
|
||
[LUT_SEQ_IDX_8 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0xD8 /* Block Erase, 1-bit */,
|
||
RADDR_SDR, FLEXSPI_1PAD, CONFIG_FLASH_ADDR_WIDTH),
|
||
#if CONFIG_FLASH_QE_ENABLE == 1
|
||
/* Quad Page Program */
|
||
[LUT_SEQ_IDX_9 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0x32,
|
||
RADDR_SDR, FLEXSPI_1PAD, CONFIG_FLASH_ADDR_WIDTH),
|
||
[LUT_SEQ_IDX_9 + LUT_SEQ_INS_2_3] = FLEXSPI_LUT_SEQ(
|
||
WRITE_SDR, FLEXSPI_4PAD, 0x04 /* any non-zero value */,
|
||
STOP, FLEXSPI_1PAD, 0x00),
|
||
#else
|
||
/* Page Program */
|
||
[LUT_SEQ_IDX_9 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0x02,
|
||
RADDR_SDR, FLEXSPI_1PAD, CONFIG_FLASH_ADDR_WIDTH),
|
||
[LUT_SEQ_IDX_9 + LUT_SEQ_INS_2_3] = FLEXSPI_LUT_SEQ(
|
||
WRITE_SDR, FLEXSPI_1PAD, 0x04 /* any non-zero value */,
|
||
STOP, FLEXSPI_1PAD, 0x00),
|
||
#endif
|
||
/* Chip Erase */
|
||
[LUT_SEQ_IDX_11 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0x60,
|
||
STOP, FLEXSPI_1PAD, 0x00),
|
||
/* SFDP - Required for get_config */
|
||
[LUT_SEQ_IDX_13 + LUT_SEQ_INS_0_1] = FLEXSPI_LUT_SEQ(
|
||
CMD_SDR, FLEXSPI_1PAD, 0x5A,
|
||
RADDR_SDR, FLEXSPI_1PAD, CONFIG_FLASH_ADDR_WIDTH ),
|
||
[LUT_SEQ_IDX_13 + LUT_SEQ_INS_2_3] = FLEXSPI_LUT_SEQ(
|
||
DUMMY_SDR, FLEXSPI_1PAD, 0x08 /* 8 dummy cycles */,
|
||
READ_SDR, FLEXSPI_4PAD, 0xFF /* Read 255 bytes */),
|
||
},
|
||
},
|
||
.pageSize = CONFIG_FLASH_PAGE_SIZE,
|
||
.sectorSize = CONFIG_FLASH_SECTOR_SIZE,
|
||
.blockSize = CONFIG_FLASH_BLOCK_SIZE,
|
||
.isUniformBlockSize = CONFIG_FLASH_UNIFORM_BLOCKSIZE,
|
||
.ipcmdSerialClkFreq = 0,
|
||
};
|
||
#endif
|
||
#endif /* CPU_MIMXRT1042XJM5B || CPU_MIMXRT1052DVJ6B */
|
||
|
||
|
||
#ifndef __FLASH_BASE
|
||
#if defined(CPU_MIMXRT1042XJM5B) || defined(CPU_MIMXRT1052DVJ6B) || defined(CPU_MIMXRT1062DVL6A)
|
||
#define __FLASH_BASE 0x60000000
|
||
#elif defined(CPU_MIMXRT1064DVL6A)
|
||
#define __FLASH_BASE 0x70000000
|
||
#else
|
||
#error "Please define MCUXPRESSO SDK CPU variant macro (e.g. CPU_MIMXRT1062DVL6A)"
|
||
#endif
|
||
#endif
|
||
|
||
#ifndef FLASH_BASE
|
||
#define FLASH_BASE __FLASH_BASE
|
||
#define PLUGIN_FLAG 0x0UL
|
||
#endif
|
||
|
||
const BOOT_DATA_T __attribute__((section(".boot_data"))) boot_data = {
|
||
FLASH_BASE, /* boot start location */
|
||
CONFIG_FLASH_SIZE, /* size */
|
||
PLUGIN_FLAG, /* Plugin flag*/
|
||
0xFFFFFFFF /* empty - extra data word */
|
||
};
|
||
|
||
|
||
extern void isr_reset(void);
|
||
extern const uint8_t __dcd_data_start;
|
||
const uint32_t dcd_data_addr = (uint32_t) &__dcd_data_start;
|
||
|
||
#ifndef NXP_CUSTOM_DCD
|
||
/* If a DCD section is populated, it should be mapped to the .dcd_data section.
|
||
* By default, provide an empty section.
|
||
*/
|
||
const uint8_t __attribute__((section(".dcd_data"))) dcd_data[sizeof(uint32_t)] = { 0 };
|
||
#endif
|
||
|
||
const ivt __attribute__((section(".image_vt"))) image_vector_table = {
|
||
IVT_HEADER, /* IVT Header */
|
||
(uint32_t)isr_reset, /* Image Entry Function */
|
||
IVT_RSVD, /* Reserved = 0 */
|
||
(uint32_t)dcd_data_addr, /* Address where DCD information is stored */
|
||
(uint32_t)&boot_data, /* Address where BOOT Data Structure is stored */
|
||
(uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
|
||
(uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
|
||
IVT_RSVD /* Reserved = 0 */
|
||
};
|
||
|
||
/*******************************************************************************
|
||
* Variables for BOARD_BootClockRUN configuration
|
||
******************************************************************************/
|
||
const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = {
|
||
.loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */
|
||
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
|
||
};
|
||
const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = {
|
||
.loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */
|
||
.numerator = 0, /* 30 bit numerator of fractional loop divider */
|
||
.denominator = 1, /* 30 bit denominator of fractional loop divider */
|
||
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
|
||
};
|
||
const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = {
|
||
.loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */
|
||
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
|
||
};
|
||
const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = {
|
||
.loopDivider = 31, /* PLL loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */
|
||
.postDivider = 8, /* Divider after PLL */
|
||
.numerator = 0, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */
|
||
.denominator = 1, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */
|
||
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
|
||
};
|
||
|
||
static void clock_init(void)
|
||
{
|
||
if (CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_BYPASS_MASK) {
|
||
/* Configure ARM_PLL */
|
||
CCM_ANALOG->PLL_ARM =
|
||
CCM_ANALOG_PLL_ARM_BYPASS(1) |
|
||
CCM_ANALOG_PLL_ARM_ENABLE(1) |
|
||
CCM_ANALOG_PLL_ARM_DIV_SELECT(24);
|
||
/* Wait Until clock is locked */
|
||
while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0);
|
||
|
||
/* Configure PLL_SYS */
|
||
CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_POWERDOWN_MASK;
|
||
/* Wait Until clock is locked */
|
||
while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0);
|
||
|
||
/* Configure PFD_528 */
|
||
CCM_ANALOG->PFD_528 =
|
||
CCM_ANALOG_PFD_528_PFD0_FRAC(24) |
|
||
CCM_ANALOG_PFD_528_PFD1_FRAC(24) |
|
||
CCM_ANALOG_PFD_528_PFD2_FRAC(19) |
|
||
CCM_ANALOG_PFD_528_PFD3_FRAC(24);
|
||
|
||
/* Configure USB1_PLL */
|
||
CCM_ANALOG->PLL_USB1 =
|
||
CCM_ANALOG_PLL_USB1_DIV_SELECT(0) |
|
||
CCM_ANALOG_PLL_USB1_POWER(1) |
|
||
CCM_ANALOG_PLL_USB1_ENABLE(1);
|
||
while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0);
|
||
CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK;
|
||
|
||
/* Configure PFD_480 */
|
||
CCM_ANALOG->PFD_480 =
|
||
CCM_ANALOG_PFD_480_PFD0_FRAC(35) |
|
||
CCM_ANALOG_PFD_480_PFD1_FRAC(35) |
|
||
CCM_ANALOG_PFD_480_PFD2_FRAC(26) |
|
||
CCM_ANALOG_PFD_480_PFD3_FRAC(15);
|
||
|
||
/* Configure Clock PODF */
|
||
CCM->CACRR = CCM_CACRR_ARM_PODF(1);
|
||
|
||
CCM->CBCDR =
|
||
(CCM->CBCDR &
|
||
(~(CCM_CBCDR_SEMC_PODF_MASK |
|
||
CCM_CBCDR_AHB_PODF_MASK |
|
||
CCM_CBCDR_IPG_PODF_MASK))) |
|
||
CCM_CBCDR_SEMC_PODF(2) |
|
||
CCM_CBCDR_AHB_PODF(2) |
|
||
CCM_CBCDR_IPG_PODF(2);
|
||
|
||
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1064DVL6A)
|
||
/* Configure FLEXSPI2 CLOCKS */
|
||
CCM->CBCMR =
|
||
(CCM->CBCMR &
|
||
(~(CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK |
|
||
CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK |
|
||
CCM_CBCMR_FLEXSPI2_PODF_MASK))) |
|
||
CCM_CBCMR_PRE_PERIPH_CLK_SEL(3) |
|
||
CCM_CBCMR_FLEXSPI2_CLK_SEL(1) |
|
||
CCM_CBCMR_FLEXSPI2_PODF(7);
|
||
#endif
|
||
|
||
/* Configure FLEXSPI CLOCKS */
|
||
CCM->CSCMR1 =
|
||
((CCM->CSCMR1 &
|
||
~(CCM_CSCMR1_FLEXSPI_CLK_SEL_MASK |
|
||
CCM_CSCMR1_FLEXSPI_PODF_MASK |
|
||
CCM_CSCMR1_PERCLK_PODF_MASK |
|
||
CCM_CSCMR1_PERCLK_CLK_SEL_MASK)) |
|
||
CCM_CSCMR1_FLEXSPI_CLK_SEL(3) |
|
||
CCM_CSCMR1_FLEXSPI_PODF(7) |
|
||
CCM_CSCMR1_PERCLK_PODF(1));
|
||
|
||
/* Finally, Enable PLL_ARM, PLL_SYS and PLL_USB1 */
|
||
CCM_ANALOG->PLL_ARM &= ~CCM_ANALOG_PLL_ARM_BYPASS_MASK;
|
||
CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_BYPASS_MASK;
|
||
CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK;
|
||
}
|
||
}
|
||
|
||
|
||
#ifdef DEBUG_UART
|
||
|
||
/* The UART interface (LPUART1 - LPUART8) */
|
||
#ifndef UART_BASEADDR
|
||
#define UART_BASEADDR LPUART1
|
||
#endif
|
||
#ifndef UART_BAUDRATE
|
||
#define UART_BAUDRATE (115200U)
|
||
#endif
|
||
|
||
void uart_init(void)
|
||
{
|
||
lpuart_config_t config;
|
||
uint32_t uartClkSrcFreq = 20000000U; /* 20 MHz */
|
||
|
||
#if UART_BASEADDR == LPUART1
|
||
/* Configure the UART IO pins for LPUART1
|
||
* Tested with RT1040, RT1050, RT1062 and RT1064
|
||
*/
|
||
CLOCK_EnableClock(kCLOCK_Iomuxc);
|
||
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U);
|
||
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U);
|
||
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U);
|
||
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U);
|
||
#endif
|
||
|
||
LPUART_GetDefaultConfig(&config);
|
||
config.baudRate_Bps = UART_BAUDRATE;
|
||
config.enableTx = true;
|
||
config.enableRx = true;
|
||
|
||
LPUART_Init(UART_BASEADDR, &config, uartClkSrcFreq);
|
||
}
|
||
|
||
void uart_write(const char* buf, unsigned int sz)
|
||
{
|
||
int doCrlf = 0;
|
||
if (buf[sz-1] == '\n') { /* handle CRLF */
|
||
doCrlf = 1;
|
||
sz--;
|
||
}
|
||
LPUART_WriteBlocking(UART_BASEADDR, (const uint8_t*)buf, sz);
|
||
if (doCrlf) {
|
||
const char* kCrlf = "\r\n";
|
||
LPUART_WriteBlocking(UART_BASEADDR, (const uint8_t*)kCrlf, 2);
|
||
}
|
||
}
|
||
|
||
#endif /* DEBUG_UART */
|
||
|
||
|
||
extern void ARM_MPU_Disable(void);
|
||
extern int wc_dcp_init(void);
|
||
static int hal_flash_init(void);
|
||
|
||
void hal_init(void)
|
||
{
|
||
#ifdef WOLFSSL_IMXRT_DCP
|
||
wc_dcp_init();
|
||
#endif
|
||
ARM_MPU_Disable();
|
||
clock_init();
|
||
#ifdef DEBUG_UART
|
||
uart_init();
|
||
uart_write("wolfBoot HAL Init\n", 18);
|
||
#endif
|
||
hal_flash_init();
|
||
#ifdef TEST_FLASH
|
||
if (test_flash() != 0) {
|
||
wolfBoot_printf("Flash Test Failed!\n");
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void hal_prepare_boot(void)
|
||
{
|
||
}
|
||
|
||
#endif /* __WOLFBOOT */
|
||
|
||
static int hal_flash_init(void)
|
||
{
|
||
#ifdef USE_GET_CONFIG
|
||
serial_nor_config_option_t flexspi_cfg_option;
|
||
#endif
|
||
if (g_bootloaderTree == NULL) {
|
||
g_bootloaderTree = (bootloader_api_entry_t *)*(uint32_t *)0x0020001c;
|
||
#ifdef USE_GET_CONFIG
|
||
memset(&flexspi_cfg_option, 0, sizeof(flexspi_cfg_option));
|
||
flexspi_cfg_option.option0.U = 0xC0000007; /* QuadSPI-NOR, f = default */
|
||
g_bootloaderTree->flexSpiNorDriver->get_config(0,
|
||
&flexspi_config,
|
||
&flexspi_cfg_option);
|
||
g_bootloaderTree->flexSpiNorDriver->init(0, &flexspi_config);
|
||
g_bootloaderTree->flexSpiNorDriver->clear_cache(0);
|
||
#endif
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
||
{
|
||
status_t status;
|
||
uint32_t wbuf[CONFIG_FLASH_PAGE_SIZE / sizeof(uint32_t)];
|
||
int i;
|
||
hal_flash_init(); /* make sure g_bootloaderTree is set */
|
||
#ifdef DEBUG_EXT_FLASH
|
||
wolfBoot_printf("flash write: addr 0x%x, len %d\n",
|
||
address - FLASH_BASE, len);
|
||
#endif
|
||
for (i = 0; i < len; i+= CONFIG_FLASH_PAGE_SIZE) {
|
||
memcpy(wbuf, data + i, CONFIG_FLASH_PAGE_SIZE);
|
||
status = g_bootloaderTree->flexSpiNorDriver->program(0, FLEXSPI_CONFIG,
|
||
(address + i) - FLASH_BASE, wbuf);
|
||
if (status != kStatus_Success)
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void RAMFUNCTION hal_flash_unlock(void)
|
||
{
|
||
}
|
||
|
||
void RAMFUNCTION hal_flash_lock(void)
|
||
{
|
||
}
|
||
|
||
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
||
{
|
||
status_t status;
|
||
hal_flash_init(); /* make sure g_bootloaderTree is set */
|
||
#ifdef DEBUG_EXT_FLASH
|
||
wolfBoot_printf("flash erase: addr 0x%x, len %d\n",
|
||
address - FLASH_BASE, len);
|
||
#endif
|
||
status = g_bootloaderTree->flexSpiNorDriver->erase(0, FLEXSPI_CONFIG,
|
||
address - FLASH_BASE, len);
|
||
if (status != kStatus_Success)
|
||
return -1;
|
||
return 0;
|
||
}
|
||
|
||
#ifdef TEST_FLASH
|
||
|
||
#ifndef TEST_ADDRESS
|
||
#define TEST_ADDRESS (FLASH_BASE + 0x700000) /* 7MB */
|
||
#endif
|
||
/* #define TEST_FLASH_READONLY */
|
||
|
||
static uint32_t pageData[WOLFBOOT_SECTOR_SIZE/4]; /* force 32-bit alignment */
|
||
|
||
static int test_flash(void)
|
||
{
|
||
int ret;
|
||
uint32_t i;
|
||
|
||
#ifndef TEST_FLASH_READONLY
|
||
/* Erase sector */
|
||
ret = hal_flash_erase(TEST_ADDRESS, WOLFBOOT_SECTOR_SIZE);
|
||
wolfBoot_printf("Erase Sector: Ret %d\n", ret);
|
||
|
||
/* Fill data into the page_buffer */
|
||
for (i=0; i<sizeof(pageData)/sizeof(pageData[0]); i++) {
|
||
pageData[i] = (i << 24) | (i << 16) | (i << 8) | i;
|
||
}
|
||
/* Write Page */
|
||
ret = hal_flash_write(TEST_ADDRESS, (uint8_t*)pageData, sizeof(pageData));
|
||
wolfBoot_printf("Write Page: Ret %d\n", ret);
|
||
#endif /* !TEST_FLASH_READONLY */
|
||
|
||
/* Compare Page */
|
||
ret = memcmp((void*)TEST_ADDRESS, pageData, sizeof(pageData));
|
||
if (ret != 0) {
|
||
wolfBoot_printf("Check Data @ %d failed\n", ret);
|
||
return ret;
|
||
}
|
||
|
||
wolfBoot_printf("Flash Test Passed\n");
|
||
return ret;
|
||
}
|
||
#endif /* TEST_FLASH */
|