Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor flash setup for MIMXRT105x devices, add flash API support for MIMXRT1062 EVK #187

Merged
merged 4 commits into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
multiplemonomials marked this conversation as resolved.
Show resolved Hide resolved
#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 @@ -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,32 @@ 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));

//uint32_t readStatusResult;

/*
* 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,
* you could temporarily change the read command to use 1-pad read during initial provisioning.
*/
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 +368,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 +385,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 +401,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 +423,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 +449,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 +584,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 +631,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 +656,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 +673,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
Loading