; -------------------------------------------------------------------------------- ; @Title: NOR FLASH Program script for the J784S4XG01EVM ; @Description: ; The NOR flash is connected to the OSPI_CS0 controller. ; FLASHFILE xSPI serial driver. ; Supported NOR flash memories: ; * S28HS512TGABHM010 ; Memory Map (MCU Cortex-R5): ; * OSPI(controller) base: 0x47040000 ; * OSPI memory mapped address: 0x50000000 ; Prerequisites: ; * Connect Debug Cable to J23 via adapter LA-3818 or ; * Connect Autofocus Preprocessor for Arm MIPI-60 to J23 ; * Set 'CONFIG_SW' switch settings: SW2[1] = OFF ; * For script based board setup scenarios set the boot mode to "No Boot". ; Other boot modes are untested and might only work with "attach" scenarios. ; No Boot: ; SW7 [8:1] = 0000 1110 ; SW11[8:1] = 0001 0001 ; ; @Chip: TDA4VH ; @Board: J784S4XG01EVM ; @Author: CMO ; @Keywords: Flash ; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only ; -------------------------------------------------------------------------------- LOCAL &PPF &PPF=OS.PresentPracticeFile() LOCAL &PDD &AUX_SCRIPT_DIR &PDD=OS.PDD() &AUX_SCRIPT_DIR="&PDD/hardware/j784s4/scripts" ; -------------------------------------------------------------------------------- ; Parse parameters PRIVATE &PARAMETERS ENTRY %LINE &PARAMETERS LOCAL &PARAM_PREPAREONLY &PARAM_PREPAREONLY=(STRing.SCAN(STRing.UPpeR("&PARAMETERS"),"PREPAREONLY",0)!=-1) LOCAL &PARAM_TARGETSETUP &PARAM_TARGETSETUP=(STRing.SCAN(STRing.UPpeR("&PARAMETERS"),"TARGETSETUP",0)!=-1) ; -------------------------------------------------------------------------------- ; Set flash type specific configuration LOCAL &CONFIG_DRIVER IF TRUE() ( &CONFIG_DRIVER="spi4b64_tiospi.bin" ; 4 byte - big ) ELSE ( &CONFIG_DRIVER="spi64_tiospi.bin" ; 3 byte - small ) LOCAL &CONFIG_DUALPORT &CONFIG_DUALPORT=TRUE() ; default to dualport flash programming ; Use PLL2 as flash controller clock source (in doubt leave as TRUE()) LOCAL &CONFIG_USE_PLL2 &CONFIG_USE_PLL2=TRUE() ; Flash controller and memory defines LOCAL &CONFIG_OSPI_BASE &CONFIG_OSPI_MEMORY_BASE &CONFIG_OSPI_BASE=0x47040000 &CONFIG_OSPI_MEMORY_BASE=0x50000000 ; flash contents memory mapped address ; TRUE() if flash has uniform 256 KB sectors LOCAL &CONFIG_UNIFORM &CONFIG_UNIFORM=TRUE() ; -------------------------------------------------------------------------------- ; Target setup RESet SYStem.RESet SYStem.CPU TDA4VH-CR5-MCU SYStem.CONFIG CORE 11. 1. CORE.ASSIGN 1. SYStem.Option RESBREAK OFF SYStem.Option EnReset OFF SYSTEM.JTAGCLOCK CTCK 10MHz Trace.METHOD NONE ; Trace components should not be accessed until fully set up ETM.OFF IF COMBIPROBE()||UTRACE() ( SYStem.CONFIG.CONNECTOR MIPI34 ; because of converter LA-3782 ) IF (&PARAM_TARGETSETUP) ( SYStem.Mode Prepare Data.Set EDBG:0x400003f0 %Long 0x00190000 ; Ensure Power-AP unlocked Data.Set EDBG:0x400003f0 %Long 0yxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1 ; Soft reset system WAIT 500.ms ; Wait some time for system to stabilize ; Configure PLLs Do "&AUX_SCRIPT_DIR/configure_pll.cmm" MAIN Do "&AUX_SCRIPT_DIR/configure_pll.cmm" DEBUG Do "&AUX_SCRIPT_DIR/configure_pll.cmm" MCU0 Do "&AUX_SCRIPT_DIR/configure_pll.cmm" MCU1 Do "&AUX_SCRIPT_DIR/configure_pll.cmm" MCU2 ; Enable Power Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 0. 0. 0. 0x1 0x3 ; LPSC_WKUP_ALWAYSON Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 0. 0. 1. 0x1 0x3 ; LPSC_DMSC Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 0. 0. 2. 0x1 0x3 ; LPSC_DEBUG2DMSC Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 0. 0. 4. 0x1 0x3 ; LPSC_WKUPMCU2MAIN Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 0. 0. 7. 0x1 0x3 ; LPSC_MCU_DEBUG Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 1. 0. 0. 0x1 0x3 ; LPSC_MAIN_ALWAYSON Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 1. 0. 13. 0x1 0x3 ; LPSC_MAIN_DEBUG Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 0. 0. 10. 0x1 0x3 ; LPSC_MCU_OSPI_0 Do "&AUX_SCRIPT_DIR/configure_psc.cmm" 0. 0. 11. 0x1 0x3 ; LPSC_MCU_OSPI_1 ; Disable CR5-MCU lockstep Data.Set EZAXI:0x45A50040 %Long 0x00000000 ) ; Connect to the MCU-CR5 to program flash SYStem.Up SCREEN.OFF ; Flash Controller Power & Clock Enable GOSUB CLK_INIT ; Flash Pin Mux Configuration GOSUB PIN_MUX ; Flash Controller Init GOSUB OSPI_INIT GOSUB CACHE_MMU_INIT GOSUB WATCHDOG_DISABLE GOSUB SPICMD 0x66 GOSUB SPICMD 0x99 ; Flash Read ID Test GOSUB READ_ID_TEST ; -------------------------------------------------------------------------------- ; Flash declaration Break.RESet FLASHFILE.RESet IF (&CONFIG_UNIFORM) ( ;S28HS512T: if CFR3N[3]=1 then uniform 256K sector decoration FLASHFILE.CREATE 0x0--0x03FFFFFF 0x40000 ; if uniform 256KB sectors ) ELSE ( ; S28HS512T: if CFR3N[3]=0 then hybrid sector decoration non-uniform FLASHFILE.Create 0x00000000--0x0001FFFF 0x01000 FLASHFILE.Create 0x00020000--0x0003FFFF 0x20000 FLASHFILE.Create 0x00040000--0x03FFFFFF 0x40000 ) //FLASFILE.CONFIG ; for indirect OSPI memory write FLASHFILE.CONFIG &CONFIG_OSPI_BASE 0x50000000 LOCAL &DUALPORT_OPTION &DUALPORT_OPTION="" IF (&CONFIG_DUALPORT) ( ; Configure and enable run time memory access DO "&AUX_SCRIPT_DIR/j784s4-cr5_runtime_memory_access.cmm" SYStem.MemAccess DAP &DUALPORT_OPTION="/DualPort" ) FLASHFILE.TARGET 0x41C00000++0x1FFF 0x41C03000++0x23FF "~~/demo/arm/flash/byte/&CONFIG_DRIVER" /KEEP /STACKSIZE 0x200 &DUALPORT_OPTION // Read FLASH Manufacturer and Device ID FLASHFILE.GETID GOSUB SPI_4B_ADDRMODE_ENABLE IF (&CONFIG_UNIFORM) ( PRIVATE ®Data //Uniform sector mode FLASHFILE.SPI.CMD 0x65 0x00 0x80 0x00 0x04 /READ 0x1 vm:0x0 ; Read Any Register to verify CFR3V ®Data=Data.Byte(vm:0x0) IF ®Data!=0x08 ( // it means the current flash is 3Byte address mode, so it should switch to the 4Byte address mode for the 4b flash driver file. FLASHFILE.SPI.CMD 0x06 ;Write Enable FLASHFILE.SPI.CMD 0x71 0x00 0x80 0x00 0x04 0x08 ;Write 0x08 to CFR3V, switch uniform mode FLASHFILE.SPI.CMD 0x65 0x00 0x80 0x00 0x04 /READ 0x1 vm:0x0 ; Read Any Register to verify CFR3V WAIT 10.ms ) ®Data=Data.Byte(vm:0x0) IF ®Data==0x08 ( PRINT "S28HS512T Uniform Mode" ) ) ; End of the test prepare only IF (&PARAM_PREPAREONLY) ( SCREEN.ON ENDDO ) ; -------------------------------------------------------------------------------- ; Flash programming example ; Open flash sector overview FLASHFILE.List ; Dump window for Serial FLASH FLASHFILE.DUMP 0x0 ; FLASHFILE.DUMP 0x0 /SPARE /Track ; Write Serial FLASH ; FLASHFILE.ERASE 0x0--0xFFFFF ; Write Serial FLASH ; FLASHFILE.LOAD * 0x0 ; FLASHFILE.LOAD * 0x0 /ComPare ; Reset device PRINT "Please power-cycle the board after flash program is complete" SCREEN.ON ENDDO READ_ID_TEST: ( ; In case of errors you can try to read the ID via: ; GOSUB READ_ID_TEST ; ; Check the output of the AREA window. ; Expected output ID: ; 0x2C ; 0x5A (or 0x5B) ; 0x1A ; 0x10 ; 0x41 ; 0x00 (or 0x04) ; ... (Unique ID code) PRIVATE &rdata &CTRLREG &RXDATA0 &RXDATA1 &CTRLREG=&CONFIG_OSPI_BASE+0x090 &RXDATA0=&CONFIG_OSPI_BASE+0x0A0 &RXDATA1=&CONFIG_OSPI_BASE+0x0A4 &cmd=0x9f<<24. ; cmd &rd=0x1<<23. ; rd data enable &rd_num=0x7<<20. ; 7+1==8bytes &cmd_exec=0x1 ; cmd execution Data.Set EZAXI:&CTRLREG %LE %Long (&cmd|&cmd_exec|&rd_num|&rd) ; write cmd + write data WAIT 100.ms &rdata=Data.Long(EZAXI:&RXDATA0) ; read lower , 8byte fifo PRinT "1st 0x" (&rdata)&0xFF " (Manufacture)" ; ; RXFIFO0 PRinT "2nd 0x" (&rdata>>8.)&0xFF " (Device ID)" PRinT "3rd 0x" (&rdata>>16.)&0xFF PRinT "4th 0x" (&rdata>>24.)&0xFF &rdata=Data.Long(EZAXI:&RXDATA1) ; read upper , 8byte fifo PRinT "5th 0x" (&rdata)&0xFF PRinT "6th 0x" (&rdata>>8.)&0xFF PRinT "7th 0x" (&rdata>>16.)&0xFF PRinT "8th 0x" (&rdata>>24.)&0xFF RETURN ) FLASHFILE_ONFI_TEST: ( FLASHFILE.GETONFI /VM PRINT "A page size: " %Decimal Data.Long(VM:0x50) "./" Data.Long(VM:0x54) ".Bytes (main/spare)" PRINT "A block size: 0x" Data.Long(VM:0x50)*Data.Long(VM:0x5C) " (" %Decimal Data.Long(VM:0x5C) ".Pages)" PRINT "A device size: 0x" Data.Long(VM:0x50)*Data.Long(VM:0x5C)*Data.Long(VM:0x60) " Bytes" RETURN ) FLASHFILE_CHECK_SPINAND_READMODE: ( ; The Buffer Read Mode (BUF=1) requires a Column Address to start outputting the existing data inside ; the Data Buffer, and once it reaches the end of the data buffer (Byte 2,111), DO (IO1) pin will become ; high-Z state. ; The Continuous Read Mode (BUF=0) doesn't require the starting Column Address. The device will ; always start output the data from the first column (Byte 0) of the Data buffer, and once the end of the ; data buffer (Byte 2,048) is reached, the data output will continue through the next memory page. ; 2048+64, Buffer Read Mode (BUF=1), bcz the OSPI RX buffer is not large enough (Not A nand page size) FLASHFILE.SPI.CMD 0x0F 0xB0 /READ 0x4 VM:0 IF Data.Byte(VM:0x0)!=0x18 ( FLASHFILE.SPI.CMD 0x1F 0xB0 0x18 ; Set ECC[4]=1, BUF[3]=1 in Status Register-2 ) RETURN ) OSPI_INIT: ( Data.Set EZAXI:&CONFIG_OSPI_BASE+0x0 %LE %Long 0x0 Data.Set EZAXI:&CONFIG_OSPI_BASE+0x4 %LE %Long 0x00000013 ; 4B Addr Read Data.Set EZAXI:&CONFIG_OSPI_BASE+0x8 %LE %Long 0x00000012 ; 4B Addr Write Data.Set EZAXI:&CONFIG_OSPI_BASE+0x0 %LE %Long 0x80800000 Data.Set EZAXI:&CONFIG_OSPI_BASE+0x14 %LE %Long 0x1003; 4B Address mode, 3B Addr: 0x1002 Data.Set EZAXI:&CONFIG_OSPI_BASE+0x10 %LE %Long 0x21 Data.Set EZAXI:&CONFIG_OSPI_BASE+0x1C %LE %Long 0xFFFFFFFF ; Data.Set EZAXI:&CONFIG_OSPI_BASE+0xC %LE %Long (0xFF<<16.)|(0xFF<<8.) ; !!!!! OSPI_DEV_DELAY_REG because of writing !!!!! Data.Set EZAXI:&CONFIG_OSPI_BASE+0x0 %LE %Long 0x00000081|(0x1<<19.)|(0xE<<10.) ; 0x1==baudrate_div4, enable usage of OSPI_CS0 Data.Set EZAXI:&CONFIG_OSPI_BASE+0x1C %LE %Long 0x04000000 ; ospi_setdirectcutoff, end of the flash address IF (&CONFIG_USE_PLL2) Data.Set EZAXI:&CONFIG_OSPI_BASE+0x0 %LE %Long 0x00000081|(0x2<<19.)|(0xE<<10.) ; pll2 divide, Enable using OSPI_CS0 ELSE Data.Set EZAXI:&CONFIG_OSPI_BASE+0x0 %LE %Long 0x00000081|(0x5<<19.)|(0xE<<10.) ; pll1 divide, Enable using OSPI_CS0 RETURN ) PIN_MUX: ( ; MMR_unlock Data.Set EZAXI:0x4301D008 %Long 0x68EF3490 ; CTRLMMR_WKUP_LOCK7_KICK0 Data.Set EZAXI:0x4301D00C %Long 0xD172BC5A Data.Set EZAXI:0x4301C000 %Long 0x00040000 ; D19: CTRLMMR_WKUP_PADCONFIG0 MCU_OSPI0_CLK Data.Set EZAXI:0x4301C004 %Long 0x00040000 ; E20: MCU_OSPI0_LBCLKO Data.Set EZAXI:0x4301C008 %Long 0x00040000 ; E18: MCU_OSPI0_DQS Data.Set EZAXI:0x4301C00C %Long 0x00040000 ; C19: MCU_OSPI0_D0 Data.Set EZAXI:0x4301C010 %Long 0x00040000 ; F16: MCU_OSPI0_D1 Data.Set EZAXI:0x4301C014 %Long 0x00040000 ; G15: MCU_OSPI0_D2 Data.Set EZAXI:0x4301C018 %Long 0x00040000 ; F18: MCU_OSPI0_D3 Data.Set EZAXI:0x4301C01C %Long 0x00040000 ; E19: MCU_OSPI0_D4 Data.Set EZAXI:0x4301C020 %Long 0x00040000 ; G19: MCU_OSPI0_D5 Data.Set EZAXI:0x4301C024 %Long 0x00040000 ; F19: MCU_OSPI0_D6 Data.Set EZAXI:0x4301C028 %Long 0x00040000 ; F20: MCU_OSPI0_D7 Data.Set EZAXI:0x4301C02C %Long 0x00040000 ; F15: MCU_OSPI0_CSn0 Data.Set EZAXI:0x4301C030 %Long 0x00040000 ; G17: MCU_OSPI0_CSn1 Data.Set EZAXI:0x4301C038 %Long 0x00040001 ; F14: MCU_OSPI0_CSn2 Data.Set EZAXI:0x4301C03C %Long 0x00040001 ; F17: MCU_OSPI0_CSn3 RETURN ) CLK_INIT: ( Data.Set EZAXI:0x40F09008 %Long 0x68EF3490 ; CTRLMMR_MCU_LOCK2_KICK0 Data.Set EZAXI:0x40F0900C %Long 0xD172BC5A Data.Set EZAXI:0x40d01010 %Long 0x68EF3490 ; MCU_PLL1_KICK0 Data.Set EZAXI:0x40d01014 %Long 0xD172BC5A ; MCU_PLL1_KICK1 SCREEN.WAIT 1.ms IF (&CONFIG_USE_PLL2) ( Data.Set EZAXI:0x40D02090 %Long 0x0000800b ; MCU_PLL2_HSDIV_CTRL4 --> 166MHz SCREEN.WAIT 1.ms Data.Set EZAXI:0x40F08030 %Long 0x1 ; CTRLMMR_MCU_OSPI0_CLKSEL, 2h - MCU_PLL2_HSDIV4_CLKOUT ) ELSE ( ; freq: PLL1 (2.4G) -> HSDIV4 (/5+1) -> 400Mhz --> BAUD/x Data.Set EZAXI:0x40D01090 %Long 0x8005 ; MCU_PLL1_HSDIV_CTRL4 SCREEN.WAIT 1.ms Data.Set EZAXI:0x40F08030 %Long 0x0 ; CTRLMMR_MCU_OSPI0_CLKSEL, 0h - MCU_PLL1_HSDIV4_CLKOUT ) SCREEN.WAIT 1.ms RETURN ) CACHE_MMU_INIT: ( PRIVATE &i &tmpReg ; Configure small region setup for flash programming PER.Set.SaveIndex C15:0x026 %Long 0x0 C15:0x016 %Long 0x00000000 ; set default PER.Set.SaveIndex C15:0x026 %Long 0x0 C15:0x216 %Long 0x0000003F PER.Set.SaveIndex C15:0x026 %Long 0x0 C15:0x416 %Long 0x00001310 PER.Set.SaveIndex C15:0x026 %Long 0x1 C15:0x016 %Long 0x50000000 ; setup flash window PER.Set.SaveIndex C15:0x026 %Long 0x1 C15:0x216 %Long 0x00000035 PER.Set.SaveIndex C15:0x026 %Long 0x1 C15:0x416 %Long 0x00001301 PER.Set.SaveIndex C15:0x026 %Long 0x2 C15:0x016 %Long 0x41C00000 ; setup buffer space PER.Set.SaveIndex C15:0x026 %Long 0x2 C15:0x216 %Long 0x00000027 PER.Set.SaveIndex C15:0x026 %Long 0x2 C15:0x416 %Long 0x0000030C ; Reset all other MPU regions &i=3. WHILE &i<16. ( PER.Set.SaveIndex C15:0x026 %Long &i C15:0x016 %Long 0x0 PER.Set.SaveIndex C15:0x026 %Long &i C15:0x216 %Long 0x0 PER.Set.SaveIndex C15:0x026 %Long &i C15:0x416 %Long 0x0 &i=&i+1. ) ; Enable MPU and I and D caches &tmpReg=Data.Long(C15:0x1) &tmpReg=&tmpReg|0x1 ; enable MPU &tmpReg=(&tmpReg|((0x1<<2.))) ; enable D cache &tmpReg=(&tmpReg|((0x1<<12.))) ; enable I cache Data.Set C15:0x1 %Long &tmpReg RETURN ) SPICMD: ( PRIVATE &CTRLREG &cmdData &cmd &cmd_exec ENTRY &cmdData &CTRLREG=&CONFIG_OSPI_BASE+0x090 &cmd=&cmdData<<24. ; cmd &cmd_exec=0x1 ; cmd execution Data.Set A:&CTRLREG %LE %Long (&cmd|&cmd_exec) ; write cmd 0x66 SCREEN.WAIT 200.ms RETURN ) ; Detect the flash address mode by the internal flash register (0x0080_0003) ; CR2V : should come 0x08(3B) or 0x88(4B) SPI_4B_ADDRMODE_ENABLE: ( PRIVATE ®Data Data.Set VM:0x0--0xFF %Long 0x0 FLASHFILE.SPICMD 0x65 0x80 0x00 0x03 0x0 /READ 0x1 vm:0x0 ; 3Bytes Address mode ®Data=Data.Byte(vm:0x0) IF ®Data==0x08 ( ; it means the current flash is 3Byte address mode, so it should switch to the 4Byte address mode for the 4b flash driver file. FLASHFILE.SPICMD 0x65 0x80 0x00 0x03 0x00 /READ 0x1 vm:0x0 ; 3Bytes Address mode FLASHFILE.SPICMD 0x06 FLASHFILE.SPICMD 0x71 0x80 0x00 0x03 0x88 ; write 0x88 to CR2V , switch 3B->4B address mode SCREEN.WAIT 10.ms ) FLASHFILE.SPICMD 0x65 0x00 0x80 0x00 0x03 0x0 /READ 0x1 vm:0x0 ; 4Bytes Address mode ®Data=Data.Byte(vm:0x0) IF ®Data!=0x88 ( PRINT "We expect 0x08 latency(dummy) cycles but we got the dummy cycle 0x" %Hex ®Data ENDDO ) RETURN ) WATCHDOG_DISABLE: ( //Fill in if >3min burn time needed RETURN )