cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H750B-DK: TouchGFX 4.26.0 + QSPI Flash - Debugger fails with protocol error on reset

ksale.1
Senior II

Setup Details:

  • Board: STM32H750B-DK Discovery Kit

  • STM32CubeIDE: Version 2.0.0 (Build 26820_20251114_1348 UTC)

  • STM32Cube FW_H7: v1.12.1

  • STM32CubeMX: v6.16.0

  • TouchGFX Designer: v4.26.0 (MVP pattern)

  • External Memory: 1GB QSPI Flash (MT25TL01G) + 8MB SDRAM

Project Configuration:

  1. Created TouchGFX project in Designer, saved and generated code

  2. Opened .ioc file in STM32CubeMX v6.16.0

  3. Configured:

    • QSPI in memory-mapped mode with 30-bit addressing (1GB flash)

    • SDRAM via FMC

    • MPU configured with QSPI region execution enabled (0x90000000, 256MB)

    • Vector table relocated to 0x90000000

    • Linker script modified for external flash execution

The Problem:

Debugger fails with protocol error when attempting to debug:

Error in final launch sequence:
Failed to execute MI command: monitor reset halt
Protocol error with Rcmd
Failed to execute MI command: monitor mww 0xE000ED08 0x90000000
Protocol error with Rcmd
Failed to execute MI command: monitor reg pc 0x90000004
Protocol error with Rcmd

What Works:

:white_heavy_check_mark: Code programs successfully to QSPI at 0x90000000 using STM32CubeProgrammer (.bin file)
:white_heavy_check_mark: After programming and power cycle, board runs code correctly (verified with LED patterns)
:white_heavy_check_mark: LED patterns show:

  • Early QSPI initialization succeeds

  • SDRAM initialization succeeds

  • Full QSPI init succeeds

  • TouchGFX initialization succeeds

  • Main loop execution confirmed
    :white_heavy_check_mark: Programming works; standalone execution works

What Doesn't Work:

:cross_mark: Debug fails every time with protocol error
:cross_mark: Error occurs during reset/halt sequence before code executes
:cross_mark: Debugger cannot access QSPI memory region (0x90000000) at reset time
:cross_mark: Trying to attach to running target fails

 

Attempted Solutions:

1. Debugger Configuration Changes:

  • Tried all reset modes: Software system reset, Hardware reset, Core reset, System reset

  • Unchecked "Run to main()"

  • Added reset delay (500ms, 1000ms)

  • Removed all initialization commands (just monitor reset halt)

  • Tried with empty initialization commands

  • Modified ST-LINK speed (4000kHz → 1000kHz)

2. Code Modifications:

  • Added early QSPI initialization in main() before any HAL init

  • Minimal QSPI config: clock enable, reset, CR=0x00000101, DCR=0x001E0000, CCR=0x00000100

  • LED debugging confirms early QSPI init runs when code executes normally

  • MPU region 1 configured with execution enabled at 0x90000000

3. Programming Attempts:

  • Programmed .elf, .hex, .bin files

  • Starting address 0x90000000 for .bin

  • Verified with STM32CubeProgrammer

  • Unchecked "Run after programming"

  • Power cycle after programming

4. Hardware Checks:

  • BOOT0 pin verified LOW (boot from flash)

  • Power cycled after each programming attempt

  • ST-LINK firmware updated

  • Different USB ports/cables tested

Modified Files (Key Sections):

main.c - Early QSPI Init:

static void Early_QSPI_Init(void)
{
  __HAL_RCC_QSPI_CLK_ENABLE();
  RCC->AHB3RSTR |= RCC_AHB3RSTR_QSPIRST;
  for(volatile int i=0;i<100;i++);
  RCC->AHB3RSTR &= ~RCC_AHB3RSTR_QSPIRST;
  QUADSPI->CR = 0x00000101;
  QUADSPI->DCR = 0x001E0000;
  QUADSPI->CCR = 0x00000100;
}

MPU Configuration:

// Region 1: QSPI Flash (0x90000000, 256MB) - Executable
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

Linker Script (.ld):

MEMORY
{
  FLASH (rx)  : ORIGIN = 0x90000000, LENGTH = 256M
  RAM   (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
  /* ... */
}

Questions:

  1. How to make the debugger initialize QSPI before attempting to set vector table?

    • Is there a way to execute initialization scripts before the debugger tries to access 0x90000000?

    • Can we redirect the debugger to use internal flash vectors while keeping code in QSPI?

  2. Is there a known issue with OpenOCD and STM32H7 QSPI memory-mapped mode during debug?

    • Does the debugger need special configuration for memory-mapped QSPI?

  3. What is the recommended debug workflow for STM32H7 with code executing from external QSPI?

    • Boot from internal flash with loader that copies/initializes QSPI?

    • Two-stage bootloader approach?

    • Debug from internal flash first, then move to QSPI?

  4. Has anyone successfully debugged STM32H750B-DK with TouchGFX and code in external QSPI?

    • What specific debugger settings are required?

    • Any special OpenOCD scripts or cfg files?

  5. Could this be related to the ST-LINK firmware or STM32CubeIDE version?

    • Using IDE 2.0.0 (2025) with FW_H7 1.12.1 - any compatibility issues?

  6. Alternative approach: Is it possible to keep the vector table in internal flash but execute code from QSPI?

    • SCB->VTOR = 0x08000000 while code executes from 0x90000000?

Current Workaround (Not Acceptable):

  • Flash with CubeProgrammer

  • Power cycle

  • Cannot debug - forced to rely on LED indicators and printf over serial

Any guidance, working debug configurations, or alternative approaches would be greatly appreciated!

 

*Will provide any additional files or configuration details needed.*

1 ACCEPTED SOLUTION

Accepted Solutions

You need to compile and upload the Boot example to the MCU internal Flash.

https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Projects/STM32H750B-DK/Templates/ExtMem_Boot

The TouchGFX application seems to be located in the QSPI Flash at the address 0x90000000, and the TouchGFX assets at 0x90200000 and this is based on the generated linker file by TouchGFX designer:

  FLASH     (rx)     : ORIGIN = 0x90000000,   LENGTH = 2048K
  ASSETS_FLASH (r)    : ORIGIN = 0x90200000, LENGTH = 126M
  BOOTLOADER   (xrw)    : ORIGIN = 0x08000000,   LENGTH = 128k

Then upload your TouchGFX application, it will be located at the QSPI flash. No need to configure QSPI flash from your side it is already configured by ExtMem_Boot application.

Hope that helps.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

5 REPLIES 5
mƎALLEm
ST Employee

Hello,

What are you trying to do? execute from QSPI (XIP mode)?

I'm not sure if that initialization is sufficient:

static void Early_QSPI_Init(void)
{
  __HAL_RCC_QSPI_CLK_ENABLE();
  RCC->AHB3RSTR |= RCC_AHB3RSTR_QSPIRST;
  for(volatile int i=0;i<100;i++);
  RCC->AHB3RSTR &= ~RCC_AHB3RSTR_QSPIRST;
  QUADSPI->CR = 0x00000101;
  QUADSPI->DCR = 0x001E0000;
  QUADSPI->CCR = 0x00000100;
}

Try to use the HAL and inspire from the External memory boot template provided in the HAL package:

https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Projects/STM32H750B-DK/Templates/ExtMem_Boot

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
MHoll.2
Senior III

Not sure if this will help, but when You can programm the External Flash via CubeProgrammer, You have a working external loader for your flash. You have to tell the CubeIDE to use this Loader by selecting it in the Debug Configuration::

MHoll2_0-1770805049741.png

 

mƎALLEm
ST Employee

Another question, why are you configuring QSPI and other stuff while you can start your project from TouchGFX Designer based on TBS board (STM32H750B-DK board) that it will configure all the stuff for you including the QSPI interface

mALLEm_0-1770805266767.png

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Thank you, this is exactly how I started TouchGFX Designer -> generate code -> open files -> STM32CubeIDE Folder -> open ioc -> configure the rcc, set the rtc timer, and adjust the clock source ->save -> generate code -> open IDE -> build -> debug -> Fail

You need to compile and upload the Boot example to the MCU internal Flash.

https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Projects/STM32H750B-DK/Templates/ExtMem_Boot

The TouchGFX application seems to be located in the QSPI Flash at the address 0x90000000, and the TouchGFX assets at 0x90200000 and this is based on the generated linker file by TouchGFX designer:

  FLASH     (rx)     : ORIGIN = 0x90000000,   LENGTH = 2048K
  ASSETS_FLASH (r)    : ORIGIN = 0x90200000, LENGTH = 126M
  BOOTLOADER   (xrw)    : ORIGIN = 0x08000000,   LENGTH = 128k

Then upload your TouchGFX application, it will be located at the QSPI flash. No need to configure QSPI flash from your side it is already configured by ExtMem_Boot application.

Hope that helps.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.