336 lines
11 KiB
Plaintext
336 lines
11 KiB
Plaintext
; --------------------------------------------------------------------------------
|
|
; @Title: SPI FLASH Program script for the S32R41
|
|
; @Description:
|
|
; The W25Q64(WINBOND) is connected to the QSPI0 controller
|
|
;
|
|
; SRAM: 0x34000000
|
|
; QuadSPI(controller) Base: 0x402D0000
|
|
; QuadSPI memory mapped ADDRESS: 0x00000000
|
|
;
|
|
; Prerequisites: Switch Settings
|
|
; Boot from QuadSPI using RCON configuration
|
|
; FUSE_SEL: 0
|
|
; BMODE1: 1
|
|
; BMODE2: 0
|
|
;
|
|
; @Keywords: ARM, Cortex-M7, QuadSPI
|
|
; @Author: STK, JIM
|
|
; @Board: X-S32R41-EVB
|
|
; @Chip: S32R41
|
|
; @Copyright: (C) 1989-2023 Lauterbach GmbH, licensed for use with TRACE32(R) only
|
|
; --------------------------------------------------------------------------------
|
|
; $Id: s32r41-cm7-qspi.cmm 12493 2023-09-14 06:43:33Z skrausse $
|
|
|
|
PRIVATE ¶meters
|
|
ENTRY %LINE ¶meters
|
|
|
|
PRIVATE ¶m_prepareonly
|
|
¶meters=STRing.UPpeR("¶meters")
|
|
¶m_prepareonly=(STRing.SCAN("¶meters","PREPAREONLY",0)!=-1)
|
|
|
|
LOCAL &QSPI_BASE
|
|
LOCAL &QSPI_Cntl_BASE
|
|
LOCAL &Flash_Mode
|
|
|
|
// for QSPI0
|
|
&QSPI_BASE=0x00000000 ;qspi0 memory mapped address, not controller address
|
|
&QSPI_Cntl_BASE=0x402D0000 ;qspi0 controller base address
|
|
&Flash_Mode=0 ; 0==spi, 1==opisdr, 2==opiddr
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Setup CPU
|
|
RESet
|
|
SYStem.CPU S32R41-M7
|
|
CORE.ASSIGN 1.
|
|
SYStem.Option.DUALPORT ON
|
|
SYStem.MemAccess DAP
|
|
SYStem.JtagClock 10MHz
|
|
ETM.OFF
|
|
ITM.OFF
|
|
STM.OFF
|
|
Trace.DISable
|
|
|
|
LOCAL &pdd
|
|
&pdd=OS.PresentDemoDirectory()
|
|
|
|
; Use an error handler for SYStem.Up
|
|
; In case the board flash is empty, then no core is booting and we have
|
|
; to wake up the core manually
|
|
ON ERROR GOSUB
|
|
(
|
|
ON ERROR DEFault
|
|
DO &pdd/hardware/s32r41/misc/s32r41_connect_m7_0.cmm
|
|
RETURN
|
|
)
|
|
SYStem.Up
|
|
ON ERROR inherit
|
|
|
|
; Disable all watchdogs
|
|
DO &pdd/hardware/s32r41/misc/s32r41_disable_watchdog.cmm
|
|
|
|
;Check if the QuadSPI AHB is already init
|
|
&IVT_header=Data.Long(A:0x0)
|
|
IF (&IVT_header==0x600001D1)
|
|
(
|
|
GOTO FLASH_DECLARATION
|
|
)
|
|
|
|
//* BEGIN QuadSPI AHB Init *//
|
|
; ------------------------------------------------------------------------------
|
|
; Flash Pin Mux Configuration
|
|
GOSUB QuadSPI_PinMux
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Flash Controller Power & Clock Enable
|
|
//CLK Enable
|
|
//MUX_5_DC_0: [31]:Enable, [23:16]: DIV 0x02
|
|
Data.Set A:0x400C8440 %Long 0x10000000 ;MUX_5_CSC
|
|
Data.Set A:0x400C8448 %Long 0x80030000 ;MUX_5_DC_0
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Flash Controller init, depends on the flash mode
|
|
GOSUB QuadSPI_Init_SPI
|
|
;GOSUB QuadSPI_Init_OPISDR
|
|
;GOSUB QuadSPI_Init_OPIDDR
|
|
|
|
//* END QuadSPI AHB Init *//
|
|
FLASH_DECLARATION:
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Flash declaration
|
|
Break.RESet
|
|
|
|
FLASH.RESet
|
|
FLASH.Create 0x00000000--0x00FFFFFF 0x10000 TARGET Byte
|
|
FLASH.TARGET 0x34000000 E:0x34002000 0x2000 ~~/demo/arm/flash/byte/snor3b_s32r41.bin /DualPort
|
|
|
|
; 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 *
|
|
;Data.LOAD.Binary * 0x0
|
|
FLASH.ReProgram.off
|
|
|
|
; Reset device
|
|
PRINT "Please power-cycle the board after flash program is complete"
|
|
)
|
|
|
|
ENDDO
|
|
|
|
READ_ID_TEST:
|
|
(
|
|
PRINT "READ_ID_TEST..."
|
|
&temp=Data.Long(A:&QSPI_Cntl_BASE)
|
|
Data.Set A:&QSPI_Cntl_BASE %Long (&temp|0x0c00) //clear Tx/Rx buffer
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x300 %LE %Long 0x5AF05AF0 ; LUTKEY
|
|
Data.Set A:&QSPI_Cntl_BASE+0x304 %LE %Long 0x2 ; LCKCR
|
|
|
|
//SEQID 5
|
|
Data.Set A:&QSPI_Cntl_BASE+0x374 %LE %Long 0x1c04049f ; LUT25. SEQID 5. (1SEQ==5ea LUTs)
|
|
Data.Set A:&QSPI_Cntl_BASE+0x378 %LE %Long 0x0
|
|
Data.Set A:&QSPI_Cntl_BASE+0x37C %LE %Long 0x0
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x100 %Long &QSPI_BASE ; SFAR , FLASH BASE ADDRESS
|
|
|
|
// assert Read id command
|
|
Data.Set A:&QSPI_Cntl_BASE+0x08 %Long (5.<<24.)
|
|
WAIT 100.ms
|
|
|
|
&temp=Data.Long(A:&QSPI_Cntl_BASE)
|
|
Data.Set ZSD:&QSPI_Cntl_BASE+0x000 %Long (&temp|0x0800) //clear Tx buffer
|
|
|
|
PRINT "1st 0x" Data.Long(A:&QSPI_Cntl_BASE+0x200)&0xFF " (Manufacturer)"
|
|
PRINT "2nd 0x" (Data.Long(A:&QSPI_Cntl_BASE+0x200)>>8.)&0xFF " (Device ID)"
|
|
PRINT "3rd 0x" (Data.Long(A:&QSPI_Cntl_BASE+0x200)>>16.)&0xFF
|
|
PRINT "4th 0x" (Data.Long(A:&QSPI_Cntl_BASE+0x200)>>24.)&0xFF
|
|
|
|
RETURN
|
|
)
|
|
|
|
WRITEBYTE_QPI:
|
|
(
|
|
ENTRY &wdata
|
|
|
|
&temp=Data.Long(A:&QSPI_Cntl_BASE)
|
|
Data.Set A:&QSPI_Cntl_BASE %Long (&temp|0x0c00) //clear Tx/Rx buffer
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x300 %LE %Long 0x5AF05AF0 ; LUTKEY
|
|
Data.Set A:&QSPI_Cntl_BASE+0x304 %LE %Long 0x2 ; LCKCR
|
|
|
|
//SEQID 5
|
|
Data.Set A:&QSPI_Cntl_BASE+0x374 %LE %Long 0x00000400|(0x2<<4)|&wdata ; LUT25. SEQID 5. (1SEQ==5ea LUTs), Send Four pads Command
|
|
Data.Set A:&QSPI_Cntl_BASE+0x378 %LE %Long 0x00000000
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x100 %Long &QSPI_BASE ; SFAR , FLASH BASE ADDRESS
|
|
|
|
// assert Read id command
|
|
Data.Set A:&QSPI_Cntl_BASE+0x08 %Long (5.<<24.)
|
|
WAIT 100.ms
|
|
|
|
&temp=Data.Long(A:&QSPI_Cntl_BASE)
|
|
Data.Set ZSD:&QSPI_Cntl_BASE+0x000 %Long (&temp|0x0800) //clear Tx buffer
|
|
|
|
RETURN
|
|
)
|
|
|
|
QuadSPI_PinMux:
|
|
(
|
|
//PIN Muxing
|
|
Data.Set A:0x401003D8 %LE %Long 0x283000 ;QSPI_DATA0 ,OBE,IBE, PUE,PUS
|
|
Data.Set A:0x401003DC %LE %Long 0x283000 ;QSPI_DATA1
|
|
Data.Set A:0x401003E0 %LE %Long 0x283000 ;QSPI_DATA2
|
|
Data.Set A:0x401003E4 %LE %Long 0x283000 ;QSPI_DATA3
|
|
Data.Set A:0x401003E8 %LE %Long 0x290000 ;QSPI_LPBK
|
|
Data.Set A:0x401003D0 %LE %Long 0x202000 ;QSPI_CK
|
|
Data.Set A:0x401003D4 %LE %Long 0x203000 ;QSPI_CS
|
|
|
|
RETURN
|
|
)
|
|
|
|
QuadSPI_Init_SPI:
|
|
(
|
|
;Internal DQS pad loopback, SPI x1 mode, AHB and IP modes configured.
|
|
Data.Set A:&QSPI_Cntl_BASE+0x000 %LE %Long 0x000F400F ; QuadSPI0->MCR = QuadSPI_MCR_MDIS_MASK; disable module
|
|
|
|
;Program LUT0 with READ (SPI 3B address mode)
|
|
Data.Set A:&QSPI_Cntl_BASE+0x310 %LE %Long 0x08180403 ; SEQID 0
|
|
Data.Set A:&QSPI_Cntl_BASE+0x314 %LE %Long 0x24001C08
|
|
Data.Set A:&QSPI_Cntl_BASE+0x318 %LE %Long 0x0
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x0C %LE %Long 0x00000303 ; QuadSPI0->FLSHCR = QuadSPI_FLSHCR_TCSH(3) | QuadSPI_FLSHCR_TCSS(3); Flash specific
|
|
; Data.Set A:&QSPI_Cntl_BASE+0x0C %LONG %LE 0x00010303 ; QuadSPI0->FLSHCR, THD[16], Serial flash data in hold time This is valid only in DDR mode
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x10 %LE %Long 0x0000200B ; QuadSPI0->BUF0CR = 32 bytes prefetch size, HSE master ID
|
|
Data.Set A:&QSPI_Cntl_BASE+0x1C %LE %Long 0x80002003 ; QuadSPI0->BUF0CR = 32 bytes prefetch size, all master
|
|
Data.Set A:&QSPI_Cntl_BASE+0x30 %LE %Long 0x00000400 ; QuadSPI0->BUF0IND = 1024 bytes buffer size
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x60 %LE %Long 0x41200507 ; QuadSPI0->DLLCRA; DDLEN=0,FREQEN=1,REFCNTR=1,DLLRES=2,SLV_FINE_OFFSET=0,SLV_DLY_OFFSET=0,SLV_DLY_COARSE=5,SLV_DLY_FINE=0,SLAVE_AUTO_UPDT=0,SLV_EN=1,SLV_DLL_BYPASS=1,SLV_UPD=1.
|
|
; Data.Set A:&QSPI_Cntl_BASE+0x60 %LE %Long 0x01200007 ; QuadSPI0->DLLCRA
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x100 %LE %Long &QSPI_BASE ; SFAR , FLASH BASE ADDRESS
|
|
Data.Set A:&QSPI_Cntl_BASE+0x104 %LE %Long 0x00000000 ; QuadSPI0->SFACR; PPWB = 0
|
|
Data.Set A:&QSPI_Cntl_BASE+0x108 %LE %Long 0x44000000 ; QuadSPI0->SMPR; DLLFSMPFA = 4, DLLFSMPFB = 4.
|
|
Data.Set A:&QSPI_Cntl_BASE+0x110 %LE %Long 0x00000100 ; QuadSPI0->RBCT; RXBRD = 1, AHB read mode.
|
|
|
|
; Setup chip select size
|
|
Data.Set A:&QSPI_Cntl_BASE+0x180 %LE %Long 0x10000000 ; QuadSPI0->SFA1AD; set top address to 256MB
|
|
Data.Set A:&QSPI_Cntl_BASE+0x184 %LE %Long 0x20000000 ; QuadSPI0->SFA2AD; set top address to 256MB
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x00 %LE %Long 0x000F0C0C ; QuadSPI0->MCR = QuadSPI_MCR_MDIS_MASK; enable module
|
|
|
|
&temp=Data.Long(A:&QSPI_Cntl_BASE)
|
|
Data.Set A:&QSPI_Cntl_BASE %Long (&temp|0x0c00) ;Clear Tx/Rx buffer
|
|
|
|
RETURN
|
|
)
|
|
|
|
QuadSPI_Init_OPISDR:
|
|
(
|
|
GOSUB QuadSPI_Init_SPI
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x000 %Long 0x010F404F ;disable MDIS (0x1<<14.) & reset
|
|
|
|
//LUT0
|
|
Data.Set A:&QSPI_Cntl_BASE+0x310 %Long 0x071307EC
|
|
Data.Set A:&QSPI_Cntl_BASE+0x314 %Long 0x0F140B20
|
|
Data.Set A:&QSPI_Cntl_BASE+0x318 %Long 0x00001F01
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x00C %Long 0x303 ;Flash memory configuration register
|
|
Data.Set A:&QSPI_Cntl_BASE+0x060 %Long 0x01200007 ;DLL A configuration register
|
|
Data.Set A:&QSPI_Cntl_BASE+0x108 %Long 0x00000020 ;sampling register
|
|
Data.Set A:&QSPI_Cntl_BASE+0x190 %Long 0xAA553443 ;data learn pattern register
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x000 %Long 0x010F004C ;Module Configuration Register
|
|
|
|
RETURN
|
|
)
|
|
|
|
QuadSPI_Init_OPIDDR:
|
|
(
|
|
|
|
GOSUB QuadSPI_Init_SPI
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x000 %LE %Long 0x030F40CF ;disable MDIS (0x1<<14.)
|
|
|
|
//LUT0
|
|
Data.Set A:&QSPI_Cntl_BASE+0x310 %LE %Long 0x471147EE
|
|
Data.Set A:&QSPI_Cntl_BASE+0x314 %LE %Long 0x0F142B20
|
|
Data.Set A:&QSPI_Cntl_BASE+0x318 %LE %Long 0x00003B80
|
|
Data.Set A:&QSPI_Cntl_BASE+0x31C %LE %Long 0x00000000
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x00C %LE %Long 0x10303 ;Flash memory configuration register
|
|
Data.Set A:&QSPI_Cntl_BASE+0x010 %LE %Long 0x0000000E ; QuadSPI0->BUF0CR = 32 bytes prefetch size, HSE master ID
|
|
Data.Set A:&QSPI_Cntl_BASE+0x01C %LE %Long 0x80080000 ; QuadSPI0->BUF0CR = 32 bytes prefetch size, all master
|
|
Data.Set A:&QSPI_Cntl_BASE+0x030 %LE %Long 0x00000000 ; QuadSPI0->BUF0IND = 1024 bytes buffer size
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x100 %LE %Long 0x0 ; SFAR , FLASH BASE ADDRESS
|
|
Data.Set A:&QSPI_Cntl_BASE+0x104 %LE %Long 0x20000 ; QuadSPI0->SFACR; SWAP n, n+1 order
|
|
Data.Set A:&QSPI_Cntl_BASE+0x108 %LE %Long 0x44000000 ; sampling register
|
|
Data.Set A:&QSPI_Cntl_BASE+0x110 %LE %Long 0x00000000 ; QuadSPI0->RBCT; RXBRD = 1, AHB read mode.
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x180 %LE %Long 0x80000000 ; QuadSPI0->SFA1AD; set top address to 256MB
|
|
Data.Set A:&QSPI_Cntl_BASE+0x184 %LE %Long 0x80000000 ; QuadSPI0->SFA2AD; set top address to 256MB
|
|
Data.Set A:&QSPI_Cntl_BASE+0x188 %LE %Long 0x80000000 ; QuadSPI0->SFB1AD; set top address to 256MB
|
|
Data.Set A:&QSPI_Cntl_BASE+0x18C %LE %Long 0x80000000 ; QuadSPI0->SFB2AD; set top address to 256MB
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x190 %LE %Long 0xAA553443 ;data learn pattern register
|
|
|
|
Data.Set A:&QSPI_Cntl_BASE+0x060 %LE %Long 0x4280000D ;QuadSPI0->DLLCRA DLL A configuration register
|
|
Data.Set A:&QSPI_Cntl_BASE+0x000 %LE %Long 0x030F00CC ;enable MDIS (0x1<<14.)
|
|
|
|
RETURN
|
|
)
|
|
|
|
Check_IVT_HEADER:
|
|
(
|
|
LOCAL &strMode
|
|
LOCAL &IVT_header
|
|
|
|
IF &Flash_Mode==0 //SPI mode
|
|
(
|
|
&strMode="SPI"
|
|
GOSUB QuadSPI_Init_SPI
|
|
)
|
|
ELSE IF &Flash_Mode==1 //OPI SDR mode
|
|
(
|
|
&strMode="OPI_SDR"
|
|
GOSUB QuadSPI_Init_OPISDR
|
|
)
|
|
ELSE IF &Flash_Mode==2 //OPI DDR mode
|
|
(
|
|
&strMode="OPI_DDR"
|
|
GOSUB QuadSPI_Init_OPIDDR
|
|
)
|
|
ELSE
|
|
(
|
|
PRINT "Fail NOT support spi mode..."
|
|
ENDDO
|
|
)
|
|
|
|
&IVT_header=Data.Long(A:0x0)
|
|
IF &IVT_header!=0x600001D1
|
|
(
|
|
IF &IVT_header!=0xFFFFFFFF
|
|
(
|
|
PRINTF "Fail IVT_header:0x%08X with the %s Mode" &IVT_header "&strMode"
|
|
&Flash_Mode=&Flash_Mode+1 ; check the next mode
|
|
GOSUB Check_IVT_HEADER &Flash_Mode
|
|
RETURN
|
|
)
|
|
PRINT "If the flash is EMPTY, then"
|
|
)
|
|
PRINTF "Pass IVT_header:0x%08X with the %s Mode" &IVT_header "&strMode"
|
|
RETURN
|
|
)
|