📄 mmc.lst
字号:
59 // mmc 协议说,要进入SPI模式,在卡接收复位命令的时候,CS应该为低.
60 // 但SD卡复位时应该不需要吧
61 //************************** 如果必须的话,Place code here**************************//
62 AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,MMC_Chip_Select) ; //***********还是职为低,确保进入SPI模式
\ 0000002C 8021 MOV R1,#+0x80
\ 0000002E 8901 LSL R1,R1,#+0x6 ;; #+0x2000
\ 00000030 .... LDR R0,??DataTable22 ;; 0xfffff400
\ 00000032 ........ _BLF AT91F_PIO_ClearOutput,AT91F_PIO_ClearOutput??rT
63 //在初始化的时候要给SD卡至少80个脉冲,(from internet)
64 for (i=0;i<0x0f;i++)
\ 00000036 0020 MOV R0,#+0
\ 00000038 061C MOV R6,R0
\ ??MMC_Init_3:
\ 0000003A 3606 LSL R6,R6,#+0x18 ;; ZeroExt R6,R6,#+0x18,#+0x18
\ 0000003C 360E LSR R6,R6,#+0x18
\ 0000003E 0F2E CMP R6,#+0xF
\ 00000040 04D2 BCS ??MMC_Init_4
65 {
66 Write_Byte_MMC(0xff); //send 80 clock at least!!!
\ 00000042 FF20 MOV R0,#+0xFF
\ 00000044 ........ BL Write_Byte_MMC
67 }
\ 00000048 761C ADD R6,#+0x1
\ 0000004A F6E7 B ??MMC_Init_3
68
69 //Send Command CMD0 to MMC/SD Card
70 retry=0;
\ ??MMC_Init_4:
\ 0000004C 0020 MOV R0,#+0
\ 0000004E 041C MOV R4,R0
71 do //retry n times to send CMD0 command
72 {
73 temp=Write_Command_MMC(CMD);
\ ??MMC_Init_5:
\ 00000050 6846 MOV R0,SP
\ 00000052 ........ BL Write_Command_MMC
\ 00000056 051C MOV R5,R0
74 retry++;
\ 00000058 641C ADD R4,#+0x1
75 if(retry==200)
\ 0000005A 2406 LSL R4,R4,#+0x18 ;; ZeroExt R4,R4,#+0x18,#+0x18
\ 0000005C 240E LSR R4,R4,#+0x18
\ 0000005E C82C CMP R4,#+0xC8
\ 00000060 01D1 BNE ??MMC_Init_6
76 { //time out
77 return(INIT_CMD0_ERROR); //CMD0 Error!
\ 00000062 0120 MOV R0,#+0x1
\ 00000064 1FE0 B ??MMC_Init_7
78 }
79 }
80 while(temp!=1);
\ ??MMC_Init_6:
\ 00000066 012D CMP R5,#+0x1
\ 00000068 F2D1 BNE ??MMC_Init_5
81
82 //Send Command CMD1 to MMC/SD-Card :Activates the card’s initialization process.
83 //启动卡的初始化进程 ,只在SPI模式才支持 ,见 90页
84 CMD[0] = 0x41; //Command 1
\ 0000006A 6846 MOV R0,SP
\ 0000006C 4121 MOV R1,#+0x41
\ 0000006E 0170 STRB R1,[R0, #+0]
85 CMD[5] = 0xFF;
\ 00000070 6846 MOV R0,SP
\ 00000072 FF21 MOV R1,#+0xFF
\ 00000074 4171 STRB R1,[R0, #+0x5]
86 retry=0;
\ 00000076 0020 MOV R0,#+0
\ 00000078 041C MOV R4,R0
87 do
88 { //retry 100 times to send CMD1 command
89 temp=Write_Command_MMC(CMD); //写成功返回 1
\ ??MMC_Init_8:
\ 0000007A 6846 MOV R0,SP
\ 0000007C ........ BL Write_Command_MMC
\ 00000080 051C MOV R5,R0
90 retry++;
\ 00000082 641C ADD R4,#+0x1
91 if(retry==100)
\ 00000084 2406 LSL R4,R4,#+0x18 ;; ZeroExt R4,R4,#+0x18,#+0x18
\ 00000086 240E LSR R4,R4,#+0x18
\ 00000088 642C CMP R4,#+0x64
\ 0000008A 01D1 BNE ??MMC_Init_9
92 { //time out
93 return(INIT_CMD1_ERROR); //CMD1 Error!
\ 0000008C 0220 MOV R0,#+0x2
\ 0000008E 0AE0 B ??MMC_Init_7
94 }
95 }
96 while(temp!=0); //直到写成功
\ ??MMC_Init_9:
\ 00000090 002D CMP R5,#+0
\ 00000092 F2D1 BNE ??MMC_Init_8
97
98 Init_Flag=0; //Init is completed,clear the flag
\ 00000094 .... LDR R0,??DataTable18 ;; Init_Flag
\ 00000096 0021 MOV R1,#+0
\ 00000098 0160 STR R1,[R0, #+0]
99
100 //进入SPi模式后,解除。可以不用
101 AT91F_PIO_SetOutput(AT91C_BASE_PIOA,MMC_Chip_Select) ; //******set MMC_Chip_Select to high
\ 0000009A 8021 MOV R1,#+0x80
\ 0000009C 8901 LSL R1,R1,#+0x6 ;; #+0x2000
\ 0000009E .... LDR R0,??DataTable22 ;; 0xfffff400
\ 000000A0 ........ _BLF AT91F_PIO_SetOutput,AT91F_PIO_SetOutput??rT
102 return(0); //All commands have been taken.
\ 000000A4 0020 MOV R0,#+0
\ ??MMC_Init_7:
\ 000000A6 02B0 ADD SP,#+0x8
\ 000000A8 70BC POP {R4-R6}
\ 000000AA 02BC POP {R1}
\ 000000AC 0847 BX R1 ;; return
\ 000000AE C046 NOP
\ ??MMC_Init_0:
\ 000000B0 ........ DC32 `?<Constant {64, 0, 0, 0, 0, 149}>`
103 }
104
105 //****************************************************************************
106 //returns the :
107 // size of the card in MB ( ret * 1024^2) == bytes
108 // sector count and multiplier MB are in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
109 // name of the media
110 // SD的参数大多都在 CSD寄存器中,只要读取CSD就可以知道容量
111 // 必须注意,由于wo人在定义读操作的时候是先读到高字节后低字节,在对应数据信息的时候,
112 // 请倒置,或自己数数吧 ! CSD寄存器信息详见 SD卡协议 62 页
113 /*void MMC_get_volume_info(void)
114 //****************************************************************************
^
Warning[Pe009]: nested comment is not allowed
115 {
116 VOLUME_INFO_TYPE MMC_volume_Info,*SDinf;
117
118 SDinf=&MMC_volume_Info; //Init the pointoer;
119 // read the CSD register
120 Read_CSD_MMC(sectorBuffer.data) ;
121
122 // 需要计算容量的相关参数如下:
123 // C_SIZE(每扇区块个数) :CSD 寄存器[73:62]位
124 // C_SIZE_MULT(扇区总数) : [49:47]
125 // READ_BL_LEN(每块可读数据长度): [83:80]
126 //列如最大容量为 4096*512*2048 = 4 GBytes.
127 //实列:: 一个 32 MByte SD 卡 当 BLOCK_LEN = 512 时,可以编码为 C_SIZE_MULT = 3 , C_SIZE = 2000
128
129 // 得到 C_SIZE 的值: CSD[73:62]
130 // [73:72] == sectorBuffer.data[6] && 0x03
131 // [71:64] == sectorBuffer.data[7]
132 // [63:62] == sectorBuffer.data[8] && 0xc0
133
134 // 为了符合资料上数据位的定义,也可以将读到的数据反转,即:[73:62]=(127-73)/8=6.7,所以从最高位
135 // 开始数的第6字节开始,也就是数组的第6项
136 SDinf->sector_count = sectorBuffer.data[6] & 0x03; // 读C_SIZE_MULT 取出[73:72]
137 SDinf->sector_count <<= 8;
138 SDinf->sector_count += sectorBuffer.data[7]; // [71:64]
139 SDinf->sector_count <<= 2;
140 SDinf->sector_count += (sectorBuffer.data[8] & 0xc0) >> 6; // [63:62]
141
142 // 得到 C_SIZE_MULT数据,CSD [49:47] 从读到的数据缓冲sectorBuffer.data
143 // [49:48] == sectorBuffer.data[9] && 0x03
144 // [47] == sectorBuffer.data[10] && 0x80
145 SDinf->sector_multiply = sectorBuffer.data[9] & 0x03; //[49:48]
146 SDinf->sector_multiply <<= 1;
147 SDinf->sector_multiply += (sectorBuffer.data[10] & 0x80) >> 7; //[47]
148
149 //READ_BL_LEN =[83:80]== sectorBuffer.data[5] && 0x80
150 SDinf->READ_BL_LEN=sectorBuffer.data[5] &0x0F ;
151
152 // 计算总容量 ( MBs)
153 //mega bytes in u08 == (C_SIZE+1) * (2^(C_SIZE_MULT+READ_BL_LEN+2)) /1000 000
154 SDinf->size_MB = (SDinf->sector_count+1) >> (SDinf->sector_multiply+SDinf->READ_BL_LEN+2-8);
155 // mega bytes in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
156 //SDinf->size_MB = SDinf->sector_count >> (9-SDinf->sector_multiply);
157
158 // get the name of the card,位置在寄存器CID的 PNM(Product name) ,[103:64],共40位,即
159 // 第三字节到第七字节
160 Read_CID_MMC(sectorBuffer.data);
161 SDinf->name[0] = sectorBuffer.data[3];
162 SDinf->name[1] = sectorBuffer.data[4];
163 SDinf->name[2] = sectorBuffer.data[5];
164 SDinf->name[3] = sectorBuffer.data[6];
165 SDinf->name[4] = sectorBuffer.data[7];
166 SDinf->name[5] = 0x00;
167
168 // de得到产品的序列号 ,CID [55:24],32位2进制数 ,有兴趣可以读出来
169 {
170 asm("nop") ; // 读PSN 的代码
171 }
172 }
173 */
174 //****************************************************************************
175 //Send a Command to MMC/SD-Card
176 //Return: the second byte of response register of MMC/SD-Card
\ In segment CODE, align 4, keep-with-next
177 unsigned char Write_Command_MMC(unsigned char *CMD)
178 //****************************************************************************
179 {
\ Write_Command_MMC:
\ 00000000 F0B5 PUSH {R4-R7,LR}
\ 00000002 041C MOV R4,R0
180 unsigned char tmp;
181 unsigned char retry=0;
\ 00000004 0020 MOV R0,#+0
\ 00000006 061C MOV R6,R0
182 unsigned char i;
183
184 //set MMC_Chip_Select to high (MMC/SD-Card disable)
185 AT91F_PIO_SetOutput(AT91C_BASE_PIOA,MMC_Chip_Select) ;
\ 00000008 8021 MOV R1,#+0x80
\ 0000000A 8901 LSL R1,R1,#+0x6 ;; #+0x2000
\ 0000000C .... LDR R0,??DataTable22 ;; 0xfffff400
\ 0000000E ........ _BLF AT91F_PIO_SetOutput,AT91F_PIO_SetOutput??rT
186 //send 8 Clock Impulse
187 Write_Byte_MMC(0xFF);
\ 00000012 FF20 MOV R0,#+0xFF
\ 00000014 ........ BL Write_Byte_MMC
188 //set MMC_Chip_Select to low (MMC/SD-Card active)
189 AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,MMC_Chip_Select) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -