Hello NXP Community,
I am currently working on a custom board that uses an i.MX RT1021 (iMXRT1021CAF4B) and a W25Q80DV Flash, connected on the same pin as the one on the EVK, with XIP code.
I am encountering an issue when trying to debug my project via JTAG using an NXP MCU-Link. When I start debugging MCUXpresso never reach the main() and if I suspend the debugger, I receive the following message: “Break at address ‘0x215a90’ with no debug information available, or outside of program code.” whit always the same address.
Here is my configuration object for the flexspi_nor_config.c file:
/* FLEXSPI memory config block related defintions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally, .csHoldTime = 3u, .csSetupTime = 3u, .deviceModeCfgEnable = true, .deviceModeType = kDeviceConfigCmdType_QuadEnable, .deviceModeSeq = { .seqNum = 1, .seqId = 4, }, .deviceModeArg = 0x40, // Set QE bit in status register .controllerMiscOption = 0u, .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_80MHz, .lutCustomSeqEnable = 0u, .lookupTable = { [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), // Fast Read Quad I/O [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), [4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), // Read Status Register [8] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x00), // Write Enable [12] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x18), // Erase Sector [16] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18), // Page Program [17] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x00), [20] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31, WRITE_SDR, FLEXSPI_1PAD, 0x01), // Set QE bit in status register }, }, .pageSize = 256u, .sectorSize = 4 * 1024u, .blockSize = 64 * 1024u, .isUniformBlockSize = false, };
I would appreciate any guidance or suggestions on how to resolve this issue.
Thank you in advance for your help.
Best,
Salvatore
Solved! Go to Solution.
Hello, could someone please provide a more detailed explanation of these NOR flash parameters? I’m unable to devise a solution to this problem without specifically using the flash chip from the evaluation board.
Hi @diego_charles, thanks for your reply.
here is the SRC Register:
I was also having trouble with the BOOT_MODE[1:0] pins, because i didn't know about the BT_FUSE_SEL and i was stuck in Serial Downloader... this post helped me understanding: Programming the i.MXRT1021 - how hard can it be? | Details | Hackaday.io
About the LUT in general and specific for my memory, I found this relevant posts, which (i think) pointed in the right direction:
Solved: Re: IMXRT1176 construct of FLEXSPI LUT entry - NXP Community
which lead me to this link: iMXRT/targets/iMXRT/Loader2/FlexSPI_Winbond.h at master · Masmiseim36/iMXRT · GitHub
I read again the AN12183.pdf and now I understood why in this screen there was only 1 LUT sequences (the QUAD-READ)
Then I tried to arrange a test using "Flexspi_nor_polling_transfer" demo code, loaded in internal RAM, for finding the correct LUT for my memory and I came up with a strange behaviour (project attached)...
using the following LUTs:
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
/* Normal read mode -SDR */
/* Normal read mode -SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Fast read mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
/* In XIP, the speed of external flash is set to 133MHz, and the external flash require to match 8 corresponding dummy cycles.
* However, other non XIP boot targets are not suitable for XIP boot flow, uses flash default configuration */
#if defined(XIP_BOOT_HEADER_ENABLE) && XIP_BOOT_HEADER_ENABLE
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x0A, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
#else
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
#endif
/* Fast read quad mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18),
#if defined(XIP_BOOT_HEADER_ENABLE) && XIP_BOOT_HEADER_ENABLE
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
#else
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
#endif
/* Read extend parameters */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
//FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Write Enable - OK */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Erase Sector - OK */
[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
//FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xD7, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
/* Page Program - single mode - OK */
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Page Program - quad mode - OK */
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Read ID */
[4 * NOR_CMD_LUT_SEQ_IDX_READID] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Enable Quad mode - OK*/
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
/* Enter QPI mode */
[4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Exit QPI mode */
[4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Read status(1) register - OK */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Read status(2) register - OK */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Erase whole chip - OK*/
[4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
};
with this App.h:
/*
* Copyright 2021 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _APP_H_
#define _APP_H_
/*******************************************************************************
* Definitions
******************************************************************************/
/*${macro:start}*/
#define EXAMPLE_FLEXSPI FLEXSPI
#define FLASH_SIZE 0x100000 /* 1MByte */
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
#define FLASH_PAGE_SIZE 256
#define EXAMPLE_SECTOR 6 //6
#define SECTOR_SIZE 0x1000 /* 4K */
#define EXAMPLE_FLEXSPI_CLOCK kCLOCK_FlexSpi
#define FLASH_PORT kFLEXSPI_PortA1
#define EXAMPLE_FLEXSPI_RX_SAMPLE_CLOCK kFLEXSPI_ReadSampleClkLoopbackInternally //kFLEXSPI_ReadSampleClkLoopbackFromDqsPad
#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 7
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST 14
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 0
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS 1
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 2
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 3
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE 6
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 4
#define NOR_CMD_LUT_SEQ_IDX_READID 8
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 9
#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10
#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 11
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 12
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG2 13
#define NOR_CMD_LUT_SEQ_IDX_ERASECHIP 5
#define CUSTOM_LUT_LENGTH 60
#define FLASH_QUAD_ENABLE 0x200 //0x40
#define FLASH_BUSY_STATUS_POL 1
#define FLASH_BUSY_STATUS_OFFSET 0
#define FLASH_ERROR_STATUS_MASK 0x0e
/*
* If cache is enabled, this example should maintain the cache to make sure
* CPU core accesses the memory, not cache only.
*/
#define CACHE_MAINTAIN 1
/*${macro:end}*/
/*******************************************************************************
* Variables
******************************************************************************/
/*${variable:start}*/
#if (defined CACHE_MAINTAIN) && (CACHE_MAINTAIN == 1)
typedef struct _flexspi_cache_status
{
volatile bool DCacheEnableFlag;
volatile bool ICacheEnableFlag;
} flexspi_cache_status_t;
#endif
/*${variable:end}*/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*${prototype:start}*/
void BOARD_InitHardware(void);
static inline void flexspi_clock_init()
{
#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
/* Switch to PLL2 for XIP to avoid hardfault during re-initialize clock. */
CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Set PLL2 PFD2 clock 396MHZ. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x2); /* Choose PLL2 PFD2 clock as flexspi source clock. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 133M. */
#else
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); /* Set PLL3 PFD0 clock 360MHZ. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); /* flexspi clock 120M. */
#endif
}
/*${prototype:end}*/
#endif /* _APP_H_ */
Based on this information found in the flash datasheet:
And modifying the main() as this:
int main(void)
{
uint32_t i = 0;
status_t status;
uint8_t vendorID = 0;
uint8_t statusReg = 0;
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
PRINTF("\r\nFLEXSPI example started!\r\n");
/* Get vendor ID. */
status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
if (status != kStatus_Success)
{
return status;
}
PRINTF("Vendor ID: 0x%x\r\n", vendorID);
#if !(defined(XIP_EXTERNAL_FLASH))
/* Erase whole chip . */
PRINTF("Erasing whole chip over FlexSPI...\r\n");
status = flexspi_nor_erase_chip(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
return status;
}
PRINTF("Erase finished !\r\n");
#endif
status = flexspi_nor_flash_read_status(EXAMPLE_FLEXSPI, &statusReg);
if (status != kStatus_Success)
{
PRINTF("ERROR getting status reg...\r\n");
}
else
{
PRINTF("STATUS REG = 0x%02x\r\n", statusReg);
}
status = flexspi_nor_flash_read_status2(EXAMPLE_FLEXSPI, &statusReg);
if (status != kStatus_Success)
{
PRINTF("ERROR getting status reg...\r\n");
}
else
{
PRINTF("STATUS REG 2 = 0x%02x\r\n", statusReg);
}
/* Enter quad mode. */
status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
return status;
}
else
{
PRINTF("Quad Mode enabled succesfully! \r\n\r\n");
}
/* Erase sectors. */
PRINTF("Erasing Serial NOR over FlexSPI...\r\n");
status = flexspi_nor_flash_erase_sector(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE);
if (status != kStatus_Success)
{
PRINTF("Erase sector failure !\r\n");
return -1;
}
memset(s_nor_program_buffer, 0xFFU, sizeof(s_nor_program_buffer));
DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);
memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
sizeof(s_nor_read_buffer));
if (memcmp(s_nor_program_buffer, s_nor_read_buffer, sizeof(s_nor_program_buffer)))
{
PRINTF("Erase data - read out data value incorrect !\r\n ");
return -1;
}
else
{
PRINTF("Erase data - successfully. \r\n");
}
for (i = 0; i < 0xFFU; i++)
{
s_nor_program_buffer[i] = i;
}
status =
flexspi_nor_flash_page_program(EXAMPLE_FLEXSPI, (EXAMPLE_SECTOR * SECTOR_SIZE), (void *)s_nor_program_buffer);
if (status != kStatus_Success)
{
PRINTF("Page program failure !\r\n");
return -1;
}
DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);
memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
sizeof(s_nor_read_buffer));
if (memcmp(s_nor_read_buffer, s_nor_program_buffer, sizeof(s_nor_program_buffer)) != 0)
{
PRINTF("Program data - read out data value incorrect !\r\n");
//return -1;
}
else
{
PRINTF("Program data - successfully. \r\n");
}
status = flexspi_nor_flash_read(EXAMPLE_FLEXSPI, (EXAMPLE_SECTOR * SECTOR_SIZE)-1, (uint32_t *)(void *)s_nor_read_buffer, FLASH_PAGE_SIZE);
if (status != kStatus_Success)
{
PRINTF("Page READ failure !\r\n");
return -1;
}
if (memcmp(s_nor_read_buffer, s_nor_program_buffer, sizeof(s_nor_program_buffer)) != 0)
{
PRINTF("Program READ 2 - read out data value incorrect !\r\n");
return -1;
}
else
{
PRINTF("Program data 2 - successfully. \r\n");
}
while (1)
{
}
}
I obtain the following output:
FLEXSPI example started!
Vendor ID: 0xef
STATUS REG = 0x 2
STATUS REG 2 = 0x 2
Quad Mode enabled succesfully!
Erasing Serial NOR over FlexSPI...
Erase data - successfully.
Program data - read out data value incorrect !
Program data 2 - successfully.
I had to add the "Program data 2" check, using a READ LUT (instead of the memcpy) and adding a "-1" to the address, because the first one, with memcpy, failed the check, because it was missing the first byte and instead had one more byte at the end. I logged this adding a PRINTF in the fsl_flexspi.c READ and WRITE blocking functions:
status_t FLEXSPI_WriteBlocking(FLEXSPI_Type *base, uint8_t *buffer, size_t size)
{
...
/* Write watermark level data into tx fifo . */
if (size >= 8U * txWatermark)
{
for (i = 0U; i < 2U * txWatermark; i++)
{
base->TFDR[i] = *(uint32_t *)(void *)buffer;
PRINTF("BUFFER TX[%d]: 0x%04x \r\n", i, *(uint32_t *)(void *)buffer);
buffer += 4U;
}
size = size - 8U * txWatermark;
}
else
{
/* Write word aligned data into tx fifo. */
for (i = 0U; i < (size / 4U); i++)
{
base->TFDR[i] = *(uint32_t *)(void *)buffer;
PRINTF("else BUFFER TX[%d]: 0x%02x \r\n", i, buffer[i]);
buffer += 4U;
}
...
}
status_t FLEXSPI_ReadBlocking(FLEXSPI_Type *base, uint8_t *buffer, size_t size)
{
...
/* Read watermark level data from rx fifo. */
if (size >= 8U * rxWatermark)
{
for (i = 0U; i < 2U * rxWatermark; i++)
{
*(uint32_t *)(void *)buffer = base->RFDR[i];
PRINTF("<-- BUFFER RX[%d]: 0x%04x \r\n", i, *(uint32_t *)(void *)buffer);
buffer += 4U;
}
size = size - 8U * rxWatermark;
}
...
}
here are the logs:
BUFFER TX[0]: 0x3020100 <--- 0x00 is the first byte in WRITE
BUFFER TX[1]: 0x7060504
BUFFER TX[0]: 0xb0a0908
BUFFER TX[1]: 0xf0e0d0c
BUFFER TX[0]: 0x13121110
BUFFER TX[1]: 0x17161514
BUFFER TX[0]: 0x1b1a1918
BUFFER TX[1]: 0x1f1e1d1c
BUFFER TX[0]: 0x23222120
BUFFER TX[1]: 0x27262524
BUFFER TX[0]: 0x2b2a2928
BUFFER TX[1]: 0x2f2e2d2c
BUFFER TX[0]: 0x33323130
BUFFER TX[1]: 0x37363534
BUFFER TX[0]: 0x3b3a3938
BUFFER TX[1]: 0x3f3e3d3c
BUFFER TX[0]: 0x43424140
BUFFER TX[1]: 0x47464544
BUFFER TX[0]: 0x4b4a4948
BUFFER TX[1]: 0x4f4e4d4c
BUFFER TX[0]: 0x53525150
BUFFER TX[1]: 0x57565554
BUFFER TX[0]: 0x5b5a5958
BUFFER TX[1]: 0x5f5e5d5c
BUFFER TX[0]: 0x63626160
BUFFER TX[1]: 0x67666564
BUFFER TX[0]: 0x6b6a6968
BUFFER TX[1]: 0x6f6e6d6c
BUFFER TX[0]: 0x73727170
BUFFER TX[1]: 0x77767574
BUFFER TX[0]: 0x7b7a7978
BUFFER TX[1]: 0x7f7e7d7c
BUFFER TX[0]: 0x83828180
BUFFER TX[1]: 0x87868584
BUFFER TX[0]: 0x8b8a8988
BUFFER TX[1]: 0x8f8e8d8c
BUFFER TX[0]: 0x93929190
BUFFER TX[1]: 0x97969594
BUFFER TX[0]: 0x9b9a9998
BUFFER TX[1]: 0x9f9e9d9c
BUFFER TX[0]: 0xa3a2a1a0
BUFFER TX[1]: 0xa7a6a5a4
BUFFER TX[0]: 0xabaaa9a8
BUFFER TX[1]: 0xafaeadac
BUFFER TX[0]: 0xb3b2b1b0
BUFFER TX[1]: 0xb7b6b5b4
BUFFER TX[0]: 0xbbbab9b8
BUFFER TX[1]: 0xbfbebdbc
BUFFER TX[0]: 0xc3c2c1c0
BUFFER TX[1]: 0xc7c6c5c4
BUFFER TX[0]: 0xcbcac9c8
BUFFER TX[1]: 0xcfcecdcc
BUFFER TX[0]: 0xd3d2d1d0
BUFFER TX[1]: 0xd7d6d5d4
BUFFER TX[0]: 0xdbdad9d8
BUFFER TX[1]: 0xdfdedddc
BUFFER TX[0]: 0xe3e2e1e0
BUFFER TX[1]: 0xe7e6e5e4
BUFFER TX[0]: 0xebeae9e8
BUFFER TX[1]: 0xefeeedec
BUFFER TX[0]: 0xf3f2f1f0
BUFFER TX[1]: 0xf7f6f5f4
BUFFER TX[0]: 0xfbfaf9f8
BUFFER TX[1]: 0xfffefdfc
<-- BUFFER RX[0]: 0x4030201 <--- 0x01 is the first byte in READ
<-- BUFFER RX[1]: 0x8070605
<-- BUFFER RX[0]: 0xc0b0a09
<-- BUFFER RX[1]: 0x100f0e0d
<-- BUFFER RX[0]: 0x14131211
<-- BUFFER RX[1]: 0x18171615
<-- BUFFER RX[0]: 0x1c1b1a19
<-- BUFFER RX[1]: 0x201f1e1d
<-- BUFFER RX[0]: 0x24232221
<-- BUFFER RX[1]: 0x28272625
<-- BUFFER RX[0]: 0x2c2b2a29
<-- BUFFER RX[1]: 0x302f2e2d
<-- BUFFER RX[0]: 0x34333231
<-- BUFFER RX[1]: 0x38373635
<-- BUFFER RX[0]: 0x3c3b3a39
<-- BUFFER RX[1]: 0x403f3e3d
<-- BUFFER RX[0]: 0x44434241
<-- BUFFER RX[1]: 0x48474645
<-- BUFFER RX[0]: 0x4c4b4a49
<-- BUFFER RX[1]: 0x504f4e4d
<-- BUFFER RX[0]: 0x54535251
<-- BUFFER RX[1]: 0x58575655
<-- BUFFER RX[0]: 0x5c5b5a59
<-- BUFFER RX[1]: 0x605f5e5d
<-- BUFFER RX[0]: 0x64636261
<-- BUFFER RX[1]: 0x68676665
<-- BUFFER RX[0]: 0x6c6b6a69
<-- BUFFER RX[1]: 0x706f6e6d
<-- BUFFER RX[0]: 0x74737271
<-- BUFFER RX[1]: 0x78777675
<-- BUFFER RX[0]: 0x7c7b7a79
<-- BUFFER RX[1]: 0x807f7e7d
<-- BUFFER RX[0]: 0x84838281
<-- BUFFER RX[1]: 0x88878685
<-- BUFFER RX[0]: 0x8c8b8a89
<-- BUFFER RX[1]: 0x908f8e8d
<-- BUFFER RX[0]: 0x94939291
<-- BUFFER RX[1]: 0x98979695
<-- BUFFER RX[0]: 0x9c9b9a99
<-- BUFFER RX[1]: 0xa09f9e9d
<-- BUFFER RX[0]: 0xa4a3a2a1
<-- BUFFER RX[1]: 0xa8a7a6a5
<-- BUFFER RX[0]: 0xacabaaa9
<-- BUFFER RX[1]: 0xb0afaead
<-- BUFFER RX[0]: 0xb4b3b2b1
<-- BUFFER RX[1]: 0xb8b7b6b5
<-- BUFFER RX[0]: 0xbcbbbab9
<-- BUFFER RX[1]: 0xc0bfbebd
<-- BUFFER RX[0]: 0xc4c3c2c1
<-- BUFFER RX[1]: 0xc8c7c6c5
<-- BUFFER RX[0]: 0xcccbcac9
<-- BUFFER RX[1]: 0xd0cfcecd
<-- BUFFER RX[0]: 0xd4d3d2d1
<-- BUFFER RX[1]: 0xd8d7d6d5
<-- BUFFER RX[0]: 0xdcdbdad9
<-- BUFFER RX[1]: 0xe0dfdedd
<-- BUFFER RX[0]: 0xe4e3e2e1
<-- BUFFER RX[1]: 0xe8e7e6e5
<-- BUFFER RX[0]: 0xecebeae9
<-- BUFFER RX[1]: 0xf0efeeed
<-- BUFFER RX[0]: 0xf4f3f2f1
<-- BUFFER RX[1]: 0xf8f7f6f5
<-- BUFFER RX[0]: 0xfcfbfaf9
<-- BUFFER RX[1]: 0xfffffefd <--- 0xff is read twice (the block was erased)
Why is this happening? I also tried to change the numbers of dummy cycles without any effect.
Why I need to add a -1 in the address of the read instruction for having the correct data back?
In the while i also tried to redo a new version of the evkmimxrt1020_flexspi_nor_config.c, for my project, with the new information, hoping there was enough (I tried also the commented values):
#define FLASH_DUMMY_CYCLES_QUAD 0x04 //0x08 //0x06
#define ADDRESS_24BIT 0x18
#define UNKNOWN_READ_PARAM 0x04
// #define FLASH_DUMMY_VALUE 0x02
const
flexspi_nor_config_t
qspiflash_config =
{
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackFromDqsPad,
.csHoldTime = 3u,
.csSetupTime = 3u,
.controllerMiscOption = 0, //(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable),
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_80MHz, //kFlexSpiSerialClk_100MHz //kFlexSpiSerialClk_30MHz
.sflashA1Size = 1u * 1024u * 1024u,
/* Enable flash configuration feature */
//.configCmdEnable = 1u,
//.configModeType[0] = kDeviceConfigCmdType_QuadEnable, // kDeviceConfigCmdType_Generic,
/* Set configuration command sequences */
/*.configCmdSeqs[0] =
{
.seqNum = 1,
.seqId = 12,
.reserved = 0,
},*/
/* Prepare setting value for Read Register in flash */
//.configCmdArgs[0] = 0x40, //((FLASH_DUMMY_VALUE << 3) | 0xE0),
.lookupTable =
{
// Read (Fast Read Quad I/O)
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, ADDRESS_24BIT),
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, FLASH_DUMMY_CYCLES_QUAD, READ_SDR, FLEXSPI_4PAD, UNKNOWN_READ_PARAM),
// READ Normal
//FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x03, RADDR_SDR, FLEXSPI_1PAD, 0x18),
//FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0),
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.ipcmdSerialClkFreq = 1u,
.blockSize = 64u * 1024u,
.isUniformBlockSize = false,
};
but ended up with this situation, still not working but with different behavior, because now i see some different address in the registers:
but from the oscilloscope, i can see that the flash SCLK line, starts at 30MHz and then goes up to 80MHz as expected, then after a short amount, it stops clocking.
The only things i still don't understand about the LUT is the last param in the READ LUT, 0x04, which i defined as "UNKNOWN_READ_PARAM" in my code abobe. What is the meaning of this parameter?
For completeness of information, I also report what I have modified to reorganize the flexRAM of the device (in case this was the cause of the problem):
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_flexspi_nor_boot.h"
/* Relocating Flex-RAM */
extern void ResetISR(void);
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.xip_device"
#endif
#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".boot_hdr.ivt"), used))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.ivt"
#endif
/*************************************
* IVT Data
*************************************/
const ivt image_vector_table = {
IVT_HEADER, /* IVT Header */
//IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
(uint32_t)ResetISR, /* Image Entry Function */
IVT_RSVD, /* Reserved = 0 */
(uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
(uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
(uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
(uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
IVT_RSVD /* Reserved = 0 */
};
#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".boot_hdr.boot_data"), used))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.boot_data"
#endif
/*************************************
* Boot Data
*************************************/
const BOOT_DATA_T g_boot_data = {
FLASH_BASE, /* boot start location */
FLASH_SIZE, /* size */
PLUGIN_FLAG, /* Plugin flag*/
0xFFFFFFFFU /* empty - extra data word */
};
#endif
...
//*****************************************************************************
// Reset entry point for your code.
// Sets up a simple runtime environment and initializes the C/C++
// library.
//*****************************************************************************
__attribute__ ((naked, section(".after_vectors.reset")))
void ResetISR(void) {
// Disable interrupts
__asm volatile ("cpsid i");
//__asm volatile ("MSR MSP, %0" : : "r" (&_vStackTop) : );
/* Reallocating the FlexRAM */
/* https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Reallocating-the-FlexRAM/ta-p/1117649
* DTC=192KB, ITC=0KB, OC=64KB
* {O,O,D,D,D,D,D,D}
* LSB --------> MSB
*
* {10,10,10,10,10,10,01,01}
* MSB ---------------> LSB
*/
__asm (".syntax unified\n"
"LDR R0, =0x2002fffc\n"//load initial value of stack pointer into R0 = ultima locazione usabile della stack mem
"MSR MSP,R0\n" //re-initialize stack pointer by new value
"LDR R0, =0x400ac044\n"//Address of register IOMUXC_GPR_GPR17
"LDR R1, =0xaaa5\n"//FlexRAM configuration DTC = 192KB, ITC = 0KB, OC = 64KB
"STR R1,[R0]\n"
"LDR R0,=0x400ac040\n"//Address of register IOMUXC_GPR_GPR16
"LDR R1,[R0]\n"
"ORR R1,R1,#4\n"//The 4 corresponds to setting the FLEXRAM_BANK_CFG_SEL bit in register IOMUXC_GPR_GPR16
"STR R1,[R0]\n"
".syntax divided\n");
#if defined (__USE_CMSIS)
...
...
/* MPU configuration. */
void BOARD_ConfigMPU(void)
{
/* Disable I cache and D cache */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
}
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
}
/* Disable MPU */
ARM_MPU_Disable();
/* MPU configure:
* Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable,
* SubRegionDisable, Size)
* API in mpu_armv7.h.
* param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches
* disabled.
* param AccessPermission Data access permissions, allows you to configure read/write access for User and
* Privileged mode.
* Use MACROS defined in mpu_armv7.h:
* ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO
* Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes.
* TypeExtField IsShareable IsCacheable IsBufferable Memory Attribute Shareability Cache
* 0 x 0 0 Strongly Ordered shareable
* 0 x 0 1 Device shareable
* 0 0 1 0 Normal not shareable Outer and inner write
* through no write allocate
* 0 0 1 1 Normal not shareable Outer and inner write
* back no write allocate
* 0 1 1 0 Normal shareable Outer and inner write
* through no write allocate
* 0 1 1 1 Normal shareable Outer and inner write
* back no write allocate
* 1 0 0 0 Normal not shareable outer and inner
* noncache
* 1 1 0 0 Normal shareable outer and inner
* noncache
* 1 0 1 1 Normal not shareable outer and inner write
* back write/read acllocate
* 1 1 1 1 Normal shareable outer and inner write
* back write/read acllocate
* 2 x 0 0 Device not shareable
* Above are normal use settings, if your want to see more details or want to config different inner/outter cache
* policy.
* please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide <dui0646b_cortex_m7_dgug.pdf>
* param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled.
* param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in
* mpu_armv7.h.
*/
/*
* Add default region to deny access to whole address space to workaround speculative prefetch.
* Refer to Arm errata 1013783-B for more details.
*
*/
/* Region 0 setting: Instruction access disabled, No data access permission. */
MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 0, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4GB);
/* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);
/* Region 2 setting: Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);
#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
/* Region 3 setting: Memory with Normal type, not shareable, outer/inner write back. */
MPU->RBAR = ARM_MPU_RBAR(3, 0x60000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_1MB);
#endif
/* Region 4 setting: Memory with Device type, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
/* **********************
* Relocating Flex-RAM
* https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Reallocating-the-FlexRAM/ta-p/1117649
* https://community.nxp.com/t5/i-MX-Processors/RT1021-reallocate-FlexRAM/m-p/1667222#M207407
* **********************
*/
/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
/* ITC Memory */
MPU->RBAR = ARM_MPU_RBAR(5, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, 0);
/* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
/* DTC Memory */
MPU->RBAR = ARM_MPU_RBAR(6, 0x20000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
/* OC Memory */
MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64KB);
/************************/
/* Region 8 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(8, 0x80000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
/* Region 10 setting: Memory with Device type, not shareable, non-cacheable */
MPU->RBAR = ARM_MPU_RBAR(10, 0x40000000);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4MB);
/* Enable MPU */
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
/* Enable I cache and D cache */
SCB_EnableDCache();
SCB_EnableICache();
}
...
I believe I am close to the solution, I hope this information will be useful to understand what is not working… thanks in advance to everyone!
Hello everyone, I have some additional information to share.
While searching online for similar cases, I came across several threads discussing this issue. However, there seems to be limited documentation from NXP on this topic. Many of these threads suggest using the MCUXpresso Secure Provisioning tool or the MCU Boot Utility (which I am already familiar with), but none of these methods have allowed me to run my code. Here are some of the links I found:
- Solved: XIP from QSPI NOR Flash on MIMXRT1062 - NXP Community
- RT1050 evkb Unable to download and debug QSPI Flash - NXP Community
- How to Enable Debugging for FLEXSPI NOR Flash (nxp.com)
Here are the steps I followed:
At this point, if I reboot with BOOT[1:0] = 0b00, nothing happens. The device is neither in ROM bootloader mode (as I can no longer see it via the MCU Boot Utility) nor is it running. I also cannot debug the code via MCUXpresso, as I consistently end up in the same situation.
Here is my Memory configuration, which works on the EVK:
Note: I need more DTC (192K) than ITC RAM (0 needed, but 4 is because otherwise MCUXpresso gives me an error), allowing the OC to be the minimum allowed (64K)
And here are my Preprocessor directives (-D):
I hope this information provides more detail than before.
Thank you in advance!
Hi @salva214
Thank you for effort adding this extra information!
What is the value of the boot mode and boot config in the SRC register? Please check this register via debug in the MCUXpresso IDE.
Diego
Hi @diego_charles,
I just realized that I responded incorrectly to your last post.
Can I ask you if you can help me with the information that I didn’t understand (In the previous post in bold)?
Thanks