Programming the internal Flash of RT1064

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Programming the internal Flash of RT1064

7,597 Views
carstengroen
Senior Contributor II

Is there any updated examples for programming ("IAP") the internal 4 MByte Flash of the RT1064 ?

In the SDK there is the "flexspi/nor/polling transfer" example, but this is only for the external Flash on the EVK (on FlexSPI). The internal Flash is located on FlexSPI2 and the SDK sample does not work when adjusted to FlexSPI2 etc (probably because the LUT is different among many things).

In the UM there is a chapter on the ROM API, I have tried implementing stuff from that, but no matter what I do, it ends up in a hard crash....

So, any samples (using plain code or the ROM API) that can program the internal Flash of the RT1064 ?

(I need this in a bootloader)

Labels (1)
4 Replies

5,680 Views
Sabina_Bruce
NXP Employee
NXP Employee

Hello carstengroen

 

Please refer to the following community document, here you will find a detailed explanation of all the modifications that you need to make to one of the SDKs examples to use the on-chip flash as NVM. 

RT1064 use on-chip flash as NVM 

 

Have a great day,

Sabina

0 Kudos
Reply

5,680 Views
carstengroen
Senior Contributor II

So, I managed to get this to work Smiley Happy

Based on the example in the Users Manual I got the following code cooked together.

Important is to disable the interrupts as code it running form internal Flash (at 0x70000000) and we are programming the same memory using the FlexSPI NOR API.

However, the HyperRAM can NOT be used, it seems the FlexSPI where I have HyperRAM on is somehow affected when doing this FlexSPI NOR API stuff

The solution seems to be to keep all data for the module below in internal SRAM, and then do a (new) initialization of the HyperRAM/FLEXSPI interface one the code below finishes. Then the HyperRAM seems to work again.

(HyperRAM on FlexSPI and the internal NOR is on FlexSPI2) 

Hope someone else can use this.

My code:

//------------------------------------------------------------------------------
// IAP.c               20190329 CHG
//------------------------------------------------------------------------------
// See section 8.13.2 in RTR1064 Users Manual regarding FlexSPI NOR API
//------------------------------------------------------------------------------
#include "fsl_flexspi.h"
#include "fsl_rtwdog.h"
#include "fsl_wdog.h"
#include "evkmimxrt1064_flexspi_nor_config.h" // Contains definition of flexspi_nor_config_t etc

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;

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;


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;

typedef struct _FlexSpiXfer {
 flexspi_operation_t operation; //!< FlexSPI operation
 uint32_t baseAddress; //!< FlexSPI operation base address
 uint32_t seqId; //!< Sequence Id
 uint32_t seqNum; //!< Sequence Number
 bool isParallelModeEnable; //!< Is a parallel transfer
 uint32_t *txBuffer; //!< Tx buffer
 uint32_t txSize; //!< Tx size in bytes
 uint32_t *rxBuffer; //!< Rx buffer
 uint32_t rxSize; //!< Rx size in bytes
} flexspi_xfer_t;


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;

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[2]; //!< Reserved
 const rtwdog_driver_interface_t *rtwdogDriver;
 const wdog_driver_interface_t *wdogDriver;
 const uint32_t *reserved2;
} bootloader_api_entry_t;
#define g_bootloaderTree (*(bootloader_api_entry_t**)(0x0020001c))








//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
status_t flexspi_nor_flash_init(uint32_t instance, flexspi_nor_config_t *config) {
 return g_bootloaderTree->flexSpiNorDriver->init(instance, config);
}

//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
status_t flexspi_nor_flash_page_program(uint32_t instance, flexspi_nor_config_t*config, uint32_t dstAddr, const uint32_t *src) {
 return g_bootloaderTree->flexSpiNorDriver->program(instance, config, dstAddr, src);
}

//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
status_t flexspi_nor_flash_erase_all(uint32_t instance, flexspi_nor_config_t *config) {
 return g_bootloaderTree->flexSpiNorDriver->erase_all(instance, config);
}

//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
status_t flexspi_nor_get_config(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option) {
 return g_bootloaderTree->flexSpiNorDriver->get_config(instance, config, option);
}

//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
status_t flexspi_nor_flash_erase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length) {
 return g_bootloaderTree->flexSpiNorDriver->erase(instance, config, start, length);
}

//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
status_t flexspi_nor_flash_read(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes) {
 return g_bootloaderTree->flexSpiNorDriver->read(instance, config, dst, start, bytes);
}



// Test data
static flexspi_nor_config_t config;
static serial_nor_config_option_t option;
static status_t status;
static uint32_t address = 0x40000; // The 256 bytes page we are programming starts at 0x70040000
static uint32_t sector_size = 0x1000; // a sector is 4KB
static uint32_t page_buffer[256/ sizeof(uint32_t)];
static uint32_t instance = 1; // Should identify NOR memory instance

//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
int testIAP(void) {
 option.option0.U = 0xC0000008; // QuadSPI NOR, Frequency: 133MHz
 
 // Need to run with interrupts disabled as all our code is running out of FlexSPI2 (internal NOT flash in RT1064)
 __disable_irq();
 
 
 status = flexspi_nor_get_config(instance, &config, &option);
 if (status != kStatus_Success) {
  __enable_irq();
  return status;
 }
 
 status = flexspi_nor_flash_init(instance, &config);
 if (status != kStatus_Success) {
  __enable_irq();
  return status;
 }
 status = flexspi_nor_flash_erase(instance, &config, address , sector_size); // Erase 1 sector
 if (status != kStatus_Success) {
  __enable_irq();
  return status;
 }
 // Fill data into the page_buffer;
 for (uint32_t i=0; i<sizeof(page_buffer)/sizeof(page_buffer[0]); i++) {
  page_buffer[i] = (i << 24) | (i << 16) | (i << 8) | i;
 }
 
 // Program data to destination (256 bytes)
 status = flexspi_nor_flash_page_program(instance, &config, address, page_buffer); // program 1 page
 if (status != kStatus_Success) {
  __enable_irq();
  return status;
 }
 
 SCB_CleanDCache();
 // Do cache maintenance here if the D-Cache is enabled
 // Use memory mapped access to verify whether data are programmed into Flash correctly
 uint32_t mem_address = 0x70000000 + address;
 if (0 == memcmp((void*)mem_address, page_buffer, sizeof(page_buffer))) {
 // Success
  __enable_irq();
  return kStatus_Success;
 } else { // Report error
  __enable_irq();
  return kStatus_Fail;
 }

}

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

5,680 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Carsten Groen,,

Good:smileylaugh:.
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
Reply

5,680 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Carsten Groen,

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
1)So, any samples (using plain code or the ROM API) that can program the internal Flash of the RT1064?
-- No, I'm afraid there's no demo about the operations of the internal flash.
About the bootloader demo, I'd like to suggest you refer to the bootloader_examples in SDK_2.5.0_EVK-MIMXRT1060.
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
Reply