Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20931 Discussions

Is Generic Serial Flash IP meant to work S25FL127S Flash in QUAD I/O mode?

BrendenB
Beginner
73 Views

I was trying to use Generic Serial Flash IP from Quartus Standard 23.1.1 to access S25FL127S using QUAD I/O command (i.e. address and data sent over SPIx4). It works some of the time but not always. This is my configuration (I'm using Standard so I had to write my own driver):

 

// Set 25MHz clock. The Flash allows up to 80MHz.
FLASH_IORW_32(FLASH_REG_BAUD, 0x1);

// Use the QUAD IO Read command with 6 dummy cycles. This is actually
// 2 cycles for the mode and 4 dummy cycles.
FLASH_IORW_32(FLASH_REG_READ, (6 <<  | 0xeb);

// Send the data and address over SPIx4.
FLASH_IORW_32(FLASH_REG_PROTOCOL, (0x2 << 16) | (0x2 << 12));

 

 

 The actual command requires (as configured above)

  1. 0xEB to be send over SPIx1
  2. Then the address to be sent over SPIx4.
  3. Then a mode byte is sent in 2 cycles over SPIx4.
  4. Then 4 dummy cycles are issued where data sent/received is ignored.
  5. Then the data to be read over SPIx4.

If the first nibble of the mode byte is 0xA then the flash assumes that the next command is a QUAD I/O read and does not expect the command to be sent on the next operation.

To get the Generic Serial Flash IP to work I essentially just configured 6 dummy cycles. The problem is that the value output during the dummy cycles seems to depend on the address of the last operation. The value output during the dummy cycles seems to be the second nibble of the last address:

 

// This read may or may not work depending on what happened before.
alt_u32 val1 = __builtin_ldwio((void*)0xf000b0);

//For this read 0xb will be output during the dummy cycles. This read
// works.
alt_u32 val2 = __builtin_ldwio((void*)0xf000a0);

//For this read 0xa will be output during the dummy cycles. This will
//interpreted by the S25FL127S as meaning the *next* read will just have
//address & dummy cycles, that is, no command needs to be sent. This read
//works.
alt_u32 val3 = __builtin_ldwio((void*)0xf000b0);

//This read fails because this sends a command but
//the flash is only expecting an address and dummy cycles because 
//of the previous read.
alt_u32 val4 = __builtin_ldwio((void*)0xf000c0);

 

You can see this below which shows the reading of val3. The first mark shows the first address nibble (in dout). The second mark shows how 0xA is output in the first dummy cycle (i.e. mode) (in dout). The third mark is the data being returned (in din).

timing.png

Is it actually possible to use the Generic Serial Flash IP when a mode is included in the operation? To make the IP work I had to configure 6 dummy cycles (+2 for the mode and +4 for the dummy cycles). Is there a way to fix the value output during dummy cycles?

Labels (1)
0 Kudos
0 Replies
Reply