Files
Gen4_R-Car_Trace32/2_Trunk/demo/arm/flash/zynq7000-spi64-template.cmm
2025-10-14 09:52:32 +09:00

284 lines
8.3 KiB
Plaintext

; --------------------------------------------------------------------------------
; @Title: Xilinx ZYNQ-7000 generic QSPI Flash Programming Template
; @Description:
; This is a generic template scripts that tries to setup flash programming
; on a ZYNQ-7000 series SoC from Xilinx. The script tries to use an as failsave
; configuration as possible.
; Flash info: all flashes with 16MB adressing mode, not valid if 4byte address
; was set beforehand
;
; internal RAM: 0x00001000
; SPI Tx Register : 0xE000D080
; SPI Rx Register : 0xE000D020
; SPI CS Register : 0xE000D000
; Prerequisites:
; * ZYNQ BOOTMODE: CASCADED, JTAG BOOT, PLL ON
;
; @Keywords: Zynq Zynq7000 flash spi
; @Author: amerkle
; @Board: ZC702 Zedboard ZC706
; @Chip: Zynq-7000
; @Props: Template
; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only
; --------------------------------------------------------------------------------
; $Id: zynq7000-spi64-template.cmm 10516 2022-02-02 11:39:30Z bschroefel $
LOCAL &arg1
ENTRY &arg1
&arg1=STRing.UPpeR("&arg1") // for example "PREPAREONLY"
LOCAL &ctrl_reg
LOCAL &tx_reg
LOCAL &rx_reg
&ctrl_reg=0xE000D000
&tx_reg=0xE000D080 ;Register TXD1 for the 1-byte instruction
&rx_reg=0xE000D020
WinCLEAR
RESet
SYStem.RESet
SYStem.CPU ZYNQ-7000
SYStem.MemAccess DAP
; This selects the DAP for accessing the ARM cores
; (accessing the TAP of the FPGA logic requires different settings)
SYStem.CONFIG DAPIRPRE 6.
SYStem.CONFIG DAPIRPOST 0.
SYStem.CONFIG DAPDRPRE 1.
SYStem.CONFIG DAPDRPOST 0.
TrOnchip.Set.RESET OFF
TrOnchip.Set.UNDEF OFF
TrOnchip.Set.DABORT OFF
TrOnchip.Set.PABORT OFF
SYStem.JtagClock CTCK 10.0MHz
CORE.ASSIGN 1.
SYStem.Mode.Attach
IF STATE.RUN()
Break
DO ~~/demo/arm/hardware/zynq-7000/scripts/zynq7000_reset
; SLCR - UNLOCK WRITE
Data.Set ASD:0XF8000008 %Long 0x0000DF0D
; Assert Reset of Second core -> we are save to remap memories
Data.Set ASD:0xF8000244 %LONG 0x2
; MMU disable, Exception Vectors HIGH
Data.Set C15:0x1 %Long 0x18C52478
; OCM_CFG - OCM[0..2]=0x0--0x2ffff OCM[3]=0xffff0000
Data.Set AZSD:0xF8000910 %Long 0x18
; exception Vectors
Data.Assemble R:0xffff0000 b $+0
Data.Assemble , b $+0
Data.Assemble , b $+0
Data.Assemble , b $+0
Data.Assemble , b $+0
Data.Assemble , b $+0
Data.Assemble , b $+0
; set PC to a endless loop in OCM - prevent issues with XIP mode
Register.Set PC 0xffff0020
Data.Assemble R:0xffff0020 b $+0
GOSUB zynq7000_io_init ; qspi pin configuration
GOSUB zynq7000_clk_init ; cpu & qspi clock configuration
(
; SLCR - UNLOCK WRITE
Data.Set AD:0XF8000008 %Long 0x0000DF0D
; LQSPI_CLK_CTRL - Divisor=0, use ARM-PLL, enable
Data.Set AD:0xF800014C %Long 0x21
; APER_CLK_CTRL set LQSPI_CPU
Data.Set AD:0xF800012C %LE %Long Data.Long(AD:0xF800012C)|0x800000 ; Enable Clock of QSPI
; toggle reset of QSPI controller
Data.Set AD:0xF8000230 %LE %Long 0x3 ; assert RESET
WAIT 100.ms
Data.Set AD:0xF8000230 %LE %Long 0x0 ; deassert RESET
WAIT 100.ms
; initialize QSPI controller
Data.Set AD:0xE000D014 %Long 0x0 ; Disable QSPI
Data.Set AD:0xE000D000 %Long 0x80020021 ; Configuration SPI, CS0, 8bits, Master Mode
Data.Set AD:0xE000D000 %Long Data.Long(AZSD:0xE000D000)|(0x1<<14.) ; manual CS mode
Data.Set AD:0xE000D008 %Long 0xFF ; Disable SPI Interupt
Data.Set AD:0xE000D0A0 %Long 0x00000003 ; disable LQ_MODE, enable TWO_MEM & SEP_BUS for dual spi devices
Data.Set AD:0xE000D028 %Long 0x1
Data.Set AD:0xE000D02C %Long 0x1
Data.Set AD:0xE000D038 %Long 0x33
Data.Set AD:0xE000D014 %Long 0x1 ; Enable QSPI
)
//FLASH READ ID TEST
AREA.view
GOSUB READ_ID_TEST
DIALOG.YESNO "Is the flash ID correctly shown in the AREA window?"
LOCAL &result
ENTRY &result
IF !&result
(
PRINT "Please check your register configuration to enable your flash controller"
ENDDO
)
//RAM TEST for algorithm file
Data.Test 0x00001000++0x7FFF /Prime
IF FOUND()
(
PRINT "RAM is NOT initialized around 0x" ADDRESS.OFFSET(TRACK.ADDRESS())
ENDDO
)
FLASHFILE.RESet
FLASHFILE.CONFIG 0xE000D080 0xE000D020 0xE000D000
FLASHFILE.TARGET 0x00001000++0x3FFF 0x00005000++0x21FF ~~/demo/arm/flash/byte/spi64_zynq7xxx.bin /KEEP ; internal RAM
FLASHFILE.GETID
//End of the test prepareonly
IF "&arg1"=="PREPAREONLY"
ENDDO
//Dump window for Serial FLASH
FLASHFILE.DUMP 0x0 ; Also can read the spi flash data at 0xFC00_0000 after LQSPI_CFG.LQ_MODE is enabled
//Unlock Serial FLASH
;FLASHFILE.UNLOCK 0x00--0xFFFFF
//Write Serial FLASH
;FLASHFILE.ERASE 0x00--0xFFFFF
//Write Serial FLASH
;FLASHFILE.LOAD * 0x00
;FLASHFILE.LOAD * 0x00 /ComPare
ENDDO
zynq7000_io_init:
(
; SLCR - UNLOCK WRITE
Data.Set AD:0XF8000008 %Long 0x0000DF0D
; MIO_PIN_[0..31] - TriState
Data.Set AD:0xF8000700++0x7f %Long 0x1201
PRIVATE &LVCMOS
; select either LVCMOS18=1/LVCMOS25=2/LVCMOS33=3
&LVCMOS=1.
; MIO1 - QSPI0 CS0
Data.Set AD:0xF8000704 %Long 0x0002|(&LVCMOS<<9.)
; MIO2 - QSPI0 IO0
Data.Set AD:0xF8000708 %Long 0x1002|(&LVCMOS<<9.)
; MIO3 - QSPI0 IO1
Data.Set AD:0xF800070c %Long 0x0002|(&LVCMOS<<9.)
; MIO5 - GPIO5
Data.Set AD:0xF8000714 %Long 0x0000|(&LVCMOS<<9.)
; MIO6 - QSPI0 CLK
Data.Set AD:0xF8000718 %Long 0x0002|(&LVCMOS<<9.)
; GPIO_RST_CTRL - Toggle Reset of GPIO
Data.Set AD:0xF800022C %Long 0x1
WAIT 1.ms
Data.Set AD:0xF800022C %Long 0x0
; ZC702 speciality
; use MIO5 as GPIO drive it high as MIO5(=DQ3) has RESET/HOLD as secondary function
; BANK0.BYPM clear MIO5
Data.Set AD:0xE000A200 %Long Data.Long(AD:0xE000A200)&~(1.<<5.)
; BANK0.DIRM set MIO5
Data.Set AD:0xE000A204 %Long Data.Long(AD:0xE000A204)|(1.<<5.)
; BANK0.OEN set MIO5
Data.Set AD:0xE000A208 %Long Data.Long(AD:0xE000A208)|(1.<<5.)
; set MIO5 high
Data.Set AD:0xE000A040 %Long Data.Long(AD:0xE000A040)|(1.<<5.)
RETURN
)
zynq7000_clk_init:
(
; SLCR - UNLOCK WRITE
Data.Set AD:0XF8000008 %Long 0x0000DF0D
; clock setup
; BYPASS all PLLs - we are running on Oscillator now
Data.Set AD:0xF8000100 %Long 0x10
Data.Set AD:0xF8000104 %Long 0x10
Data.Set AD:0xF8000108 %Long 0x10
; ARM_CLK_CTRL - DIVISOR 0
Data.Set AD:0xF8000120 %Long 0x1F000000
IF FALSE()
(
; optional - start the PLL again - e.g. slow as possible
; ARM_PLL_CTRL - set F_DIV=13.
Data.Set AD:0xF8000100 %Long Data.Long(AD:0xF8000100)|(13.<<12.)
; ARM_PLL_CFG for Divisor 0xd - PLL_CP=2 PLL_RES=6 LOCK_CNT=750
Data.Set AD:0xF8000110 %Long (750.<<12.)|(2.<<8.)|(6.<<4.)
; ARM_PLL_CTRL - toggle reset
Data.Set AD:0xF8000100 %Long Data.Long(AD:0xF8000100)|0x1
WAIT 10.ms
Data.Set AD:0xF8000100 %Long Data.Long(AD:0xF8000100)&~0x1
; PLL_STATUS wait for ARM_PLL_STABLE
WAIT (Data.Long(AD:0xF800010C)&0x4)!=0
; ARM_PLL_CTRL - clear bypass
Data.Set AD:0xF8000100 %Long Data.Long(AD:0xF8000100)&~0x10
)
RETURN
)
READ_ID_TEST:
(
LOCAL &data
&data=Data.Long(AD:&ctrl_reg)
PRINT "ctrl_reg : &data "
Data.Set AD:&ctrl_reg %Long (&data&(~(0x1<<10.))) ; cs low
Data.Set &tx_reg %Byte 0x9F
&data=Data.Long(AD:&ctrl_reg)
Data.Set AD:&ctrl_reg %Long (&data|(0x1<<16.)) ; start cmd
WAIT 1.ms
PRINT " 0x" FORMAT.HEX(2,(Data.Long(AD:&rx_reg)>>24.)&0xFF)
Data.Set &tx_reg %Byte 0x00
&data=Data.Long(AD:&ctrl_reg)
Data.Set AD:&ctrl_reg %Long (&data|(0x1<<16.)) ; start cmd
WAIT 1.ms
PRINT "1st : 0x" FORMAT.HEX(2,(Data.Long(AD:&rx_reg)>>24.)&0xFF)
Data.Set &tx_reg %Byte 0x00
&data=Data.Long(AD:&ctrl_reg)
Data.Set AD:&ctrl_reg %Long (&data|(0x1<<16.)) ; start cmd
WAIT 1.ms
PRINT "2nd : 0x" FORMAT.HEX(2,(Data.Long(AD:&rx_reg)>>24.)&0xFF)
Data.Set &tx_reg %Byte 0x00
&data=Data.Long(AD:&ctrl_reg)
Data.Set AD:&ctrl_reg %Long (&data|(0x1<<16.)) ; start cmd
WAIT 1.ms
PRINT "3rd : 0x" FORMAT.HEX(2,(Data.Long(AD:&rx_reg)>>24.)&0xFF)
Data.Set &tx_reg %Byte 0x00
&data=Data.Long(AD:&ctrl_reg)
Data.Set AD:&ctrl_reg %Long (&data|(0x1<<16.)) ; start cmd
WAIT 1.ms
PRINT "4th : 0x" FORMAT.HEX(2,(Data.Long(AD:&rx_reg)>>24.)&0xFF)
Data.Set &tx_reg %Byte 0x00
&data=Data.Long(AD:&ctrl_reg)
Data.Set AD:&ctrl_reg %Long (&data|(0x1<<16.)) ; start cmd
WAIT 1.ms
PRINT "5th : 0x" FORMAT.HEX(2,(Data.Long(AD:&rx_reg)>>24.)&0xFF)
Data.Set AD:&ctrl_reg %Long (&data|(0x1<<10.)) ; cs high
RETURN
)