# daisy_qspi.cfg adapter speed 1800 transport select swd reset_config none set QUADSPI 1 source [find target/stm32h7x.cfg] proc daisy_qspi_unlock {} { global _CHIPNAME puts "> QSPI > Hardware Wakeup & Memory-Mapped Handover" # 1. ENABLE CLOCKS & HARDWARE PULSE set RCC_AHB4ENR 0x580244E0 mww $RCC_AHB4ENR [expr {[mrw $RCC_AHB4ENR] | (1 << 5) | (1 << 6)}] set GPIOF_BASE 0x58021400 set GPIOG_BASE 0x58021800 mww [expr {$GPIOG_BASE + 0x14}] [expr {[mrw [expr {$GPIOG_BASE + 0x14}]] | 0x00000040}] mww [expr {$GPIOG_BASE + 0x00}] [expr {([mrw [expr {$GPIOG_BASE + 0x00}]] & 0xFFFFCFFF) | 0x00001000}] mww [expr {$GPIOF_BASE + 0x14}] [expr {[mrw [expr {$GPIOF_BASE + 0x14}]] | 0x000000C0}] mww [expr {$GPIOF_BASE + 0x00}] [expr {([mrw [expr {$GPIOF_BASE + 0x00}]] & 0xFFFF0FFF) | 0x00005000}] sleep 20 mww [expr {$GPIOF_BASE + 0x14}] [expr {[mrw [expr {$GPIOF_BASE + 0x14}]] & 0xFFFFFF3F}] sleep 20 mww [expr {$GPIOF_BASE + 0x14}] [expr {[mrw [expr {$GPIOF_BASE + 0x14}]] | 0x000000C0}] sleep 20 # 2. TEMPORARILY MUX ALL PINS TO ALTERNATE FUNCTION mww [expr {$GPIOF_BASE + 0x0C}] [expr {([mrw [expr {$GPIOF_BASE + 0x0C}]] & 0xFFC00FFF) | 0x00155000}] mww [expr {$GPIOG_BASE + 0x0C}] [expr {([mrw [expr {$GPIOG_BASE + 0x0C}]] & 0xFFFFCFFF) | 0x00001000}] mww [expr {$GPIOF_BASE + 0x08}] [expr {[mrw [expr {$GPIOF_BASE + 0x08}]] | 0x003FF000}] mww [expr {$GPIOG_BASE + 0x08}] [expr {[mrw [expr {$GPIOG_BASE + 0x08}]] | 0x00003000}] mww [expr {$GPIOF_BASE + 0x20}] [expr {([mrw [expr {$GPIOF_BASE + 0x20}]] & 0x00FFFFFF) | 0x99000000}] mww [expr {$GPIOF_BASE + 0x24}] [expr {([mrw [expr {$GPIOF_BASE + 0x24}]] & 0xFFFFF000) | 0x000009AA}] mww [expr {$GPIOG_BASE + 0x20}] [expr {([mrw [expr {$GPIOG_BASE + 0x20}]] & 0xF0FFFFFF) | 0x0A000000}] # 0x002AA000 sets PF6-PF10 to Alternate Function mode mww [expr {$GPIOF_BASE + 0x00}] [expr {([mrw [expr {$GPIOF_BASE + 0x00}]] & 0xFFC00FFF) | 0x002AA000}] mww [expr {$GPIOG_BASE + 0x00}] [expr {([mrw [expr {$GPIOG_BASE + 0x00}]] & 0xFFFFCFFF) | 0x00002000}] # 3. ENABLE QUADSPI & UNLOCK CHIP set RCC_AHB3RSTR 0x58024484 set RCC_AHB3ENR 0x580244D4 mww $RCC_AHB3RSTR [expr {[mrw $RCC_AHB3RSTR] | 0x00004000}] mww $RCC_AHB3RSTR [expr {[mrw $RCC_AHB3RSTR] & 0xFFFFBFFF}] mww $RCC_AHB3ENR [expr {[mrw $RCC_AHB3ENR] | 0x00004000}] set QUADSPI_CR 0x52005000 set QUADSPI_DCR 0x52005004 set QUADSPI_FCR 0x5200500C set QUADSPI_CCR 0x52005014 mww $QUADSPI_CR 0x03000001 mww $QUADSPI_DCR 0x00160100 sleep 5 # Exit QPI, Reset Enable, Reset mww $QUADSPI_CCR 0x000003F5 sleep 5 mww $QUADSPI_CCR 0x00000166 sleep 5 mww $QUADSPI_CCR 0x00000199 sleep 10 # Write Enable + Global Block Unlock mww $QUADSPI_FCR 0x1B mww $QUADSPI_CCR 0x00000106 sleep 5 mww $QUADSPI_FCR 0x1B mww $QUADSPI_CCR 0x00000198 sleep 10 # 4. HIJACK PF6 AND PF7 AS SOLID OUTPUTS (Cures Erase Bug) puts "> QSPI > Locking HOLD# and WP# to Solid 3.3V Output..." # 0x002A5000 switches PF6 and PF7 back to General Purpose Output High # This prevents the flash chip from aborting 1-line erases! mww [expr {$GPIOF_BASE + 0x00}] [expr {([mrw [expr {$GPIOF_BASE + 0x00}]] & 0xFFC00FFF) | 0x002A5000}] sleep 5 # 5. MEMORY MAPPED HANDOVER puts "> QSPI > Enabling Memory Mapped Mode for seamless verification..." mww $QUADSPI_CR 0x03000003 ;# ABORT # FMODE=3 (Map), DMODE=1, ADSIZE=2 (24-bit), ADMODE=1, IMODE=1, CMD=0x03 mww $QUADSPI_CCR 0x0D002503 puts "> QSPI > ...mapped to 0x90000000. Exiting init." } # ========================================================= # SAFELY APPEND TO OPENOCD'S INIT # ========================================================= global _CHIPNAME set old_reset_init [$_CHIPNAME.cpu0 cget -event reset-init] $_CHIPNAME.cpu0 configure -event reset-init "$old_reset_init; daisy_qspi_unlock"