; -------------------------------------------------------------------------------- ; @Title: Serial Flash for ST STM32H7A3/7B3 and STM32H7B0 OctoSPI flash program ; @Description: ; Winbond W25Q128 is on the OCTOSPI controller ; ; C <-> GPIOB[2] en ALT 9, (OCTOSPI_CLK) ; CS <-> GPIOB[6] en ALT 10, (OCTOSPI_NCS) ; DQ0 <-> GPIOD[11] en ALT 9, (OCTOSPI_IO0) ; DQ1 <-> GPIOD[12] en ALT 9, (OCTOSPI_IO1) ; DQ2 <-> GPIOE[2] en ALT 9, (OCTOSPI_IO2) ; DQ3 <-> GPIOD[13] en ALT 9. (OCTOSPI_IO3) ; ; @Author: JIM ; @Chip: STM32H7A3NG ; @Copyright: (C) 1989-2023 Lauterbach GmbH, licensed for use with TRACE32(R) only ; -------------------------------------------------------------------------------- ; $Rev: 12745 $ ; $Id: stm32h7xx-ospi.cmm 12745 2023-11-17 08:43:11Z mschaeffner $ &OSPI_BASE=0x52005000 ;OCTOSPI Controller &OSPI_AHB=0x90000000 ;OCTOSPI_AHB (memory mapped) PRIVATE ¶meters ENTRY %LINE ¶meters PRIVATE ¶m_prepareonly ¶m_cpu ¶m_dualport ¶m_prepareonly=(STRing.SCAN(STRing.UPpeR("¶meters"),"PREPAREONLY",0)!=-1) ¶m_cpu=STRing.SCANAndExtract(STRing.UPpeR("¶meters"),"CPU=","") ¶m_dualport=STRing.SCANAndExtract(STRing.UPpeR("¶meters"),"DUALPORT=","0") ; -------------------------------------------------------------------------------- ; initialize and start the debugger RESet SYStem.RESet SYStem.CPU STM32H7A3NG SYStem.CONFIG.DEBUGPORTTYPE SWD IF hardware.COMBIPROBE()||hardware.UTRACE() ( SYStem.CONFIG.CONNECTOR MIPI20T ) SYStem.Option DUALPORT ON SYStem.MemAccess DAP SYStem.JtagClock CTCK 10MHz Trace.DISable SYStem.Up GOSUB RCC_Init GOSUB GPIO_PIN_MUX GOSUB OCTOSPI_Init ;GOSUB READ_ID_TEST ; ------------------------------------------------------------------------------ ; Flash declaration GOSUB FlashDeclaration "¶m_dualport" //Flash read_id test FLASH.SPI.CMD 2. 0x9F /READ 0x8 ;send 0x9F , read 8 bytes ; Flash script ends here if called with parameter PREPAREONLY IF ¶m_prepareonly ENDDO PREPAREDONE ; ------------------------------------------------------------------------------- ; Flash programming example DIALOG.YESNO "Program flash memory?" LOCAL &progflash ENTRY &progflash IF &progflash ( FLASH.ReProgram.ALL Data.LOAD.auto * FLASH.ReProgram.off ; Reset device SYStem.Down SYStem.Up ) ENDDO RCC_Init: ( PER.Set.simple ASD:0x58024400 %LE %Long 0x0303F1A5 ;RCC_CR PER.Set.simple ASD:0x58024540 %LE %Long 0x1000001F ;GPIOB & GPIOC & GPIOD & GPIOE & Back up RAM clk enable PER.Set.simple ASD:0x5802444C %LE %Long 0x00000011 ;RCC_CDCCIPR PER.Set.simple ASD:0x5802447C %LE %Long 0x00000000 ;RCC_AHB3RSTR, release OCTO SPI memory controller reset PER.Set.simple ASD:0x580244B0 %LE %Long 0x00000000 ;RCC AXI clocks gating enable register PER.Set.simple ASD:0x58024534 %LE %Long 0x00205001 ;RCC AHB3 clock register (RCC_AHB3ENR) PER.Set.simple ASD:0x580244D4 %LE %Long 0x00205001 ;RCC_AHB3ENR PER.Set.simple ASD:0x5802455C %LE %Long 0xFDE95131 ;RCC AHB3 sleep clock register (RCC_AHB3LPENR) PER.Set.simple ASD:0x58024458 %LE %Long 0x00020000 RETURN ) GPIO_PIN_MUX: ( ;C <-> GPIOB[2] en ALT 9, (OCTOSPI_CLK) ;CS <-> GPIOB[10] en ALT 10, (OCTOSPI_NCS) ;DQ0 <-> GPIOD[11] en ALT 9, (OCTOSPI_IO0) ;DQ1 <-> GPIOD[12] en ALT 9, (OCTOSPI_IO1) ;DQ2 <-> GPIOE[2] en ALT 9, (OCTOSPI_IO2) ;DQ3 <-> GPIOD[13] en ALT 9. (OCTOSPI_IO3) ;PB2, 6 PER.Set.simple ASD:0x58020400 %LE %Long 0xAFEAAEA5 ; GPIOB_MODER [15:0] PER.Set.simple ASD:0x58020408 %LE %Long 0x00003030 ; 00:low sped, ... 11:Very high speed PER.Set.simple ASD:0x58020420 %LE %Long 0x0A000900 ; AFRL[7:0] PB2 alt 9 , PB6 alt 10 ;PD11,12,13 PER.Set.simple ASD:0x58020C00 %LE %Long 0xAA9FFAFA ; GPIOD_MODER PER.Set.simple ASD:0x58020C08 %LE %Long 0x5FC00505 ; 00:low sped, ... 11:Very high speed PER.Set.simple ASD:0x58020C24 %LE %Long 0x00999000 ; AFRH[15:8] PD11,12,13 alt 9 ;PE2 PER.Set.simple ASD:0x58021000 %LE %Long 0xFFEABFAF ; GPIOE_MODER PER.Set.simple ASD:0x58021008 %LE %Long 0x00154070 ; 00:low sped, ... 11:Very high speed PER.Set.simple ASD:0x58021020 %LE %Long 0xC000C900 ; AFRL[7:0] PE2 alt 9 RETURN ) OCTOSPI_Init: ( //OCTOSPIM_Init PER.Set.simple ASD:0x5200B404 %LE %Long 0x03010111 PER.Set.simple ASD:0x5200B408 %LE %Long 0x07050333 //OCTOSPI_Init PER.Set.simple ASD:&OSPI_BASE+0x000 %LE %Long 0x30400300 ;disable & memory mapped PER.Set.simple ASD:&OSPI_BASE+0x040 %LE %Long 0xFF ;clear status register PER.Set.simple ASD:&OSPI_BASE+0x00C %LE %Long 0x1 ;prescaler PER.Set.simple ASD:&OSPI_BASE+0x100 %LE %Long 0x03032301 ;ccr PER.Set.simple ASD:&OSPI_BASE+0x008 %LE %Long 0x00160008 ; PER.Set.simple ASD:&OSPI_BASE+0x108 %LE %Long 0x40000004 ;dummy cycles PER.Set.simple ASD:&OSPI_BASE+0x110 %LE %Long 0xEB ;opcode for read (1-4-4) PER.Set.simple ASD:&OSPI_BASE+0x180 %LE %Long 0x03002301 PER.Set.simple ASD:&OSPI_BASE+0x190 %LE %Long 0x32 PER.Set.simple ASD:&OSPI_BASE+0x000 %LE %Long Data.Long(ASD:&OSPI_BASE+0x000)|0x1 ;enable RETURN ) FlashDeclaration: ( PRIVATE &FlashSize &FlashDriver &FlashBaseAddr PARAMETERS &DualPort &FlashDriver="snor3b_stm32h7ospi.bin" &FlashSize=0x1000000 ;16MB &FlashBaseAddr=0x90000000 ;SPI AHB base address FLASH.RESet FLASH.Create 2. &FlashBaseAddr++(&FlashSize-1) 0x10000 TARGET2 Byte IF "&DualPort"=="0" FLASH.TARGET2 0x20000000 0x20002000 0x4000 ~~/demo/arm/flash/byte/&FlashDriver /STACKSIZE 0x200 ELSE FLASH.TARGET2 0x20000000 E:0x20002000 0x4000 ~~/demo/arm/flash/byte/&FlashDriver /STACKSIZE 0x200 /DualPort FLASH.List RETURN ) READ_ID_TEST: ( WHILE ((Data.Long(ANSD:&OSPI_BASE+0x20)>>8.)&0x1F)!=0x0 ( PRINT "read 0x" Data.Byte(ANSD:&OSPI_BASE+0x50) ;read data.. ) PER.Set.simple ANSD:&OSPI_BASE %Long 0x10400300 ;indirect-read mode and disable OCTOSPI &ccr_data= (0x0<<4.)|(1<<0.) ; 8bit(1byte) | 1bit opcode &ccr_data=&ccr_data|(0x2<<12.)|(0<<8.) ; 24bit(3bytes) | no addr out &ccr_data=&ccr_data|(0<<16.) ; no extra bytes &ccr_data=&ccr_data|(1<<24.) ; 24bit | 1bit data no extra bytes ;data enable PER.Set.simple ANSD:&OSPI_BASE+0x40 %Long 0xF ;4bytes read PER.Set.simple ANSD:&OSPI_BASE+0x108 %Long 0x0 ;no dummy PER.Set.simple ANSD:&OSPI_BASE %Long Data.Long(ANSD:&OSPI_BASE)|0x1 ;enable PER.Set.simple ANSD:&OSPI_BASE+0x100 %Long &ccr_data ; ccr_register PER.Set.simple ANSD:&OSPI_BASE+0x110 %Long 0x9f ; cmd opcode RePeaT Data.Byte(ANSD:&OSPI_BASE+0x40)+1. ( PRINT "read 0x" Data.Byte(ANSD:&OSPI_BASE+0x50) ;read data.. ) GOSUB OCTOSPI_Init RETURN )