cancel
Showing results for 
Search instead for 
Did you mean: 

QSPI reads only 0x9999

ronnietango
Associate II

I have a custom board with STM32H747IGT6 MCU, which communicates with a S25HL512TFAMHI010 flash memory chip over QSPI. I have made several iterations of this board, and the QSPI communication has always been fine.

However, on the most recent iteration of the board, I am finding a very strange problem. I am able to erase/program the flash chip with external loader file using STM32CubeProgrammer, and to use this to read the 0x90000000 address, which shows my data has been programmed as expected.

But when I try to run my code as normal, the memory mapped QSPI read always returns 0x9999 (39321) for every address.

I've tried several of the new boards with the same results, and checked that the exact same code still works on the previous iterations of the hardware.

I'm at something of a loss for how to debug this..!

9 REPLIES 9
TDK
Guru

Since it's the same 4-bit 0b1001 pattern repeating, it's probably there is a hardware issue with how your QSPI data lines are connected to the chip, or how the clock line is connected, or something hardware problem. It's the absence of data.

Connect a logic analyzer to the leads on the actual QSPI chip to verify signal is as expected.

If you feel a post has answered your question, please click "Accept as Solution".

Unfortunately I don't have access to a logic analyser at present - I'll have to order one.

But I can't understand how it can be a hardware issue when the external loader file in STM32CubeProgrammer is able to program the QSPI chip?

Yep, reasonable conclusion. The logic analyzer would give you insight into what is happening at the chip level. Even if it's not a hardware issue, you will either see the chip returning 0x9999 everywhere, or (more likely) you will see the commands sent over QSPI don't line up with what you expect. You can use that information to troubleshoot the firmware.

 

> But when I try to run my code as normal, the memory mapped QSPI read always returns 0x9999 (39321) for every address.

How about in non-memory mapped mode? Does the Memory Map view also return 0x9999 everywhere in this region?

 

 

If you feel a post has answered your question, please click "Accept as Solution".

It suggests a disparity between the mode the memory thinks it's in vs what the MCU is doing.

The S25HL512 has different commands for different modes, as I recollect, for 24 vs 32-bit addressing

Your BSP code on the app side needs to more tightly match what is being done on the External Loader side.

If using Memory Mapped Mode, the reading template command has to be correct.

At 64MB 4-byte (32-bit) addressing is going to be need.

Check that STM32 Cube Programmer + External Loader can Program and Validate large blocks of binary data in the 4, 16, 32, 64MB sense. If those are working it's not a hardware issue, but more one of software and BSP implementation.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Good point - I should have mentioned that my firmware can communicate with the chip in non-memory mapped mode - part of the initialisation procedure is to read the ID register of the chip, and this succeeds - code below:

	//  Read ID registers
	sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
	sCommand.Instruction = READ_MANUFACTURER_ID;
	sCommand.AddressMode = QSPI_ADDRESS_NONE;
	sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
	sCommand.DataMode = QSPI_DATA_1_LINE;
	sCommand.DummyCycles = 0;
	sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
	sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
	sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
	sCommand.NbData = 6;

	HAL_Delay(100);

	if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		return HAL_ERROR;
	}
	if (HAL_QSPI_Receive(&hqspi, &(ID_buffer[0]),
	HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
		return HAL_ERROR;
	}

	//  Check manufacturer ID (CYPRESS) to test reading is working
	if(ID_buffer[0] != 0x34)
	{
		return HAL_ERROR;
	}

@TDK wrote:

How about in non-memory mapped mode? Does the Memory Map view also return 0x9999 everywhere in this region?

 By "Memory Map view", do you mean in STM32CubeProgrammer? This reads the values as expected (see attached screenshot) - apologies if I've misunderstood.

Aha sorry, I think you probably meant the Memory tab in the STM32CubeIDE - yes, this also returns 0x9999 (screenshot attached) 

Screenshot 2025-01-02 at 17.21.14.png

Thanks for this. My code is already using 32-bit addressing - and the Memory Mapped Mode works properly with the same code on what *should be* exactly the same hardware configuration (the changes to the board for this iteration did not concern the QSPI section...)

 


@Tesla DeLorean wrote:

Check that STM32 Cube Programmer + External Loader can Program and Validate large blocks of binary data in the 4, 16, 32, 64MB sense.


My original binary data file is around 13MB - this loaded fine using STM32CubeProgrammer and External Loader. I then tried loading a file double this size, and it failed ("Error: failed to download the file"). Interestingly, it now doesn't seem to want to perform a Mass Erase operation, or even to re-load the original binary data file any more (log below in case that sheds any light)...

18:32:05:246 : Memory Programming ...
18:32:05:247 : Opening and parsing file: myBinaryFile.bin
18:32:05:269 : File : myBinaryFile.bin
18:32:05:269 : Size : 12.97 MB
18:32:05:269 : Address : 0x90000000
18:32:05:269 : Erasing Segment <0> Address <0x90000000> Size <13602182>Bytes
18:32:05:269 : Erasing memory corresponding to segment 0:
18:32:05:269 : Memory erase...
18:32:05:270 : halt ap 0 Status = 0
18:32:05:270 : halt ap 1 Status = 32
18:32:05:270 : halt ap 2 Status = 32
18:32:07:000 : halt ap 3 Status = 17
18:32:07:000 : w ap 0 reg 15 PC (0x24000000)
18:32:07:000 : w ap 0 reg 17 MSP (0x24000500)
18:32:07:002 : w ap 0 reg 16 xPSR (0x01000000)
18:32:07:003 : w ap 0 @0x24001F80 : 0x00000200 bytes, Data 0x00000000...
18:32:07:003 : w ap 0 @0x24000000 : 0x00000004 bytes, Data 0x0000BE00...
18:32:07:016 : w ap 0 @0x24000004 : 0x00001B54 bytes, Data 0x4000F080...
18:32:07:016 : Erasing external memory sectors [0 51]
18:32:07:016 : Init flashloader...
18:32:07:018 : halt ap 0
18:32:07:018 : w ap 0 reg 0 R0 0x00000001
18:32:07:019 : w ap 0 reg 1 R1 0x00000000
18:32:07:019 : w ap 0 reg 2 R2 0x00000000
18:32:07:019 : w ap 0 reg 3 R3 0x00000000
18:32:07:019 : w ap 0 reg 4 R4 0x00000000
18:32:07:019 : w ap 0 reg 5 R5 0x00000000
18:32:07:019 : w ap 0 reg 6 R6 0x00000000
18:32:07:019 : w ap 0 reg 7 R7 0x00000000
18:32:07:020 : w ap 0 reg 8 R8 0x00000000
18:32:07:020 : w ap 0 reg 9 R9 0x00000000
18:32:07:020 : w ap 0 reg 10 R10 0x00000000
18:32:07:021 : w ap 0 reg 11 R11 0x00000000
18:32:07:021 : w ap 0 reg 12 R12 0x00000000
18:32:07:022 : w ap 0 reg 13 SP 0x00000000
18:32:07:029 : w ap 0 reg 14 LR 0x24000001
18:32:07:030 : w ap 0 reg 15 PC 0x24000799
18:32:07:030 : w ap 0 reg 16 xPSR 0x01000000
18:32:07:030 : w ap 0 reg 17 MSP 0x24001F54
18:32:07:030 : w ap 0 reg 18 PSP 0x00000000
18:32:07:030 : run ap 0
18:32:07:031 : halt ap 0
18:32:07:031 : r ap 0 reg 0 R0 0x00000001
18:32:07:031 : Loader sector erase...
18:32:07:031 : w ap 0 reg 0 R0 0x90000000
18:32:07:031 : w ap 0 reg 1 R1 0x90CC0000
18:32:07:035 : w ap 0 reg 2 R2 0x00000002
18:32:07:035 : w ap 0 reg 3 R3 0x00000000
18:32:07:035 : w ap 0 reg 4 R4 0x00000000
18:32:07:035 : w ap 0 reg 5 R5 0x00000000
18:32:07:035 : w ap 0 reg 6 R6 0x00000000
18:32:07:035 : w ap 0 reg 7 R7 0x00000000
18:32:07:035 : w ap 0 reg 8 R8 0x00000000
18:32:07:035 : w ap 0 reg 9 R9 0x00000000
18:32:07:035 : w ap 0 reg 10 R10 0x00000000
18:32:07:035 : w ap 0 reg 11 R11 0x00000000
18:32:07:036 : w ap 0 reg 12 R12 0x00000000
18:32:07:036 : w ap 0 reg 13 SP 0x00000000
18:32:07:036 : w ap 0 reg 14 LR 0x24000001
18:32:07:036 : w ap 0 reg 15 PC 0x24000935
18:32:07:036 : w ap 0 reg 16 xPSR 0x01000000
18:32:07:036 : w ap 0 reg 17 MSP 0x24001F54
18:32:07:036 : w ap 0 reg 18 PSP 0x00000000
18:32:07:036 : run ap 0
18:32:57:366 : halt ap 0
18:32:57:366 : r ap 0 reg 0 R0 0x00000001
18:32:57:367 : erase: 52109ms
18:32:57:367 : Download in Progress:
18:32:57:369 : Size : 13602184 Bytes
18:32:57:369 : Address : 0x90000000
18:32:57:369 : Buffer program...
18:32:57:373 : halt ap 0 Status = 0
18:32:57:374 : halt ap 1 Status = 32
18:32:57:374 : halt ap 2 Status = 32
18:32:59:001 : halt ap 3 Status = 17
18:32:59:001 : w ap 0 reg 15 PC (0x24000000)
18:32:59:001 : w ap 0 reg 17 MSP (0x24000500)
18:32:59:001 : w ap 0 reg 16 xPSR (0x01000000)
18:32:59:008 : w ap 0 @0x24001F80 : 0x00000200 bytes, Data 0x00000000...
18:32:59:008 : w ap 0 @0x24000000 : 0x00000004 bytes, Data 0x0000BE00...
18:32:59:017 : w ap 0 @0x24000004 : 0x00001B54 bytes, Data 0x4000F080...
18:32:59:017 : Loader write range...
18:32:59:582 : w ap 0 @0x24001F80 : 0x0003EF00 bytes, Data 0x4EDAD666...
18:32:59:583 : W B1 in RAM @0x24001F80 size 0x0003EF00 : 0565ms
18:32:59:583 : Init flashloader...
18:32:59:587 : halt ap 0
18:32:59:588 : w ap 0 reg 0 R0 0x00000001
18:32:59:588 : w ap 0 reg 1 R1 0x00000000
18:32:59:588 : w ap 0 reg 2 R2 0x00000000
18:32:59:589 : w ap 0 reg 3 R3 0x00000000
18:32:59:589 : w ap 0 reg 4 R4 0x00000000
18:32:59:589 : w ap 0 reg 5 R5 0x00000000
18:32:59:589 : w ap 0 reg 6 R6 0x00000000
18:32:59:589 : w ap 0 reg 7 R7 0x00000000
18:32:59:590 : w ap 0 reg 8 R8 0x00000000
18:32:59:590 : w ap 0 reg 9 R9 0x00000000
18:32:59:591 : w ap 0 reg 10 R10 0x00000000
18:32:59:591 : w ap 0 reg 11 R11 0x00000000
18:32:59:592 : w ap 0 reg 12 R12 0x00000000
18:32:59:592 : w ap 0 reg 13 SP 0x00000000
18:32:59:592 : w ap 0 reg 14 LR 0x24000001
18:32:59:594 : w ap 0 reg 15 PC 0x24000799
18:32:59:595 : w ap 0 reg 16 xPSR 0x01000000
18:32:59:608 : w ap 0 reg 17 MSP 0x24001F54
18:32:59:613 : w ap 0 reg 18 PSP 0x00000000
18:32:59:613 : run ap 0
18:32:59:615 : halt ap 0
18:32:59:616 : r ap 0 reg 0 R0 0x00000001
18:32:59:616 : w ap 0 reg 0 R0 0x90000000
18:32:59:617 : w ap 0 reg 1 R1 0x0003EF00
18:32:59:617 : w ap 0 reg 2 R2 0x24001F80
18:32:59:617 : w ap 0 reg 3 R3 0x00000002
18:32:59:617 : w ap 0 reg 4 R4 0x00000000
18:32:59:617 : w ap 0 reg 5 R5 0x00000000
18:32:59:617 : w ap 0 reg 6 R6 0x00000000
18:32:59:618 : w ap 0 reg 7 R7 0x00000000
18:32:59:618 : w ap 0 reg 8 R8 0x00000000
18:32:59:618 : w ap 0 reg 9 R9 0x00000000
18:32:59:618 : w ap 0 reg 10 R10 0x00000000
18:32:59:618 : w ap 0 reg 11 R11 0x00000000
18:32:59:618 : w ap 0 reg 12 R12 0x00000000
18:32:59:618 : w ap 0 reg 13 SP 0x00000000
18:32:59:618 : w ap 0 reg 14 LR 0x24000001
18:32:59:618 : w ap 0 reg 15 PC 0x24000A35
18:32:59:618 : w ap 0 reg 16 xPSR 0x01000000
18:32:59:618 : w ap 0 reg 17 MSP 0x24001F54
18:32:59:619 : w ap 0 reg 18 PSP 0x00000000
18:32:59:619 : run ap 0
18:33:00:263 : w ap 0 @0x24040E80 : 0x0003EF00 bytes, Data 0xFE39FF0F...
18:33:00:265 : W B2 in RAM @0x24040E80 size 0x0003EF00: 0678ms
18:33:04:590 : r ap 0 reg 0 R0 0x00000000
18:33:04:594 : halt ap 0 Status = 0
18:33:04:594 : halt ap 1 Status = 32
18:33:04:594 : halt ap 2 Status = 32
18:33:06:001 : halt ap 3 Status = 17
18:33:06:001 : w ap 0 reg 15 PC (0x24000000)
18:33:06:001 : w ap 0 reg 17 MSP (0x24000500)
18:33:06:004 : w ap 0 reg 16 xPSR (0x01000000)
18:33:06:004 : Loader write range...
18:33:06:545 : w ap 0 @0x24001F80 : 0x0003EF00 bytes, Data 0x4EDAD666...
18:33:06:545 : W B1 in RAM @0x24001F80 size 0x0003EF00 : 0544ms
18:33:06:551 : halt ap 0
18:33:06:551 : r ap 0 reg 0 R0 0x00000000
18:33:06:552 : Error: failed to download Segment[0]
18:33:06:552 : Error: failed to download the File

 

Yes, this is how you look inside the memory when "Memory Mapping" is enabled.

If you don't map this will Hard Fault

If the read command template you supply in mapped mode is wrong, you'll get confused junk from the memory, or static bytes if the command is wrong/ignored.

By template I mean the same Read Command that works in the direct mode, but now stuffed with an address supplies by the MCU bus on-the-fly.

You can't use both modes concurrently, you can't send commands in memory mapped mode, you need to HAL_QSPI_Abort() to exit, and use HAL_QSPI_Command(), HAL_QSPI_Receive(), etc otherwise those commands will fail with a busy error.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Mass Erase can fail if any of the BP (Block Protect) bits in the Status Register (1) are set.

The Cypress/Infineon S25HL512T type memories can come in all kinds of variants with different sector/page sizes and combinations, or more uniform block sizes.

Perhaps dump all 6 bytes from the READ ID to ensure you're looking at the same devices.

Make sure to explicitly clear sCommand structure in auto/local variable usage, as otherwise can contain random stack junk.

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..