Hello friends.
I have a small problem with my QSPI on STM32F7. I connect memory on this
pins.
PB10 - CS flash
PF8 - IO0 (SI)
PF9 - IO1 (SO)
PF10 - SCK
And I call in main:
1
intmain(void)
2
{
3
/* init NVICcm */
4
LL_Init();
5
/* init system clock */
6
SystemClock_Config();
7
8
qspi_init();
9
QSPI_Cmd(ENABLE);
10
QSPI_WriteEnable();
11
while(1){
12
blink_led();
13
LL_mDelay(200);}
And qspi_init() is OK, but the function QSPI_WriteEnable isn't work. It
is wait on this line:
If you really want to have support, then you should give more info.
Which flash you're using. Do you use the right commands according to the
datasheet? From your pin configuration I can see that you're using the
flash in a dual Modus, means two lines. You have to take in account that
all the examples are designed for quad. Therefore copy paste wouldn't
help you here.
Petr K. schrieb:> void QSPI_WriteEnable(void)> QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode => QSPI_ComConfig_FMode_Auto_Polling;> QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADMode => QSPI_ComConfig_ADMode_NoAddress;> QSPI_ComConfig_InitStructure.QSPI_ComConfig_DMode => QSPI_ComConfig_DMode_1Line;> QSPI_ComConfig_InitStructure.QSPI_ComConfig_Ins => READ_STATUS_REG_CMD ;> QSPI_ComConfig_Init(&QSPI_ComConfig_InitStructure);>> while(QSPI_GetFlagStatus(QSPI_FLAG_SM) == RESET)> {}> QSPI_ClearFlag(QSPI_FLAG_SM);> QSPI_ClearFlag(QSPI_FLAG_TC);> while(QSPI_GetFlagStatus(QSPI_FLAG_BUSY) != RESET)> {}> asm("NOP");
Although I've never used the autopolling feature: Why did you ever think
of using this mode for write enable??? The "Write Enable" command just
sets the "Write Enable" bit in the status register of the flash chip. So
this works instantly, i. e. as soon as the command has been sent to
the flash the very next "Status Read" command MUST return the status
register with WE bit set or something is quite wrong. It doesn't make
any sense to poll the status register several times for the WE bit to
become set.
Automatic polling only makes sense for commands which require some time
to finish like page programming, sector erase, mass erase.
Petr K. schrieb:> I use: single-SPI mode
- Are you also using a "normal" (non-QSPI) SPI flash memory?
- Which one?
- How do you handle HOLD and WR inputs?
Type of memory is: IS25LP128
Datasheet: [[http://www.issi.com/WW/pdf/25LP128.pdf]]
Connect to my MCU is:
PB10 - CS flash
PF8 - IO0 (SI)
PF9 - IO1 (SO)
PF10 - SCK
A. B. schrieb:> Although I've never used the autopolling feature: Why did you ever think> of using this mode for write enable??? The "Write Enable" command just> sets the "Write Enable" bit in the status register of the flash chip. So> this works instantly, i. e. as soon as the command has been sent to> the flash the very next "Status Read" command MUST return the status> register with WE bit set or something is quite wrong. It doesn't make> any sense to poll the status register several times for the WE bit to> become set.
I've here other experiences. It makes sense to poll the Status everytime
even it's for the WE command.
In most of the cases you have different Status Registers for some
commands (e.g. WE) and for the Memory Access itself.
Petr K. schrieb:> while(QSPI_GetFlagStatus(QSPI_FLAG_SM) == RESET){};
What is inside of QSPI_FLAG_SM?
The Datasheet is saying:
WEL bit: The Write Enable Latch (WEL) bit indicates the status of the
internal write enable latch. When the
WEL is “0”, the write enable latch is disabled and all write operations,
including write status register, write
configuration register, page program, sector erase, block and chip erase
operations are inhibited. When the
WEL bit is “1”, write operations are allowed. The WEL bit is set by a
Write Enable (WREN) instruction. Each
write register, program and erase instruction must be preceded by a WREN
instruction. The WEL bit can be
reset by a Write Disable (WRDI) instruction. It will automatically be
reset after the completion of any write
operation.
Below how I would solve it with HAL
Bülent C. schrieb:> I've here other experiences. It makes sense to poll the Status everytime> even it's for the WE command.
Maybe you should have read (and try to understand) my comment:
Yes, of course, it does make sense to check the status register ONCE.
But to attempt to check it several times is plain rubbish.
Either it is already set on the first read after the Write Enable
command,
or the command failed (for whatever reason). And if it failed, it
doesn't make sense to check it again. It won't come on magically later.
If the Write Enable command failed, the only reasonable recovery is to
reset the interface (and maybe the flash chip) and start over.
But anyway, the code posted is rather complete nonsense. Why would one
enable an interrupt and then poll for this very same event???
(BTW: The same question was posted under different name on ST's
community)
> In most of the cases you have different Status Registers for some> commands (e.g. WE) and for the Memory Access itself.
What's that supposed to mean?
A. B. schrieb:> Yes, of course, it does make sense to check the status register ONCE.> But to attempt to check it several times is plain rubbish.> Either it is already set on the first read after the Write Enable> command,> or the command failed (for whatever reason). And if it failed, it> doesn't make sense to check it again. It won't come on magically later.
OK, for at least one Point we're on the same page. It really doesn't
make sense to check the WEL Bit within the infinity Loop like the TO is
doing that.
The HAL Driver is given the posibility to incorporate a timeout check
for the polling of the WEL Bit. This is how I implemented it in my
application.
1
/* Configure automatic polling mode to wait for write enabling */
The Timeout is set to 100ms. This is in my point of view enough. If the
WLE Bit isn't set within 100ms, then I've other issues what I'm trying
to handle it somewhere else.
A. B. schrieb:> If the Write Enable command failed, the only reasonable recovery is to> reset the interface (and maybe the flash chip) and start over.
see above
A. B. schrieb:> But anyway, the code posted is rather complete nonsense. Why would one> enable an interrupt and then poll for this very same event???
I think you mean the TO's Code?! Yes, agree. The Code from him is really
nonsense
A. B. schrieb:>> In most of the cases you have different Status Registers for some>> commands (e.g. WE) and for the Memory Access itself.>> What's that supposed to mean?
You would check the WLE Bit just one time, right? But it's not as simple
as that! How do you know when exactly you Need to check the WLE Bit?
Assume you're using your Code for different STM32's with different clock
Settings or something like that?
That's the reason why I do it like posted above (multiple checks with
timeout) makes more sense than to check the WLE just once.
The same is for the write/Program sequence. You could write 1 Byte or a
complete Page at once. After the program command is performed you Need
to wait until the Bytes are completly written. From where do you know
how long you have to wait?
QSPI_InitStructure.QSPI_SShift=QSPI_SShift_HalfCycleShift;//By default, the QUADSPI samples data 1/2 of a CLK cycle after the data is driven by the Flash memory
QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode=QSPI_ComConfig_FMode_Indirect_Write;//QUADSPI is in indirect write mode, where bytes are sent to the Flash memory during the data phase
Hello,
I analyze my problem. And my init qspi is good, because:
1. Init GPIO is OK. Communication is workign.
2. Init qspi (default setting) is good, because I can send everything.
And now, I'm looking on my program:
1. Send command 0x06 is OK.
2. Send command 0x05 is OK.
3. Receive datas is wrong. Because they have 9 bits.
And I don't know, why the receive datas have 9bits.
What do you think, what is wrong?
1
/* Send 0x05 and receive 1 byte */
2
while(QSPI_GetFlagStatus(QSPI_FLAG_BUSY)!=RESET)
3
{}
4
QSPI_AutoPollingMode_SetInterval(0x10);//Number of CLK cycles between to read during automatic polling phases.
5
QSPI_AutoPollingMode_Config(0x02,0x02,QSPI_PMM_AND);//set compare mode for autopolling