Program aborts on DDR read while erasing QSPI flash block

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Program aborts on DDR read while erasing QSPI flash block

948 次查看
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 项奖励
回复
2 回复数

839 次查看
jimmychan
NXP TechSupport
NXP TechSupport

Please read the i.MX7DRM Table 6-50.

i.MX 7Dual Applications Processor Reference Manual

0 项奖励
回复

839 次查看
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 项奖励
回复