Fixed IMX-RT-1060 flash driver, working update

pull/81/head
Daniele Lacamera 2020-10-09 13:26:28 +02:00
parent c26d2c0517
commit 9186c263a2
4 changed files with 237 additions and 69 deletions

12
arch.mk
View File

@ -137,19 +137,9 @@ ifeq ($(TARGET),imx_rt)
-I$(MCUXPRESSO)/components/serial_manager/ \
-DCPU_$(MCUXPRESSO_CPU) -I$(MCUXPRESSO_CMSIS)/Include -DDEBUG_CONSOLE_ASSERT_DISABLE=1 -I$(MCUXPRESSO_DRIVERS)/project_template/ \
-I$(MCUXPRESSO)/boards/evkmimxrt1060/xip/ -DXIP_EXTERNAL_FLASH=1 -DDEBUG_CONSOLE_ASSERT_DISABLE=1 -DPRINTF_ADVANCED_ENABLE=1 \
-DSCANF_ADVANCED_ENABLE=1 -DSERIAL_PORT_TYPE_UART=1
-DSCANF_ADVANCED_ENABLE=1 -DSERIAL_PORT_TYPE_UART=1 -DNDEBUG=1
OBJS+= $(MCUXPRESSO)/middleware/mflash/mimxrt1062/mflash_drv.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_dcp.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_flexspi.o
OBJS+= $(MCUXPRESSO_DRIVERS)/utilities/str/fsl_str.o \
$(MCUXPRESSO)/components/uart/lpuart_adapter.o \
$(MCUXPRESSO)/components/serial_manager/serial_manager.o \
$(MCUXPRESSO)/components/lists/generic_list.o \
$(MCUXPRESSO)/components/serial_manager/serial_port_uart.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_lpuart.o \
$(MCUXPRESSO_DRIVERS)/utilities/debug_console/fsl_debug_console.o \
$(MCUXPRESSO)/components/flash/nor/flexspi/fsl_flexspi_nor_flash.o \
$(MCUXPRESSO_DRIVERS)/system_MIMXRT1062.o
ifeq ($(PKA),1)
PKA_EXTRA_OBJS+=\
$(MCUXPRESSO_DRIVERS)/drivers/fsl_dcp.o \

View File

@ -34,11 +34,153 @@
#include "imx_rt_nor.h"
#include "xip/fsl_flexspi_nor_boot.h"
#define FLASH_PAGE_SIZE WOLFBOOT_SECTOR_SIZE
#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, //!< FlexSPI operation: Only command, both TX and
//! RX buffer are ignored.
kFlexSpiOperation_Config, //!< FlexSPI operation: Configure device mode, the
//! TX FIFO size is fixed in LUT.
kFlexSpiOperation_Write, //!< FlexSPI operation: Write, only TX buffer is
//! effective
kFlexSpiOperation_Read, //!< FlexSPI operation: Read, only Rx Buffer is
//! effective.
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;
flexspi_nor_config_t flexspi_config;
/** Flash configuration in the .flash_config section of flash **/
const flexspi_nor_config_t __attribute__((section(".flash_config"))) qspiflash_config = {
.memConfig =
{
@ -123,8 +265,77 @@ const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN =
};
static int nor_flash_init(void);
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);
// 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);
// Confgiure 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;
}
}
extern void ARM_MPU_Disable(void);
void hal_init(void)
{
ARM_MPU_Disable();
g_bootloaderTree = (bootloader_api_entry_t *)*(uint32_t *)0x0020001c;
clock_init();
nor_flash_init();
}
void hal_prepare_boot(void)
@ -133,60 +344,29 @@ void hal_prepare_boot(void)
#endif
flexspi_mem_config_t flexcfg = {
.deviceConfig =
{
.flexspiRootClk = 120000000,
.flashSize = FLASH_SIZE,
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 2,
.CSHoldTime = 3,
.CSSetupTime = 3,
.dataValidTime = 0,
.columnspace = 0,
.enableWordAddress = 0,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 0,
},
.devicePort = kFLEXSPI_PortA1,
.deviceType = kSerialNorCfgOption_DeviceType_ReadSFDP_SDR,
.quadMode = kSerialNorQuadMode_NotConfig,
.transferMode = kSerialNorTransferMode_SDR,
.enhanceMode = kSerialNorEnhanceMode_Disabled,
.commandPads = kFLEXSPI_1PAD,
.queryPads = kFLEXSPI_1PAD,
.statusOverride = 0,
.busyOffset = 0,
.busyBitPolarity = 0,
};
static nor_config_t norConfig = {
.memControlConfig = &flexcfg,
.driverBaseAddr = FLEXSPI,
};
static nor_handle_t norHandle = {NULL};
void FLEXSPI_ClockInit();
static serial_nor_config_option_t flexspi_cfg_option = {};
static int nor_flash_init(void)
{
status_t status;
FLEXSPI_ClockInit();
return Nor_Flash_Init(&norConfig, &norHandle);
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);
return 0;
}
#define FLASH_PAGE_SIZE 0x100
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
{
/*
status_t status;
status = Nor_Flash_Page_Program(&norHandle, address, data);
if (kStatus_Success != status)
return -1;
*/
uint32_t wbuf[FLASH_PAGE_SIZE / 4];
int i;
for (i = 0; i < len; i+= FLASH_PAGE_SIZE) {
memcpy(wbuf, data + i, FLASH_PAGE_SIZE);
status = g_bootloaderTree->flexSpiNorDriver->program(0, &flexspi_config, (address + i) - FLASH_BASE, wbuf);
if (kStatus_Success != status)
return -1;
}
return 0;
}
@ -200,16 +380,10 @@ void RAMFUNCTION hal_flash_lock(void)
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
{
/*
uint32_t end = address + len - 1;
uint32_t p;
status_t status;
for (p = address; p <= end; p += FLASH_PAGE_SIZE) {
status = Nor_Flash_Erase_Sector(&norHandle, address);
if (status != kStatus_Success)
return -1;
}
*/
status = g_bootloaderTree->flexSpiNorDriver->erase(0, &flexspi_config, address - FLASH_BASE, len);
if (status != kStatus_Success)
return -1;
return 0;
}

View File

@ -2,7 +2,7 @@
MEMORY
{
FLASH(rx) : ORIGIN = 0x60000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS##
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 0x0001FFF0
}
/* Define output sections */

View File

@ -81,17 +81,21 @@ ifeq ($(TARGET),imx_rt)
-I$(MCUXPRESSO_DRIVERS)/project_template/ -I$(MCUXPRESSO)/boards/evkmimxrt1060/xip/ \
-I$(MCUXPRESSO_DRIVERS)/utilities/debug_console/ -I$(MCUXPRESSO)/components/serial_manager \
-I$(MCUXPRESSO)/components/uart/ -I$(MCUXPRESSO_DRIVERS)/utilities/str/ \
-DPRINTF_ADVANCED_ENABLE=1 -DSCANF_ADVANCED_ENABLE=1 -DSERIAL_PORT_TYPE_UART=1
-I$(MCUXPRESSO)/components/flash/nor \
-I$(MCUXPRESSO)/components/flash/nor/flexspi \
-DPRINTF_ADVANCED_ENABLE=1 -DSCANF_ADVANCED_ENABLE=1 -DSERIAL_PORT_TYPE_UART=1 -DNDEBUG=1
LDFLAGS+=-mcpu=cortex-m7 -Wall --specs=nosys.specs -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -mthumb -mapcs -Xlinker --gc-sections -Xlinker -static -Xlinker -z -Xlinker muldefs -Xlinker -Map=output.map -static -lm -lc -lnosys
LSCRIPT_TEMPLATE=imx_rt.ld
APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_gpio.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_common.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o \
imx_rt_board.o imx_rt_pin_mux.o imx_rt_clock_config.o $(MCUXPRESSO_DRIVERS)/system_MIMXRT1062.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_flexspi.o \
$(MCUXPRESSO_DRIVERS)/utilities/str/fsl_str.o \
$(MCUXPRESSO)/components/uart/lpuart_adapter.o \
$(MCUXPRESSO)/components/uart/lpuart_adapter.o \
$(MCUXPRESSO)/components/serial_manager/serial_manager.o \
$(MCUXPRESSO)/components/lists/generic_list.o \
$(MCUXPRESSO)/components/serial_manager/serial_port_uart.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_lpuart.o \
$(MCUXPRESSO)/components/flash/nor/flexspi/fsl_flexspi_nor_flash.o \
$(MCUXPRESSO_DRIVERS)/utilities/debug_console/fsl_debug_console.o
endif