AnsweredAssumed Answered

QuadSPI AHB not reading correctly after erasing a sector

Question asked by martir on Apr 27, 2018
Latest reply on May 11, 2018 by xiangjun.rong

Hi there,

I'm using a MKL82Z on a custom board with Cypress S25FL256S (http://www.cypress.com/file/177966/download ) external memory. I'm using SDK SDK_2.2_MKL82Z128xxx7, with a little modification of the LUT for the memory mentioned.

 

The thing is I'm observing a weird behavior when I watch the external memory with the memory browser (or also when I consult its content via an USB driver that I developed).

 

I have a similar program as below (let's say number in paranthesis are the line numbers):

int main(){
(1)Initializations(); //<-- clock, module initializations, etc

 

(2)Save_4Bytes_to_external_memory();   //I save 4 bytes to position 0x6810 0000
(3)Erase_sector( 0x6810 0000 );            //Erase the sector where the address is contained

 

(4)Create_Tasks();
(5)StartScheduler();
while(1);
}

 

With the memory browser window open, I'm using breakpoints at line (2). So, when the breakpoint is at (2) and I execute Step Over, I see in the memory browser how the 4 bytes are saved. Then I pulse again a Step Over on the line (3) and sometimes you can see the flash all going to FF's (how it's expected) but most of times it just does nothing. When it's just does nothing then I run the program, I pause it and the memory is still with the 4 bytes.

Also, instead of running if I reset the program and execute again without execute Save_4Bytes(), memory is full of FF's, as if previous erase_sector was done ok but it hadn't shown in the memory browser. (that's why my suspicion about AHB).

 

Also I've observed that if I don't use any breakpoint and then I pause the program, the memory is full FF's as if the erase_sector is executing correctly.

 

Also tried not to use the debugger, and consult the memory content via an USB API. With this API, I erase the sector and then read the memory and most of the times it reads the 4 bytes (the erase_sector didn't do anything).

 

So what's going on? Is AHB not working? Am I missing something to configure in the external memory?

 

Any advice will be much apreciated. Thanks.

PD: I don't know if I've explained myself enough, it's a bit twisted to explain and my english isn't perfect so let me know and I'll try to explain better ... >_<'

 

 

I put my LUT table here, maybe there's something wrong:

 

/* Seq0 :Quad Read */
/* CMD: 0xEB - Quad Read, Single pad */
/* ADDR: 0x18 - 24bit address, Quad pads */
/* DUMMY: 0x06 - 6 clock cyles, Quad pads */
/* READ: 0x80 - Read 128 bytes, Quad pads */
/* JUMP_ON_CS: 0 */
[0] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0xEB, QSPI_ADDR, QSPI_PAD_4, 0x18),
[1] = QSPI_LUT_SEQ(QSPI_DUMMY, QSPI_PAD_4, 0x06, QSPI_READ, QSPI_PAD_4, 0x80), 
[2] = QSPI_LUT_SEQ(QSPI_JMP_ON_CS, QSPI_PAD_1, 0x0, 0, 0, 0),

/* this this one but same behavior  */
//[0] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0xEB, QSPI_ADDR, QSPI_PAD_4, 0x18),
//[1] = QSPI_LUT_SEQ(QSPI_MODE4, QSPI_PAD_4, 0x00, QSPI_DUMMY, QSPI_PAD_4, 0x05),
//[2] = QSPI_LUT_SEQ(QSPI_READ, QSPI_PAD_4, 0x80, QSPI_JMP_ON_CS, QSPI_PAD_1, 0x00),

/* Seq1: Write Enable */
/* CMD: 0x06 - Write Enable, Single pad */
[4] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x06, 0, 0, 0),

/* Seq2: Erase All */
/* CMD: 0x60 - Erase All chip, Single pad */
[8] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x60, 0, 0, 0),

/* Seq3: Read Status */
/* CMD: 0x05 - Read Status, single pad */
/* READ: 0x01 - Read 1 byte */
[12] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x05, QSPI_READ, QSPI_PAD_1, 0x1),

/* Seq4: Page Program */
/* CMD: 0x02 - Page Program, Single pad */
/* ADDR: 0x18 - 24bit address, Single pad */
/* WRITE: 0x80 - Write 128 bytes at one pass, Single pad */
[16] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x02, QSPI_ADDR, QSPI_PAD_1, 0x18),
[17] = QSPI_LUT_SEQ(QSPI_WRITE, QSPI_PAD_1, 0x01, 0, 0, 0),
// [17] Modified according to https://community.nxp.com/message/962630?commentID=962630&et=watches.email.thread#comment-962630
// Original: [17] = QSPI_LUT_SEQ(QSPI_WRITE, QSPI_PAD_1, 0x80, 0, 0, 0),

/* Seq5: Write Register */
/* CMD: 0x01 - Write Status Register, single pad */
/* WRITE: 0x01 - Write 1 byte of data, single pad */
#ifdef MACRONIX_MX25L
[20] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x01, QSPI_WRITE, QSPI_PAD_1, 0x1), // FRDM-KL82Z
#endif
#ifdef CYPRESS_S25FL
[20] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x01, QSPI_WRITE, QSPI_PAD_1, 0x2), // CYPRESS
#endif

/* Seq6: Read Config Register */
/* CMD: 0x15 - Read Config register, single pad */
/* READ: 0x01 - Read 1 byte */
#ifdef MACRONIX_MX25L
[24] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x15, QSPI_READ, QSPI_PAD_1, 0x1), // FRDM-KL82Z
#endif
#ifdef CYPRESS_S25FL
[24] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x35, QSPI_READ, QSPI_PAD_1, 0x1), // CPYRESS
#endif

/* Seq7: Erase Sector */
/* CMD: 0x20 - Sector Erase, single pad */
/* ADDR: 0x18 - 24 bit address, single pad */
// For 64 kB sectors erase on CYPRESS flash please see [40] below
//#ifdef MACRONIX_MX25L
[28] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x20, QSPI_ADDR, QSPI_PAD_1, 0x18), // FRDM-KL82Z
/*#endif
#ifdef CYPRESS_S25FL
// Hybrid sectors of 4kb and 64kb, command 0x20 is for 4kb and command 0xd8 is for 64kb
// [28] erases 4 kB sectors, [40] erases 64 kB sectors
[28] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x20, QSPI_ADDR, QSPI_PAD_1, 0x18), // CYPRESS
#endif
*/

/* READ ID*/
[32] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x90, QSPI_ADDR, QSPI_PAD_1, 0x18), [33] = QSPI_LUT_SEQ(QSPI_READ, QSPI_PAD_1, 0x02, 0, 0, 0),

/* READ DATA*/
[36] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x03, QSPI_ADDR, QSPI_PAD_1, 0x18), [37] = QSPI_LUT_SEQ(QSPI_READ, QSPI_PAD_1, 16, 0, 0, 0),

#ifdef CYPRESS_S25FL
/* Seq7: Erase Sector */
/* CMD: 0x20 - Sector Erase, single pad */
/* ADDR: 0x18 - 24 bit address, single pad */
// Hybrid sectors of 4kb and 64kb, command 0x20 is for 4kb and command 0xd8 is for 64kb
// [28] erases 4 kB sectors, [40] erases 64 kB sectors
[40] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0xD8, QSPI_ADDR, QSPI_PAD_1, 0x18), // CYPRESS
#endif
/* Match MISRA rule */
[63] = 0 };

Outcomes