Files
Gen4_R-Car_Trace32/2_Trunk/demo/arm/flash/rcarv3h-cr7-emmc.cmm
2025-10-14 09:52:32 +09:00

331 lines
9.9 KiB
Plaintext

; --------------------------------------------------------------------------------
; @Title: eMMC FLASH Program script by the core for the RCARV3H Evaluation Board
; @Description:
; eMMC FLASH KLMBG4GESD
; The eMMC is connected to the SDHI Controller
;
; Prerequisites:
; * Connect Debug Cable/Combiprobe to CN29 JTAG
; * set CortexR7 as boot core
; MD[7..6] = 0y00 -> SW3[1..2] = 0y00
; * activate Coresight on JTAG1 (CN29)
; MD10 = 0 -> SW20[3] = 1
; MD[21..20] = 0y10 -> SW20[4..5] = 0y01
;
; SRAM: 0xE6328000
; SDHI(MMC) controller Base: 0xEE140000
;
; @Keywords: ARM, Cortex-R7, RCarV3H
; @Author: jjeong
; @Board: R-CarV3H System Evaluation Board "Condor", V3H Starter Kit
; @Chip: RCARV3H-CR7
; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only
; --------------------------------------------------------------------------------
; $Id: rcarv3h-cr7-emmc.cmm 12742 2023-11-17 08:05:09Z mschaeffner $
LOCAL &arg1
ENTRY &arg1
&arg1=STRing.UPpeR("&arg1") // for example "PREPAREONLY"
&MMC_BASE=0xEE140000
; ------------------------------------------------------------------------------
; Setup CPU
RESet
SYStem.RESet
SYStem.CPU R8A77960-CR7
SYStem.MemAccess DAP
SYStem.JtagClock CTCK 10MHz
Trace.DISable
SYStem.Up
; --------------------------------------------------------------------------------
; enable the SRAM & MPU - alternative execute BootROM e.g. Go/Wait/Break
IF TRUE()
(
; enable SRAM
Data.Set AD:0xE67F0018 %LE %Long 0x1
; disable MPU
Data.Set C15:0x1 %Long 0xC50078
; disable all regions
PRIVATE &i
&i=0
RePeaT 16.
(
; set MRNR
Data.Set C15:0x26 %Long &i
; clear RSER
Data.Set C15:0x216 %Long 0x0
&i=&i+1.
)
; setup regions for simplicity only region 0&1
; region 0: 0x00000000--0xffffffff - Shareable Device - all permissions
Data.Set C15:0x26 %Long 0x0
Data.Set C15:0x16 %Long 0x0
Data.Set C15:0x216 %Long 0x3f
Data.Set C15:0x416 %Long 0x305
; region 1: 0xe6300000--0xe637ffff - non-cacheable - all permissions
Data.Set C15:0x26 %Long 0x1
Data.Set C15:0x16 %Long 0xe6300000
Data.Set C15:0x216 %Long 0x25
Data.Set C15:0x416 %Long 0x30c
; enable MPU
Data.Set C15:0x1 %Long Data.Long(C15:0x1)|0x1
)
ELSE
(
Go.direct 0x268
WAIT !STATE.RUN() 0.2s
IF STATE.RUN()
Break.direct
)
; ------------------------------------------------------------------------------
; Flash Controller Power & Clock Enable
; ------------------------------------------------------------------------------
; Flash Pin Mux Configuration
GOSUB PIN_MUX
GOSUB POWERON_MMC0
GOSUB CLKINIT_MMC0
GOSUB INIT_MMC0
GOSUB WDOG_DISABLE
GOSUB READ_ID_TEST
LOCAL &pdd
&pdd=OS.PresentDemoDirectory()
Break.RESet
FLASHFILE.RESet
//FLASHFILE.CONFIG <MMC Base Address>
FLASHFILE.CONFIG &MMC_BASE
//FLASHFILE.TARGET <code range> <data range> <Algorithm file>
FLASHFILE.TARGET 0xE6328000++0x1FFF EA:0xE632A000++0x43FF &pdd/flash/byte/emmc_shsdhi.bin /KEEP /STACKSIZE 0x200 /DUALPORT
GOSUB CLK_DOWN_400KHz
FLASHFILE.GETID
GOSUB CLK_UP_20MHz
//Get EXTended CSD registers
FLASHFILE.GETEXTCSD
//End of the test prepareonly
IF "&arg1"=="PREPAREONLY"
ENDDO
//When you access to the other partition on the flash
; FLASHFILE.SETEXTCSD 179. 0x00 ; access: partition null, no boot, access: no boot partition
; FLASHFILE.SETEXTCSD 179. 0x48 ; access: partition null
; FLASHFILE.SETEXTCSD 179. 0x49 ; access: partition boot 1
; FLASHFILE.SETEXTCSD 179. 0x4A ; access: partition boot 2
FLASHFILE.DUMP 0x0 ; Read eMMC
;FLASHFILE.ERASE 0x0--0xFFFFF ; Erase eMMC
;FLASHFILE.LOAD * 0x0 ; Write eMMC
ENDDO
POWERON_MMC0:
//poweronmmc0, Bit12,13,14 clear
&value=0xFFFF8FDF
Data.Set A:0xE6150900 %Long ~(&value)
Data.Set A:0xE615013C %Long &value
PRINT "MSTPSR3: 0x" Data.Long(A:0xE6150048) ; //bit 12,13,14 have to be cleared.
RETURN
//InitMmc0PinFunction
PIN_MUX:
//eMMC pin mapping
//VI1_DATA3 : MMC_CMD
//VI1_DATA4 : MMC_DAT0
//VI1_DATA8 : MMC_CLK
&value=0x44440000
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
Data.Set A:0xE6060214 %Long &value ;PFC_IPSR5 [31:16]
&value=0x44444444
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
Data.Set A:0xE6060218 %Long &value ;PFC_IPSR6 [31:0]
&value=0x00000004
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
Data.Set A:0xE606021C %Long &value ;PFC_IPSR7 [3:0]
&value=0x01FFFF
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
Data.Set A:0xE606010C %Long &value ;PFC_GPSR3
&value=0x00000077
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
Data.Set A:0xE606031C %Long &value ;PFC_DRVCTRL7
&value=0x77777777
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
Data.Set A:0xE6060320 %Long &value ;PFC_DRVCTRL8
&value=0x77700000
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
Data.Set A:0xE6060324 %Long &value ;PFC_DRVCTRL9
//Function: Each bit in POCCTRL0 must be set according to IO voltage level that is supplied to the pin.
//0: 1.8v 1: 3.3v
&value=0xFF0000FF
Data.Set A:0xE6060000 %Long ~(&value)
Data.Set A:0xE6060384 %Long &value ;PFC_POCCTRL1
&value=0x0
Data.Set A:0xE6060000 %Long ~(&value)
Data.Set A:0xE60603C0 %Long &value ;TDSELCTRL0
RETURN
CLK_UP_20MHz:
PER.Set.simple A:&MMC_BASE+0x0090 %Long 0x0
//*((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x101; //1/4 ; 20Mhz
PER.Set.simple A:&MMC_BASE+0x0090 %Quad 0x101
//*((volatile uint32_t*)(MMC_CH0_SCC_DTCNTL)) = 0x00080000; // SCC_DTCNTL.TAPEN=0
PER.Set.simple A:&MMC_BASE+0x1000 %Long 0x00080000
//*((volatile uint32_t*)(MMC_CH0_SCC_TAPSET)) = 2; // SCC_TAPSET
PER.Set.simple A:&MMC_BASE+0x1008 %Long 0x2
//*((volatile uint32_t*)(MMC_CH0_SCC_CKSEL)) = 0x00000000; // SCC_CKSEL=0
PER.Set.simple A:&MMC_BASE+0x1018 %Long 0x0
RETURN
CLK_DOWN_400KHz:
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x00000000; // Automatic Control=Disable, Clock Output=Disable
PER.Set.simple A:&MMC_BASE+0x0090 %Long 0x0
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x180; //1/512 ; 400KHz
PER.Set.simple A:&MMC_BASE+0x0090 %Quad 0x120
//*((volatile uint32_t*)(MMC_CH0_SCC_DTCNTL)) = 0x00080000; // SCC_DTCNTL.TAPEN=0
PER.Set.simple A:&MMC_BASE+0x1000 %Long 0x00080000
//*((volatile uint32_t*)(MMC_CH0_SCC_TAPSET)) = 2; // SCC_TAPSET
PER.Set.simple A:&MMC_BASE+0x1008 %Long 0x2
//*((volatile uint32_t*)(MMC_CH0_SCC_CKSEL)) = 0x00000000; // SCC_CKSEL=0
PER.Set.simple A:&MMC_BASE+0x1018 %Long 0x0
RETURN
CLKINIT_MMC0:
//clock init
&value=0x1|(0x2<<2)
Data.Set A:0xE6150900 %Long ~(&value)
Data.Set A:0xE6150074 %Long &value ;SD0 ;for rcharv3h
Data.Set A:0xE6150078 %Long &value ;SD1
Data.Set A:0xE6150268 %Long &value ;SD2
Data.Set A:0xE615026C %Long &value ;SD3
RETURN
INIT_MMC0:
//SW Reset for the MMC memory
Data.Set A:&MMC_BASE+0x380 %LE %Quad 0x0
WAIT 100.ms
Data.Set A:&MMC_BASE+0x380 %LE %Quad 0x7
// *((volatile uint32_t*)MMC_CH0_HOST_MODE) = 0x00000000; // SD_BUF access width = 64-bit
PER.Set.simple A:&MMC_BASE+0x0390 %Long 0x0
// *((volatile uint32_t*)MMC_CH0_SD_OPTION) = 0x0000C0EE; // Bus width = 1bit, timeout=MAX
PER.Set.simple A:&MMC_BASE+0x00A0 %Long 0xc0EE
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x00000000; // Automatic Control=Disable, Clock Output=Disable
PER.Set.simple A:&MMC_BASE+0x0090 %Long 0x0
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x180; //1/512 ; 400KHz
PER.Set.simple A:&MMC_BASE+0x0090 %Quad 0x180
//*((volatile uint32_t*)(MMC_CH0_SCC_DTCNTL)) = 0x00080000; // SCC_DTCNTL.TAPEN=0
PER.Set.simple A:&MMC_BASE+0x1000 %Long 0x00080000
//*((volatile uint32_t*)(MMC_CH0_SCC_TAPSET)) = 2; // SCC_TAPSET
PER.Set.simple A:&MMC_BASE+0x1008 %Long 0x2
//*((volatile uint32_t*)(MMC_CH0_SCC_CKSEL)) = 0x00000000; // SCC_CKSEL=0
PER.Set.simple A:&MMC_BASE+0x1018 %Long 0x0
// *((volatile uint32_t*)MMC_CH0_SD_INFO1_MASK) = 0x0001031D; // all mask (0x0000FFFE in HWM)
PER.Set.simple A:&MMC_BASE+0x0080 %Quad 0x1031D
// *((volatile uint32_t*)MMC_CH0_SD_INFO2_MASK) = 0x00008B7F; // all mask (0x00007F80 in HWM)
PER.Set.simple A:&MMC_BASE+0x0088 %Quad 0x8B7F
RETURN
READ_ID_TEST:
//CMD0
RePeaT 2.
(
//MMC_CH0_SD_INFO1
PER.Set.simple A:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
// SendMmc0Cmd0(0x00000000);
PER.Set.simple A:&MMC_BASE+0x0010 %Long 0x0 ;arg
PER.Set.simple A:&MMC_BASE+0x0000 %Quad 0x0 ;cmd
WAIT 100.ms
)
//CMD1
RePeaT 10.
(
//SendMmc0Command(MMC_CMD1,ocr);
//MMC_CH0_SD_INFO1
PER.Set.simple A:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
PER.Set.simple A:&MMC_BASE+0x0010 %Long 0x40FF8080 ;arg
PER.Set.simple A:&MMC_BASE+0x0000 %Quad 0x701 ;cmd
WAIT 100.ms
&resp=Data.Long(A:&MMC_BASE+0x0030)
//print "CMD1 resp: 0x" &resp
IF (&resp&0x80000000)==0x80000000
(
GOTO jump_cmd2
)
)
PRINT "CMD1 fail"
END
jump_cmd2:
//CMD2
PER.Set.simple A:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
PER.Set.simple A:&MMC_BASE+0x0010 %Long 0x0 ;arg
PER.Set.simple A:&MMC_BASE+0x0000 %Quad 0x2 ;cmd
WAIT 10.ms
//CMD3
PER.Set.simple A:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
PER.Set.simple A:&MMC_BASE+0x0010 %Long 0x10000 ;arg
PER.Set.simple A:&MMC_BASE+0x0000 %Quad 0x3 ;cmd
WAIT 10.ms
//CMD10
PER.Set.simple A:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
PER.Set.simple A:&MMC_BASE+0x0010 %Long 0x10000 ;arg
PER.Set.simple A:&MMC_BASE+0x0000 %Quad 0x0000000A ;cmd
WAIT 10.ms
//Response2
PRINT "CID register"
PRINT "[127:104] 0x" Data.Long(A:&MMC_BASE+0x0060)
PRINT "[103:72] 0x" Data.Long(A:&MMC_BASE+0x0050)
PRINT "[71:40] 0x" Data.Long(A:&MMC_BASE+0x0040)
PRINT "[39:8] 0x" Data.Long(A:&MMC_BASE+0x0030)
RETURN
WDOG_DISABLE:
//RCLK Watchdog Timer disable
Data.Set ZAXI:0xE6020004 %Long 0xA5A5A500|0x00 ; Write 0 to the RCLK Watchdog Timer Control Register A
Data.Set ZAXI:0xE6020008 %Long 0xA5A5A500|0x00 ; Write 0 to the RCLK Watchdog Timer Control Register B
//System Watchdog Timer disable
Data.Set ZAXI:0xE6030004 %Long 0xA5A5A500|0x00 ; Write 0 to the System Watchdog Timer Control Register A
Data.Set ZAXI:0xE6030008 %Long 0xA5A5A500|0x00 ; Write 0 to the System Watchdog Timer Control Register B
RETURN