Hi,
I have a project using the i.MX RT1061 with a W25Q128JVSIQ external flash. I'm looking to also support the W25Q128JVSIM (due to availability). However, the W25Q128JVSIM doesn't come with the QE-bit (Quad Enable) locked to enabled. When trying to boot from it I see what I assume is the boot ROM trying to execute a Fast Read Quad I/O without first enabling the QE-bit (see screenshots for the two first commands sent).
It seems to first read the FlexSPI Configuration Block (which is expected), but then the quad read fails and nothing happens (bootloader isn't started).
I suspect I have to ensure the QE-bit is enabled during production for this to work, but I was curious whether the i.MX RT1061 supports booting from non-QuadSPI NOR flash at all? It kind of seems that only Quad and Octal flash are supported (see screenshot for BOOT_CFG1 fuse)?
Thanks,
Daniel
Hi @Habib_MS,
Thanks for your reply!
Hmm...my understanding was that the quad_mode_setting would only be applied when calling flexspi_nor_get_config, am I misunderstanding something?
Is there a way to configure the BootROM to access the flash as QuadSPI through the FlexSPI Configuration Block?
Thanks,
Daniel
Hello @MulattoKid,
Booting from non (serial)‑QuadSPI NOR flash is supported. for more details about which flash devices are supported, please refer to Chapter 9.6 “Boot devices” in the RM. I also understand that you highlighted the BOOT_CFG1[3:2] bits in your image. These fields are used by the auto‑probe mechanism, as described in their definition. Therefore, these bits only provide additional information about the flash device rather than controlling its configuration.
Concerning the QE bit configuration of the QSPI NOR flash: normally, selecting the correct boot option configuration is sufficient.
BR
Habib
I've found why the BootROM sends quad read commands right after reading the FCB: it's because our bootloader had a custom LUT specified in the FCB. Changing the LUT entry for reading also changed the SPI traffic.
As mentioned, the reason I'm looking at this is that I want to be able to support both W25Q128JVSIQ and W25Q128JVSIM, with W25Q128JVSIM not having the QE bit set by default from the factory. I want to set the QE bit during our own production. The way I've been investigating is through using a JLink script to control the FLexSPI peripheral directly. However, I'm having some trouble.
I have a command sequence for reading out the Status Register-2 of the W25Q128JVSIM, but it only works if the MCU has first booted into our application (which it fails to do unless the QE bit is already set). If the flash is empty and the BootROM doesn't have anything to boot the JLink script doesn't work, so I'm wondering if there's anything additional setup that's required to configure the FlexSPI peripheral?
Here's the script for reference:
ExitOnError 1
Device MIMXRT1061xxx5B
SelectInterface SWD
Speed 4000
Connect
halt
// Enable clock
w4 0x400FC078, 0xFFFFFFFF
// Reset module
w4 0x402A8000, 0x00000002
sleep 20
w4 0x402A8000, 0x00000000
sleep 20
// Clear errors
w4 0x402A8014, 0xFFFFFFFF
w4 0x402A80B4, 0xFFFFFFFF
sleep 20
// 2) Update LUT to include Read Status Register 2 and Write Status Register 2 commands
w4 0x402A8018, 0x5AF05AF0 // Write magic value (i.MX RT1060 reference manual rev3, p.1612)
sleep 20
w4 0x402A801C, 0x2 // Unlock LUT (i.MX RT1060 reference manual rev3, p.1612)
sleep 20
// LUT entry structure (i.MX RT1060 reference manual rev3, p.1709):
// [31:26] = opcode1
// [25:24] = num_pads1
// [23:16] = operand1
// [15:10] = opcode0
// [ 9: 8] = num_pads0
// [ 7: 0] = operand0
// #include
//
// #define OPERAND_0(x) (x << 0)
// #define NUMPADS_0(x) (x << 8)
// #define OPCODE_0(x) (x << 10)
// #define OPERAND_1(x) (x << 16)
// #define NUMPADS_1(x) (x << 24)
// #define OPCODE_1(x) (x << 26)
//
// #define kFLEXSPI_Command_STOP 0x0
// #define kFLEXSPI_Command_SDR 0x1
// #define kFLEXSPI_Command_RADDR_SDR 0x2
// #define kFLEXSPI_Command_WRITE_SDR 0x8
// #define kFLEXSPI_Command_READ_SDR 0x9
// #define kFLEXSPI_1PAD 0x0
//
// #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) (OPERAND_0(op0) | NUMPADS_0(pad0) | OPCODE_0(cmd0) | OPERAND_1(op1) | NUMPADS_1(pad1) | OPCODE_1(cmd1))
//
// int main()
// {
// printf("WriteEnable: 0x%08X\n", FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0));
// printf("ReadStatusRegister2: 0x%08X\n", FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04));
// printf("WriteStatusRegister2: 0x%08X\n", FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x31, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04));
//
// return 0;
// }
// Each command sequence in the LUT is 4 entires with each entry being 4 bytes (one word)
w4 0x402A82E0, 0x24040435 // LUT[14 * 4] = Read Status Register-2 command sequence
sleep 20
w4 0x402A8018, 0x5AF05AF0 // Write magic value (i.MX RT1060 reference manual rev3, p.1612)
sleep 20
w4 0x402A801C, 0x1 // Lock LUT (i.MX RT1060 reference manual rev3, p.1612)
sleep 20
// Read Status Register-2
w4 0x402A8080, 0x80000000 // Clear sequence pointer for port A
w4 0x402A8014, 0x1F // Clear pending status
w4 0x402A80A0, 0x0 // Set base address
w4 0x402A80B8, 0x1 // Reset RX FIFO
w4 0x402A80A4, 0xE0001 // SEQID=14, SEQNUM=1, 1 byte
w4 0x402A80B0, 0x00000001 // Trigger IP command
sleep 50 Hello @dafela,
You can use the FlexSPI NOR APIs to enable the QE bit, using the configuration mentioned in my previous message. For additional details on the different methods available to enable the QE bit, please refer to item 19 in this post.
You can also find more information about the FlexSPI ROM API in Section 9.13.2 of the RM.
On the other hand, if you need guidance on using J-Link, this post provides a general overview along with several useful considerations that may help you.
BR
Habib