Skip to content

Commit

Permalink
Refactor flash setup for MIMXRT105x devices, add flash API support fo…
Browse files Browse the repository at this point in the history
…r MIMXRT1062 EVK (#187)

* Refactor flash setup for MIMXRT105x devices, adds flash support for MIMXRT1062 EVK

* Remove commented code

* Use BOARD_FLASH_SIZE in boot headers

* Fix setting which should be disabled in run mode
  • Loading branch information
multiplemonomials authored Oct 1, 2023
1 parent 05a57dc commit 9f4987d
Show file tree
Hide file tree
Showing 25 changed files with 388 additions and 155 deletions.
5 changes: 1 addition & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,8 @@ if(NOT MBED_IS_NATIVE_BUILD)
# We must set this global property before the targets subdirectory is added to the project. This is
# required because the MBED_TARGET depends on the response file. If the path to the response file
# is not defined when the target requests it the config definitions will not be passed to CPP.
#
# TODO: Remove this and find a more idiomatic way of passing compile definitions to CPP without
# using response files or global properties.
mbed_generate_options_for_linker(mbed-core-flags RESPONSE_FILE_PATH)
set_property(GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE ${RESPONSE_FILE_PATH})
set_property(GLOBAL PROPERTY LINKER_SCRIPT_PREPROCESS_FLAGS_RESPONSE_FILE ${RESPONSE_FILE_PATH})

# Add compile definitions for backward compatibility with the toolchain
# supported. New source files should instead check for __GNUC__ and __clang__
Expand Down
4 changes: 3 additions & 1 deletion drivers/include/drivers/FlashIAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
#include "platform/NonCopyable.h"
#include <algorithm>

// Export ROM end address
// Export ROM end address, if not defined by HAL layer
#ifndef FLASHIAP_APP_ROM_END_ADDR
#if defined(TOOLCHAIN_GCC_ARM)
extern uint32_t __etext;
extern uint32_t __data_start__;
Expand All @@ -48,6 +49,7 @@ extern uint32_t Load$$LR$$LR_IROM1$$Limit[];
#define FLASHIAP_APP_ROM_END_ADDR std::max(std::max((uint32_t) __section_end(".rodata"), (uint32_t) __section_end(".text")), \
(uint32_t) __section_end(".init_array"))
#endif
#endif

namespace mbed {

Expand Down
5 changes: 4 additions & 1 deletion hal/include/hal/flash_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address);
*/
uint32_t flash_get_page_size(const flash_t *obj);

/** Get start address for the flash region
/** Get start address for the flash region (as in, where the flash is mapped in main memory).
*
* \note This should return the start address of the entire flash region, not
* the first address after the end of the program in flash.
*
* @param obj The flash object
* @return The start address for the flash region
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ target_include_directories(mbed-mimxrt1050-evk
target_sources(mbed-mimxrt1050-evk
INTERFACE
fsl_flexspi_nor_boot.c

TARGET_1050_EVK/flash_api.c
flash_api.c

TARGET_1050_EVK/xip/evkbimxrt1050_flexspi_nor_config.c
TARGET_1050_EVK/xip/evkbimxrt1050_sdram_ini_dcd.c
Expand All @@ -35,6 +34,7 @@ target_include_directories(mbed-mimxrt1060-evk
target_sources(mbed-mimxrt1060-evk
INTERFACE
fsl_flexspi_nor_boot.c
flash_api.c

TARGET_1060_EVK/xip/evkbmimxrt1060_flexspi_nor_config.c
TARGET_1060_EVK/xip/dcd.c
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#define FSL_COMPONENT_ID "platform.drivers.xip_board"
#endif

#include "mimxrt_memory_info.h"

/*******************************************************************************
* Code
******************************************************************************/
Expand All @@ -37,7 +39,7 @@ const flexspi_nor_config_t hyperflash_config = {
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable),
.sflashPadType = kSerialFlash_8Pads,
.serialClkFreq = kFlexSpiSerialClk_133MHz,
.sflashA1Size = 64u * 1024u * 1024u,
.sflashA1Size = BOARD_FLASH_SIZE,
.dataValidTime = {16u, 16u},
.lookupTable = {
// Read LUTs
Expand Down Expand Up @@ -66,7 +68,7 @@ const flexspi_nor_config_t qspiflash_config = {
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_133MHz,
.lutCustomSeqEnable = 0u,
.sflashA1Size = 0x00800000u, /* 8MB/64Mbit */
.sflashA1Size = BOARD_FLASH_SIZE,
.lookupTable = {
// Fast read sequence
[0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include "evkbmimxrt1060_flexspi_nor_config.h"
#include "mimxrt_memory_info.h"

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
Expand Down Expand Up @@ -34,7 +35,7 @@ const flexspi_nor_config_t qspiflash_config = {
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_120MHz,
.sflashA1Size = 8u * 1024u * 1024u,
.sflashA1Size = BOARD_FLASH_SIZE,
.lookupTable =
{
// Read LUTs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,22 @@
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H

#define DEVICE_ID_LENGTH 24
#include <stdint.h>

#ifdef HYPERFLASH_BOOT
/* 64MB HyperFlash, 4MB reserved for mbed-os */
#define BOARD_FLASH_SIZE (0x4000000U)
#define BOARD_FLASH_START_ADDR (0x60000000U)
#define BOARD_FLASHIAP_SIZE (0x3C00000U)
#define BOARD_FLASHIAP_START_ADDR (0x60400000U)
#define BOARD_FLASH_PAGE_SIZE (512)
#define BOARD_FLASH_SECTOR_SIZE (262144)
#else
/* 8MB QSPI Flash, 64KB reserved for mbed_bootloader */
#define BOARD_FLASH_SIZE (0x800000U)
#define BOARD_FLASH_START_ADDR (0x60000000U)
#define BOARD_FLASHIAP_SIZE (0x7F0000U)
#define BOARD_FLASHIAP_START_ADDR (0x60010000U)
#define BOARD_FLASH_PAGE_SIZE (256)
#define BOARD_FLASH_SECTOR_SIZE (4096)
#endif
#define DEVICE_ID_LENGTH 24

#define BOARD_ENET_PHY_ADDR (2)

/* CMSIS defines this, we use it as linker symbol, undefined it and let a linker symbol
to be as vector table */
#undef __VECTOR_TABLE

// The MIMXRT linker script provides the __USED_FLASH_END symbol to
// indicate where application data ends in flash
extern uint8_t __USED_FLASH_END[0];
#define FLASHIAP_APP_ROM_END_ADDR ((uint32_t)__USED_FLASH_END)

#include "mimxrt_memory_info.h"
#include "objects.h"

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include "fsl_flexspi.h"
#include "fsl_cache.h"
#include "flash_defines.h"
#include "mimxrt_flash_api.h"

#include <inttypes.h>
#include <stdio.h>

AT_QUICKACCESS_SECTION_CODE(void flexspi_update_lut_ram(void));
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_write_enable_ram(uint32_t baseAddr));
Expand Down Expand Up @@ -103,6 +107,13 @@ void flexspi_update_lut_ram(void)
config.enableSckBDiffOpt = true;
config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad;
config.enableCombination = true;

/* Wait for bus idle. It seems to be important to hold off on calling
* FLEXSPI_Init() until after the bus is idle; I was getting random crashes
* until I added this. */
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
}

FLEXSPI_Init(FLEXSPI, &config);

/* Configure flash settings according to serial flash feature. */
Expand All @@ -116,6 +127,10 @@ void flexspi_update_lut_ram(void)
/* Wait for bus idle. */
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
}

// Just in case any bad data got into the I-cache while we were reconfiguring
// the flash, wipe it.
SCB_InvalidateICache();
}

status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
Expand Down Expand Up @@ -319,13 +334,31 @@ status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *sr

#else
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_enable_quad_mode_ram(void));
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_read_status_register_ram(uint32_t * result));

/*
* Check if quad SPI mode is enabled and, if not, enable it.
*
* Note that I'm not totally sure if this function is needed because I don't think
* that the application could boot without quad mode enabled, but this might be
* useful for programming non-boot-device flashes at a later date.
* Or, if you must run the application on a flash which does not have quad mode enabled,
* you could temporarily change the boot header read command to use 1-pad read,
* then rely on this function to update the setting.
*/
status_t flexspi_nor_enable_quad_mode_ram(void)
{
flexspi_transfer_t flashXfer;
uint32_t writeValue = FLASH_QUAD_ENABLE;
status_t status = kStatus_Success;
uint32_t readResult = 0;
status_t status = flexspi_nor_read_status_register_ram(&readResult);
if (status != kStatus_Success) {
return status;
}

if(readResult & (1 << FLASH_QE_STATUS_OFFSET)) {
// QSPI mode already enabled, don't need to do anything
return kStatus_Success;
}

flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
/* Write enable */
status = flexspi_nor_write_enable_ram(0);

Expand All @@ -334,6 +367,8 @@ status_t flexspi_nor_enable_quad_mode_ram(void)
}

/* Enable quad mode. */
flexspi_transfer_t flashXfer = {};
uint32_t writeValue = (1 << FLASH_QE_STATUS_OFFSET);
flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
Expand All @@ -349,17 +384,12 @@ status_t flexspi_nor_enable_quad_mode_ram(void)

status = flexspi_nor_wait_bus_busy_ram();

/* Do software reset. */
FLEXSPI_SoftwareReset(FLEXSPI);

return status;
}

void flexspi_update_lut_ram(void)
{
flexspi_config_t config;

flexspi_memset(&config, 0, sizeof(config));
flexspi_config_t config = {};

/*Get FLEXSPI default settings and configure the flexspi. */
FLEXSPI_GetDefaultConfig(&config);
Expand All @@ -370,6 +400,15 @@ void flexspi_update_lut_ram(void)
config.ahbConfig.enableReadAddressOpt = true;
config.ahbConfig.enableAHBCachable = true;
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
config.enableDoze = false; // matches boot rom setting
config.seqTimeoutCycle = 0xee6c; // matches boot rom setting

/* Wait for bus idle. It seems to be important to hold off on calling
* FLEXSPI_Init() until after the bus is idle; I was getting random crashes
* until I added this. */
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
}

FLEXSPI_Init(FLEXSPI, &config);

/* Configure flash settings according to serial flash feature. */
Expand All @@ -383,7 +422,12 @@ void flexspi_update_lut_ram(void)
/* Wait for bus idle. */
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
}

flexspi_nor_enable_quad_mode_ram();

// Just in case any bad data got into the I-cache while we were reconfiguring
// the flash, wipe it.
SCB_InvalidateICache();
}

status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
Expand All @@ -404,47 +448,46 @@ status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
return status;
}

status_t flexspi_nor_wait_bus_busy_ram(void)
// Read the status register and save the result into the given pointer
status_t flexspi_nor_read_status_register_ram(uint32_t * result)
{
/* Wait status ready. */
bool isBusy;
uint32_t readValue;
status_t status = kStatus_Success;
flexspi_transfer_t flashXfer;

flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
flexspi_transfer_t flashXfer = {};

flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG;
flashXfer.data = &readValue;
flashXfer.data = result;
flashXfer.dataSize = 1;

return FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
}

status_t flexspi_nor_wait_bus_busy_ram(void)
{
/* Wait status ready. */
bool isBusy;

do {
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
uint32_t readResult;
status_t status = flexspi_nor_read_status_register_ram(&readResult);

if (status != kStatus_Success) {
return status;
}
if (FLASH_BUSY_STATUS_POL) {
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) {
isBusy = true;
} else {
isBusy = false;
}
} else {
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) {
isBusy = false;
} else {
isBusy = true;
}

if(readResult & (1U << FLASH_BUSY_STATUS_OFFSET)) {
isBusy = FLASH_BUSY_STATUS_POL;
}
else
{
isBusy = !FLASH_BUSY_STATUS_POL;
}

} while (isBusy);

return status;
return kStatus_Success;
}


Expand Down Expand Up @@ -540,12 +583,18 @@ void flexspi_nor_flash_read_data_ram(uint32_t addr, uint32_t *buffer, uint32_t s
memcpy(buffer, (void *)addr, size);
}

int32_t flash_init(flash_t *obj)
void mimxrt_flash_setup(void)
{
core_util_critical_section_enter();
flexspi_update_lut_ram();
core_util_critical_section_exit();
}

int32_t flash_init(flash_t *obj)
{
// Setup is already done when the application boots by flash_setup().
// Nothing left to do.
(void)obj;
return 0;
}

Expand Down Expand Up @@ -581,6 +630,8 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
if (status != kStatus_Success) {
ret = -1;
} else {
SCB_InvalidateICache_by_Addr((void*)address, (int32_t)size);
SCB_InvalidateDCache_by_Addr((void*)address, (int32_t)size);
DCACHE_InvalidateByRange(address, size);
}

Expand All @@ -604,8 +655,8 @@ int32_t flash_free(flash_t *obj)
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
{
uint32_t sectorsize = MBED_FLASH_INVALID_SIZE;
uint32_t devicesize = BOARD_FLASHIAP_SIZE;
uint32_t startaddr = BOARD_FLASHIAP_START_ADDR;
uint32_t devicesize = BOARD_FLASH_SIZE;
uint32_t startaddr = BOARD_FLASH_START_ADDR;

if ((address >= startaddr) && (address < (startaddr + devicesize))) {
sectorsize = BOARD_FLASH_SECTOR_SIZE;
Expand All @@ -621,12 +672,12 @@ uint32_t flash_get_page_size(const flash_t *obj)

uint32_t flash_get_start_address(const flash_t *obj)
{
return BOARD_FLASHIAP_START_ADDR;
return BOARD_FLASH_START_ADDR;
}

uint32_t flash_get_size(const flash_t *obj)
{
return BOARD_FLASHIAP_SIZE;
return BOARD_FLASH_SIZE;
}

uint8_t flash_get_erase_value(const flash_t *obj)
Expand Down
Loading

0 comments on commit 9f4987d

Please sign in to comment.