cancel
Showing results for 
Search instead for 
Did you mean: 

QSPI Command sends extra byte in Instruction Only mode - STM32L452

underpickled
Associate II

I'm having a doozy of a time writing to some external flash. I am able to read the MFG ID and the status registers, but I cannot write to it. I believe this is because of an issue with the write enable command. Here's how I'm configuring the command:

.InstructionMode = QSPI_INSTRUCTION_1_LINE,
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
.DataMode = QSPI_DATA_NONE,
.DdrMode = QSPI_DDR_MODE_DISABLE,
.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY,
.SIOOMode = QSPI_SIOO_INST_EVERY_CMD,
.AddressMode = QSPI_ADDRESS_NONE,
.Instruction = CMD_WRITE_ENABLE; // 0x06
.Address = 0x000000;
.DummyCycles = 0;
.NbData = 0;

I'm sending it with

status = HAL_QSPI_Command(&hqspi, cmd, DEFAULT_TIMEOUT_MS);

For good measure, here's my QSPI base config

hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 1;
hqspi.Init.FifoThreshold = 8;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
hqspi.Init.FlashSize = 23;  // 128 Mb = 16MB -> 24 bits of address space. 24 - 1 = 23
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
hqspi.Init.FlashID = QSPI_FLASH_ID_1;
hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;

While I can read from the registers just fine (which otherwise indicates the connections and configuration is sound) here's what shows up on my scope when I issue the write enable command. An extra byte is sent before CS goes high again, which I believe is causing the write enable command to fail. I know it fails because subsequent register reads via auto-polling show the write enable bit has not latched. I've been at this for hours and cannot find a way to just sent a single instruction byte! 0693W000004IZ82QAG.png

The flash datasheet (Winbond W25Q128JV) clearly specifies that the write enable command should be 0x06 bounded by CS transitions

0693W000004IZAmQAO.png

Finally, this part had the Quad Enable bit baked in high, so the WP pin is not used, but I have tried this with the WP pin pulled up just to be sure.

Even configuring the command as QSPI_INSTRUCTION_NONE with QSPI_DATA_1_LINE then trying to manually send the 0x06 as a 1 byte transfer with the HAL_QSPI_Transmit function just sends those in reverse. It's like the HAL_QSPI_Command function is determined to send a byte of 0x00 no matter how it is configured. Really hoping this can be answered by someone.

Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
underpickled
Associate II

Whoops, found my mistake after a weekend to clear my head. I had AddressSize = QSPI_ADDRESS_NONE, but AddressMode = QSPI_ADDRESS_1_LINE (which I did not properly copy into the description above, clearly indicating that my brain was not properly registering that text)

Thank you to those who gave helpful answers.

View solution in original post

7 REPLIES 7
Not applicable

STM32L4 training: 02.9 System and memories - Quad SPI memory controller (QSPI) theory:

https://www.youtube.com/watch?v=tYoc5Y-Mfd4

Can you please be a little more specific as to what you think I'm missing? My command configuration explicitly disables the address, alt bytes, dummy, and data parts of the message. According to that video (and the documentation that it references, that I've already read) I should be able to just send a one byte instruction by disabling the other parts of the message. I am configuring the options to do exactly that, but I'm still getting two bytes out instead of one.

Andreas Bolsch
Lead II

Check for BUSY or TCF flag in QUADSPI_SR to wait for command completion, read QUADSPI_CCR and inspect every single bit according to RM.

There is certainly something configured incorrectly. Don't trust HAL (or any other software) to do exactly what you *think* it does.

underpickled
Associate II

Whoops, found my mistake after a weekend to clear my head. I had AddressSize = QSPI_ADDRESS_NONE, but AddressMode = QSPI_ADDRESS_1_LINE (which I did not properly copy into the description above, clearly indicating that my brain was not properly registering that text)

Thank you to those who gave helpful answers.

ANaga.2
Associate II

Hello People, I am using the same controller STM32L452 and trying to write data to NOR flash (GD25Q127C). I am getting the HAL_ERROR because QSPI_FLAG_TC is not set. I assume this is the issue with my QSPI configuration. Could you please help me with this.

The QSPI configurations are as below.

sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_2_LINES;

      sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;

      sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;

      sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

      sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;

      sCommand.DummyCycles = 0;

      sCommand.Address = address;

      sCommand.AddressMode = QSPI_ADDRESS_1_LINE;

      sCommand.AddressSize = QSPI_ADDRESS_24_BITS;

      sCommand.DataMode = QSPI_DATA_2_LINES;

      sCommand.NbData = len;

      sCommand.Instruction = PAGE_PROGRAM;

And my code where I am trying to write to the memory is as below.

uint8_t Data[10] = {'S','F', 'U', 'M', 'M', 'M', 'M', 'M', 'M', 'M'};

 NOR_EraseSector(0x90000000);

 NOR_WriteData(0x90000000, &Data, 5);

Here I assume 0x90000000 is the start address of NOR flash. Please correct me if I am wrong.

Thanks for this. I was having troubles with write enable as well and i realized through this thread I had DataMode = QSPI_DATA_1_LINE. Please sort of oscilloscope are you using to scope this?

I use a Saleae logic analyzer. They're fantastic devices. Absolutely essential for developing boards with SPI and I2C communication.​