i.MX RT1064 programming

cancel
Showing results for 
Search instead for 
Did you mean: 

i.MX RT1064 programming

327 Views
dwswensen
Contributor I

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,

 

0 Kudos
5 Replies

281 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

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.
-------------------------------------------------------------------------------

0 Kudos

288 Views
dwswensen
Contributor I

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!

0 Kudos

270 Views
carstengroen
Senior Contributor II

I used examples from the SDK and some "detective work"

 

0 Kudos

293 Views
dwswensen
Contributor I

Thanks so much for the quick response. this is helpful.

0 Kudos

317 Views
carstengroen
Senior Contributor II

@dwswensen ,

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;
}


0 Kudos