game-and-watch-backup/openocd/stm32h7x_spiflash.cfg

78 lines
3.2 KiB
INI

# Nintendo Game & Watch: Super Mario Bros. and Zelda
set OCTOSPI1 1
set OCTOSPI2 0
source [find target/stm32h7x.cfg]
# HXA-001 QSPI initialization
# Based on https://forums.pimoroni.com/t/accessing-external-flash-from-openocd/12558
# With contributions by https://github.com/jan2642 and https://github.com/GMMan
proc hxa-001_qspi_init { } {
echo "Initializing Octo-SPI interface"
# PB01: OCTOSPIM_P1_IO0, PD12: OCTOSPIM_P1_IO1, PE02: OCTOSPIM_P1_IO2,
# PA01: OCTOSPIM_P1_IO3, PB02: OCTOSPIM_P1_CLK, PE11: OCTOSPIM_P1_NCS,
# PD01: 1.8V power
# Enable GPIO clocks
mmw 0x58024540 0x0000001b 0x00000000 ;# RCC_AHB4ENR |= GPIOAEN | GPIOBEN | GPIODEN | GPIOEEN
# Enable Octo-SPI clocks
mmw 0x58024534 0x00204000 0x00000000 ;# RCC_AHB3ENR |= OCTOSPI1EN | OCTOSPIMEN (enable clocks)
sleep 1 ;# Wait for clock startup
# Set GPIO ports (push-pull, no pull)
# Port A: PA01:AF09:V
mmw 0x58020000 0x00000000 0x00000004 ;# GPIOA_MODER
mmw 0x58020008 0x0000000c 0x00000000 ;# GPIOA_OSPEEDR
mmw 0x58020020 0x00000090 0x00000000 ;# GPIOA_AFRL
# Port B: PB01:AF11:V PB02:AF09:V
mmw 0x58020400 0x00000000 0x00000014 ;# GPIOB_MODER
mmw 0x58020408 0x0000003c 0x00000000 ;# GPIOB_OSPEEDR
mmw 0x58020420 0x000009b0 0x00000000 ;# GPIOB_AFRL
# Port D: PD01:OP:L PD12:AF09:V
mmw 0x58020c00 0x00000000 0x01000008 ;# GPIOD_MODER
mmw 0x58020c08 0x03000000 0x00000000 ;# GPIOD_OSPEEDR
mmw 0x58020c24 0x00090000 0x00000000 ;# GPIOD_AFRH
# Port E: PE02:AF09:V PE11:AF11:V
mmw 0x58021000 0x00000000 0x00400010 ;# GPIOE_MODER
mmw 0x58021008 0x00c00030 0x00000000 ;# GPIOE_OSPEEDR
mmw 0x58021020 0x00000900 0x00000000 ;# GPIOE_AFRL
mmw 0x58021024 0x0000b000 0x00000000 ;# GPIOE_AFRH
# Reset Octo-SPI
mmw 0x5802447c 0x00204000 0x00000000 ;# RCC_AHB3RSTR |= OCTOSPIMRST | OCTOSPI1RST
# Take Octo-SPI out of reset
mmw 0x5802447c 0x00000000 0x00204000 ;# RCC_AHB3RSTR &= ~(OCTOSPIMRST | OCTOSPI1RST)
# Turn on 1.8v power
mww 0x58020c18 0x00010000 ;# GPIOD_BSRR |= BR1
# Set up Octo-SPI interface
mww 0x52005000 0x00000400 ;# OCTOSPI_CR: FMODE=0x0, FTHRES=0x04
mww 0x52005008 0x011B0208 ;# OCTOSPI_DCR1: MTYP=0x1, DEVSIZE=0x1B, CSHT=0x2, DLYBYP=0x1
mww 0x5200500c 0x00000002 ;# OCTOSPI_DCR2: PRESCALER=0x02
mmw 0x52005000 0x00000001 0x00000000 ;# OCTOSPI_CR: EN=0x1
# reset the Macronix flash
mww 0x52005100 0x00000001 ;# OCTOSPI_CCR: no data, no address, no alternate bytes, instruction on a single line
# indirect write mode without data, address and alternate bytes causes the following commands to be sent immediately
mww 0x52005110 0x00000066 ;# OCTOSPI_IR: Reset-Enable (RSTEN)
sleep 1
mww 0x52005110 0x00000099 ;# OCTOSPI_IR: Reset (RST)
sleep 20 ;# wait for the flash to come out of reset
mmw 0x52005000 0x30000000 0x00000001 ;# OCTOSPI_CR |= FMODE=0x3, &= ~EN
# OCTOSPI1: memory-mapped 1-line read mode with 3-byte addresses
mww 0x52005100 0x01002101 ;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x2, ADMODE=0x1, ISIZE=0x0, IMODE=0x1
mww 0x52005110 0x00000003 ;# OCTOSPI_IR: INSTR=READ
mmw 0x52005000 0x00000001 0x00000000 ;# OCTOSPI_CR |= EN
flash probe 1 ;# load configuration from CR, TCR, CCR, IR register values
}
$_CHIPNAME.cpu0 configure -event reset-end {
flash probe 0
hxa-001_qspi_init
}