Hey all,
I'm new to the i.MX RT1064 platform and I was wondering what documentation covers how to program the flash with a custom bootloader. I've searched the forums and knowledge base but I cannot find any general information about how that is done and what setup is required.
Any help would be appreciated.
Thanks and regards,
Hi
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
To provide the fastest possible support, I'd highly recommend you refer to the application note.
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Sorry, one more question. What NXP documentation did you use that guided the development of this code? Is there an NXP document that defines the required steps for setting up and programming the flash?
Thanks again!
I used examples from the SDK and some "detective work"
Thanks so much for the quick response. this is helpful.
I use the 1064 devices (among others of the RT family), below is some of the code I use for programming the flash (bootloader programs the firmware etc)
Maybe it can be of some help?
//----------------------------------------------------------------------------------
// IAP.c 20210211 CHG
//
// "IAP" functions for NOR Flash on FlexSPI2 (RT1064) at 0x70000000
//----------------------------------------------------------------------------------
#include "system.h"
#include "Debug.h"
#include "IAP.h"
#include "math.h"
#include "fsl_romapi.h"
#include "fsl_common.h"
#include "fsl_cache.h"
#define FlexSpiInstance 1U
#define FLASH_SIZE 0x400000UL // 4MBytes
#define FLASH_PAGE_SIZE 256UL // 256Bytes
#define FLASH_SECTOR_SIZE 0x1000UL // 4KBytes
#define FLASH_BLOCK_SIZE 0x10000UL // 64KBytes
#define BUFFER_LEN FLASH_PAGE_SIZE
// config serial NOR option
static serial_nor_config_option_t option = {
.option0.U = 0xc0000007U,
.option1.U = 0U,
};
static flexspi_nor_config_t norConfig;
static int init=FALSE;
static status_t FLEXSPI_NorFlash_GetVendorID(uint32_t instance, uint32_t *vendorID) {
uint32_t lut_seq[4];
memset(lut_seq, 0, sizeof(lut_seq));
// Read manufacturer ID
lut_seq[0] = FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x9F, READ_SDR, FLEXSPI_1PAD, 4);
ROM_FLEXSPI_NorFlash_UpdateLut(instance, NOR_CMD_LUT_SEQ_IDX_READID, (const uint32_t *)lut_seq, 1U);
flexspi_xfer_t xfer;
xfer.operation = kFLEXSPIOperation_Read;
xfer.seqId = NOR_CMD_LUT_SEQ_IDX_READID;
xfer.seqNum = 1U;
xfer.baseAddress = 0U;
xfer.isParallelModeEnable = false;
xfer.rxBuffer = vendorID;
xfer.rxSize = 1U;
uint32_t status = ROM_FLEXSPI_NorFlash_CommandXfer(instance, &xfer);
if (*vendorID != kSerialFlash_Winbond_ManufacturerID) {
return kStatus_ROM_FLEXSPINOR_Flash_NotFound;
}
return status;
}
//---------------------------------------------------------------------------------------
// Erase a number of sectors. Length must be multiplum of 4KBytes (sector size)
// Baseaddress for the Flash is 0x70000000
//---------------------------------------------------------------------------------------
int eraseSectorIAP(unsigned int startaddress, unsigned int length) {
status_t status;
// Calculate number of (4 KByte) sectors
// We round up to the nearest number of sectors
int totalsectors=ceil(((float)length / (float)norConfig.sectorSize));
if (totalsectors==0)
totalsectors=1;
int togo = totalsectors;
// Make address 0 based
startaddress = startaddress - FlexSPI2_AMBA_BASE;
unsigned int address = startaddress;
if (init==FALSE)
return 1;
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"%i sectors to erase", togo);
while (togo) {
//messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Erasing sector at 0x%08X", FlexSPI2_AMBA_BASE+address);
__disable_irq();
status=ROM_FLEXSPI_NorFlash_Erase(FlexSpiInstance, &norConfig, address, norConfig.sectorSize);
__enable_irq();
if (status != kStatus_Success)
return 2;
// Next sector
togo --;
address += norConfig.sectorSize;
}
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"%i sectors erased", totalsectors);
DCACHE_InvalidateByRange(startaddress, length);
return 0;
}
//---------------------------------------------------------------------------------------
// Program a number of pages in flash. Length must be multiplum of 256 bytes (page size)
// Baseaddress for the Flash is 0x70000000
// Note that if length is NOT a multiplum of a pagesize (256 bytes), garbage will be written
// at the last part of the page
//---------------------------------------------------------------------------------------
int programPageIAP(unsigned int startaddress, unsigned char *buffer, unsigned int length) {
status_t status;
// Calculate number of (256 bytes) pages
int togo = (length / norConfig.pageSize);
if (togo==0)
togo=1;
// Make address 0 based
unsigned int address = startaddress - FlexSPI2_AMBA_BASE;
unsigned int indexBuffer=0;
if (init==FALSE)
return 1;
// messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"%i pages to program", togo);
while (togo) {
//messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Programming page at 0x%08X", address);
__disable_irq();
status=ROM_FLEXSPI_NorFlash_ProgramPage(FlexSpiInstance, &norConfig, address, (const uint32_t *)&buffer[indexBuffer]);
__enable_irq();
if (status != kStatus_Success)
return 2;
// Next sector
togo --;
address += norConfig.pageSize;
indexBuffer += norConfig.pageSize;
}
DCACHE_InvalidateByRange(startaddress, length);
return 0;
}
//---------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------
int initIAP(void) {
status_t status;
uint32_t vendorID = 0U;
if (init)
return 0;
// Disable I cache
SCB_DisableICache();
// Clean up FLEXSPI NOR flash driver Structure
memset(&norConfig, 0U, sizeof(flexspi_nor_config_t));
// Setup FLEXSPI NOR Configuration Block
status = ROM_FLEXSPI_NorFlash_GetConfig(FlexSpiInstance, &norConfig, &option);
if (status == kStatus_Success)
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Successfully get FLEXSPI NOR configuration block");
else {
messageDebug(DBG_ERR, __FILE_NAME__, __LINE__,"Get FLEXSPI NOR configuration block failure!");
return 1;
}
// Initializes the FLEXSPI module for the other FLEXSPI APIs
status = ROM_FLEXSPI_NorFlash_Init(FlexSpiInstance, &norConfig);
if (status == kStatus_Success)
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Successfully init FLEXSPI serial NOR flash");
else {
messageDebug(DBG_ERR, __FILE_NAME__, __LINE__,"Could not init FLEXSPI serial NOR flash");
return 2;
}
// Perform software reset after initializing flexspi module
ROM_FLEXSPI_NorFlash_ClearCache(FlexSpiInstance);
// Probe device presence by verifying Manufacturer ID
status = FLEXSPI_NorFlash_GetVendorID(FlexSpiInstance, &vendorID);
if (status == kStatus_Success)
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Serial flash has been found successfully, VendorID=0x%08X", vendorID);
else {
messageDebug(DBG_ERR, __FILE_NAME__, __LINE__,"Serial flash can not be found");
return 3;
}
// Enable I cache again
SCB_EnableICache();
init=true;
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Serial NOR flash Information:");
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__," Total program flash size: %d KByte", (norConfig.memConfig.sflashA1Size / 1024U));
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__," Program flash sector size: %d KByte", (norConfig.sectorSize / 1024U));
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__," Program flash page size: %d Byte", norConfig.pageSize);
return 0;
static unsigned char buffer[256];
status=eraseSectorIAP(0x70020100, sizeof(buffer));
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Erase sector, rc=%i", status);
hexDumpDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Data before", (unsigned char*)0x70020100, sizeof(buffer),0);
for (int i=0; i<sizeof(buffer);i++)
buffer[i]=i;
status=programPageIAP(0x70020100, buffer, sizeof(buffer));
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Program page, rc=%i", status);
/*
__disable_irq();
status=ROM_FLEXSPI_NorFlash_ProgramPage(FlexSpiInstance, &norConfig, 0x20000, (const uint32_t *)buffer);
__enable_irq();
DCACHE_InvalidateByRange(0x70020000, sizeof(buffer));
messageDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Program page, rc=%i", status);
*/
hexDumpDebug(DBG_NOTE, __FILE_NAME__, __LINE__,"Data", (unsigned char*)0x70020100, sizeof(buffer), 0);
return 0;
}