RT1064 programming the internal Flash at the same time as using HyperRAM

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

RT1064 programming the internal Flash at the same time as using HyperRAM

2,232 Views
carstengroen
Senior Contributor II

I have come to a tiresome problem in one of our projects. 

The system uses a RT1064, HyperRAM (8 Mbyte) and the code runs out of the internal 4 MByte Flash in the 1064.

The HyperRAM is connected to FlexSPI and the internal Flash is by nature, connected to FlexSPI2.

In my bootloader, I need to have access to the HyperRAM at the same time as programming the internal Flash. This seems not to be possible ??

I can program the internal flash just fine using the NOR Flash driver in the device, but as soon as I do:

status = flexspi_nor_flash_init(instance, &config); // instance is 1 in this case

I loose the connection to the HyperRAM.

Is that to be expected, and more importantly, is there a way around it ?

In this particular case I need to load a firmware file from a filesystem and program that to the internal Flash.

(I'm using the internal 1 MB SRAM for other purposes (filesystem etc etc) so its not an option to use that)

When debugging, I can see that as soon as the NOR Flash driver is called for the internal Flash on FlexSPI2, the FlexSPI is also affected, most of its registers are set to 0. This seems strange as I specifically asks for FlexSPI2 which should be for the internal Flash (or is that determined by the address space)?

Labels (1)
0 Kudos
Reply
7 Replies

1,695 Views
art
NXP Employee
NXP Employee

To make the situation more clear, please specify the following: where your code runs from when you try to initialize the NOR Flash for write? Is it XiP from HyperRAM on FlexSPI, or XiP from QSPI NOR Flash on FlexSPI2, or is it internal RAM? In case of XiP from QSPI NOR Flash on FlexSPI2, the situation is clear and the answer is: there is no way to XiP from a QSPI NOR Flash and write to the same Flash at the same time.


Have a great day,
Artur

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

1,695 Views
carstengroen
Senior Contributor II

Thanks Arthur.

The code runs from XIP (internal NOR Flash of the RT1064 on FlexSPI2 at 0x70000000). The HyperRAM is connected to FlexSPI (at 0x60000000).

I use the Flash NOR drivers of the chip (I assume they are in ROM). This works perfectly fine, I can program the Flash without problems.

The "only" issue is that when the ROM driver function flexspi_nor_flash_init(instance, &config); is called (to start the programming access to the internal NOR Flash) I loose connection to the HyperRAM.

The strange thing is that the internal Flash and the HyperRAM is on seperate FlexSPI busses, but nevertheless, when I access the Flash on FlexSPI2, the HyperRAM on FlexSPI is failing.

After the Flash access (after I update my main firmware), I need to init the HyperRAM again to re-gain access to it (contents are destroyed).

Hope this makes it clear ?

0 Kudos
Reply

1,695 Views
art
NXP Employee
NXP Employee

The QSPI NOR Flash driver is not located in the on-chip ROM, it is the part of the MCUXpresso SDK.

So, the issue mostly looks like the bug in the driver. So, you have to check/debug the driver code.

On my side, I can try to escalate the issue to R&D, but the fast bug fix is not guaranteed.

Best Regards,
Artur

0 Kudos
Reply

1,695 Views
carstengroen
Senior Contributor II

Artur,

This is the code I use:

//------------------------------------------------------------------------------
// IAP.c               20190329 CHG
//------------------------------------------------------------------------------
// See section 8.13.2 in RTR1064 Users Manual regarding FlexSPI NOR API
//------------------------------------------------------------------------------
#include "System.h"
#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
#include "IAP.h"

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

//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
void flexspi_nor_flash_clear_cache(uint32_t instance) {
 g_bootloaderTree->flexSpiNorDriver->clear_cache(instance);
}


// Test data
static flexspi_nor_config_t config;
static serial_nor_config_option_t option;
static status_t status;
static uint32_t instance = 1; // Should identify NOR memory instance

 



//------------------------------------------------------------------------------
// Prepare Flash programming interface to internal Flash
// WARNING: All access to the IAP flash routines must be with interrupts disabled
// if code is executing from internal Flash
// If HyperRAM is used in the system, this is NOT accessible at the same time as these
// routines run, and you MUST re-initialize the HyperRAM interface after you are done 
// using these IAP routines !
//------------------------------------------------------------------------------
int initIAP(void) {
 option.option0.U = 0xC0000008; // QuadSPI NOR, Frequency: 133MHz

 status = flexspi_nor_get_config(instance, &config, &option);
 if (status != kStatus_Success) {
  messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error erasing, rc=", status);

  return status;
 }

 status = flexspi_nor_flash_init(instance, &config);
 if (status != kStatus_Success) {
  messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error init, rc=", status);
  return status;
 }
 return kStatus_Success;
}


//------------------------------------------------------------------------------
// Erase an area in the internal 4 MByte Flash (granularity is 1 sector which is 4 KByte)
// Flash is located at address 0x70000000 and is 0x400000 (4 MByte) in size
// WARNING: All access to the IAP flash routines must be with interrupts disabled
//------------------------------------------------------------------------------
int eraseIAP(unsigned int startaddress, unsigned int length) {
 unsigned int address;
 for (address=startaddress - 0x70000000; address<=startaddress - 0x70000000 + length; address+=config.sectorSize) {
  status = flexspi_nor_flash_erase(instance, &config, address , config.sectorSize); // Erase 1 sector
  if (status != kStatus_Success) {
   messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error erasing, rc=%i, address=0x%08X", status, 0x70000000 + address);
   return status;
  }
 }
 return kStatus_Success;
}


//------------------------------------------------------------------------------
// Program an page (256 bytes) in the internal 4 MByte Flash
// Flash is located at address 0x70000000 and is 0x400000 (4 MByte) in size
// WARNING: All access to the IAP flash routines must be with interrupts disabled
//------------------------------------------------------------------------------
int programIAP(unsigned int startAddress, unsigned int *page_buffer) {
 // Program data to destination (256 bytes)
 status = flexspi_nor_flash_page_program(instance, &config, startAddress - 0x70000000, page_buffer); // program 1 page
 if (status != kStatus_Success) {
  messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error programming, rc=%i, address=0x%08X", status, startAddress);
  return status;
 }
 return kStatus_Success;
}




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

And according to that, the driverstuff is located at

#define g_bootloaderTree (*(bootloader_api_entry_t**)(0x0020001c))

And according to UM:

pastedImage_1.png

0 Kudos
Reply

1,695 Views
art
NXP Employee
NXP Employee

Yes, according to the code you've provided, you really use the ROM API routines.

So, seems that the current version of the ROM NOR Flash API code really affects the FlexSPI1 controller when erase/program operations of the internal NOR Flash occur on FlexSPI2.

As I told before, I can raise a ticket to our R&D team to check the issue, but, anyway, there will be no fast solution for ROM code fix. The possible solution is to use non-ROM code running from some other place e.g. from RAM.

Best Regards,
Artur

0 Kudos
Reply

1,695 Views
carstengroen
Senior Contributor II

Thanks Arthur,

I tried getting the "flexspi_nor_flash_ops.c" functions to work, but no success (I gues LUT etc are not working for the internal Flash). Is there some samples for the internal NOR Flash using the SDK code ??

0 Kudos
Reply

1,695 Views
art
NXP Employee
NXP Employee

The SDK_x.y.z_EVK-MIMXRT1064\boards\evkmimxrt1064\driver_examples\flexspi\nor code seems to be the right one to try. Please try to bring it up using the MCUxpresso IDE. Also, please follow the SDK and IDE documentation.

Best Regards,
Artur

0 Kudos
Reply