; -------------------------------------------------------------------------------- ; @Title: eMMC/SD Program script for MIMXRT1170-CM33 ; @Description: ; The external SD card socket (J15) is connected to USDHC1. ; ; SRAM: 0x20010000 ; USDHC(controller) Base: 0x0x40418000 (MicroSD) ; ; Prerequisites: ; To enable SDHC: default ; ; @Keywords: ARM, Cortex-M33, eMMC, SD ; @Author: JIM ; @Board: IMXRT1170-EVK ; @Chip: IMXRT1176-CM7 ; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only ; -------------------------------------------------------------------------------- ; $Id: imxrt1170-cm7-emmcsd.cmm 12996 2024-01-29 03:23:55Z jjeong $ PRIVATE &arg1 ENTRY &arg1 &arg1=STRing.UPpeR("&arg1") // for example "PREPAREONLY" LOCAL &pdd &uSDHC &MMC_BASE &SDCARD &uSDHC=1. ; SDHC1==MicroSD &SDCARD=TRUE() ; SDCARD(1) or EMMC(0) ; initialize and start the debugger ; ------------------------------------------------------------------------------ ; Setup CPU SYStem.Down IF SYStem.Mode()<5 ( RESet SYStem.RESet SYStem.CPU IMXRT1176-CM7 SYStem.CONFIG.DEBUGPORTTYPE SWD SYStem.Option.DUALPORT ON SYStem.MemAccess DAP SYStem.JtagClock 10MHz Trace.DISable SYStem.Up ) ; -------------------------------------------------------------------------------- ; Init ECC SRAM Data.Set 0x20000000++0x1FFFF %Long 0x0 ; -------------------------------------------------------------------------------- ; Init SDHC Clock & Mux IF &uSDHC==1. ( ; usdhc1_clk_root -- BUS_CLK_ROOT -- CLOCK_ROOT58 -- LPCG117 &CLK_ROOT_BASE = 0x40CC0000 &MMC_BASE=0x40418000 ;SDHC1 Data.Set A:&CLK_ROOT_BASE+0x1D00 %LE %Long 0x0 ;Clock Root Control Register (CLOCK_ROOT41_CONTROL), 58.x0x80h == 0x1D00 Data.Set A:&CLK_ROOT_BASE+0x6EA0 %LE %Long 0x1 ;LPCG direct control (LPCG105_DIRECT), LPCGa_DIRECT == 6000h + (a × 20h) GOSUB IOMUX_uSDHC1 ) ELSE IF &uSDHC==2. ( ; usdhc1_clk_root -- BUS_CLK_ROOT -- CLOCK_ROOT59 -- LPCG118 &MMC_BASE=0x4041C000 ;SDHC2 Data.Set A:&CLK_ROOT_BASE+0x1D80 %LE %Long 0x0 ;Clock Root Control Register (CLOCK_ROOT41_CONTROL), 59.x0x80h == 0x1D80 Data.Set A:&CLK_ROOT_BASE+0x6EC0 %LE %Long 0x1 ;LPCG direct control (LPCG105_DIRECT), LPCGa_DIRECT == 6000h + (a × 20h) GOSUB IOMUX_uSDHC2 ) ; -------------------------------------------------------------------------------- ; Init SDHC Controller GOSUB CONFIG_uSDHC GOSUB READ_ID_TEST ; ------------------------------------------------------------------------------ ; Flash declaration &pdd=OS.PresentDemoDirectory() FLASHFILE.RESet ;FLASHFILE.CONFIG <0x0> <0x0> FLASHFILE.CONFIG &MMC_BASE 0x0 0x0 ;FLASHFILE.TARGET <> <> <> IF &SDCARD ( FLASHFILE.TARGET 0x20001000++0x1fff 0x20003000++0x27ff &pdd/flash/byte/emmcsd_imx8.bin /KEEP /STACKSIZE 0x200 Data.Set A:&MMC_BASE+0x2C %LE %Long 0x008E1018 ; around 400khz FLASHFILE.GETID Data.Set A:&MMC_BASE+0x2C %LE %Long 0x008E0008 ; 24MHz clk ) ELSE ( FLASHFILE.TARGET 0x20001000++0x1fff 0x20003000++0x27ff &pdd/flash/byte/emmc_imx8.bin /KEEP /STACKSIZE 0x200 Data.Set A:&MMC_BASE+0x2C %LE %Long 0x008E1018 ; around 400khz FLASHFILE.GETID Data.Set A:&MMC_BASE+0x2C %LE %Long 0x008E0008 ; 24MHz clk //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/SD ;FLASHFILE.ERASE 0x0--0xFFFFF ; Erase eMMC/SD ;FLASHFILE.LOAD * 0x0 ; Write eMMC/SD ENDDO CONFIG_uSDHC: ( ; -------------------------------------------------------------------------------- ; Config SDHC ; -------------------------------------------------------------------------------- Data.Set A:&MMC_BASE+0x04 %LE %Long 0x00010200 ; blk size,cnt Data.Set A:&MMC_BASE+0x28 %LE %Long 0x08800020 ; bus width, endian Data.Set A:&MMC_BASE+0x2C %LE %Long 0x008E1018 ; Data.Set A:&MMC_BASE+0x34 %LE %Long 0x007F0037 ; BRR,BWR, TCI, CCI interrupt enable Data.Set A:&MMC_BASE+0x38 %LE %Long 0x007F0037 ; BRR,BWR, TCI, CCI interrupt enable Data.Set A:&MMC_BASE+0x44 %LE %Long 0x00100010 ; read/write fifo threshold level 64bytes RETURN ) IOMUX_uSDHC1: ( ; -------------------------------------------------------------------------------- ; IO Mux for SDHC1 ; -------------------------------------------------------------------------------- Data.Set A:0x400E8000+0x19C %LE %Long 0x0 ;USDHC1_CMD, SW_MUX_CTL_PAD_GPIO_SD_B1_00 Data.Set A:0x400E8000+0x1A0 %LE %Long 0x0 ;USDHC1_CLK, SW_MUX_CTL_PAD_GPIO_SD_B1_01 Data.Set A:0x400E8000+0x1A4 %LE %Long 0x0 ;USDHC1_DAT0, SW_MUX_CTL_PAD_GPIO_SD_B1_02 Data.Set A:0x400E8000+0x1A8 %LE %Long 0x0 ;USDHC1_DAT1, SW_MUX_CTL_PAD_GPIO_SD_B1_03 Data.Set A:0x400E8000+0x1AC %LE %Long 0x0 ;USDHC1_DAT2, SW_MUX_CTL_PAD_GPIO_SD_B1_04 Data.Set A:0x400E8000+0x1B0 %LE %Long 0x0 ;USDHC1_DAT3, SW_MUX_CTL_PAD_GPIO_SD_B1_05 //[3:2]:01 pull up Data.Set A:0x400E8000+0x3E0 %LE %Long 0x4 ;CMD Data.Set A:0x400E8000+0x3E4 %LE %Long 0x4 ;CLK, +pull up, [3:2]=PU Data.Set A:0x400E8000+0x3E8 %LE %Long 0x4 ;DAT0 Data.Set A:0x400E8000+0x3EC %LE %Long 0x4 ;DAT1 Data.Set A:0x400E8000+0x3F0 %LE %Long 0x4 ;DAT2 Data.Set A:0x400E8000+0x3F4 %LE %Long 0x4 ;DAT3 RETURN ) IOMUX_uSDHC2: ( ; -------------------------------------------------------------------------------- ; IO Mux for SDHC2 ; -------------------------------------------------------------------------------- ; RETURN ) IOMUX_uSDHC3: ( ; -------------------------------------------------------------------------------- ; IO Mux for SDHC3 ; -------------------------------------------------------------------------------- ; RETURN ) READ_ID_TEST: ( LOCAL &cardaddress IF !&SDCARD &OCR=0x40FF8080 ; init with low voltage power 1.7~1.95v, ex. eMMC ELSE &OCR=0x40FF8000 ; init with defualt voltage power 2.7~3.6v, ex. SD //CMD0 RePeaT 2. ( Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long 0x0 ;arg Data.Set &MMC_BASE+0xc %Long 0x0 ;cmd WAIT 10.ms ) IF !&SDCARD ( //CMD1 RePeaT 10. ( Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long &OCR ;arg Data.Set &MMC_BASE+0xc %Long 0x01020000 ;cmd1 &resp=Data.Long(A:(&MMC_BASE+0x10)) WAIT 100.ms //print "CMD1 resp: 0x" &resp IF (&resp&0x80000000)==0x80000000 ( GOTO jump_cmd2 ) ) PRINT "CMD1 fail" END ) ELSE ( //CMD8, is madatory to intialize High Capacity SD Memory Card RePeaT 2. ( Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long 0x1AA ;arg Data.Set &MMC_BASE+0xc %Long 0x08020000 ;cmd WAIT 10.ms &status=Data.Long(A:&MMC_BASE+0x30) IF (&status&0x30000)==0x0 ( PRINT "passed CMD8(voltage check)" GOTO jump_cmd55 ) ELSE ( //CMD0 Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long 0x0 ;arg Data.Set &MMC_BASE+0xc %Long 0x0 ;cmd WAIT 10.ms ) ) jump_cmd55: //CMD55 RePeaT 10. ( Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long 0x0 ;arg Data.Set &MMC_BASE+0xc %Long 0x37020000 ;cmd55, resp1 WAIT 100.ms //ACMD41 Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long &OCR ;arg Data.Set &MMC_BASE+0xc %Long 0x29020000 ;cmd41, resp1 WAIT 100.ms &resp=Data.Long(A:(&MMC_BASE+0x10)) //print "CMD1 resp: 0x" &resp IF (&resp&0x80000000)==0x80000000 ( GOTO jump_cmd2 ) ) ) jump_cmd2: //CMD2 Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long 0x0 ;arg Data.Set &MMC_BASE+0xc %Long 0x02010000 ;cmd2 WAIT 10.ms //CMD3 Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long 0x00010000 ; arg, MMC RCA is (0x0001<<16.) Data.Set &MMC_BASE+0xc %Long 0x03020000 ;cmd3 WAIT 10.ms IF !&SDCARD ( &cardaddress=0x00010000 ; arg, MMC RCA is (0x0001<<16.) ) ELSE ( &cardaddress=Data.Long(A:(&MMC_BASE+0x10)) &cardaddress=&cardaddress&0xFFFF0000 ) //CMD10 Data.Set &MMC_BASE+0x30 %Long 0xFFFFFFFF ;clear status Data.Set &MMC_BASE+0x8 %Long &cardaddress ; arg, card address Data.Set &MMC_BASE+0xc %Long 0x0A010000 ;cmd10 WAIT 10.ms //Response2 PRINT "CID register" PRINT "[127:104] 0x" Data.Long(A:(&MMC_BASE+0x1c)) PRINT "[103:72] 0x" Data.Long(A:(&MMC_BASE+0x18)) PRINT "[71:40] 0x" Data.Long(A:(&MMC_BASE+0x14)) PRINT "[39:8] 0x" Data.Long(A:(&MMC_BASE+0x10)) RETURN )