Program aborts on DDR read while erasing QSPI flash block

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

Program aborts on DDR read while erasing QSPI flash block

656 Views
takashi_kojima
Contributor I

Hello, Community.

I created a program to erase blocks using the block erase command of QSPI flash.
After executing the block erase command, wait in the do-while loop until the WIP bit (Write In Progress Bit) of the flash status register becomes 0.
In that do-while loop, when I continued to read the status register, the WIP bit stayed at 1, and the program aborted.
CPU is i.MX 7Dual Applications Processor.
Flash memory type is ISSI IS25WP512M.
Flash read uses DDR.
The command used is Fast Read Quad IO DTR.
I didn't abort if I didn't use DDR (if I used SDR). When using DDR, I think it will abort because the read speed is fast.
/********************************* Erase Program Start ***************************************/
uint32_t FlashErase(uint32_t addr)
{
/*Erase Sector*/
SectorErase(addr);

do
{
/*Read QSPI Flash Status*/
ReadStatus(addr);
}while(QuadSPI_RBDR_REG(QuadSPI_BASE,0) & 1); /* Check write in progress */

return (RESULT_OK);
}

static uint32_t SectorErase(uint32_t addr)
{
/*Clear status flags*/
QuadSPI_FR_REG(QuadSPI_BASE) = 0xFFFFFFFF;
/*Serial Flash Address*/
QuadSPI_SFAR_REG(QuadSPI_BASE) = addr;

/*Start Write enable sequence*/
QuadSPI_IPCR_REG(QuadSPI_BASE) = WRITE_E_SEQUENCE<<24;  /*Command:0x06*/
/*Wait for the end of the sequence*/
while(QuadSPI_SR_REG(QuadSPI_BASE) & QuadSPI_SR_BUSY_MASK);

/*Start Sector Erase sequence*/
QuadSPI_IPCR_REG(QuadSPI_BASE) = SECT_ERASE_SEQUENCE<<24;  /*Command:0xDC*/

/*Wait for the end of the sequence*/
while(QuadSPI_SR_REG(QuadSPI_BASE) & (QuadSPI_SR_BUSY_MASK));

/*return flags*/
return QuadSPI_FR_REG(QuadSPI_BASE);
}

static uint32_t ReadStatus(uint32_t addr)
{
/*Clear status flags*/
QuadSPI_FR_REG(QuadSPI_BASE) = 0xFFFFFFFF;
/*Serial Flash Address*/
QuadSPI_SFAR_REG(QuadSPI_BASE) = addr;
/*Clear RX Buffer*/
QuadSPI_MCR_REG(QuadSPI_BASE) |= 1<<QuadSPI_MCR_CLR_RXF_SHIFT;

/*Read Status Register sequence*/
QuadSPI_IPCR_REG(QuadSPI_BASE) = RD_STATUS_REG_SEQUENCE<<24;  /*Command:0x05*/

/*Wait for the end of the sequence*/
while(QuadSPI_SR_REG(QuadSPI_BASE) & QuadSPI_SR_BUSY_MASK);

/*return flags*/
return QuadSPI_FR_REG(QuadSPI_BASE);
}
/********************************* Erase Program End ***************************************/

/********************************* DDR set Program Start ************************************/
/* Disable the module */
reg = QuadSPI_MCR_REG(QuadSPI_BASE_PTR);
reg |= QuadSPI_MCR_MDIS_MASK;
QuadSPI_MCR_REG(QuadSPI_BASE_PTR) = reg;

/* Set the Sampling Register for DDR */
reg = QuadSPI_SMPR_REG(QuadSPI_BASE_PTR);
reg &= ~QuadSPI_SMPR_DDRSMP_MASK;
reg |= (2 << QuadSPI_SMPR_DDRSMP_SHIFT);
QuadSPI_SMPR_REG(QuadSPI_BASE_PTR) = reg;

/* Enable the module again (enable the DDR too) */
reg = QuadSPI_MCR_REG(QuadSPI_BASE_PTR);
reg |= QuadSPI_MCR_DDR_EN_MASK;
QuadSPI_MCR_REG(QuadSPI_BASE_PTR) = reg;

while( (QuadSPI_SR_REG(QuadSPI_BASE_PTR) & QuadSPI_SR_BUSY_MASK) == QuadSPI_SR_BUSY_MASK );

/* Enable the TDH to 1 for some platforms like imx6ul, imx7d, etc
* These two bits are reserved on other platforms
*/
reg = QuadSPI_FLSHCR_REG(QuadSPI_BASE_PTR);
reg &= ~QuadSPI_FLSHCR_TDH_MASK;
reg |= (1 << QuadSPI_FLSHCR_TDH_SHIFT);
QuadSPI_FLSHCR_REG(QuadSPI_BASE_PTR) = reg;
/********************************* DDR set Program  End ************************************/

/********************************* DDR Read Command Start *******************************/
lut_table[0] = QSPI_LUT_INST(LUT_CODE_CMD, LUT_PADS_ONE, 0xEE);
lut_table[1] = QSPI_LUT_INST(LUT_CODE_ADDR_DDR, LUT_PADS_FOUR, ADDR_4B);
lut_table[2] = QSPI_LUT_INST(LUT_CODE_DUMMY, LUT_PADS_FOUR, 0x06);
lut_table[3] = QSPI_LUT_INST(LUT_CODE_READ_DDR, LUT_PADS_FOUR, 0x08);
lut_table[4] = QSPI_LUT_INST(LUT_CODE_STOP, 0, 0);
/********************************* DDR Read Command End *********************************/

Question 1
I found an article stating that DDR reads are stable when using DQS. However, I couldn't find a way to configure DQS.
Can you tell me how to configure DQS with QSPI configuration parameters or registers?

Question 2
Could you tell me if there is a way to stabilize DDR reading other than DQS?

Best Regards,

Takashi Kojima

0 Kudos
2 Replies

547 Views
jimmychan
NXP TechSupport
NXP TechSupport

Please read the i.MX7DRM Table 6-50.

i.MX 7Dual Applications Processor Reference Manual

0 Kudos

547 Views
takashi_kojima
Contributor I

Hi, jimmychan,
Thank you for your reply!

I have read i.MX7DRM Table 6-50.
I made the following settings, but the program did not work properly (it aborted).

DQS Loopback = 1
Dual Data Rate mode enable = 1
Data Strobe Signal enable in Serial Flash = 1
DDR Sampling Point = 2
enable_dqs_phase = 1

The following items are left at their default values because the setting method is unknown.

dqs_pad_setting_override = 0
dqs_loopback_internal = 0
dqs_phase_sel = 0
dqs_fa_delay_chain_sel = 0
dqs_fb_delay_chain_sel = 0

Is there anything wrong with the above settings?
Can you tell me the correct settings to enable DQS?

Best regards,
Takashi Kojima

0 Kudos