📄 mmc.lst
字号:
261 if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
\ 00000040 4C2C CMP R4,#+76
\ 00000042 02D1 BNE ??send_cmd_2
\ 00000044 FF20 MOV R0,#+255
\ 00000046 ........ BL AT91_spi
262 n = 10; /* Wait for a valid response in timeout of 10 attempts */
\ ??send_cmd_2:
\ 0000004A 0A24 MOV R4,#+10
263 do
264 res = rcvr_spi();
\ ??send_cmd_3:
\ 0000004C FF20 MOV R0,#+255
\ 0000004E ........ BL AT91_spi
265 while ((res & 0x80) && --n);
\ 00000052 0106 LSL R1,R0,#+24
\ 00000054 02D5 BPL ??send_cmd_1
\ 00000056 641E SUB R4,R4,#+1
\ 00000058 2106 LSL R1,R4,#+24
\ 0000005A F7D1 BNE ??send_cmd_3
266
267 return res; /* Return with the response value */
\ ??send_cmd_1:
\ 0000005C 30BC POP {R4,R5}
\ 0000005E 02BC POP {R1}
\ 00000060 0847 BX R1 ;; return
268 }
269
270
271
272
273 /*-----------------------------------------------------------------------*/
274 /* Public Functions */
275
276
277 /*-----------------------*/
278 /* Initialize Disk Drive */
279 /* (Platform dependent) */
280
281 //extern
\ In segment CODE, align 4, keep-with-next
282 DSTATUS disk_initialize ()
283 {
\ disk_initialize:
\ 00000000 F0B5 PUSH {R4-R7,LR}
284 BYTE n;
285
286 AT91PS_PMC pPMC = AT91C_BASE_PMC;
287
288 POWER_ON(); /* Socket power ON */
289 //for (Timer = 3; Timer; ); /* Wait for 30ms */
290 for (int n = 3000; n;n-- );
291 /* MMC socket-switch init */
292 // disable internal Pull-Ups if needed
293
294 // disable PIO from controlling MOSI, MISO, SCK (=hand over to SPI)
295 // keep CS untouched - used as GPIO pin during init
296 pPIOA->PIO_PDR = AT91C_PA16_SPI0_MISO | AT91C_PA17_SPI0_MOSI | AT91C_PA18_SPI0_SPCK; // | NCPS_PDR_BIT;
\ 00000002 E020 MOV R0,#+224
\ 00000004 C002 LSL R0,R0,#+11 ;; #+458752
\ 00000006 2749 LDR R1,??disk_initialize_0 ;; 0xfffff404
\ 00000008 0860 STR R0,[R1, #+0]
297 // set pin-functions in PIO Controller
298 pPIOA->PIO_ASR = AT91C_PA16_SPI0_MISO | AT91C_PA17_SPI0_MOSI | AT91C_PA18_SPI0_SPCK; /// not here: | NCPS_ASR_BIT;
\ 0000000A 2749 LDR R1,??disk_initialize_0+0x4 ;; 0xfffff470
\ 0000000C 0860 STR R0,[R1, #+0]
299
300 // set chip-select as output high (unselect card)
301 pPIOA->PIO_PER = CARD_SELECT_PIN; // enable GPIO of CS-pin
\ 0000000E 8024 MOV R4,#+128
\ 00000010 A401 LSL R4,R4,#+6 ;; #+8192
\ 00000012 2648 LDR R0,??disk_initialize_0+0x8 ;; 0xfffff400
\ 00000014 0460 STR R4,[R0, #+0]
302 pPIOA->PIO_SODR = CARD_SELECT_PIN; // set high
\ 00000016 .... LDR R5,??DataTable16 ;; 0xfffff430
\ 00000018 2C60 STR R4,[R5, #+0]
303 pPIOA->PIO_OER = CARD_SELECT_PIN; // output enable
\ 0000001A 2548 LDR R0,??disk_initialize_0+0xC ;; 0xfffff410
\ 0000001C 0460 STR R4,[R0, #+0]
304
305 // enable peripheral clock for SPI ( PID Bit 5 )
306 pPMC->PMC_PCER = ( (DWORD) 1 << AT91C_ID_SPI0 ); // n.b. IDs are just bit-numbers
\ 0000001E 2548 LDR R0,??disk_initialize_0+0x10 ;; 0xfffffc10
\ 00000020 1021 MOV R1,#+16
\ 00000022 0160 STR R1,[R0, #+0]
307
308 // SPI enable and reset
309 pSPI->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;
\ 00000024 244E LDR R6,??disk_initialize_0+0x14 ;; 0xfffe0000
\ 00000026 8120 MOV R0,#+129
\ 00000028 3060 STR R0,[R6, #+0]
310
311 // SPI mode: master, FDIV=0, fault detection disabled
312 pSPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS;
\ 0000002A 2448 LDR R0,??disk_initialize_0+0x18 ;; 0xfffe0004
\ 0000002C 1121 MOV R1,#+17
\ 0000002E 0160 STR R1,[R0, #+0]
313
314 // set chip-select-register
315 // 8 bits per transfer, CPOL=1, ClockPhase=0, DLYBCT = 0
316 pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8;
\ 00000030 .... LDR R0,??DataTable4 ;; 0xfffe0030
\ 00000032 0121 MOV R1,#+1
\ 00000034 0160 STR R1,[R0, #+0]
317
318 // slow during init
319 AT91_spiSetSpeed(0xFE);
\ 00000036 FE20 MOV R0,#+254
\ 00000038 ........ BL AT91_spiSetSpeed
320
321 // enable
322 pSPI->SPI_CR = AT91C_SPI_SPIEN;
\ 0000003C 0120 MOV R0,#+1
\ 0000003E 3060 STR R0,[R6, #+0]
323
324 Stat |= STA_NOINIT;
\ 00000040 .... LDR R6,??DataTable8 ;; Stat
\ 00000042 3078 LDRB R0,[R6, #+0]
\ 00000044 0121 MOV R1,#+1
\ 00000046 0143 ORR R1,R0
\ 00000048 3170 STRB R1,[R6, #+0]
325 if (!(Stat & STA_NODISK)) {
\ 0000004A 3078 LDRB R0,[R6, #+0]
\ 0000004C 8007 LSL R0,R0,#+30
\ 0000004E 26D4 BMI ??disk_initialize_1
326 n = 10; /* Dummy clock */
\ 00000050 0A27 MOV R7,#+10
327 do
328 rcvr_spi();
\ ??disk_initialize_2:
\ 00000052 FF20 MOV R0,#+255
\ 00000054 ........ BL AT91_spi
329 while (--n);
\ 00000058 7F1E SUB R7,R7,#+1
\ 0000005A FAD1 BNE ??disk_initialize_2
330
331 //AT91F_DBGU_Printk("SPI prepare done\n"); /////////////////////////////////////////
332
333 SELECT(); /* CS = L */
\ 0000005C .... LDR R0,??DataTable15 ;; 0xfffff434
\ 0000005E 0460 STR R4,[R0, #+0]
334 if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
\ 00000060 0021 MOV R1,#+0
\ 00000062 4020 MOV R0,#+64
\ 00000064 ........ BL send_cmd
\ 00000068 0128 CMP R0,#+1
\ 0000006A 11D1 BNE ??disk_initialize_3
335 Timer = 100; /* Wait for card ready in timeout of 1 sec */
\ 0000006C 6420 MOV R0,#+100
\ 0000006E 7070 STRB R0,[R6, #+1]
336 while (Timer && send_cmd(CMD1, 0));
\ ??disk_initialize_4:
\ 00000070 7078 LDRB R0,[R6, #+1]
\ 00000072 0028 CMP R0,#+0
\ 00000074 05D0 BEQ ??disk_initialize_5
\ 00000076 0021 MOV R1,#+0
\ 00000078 4120 MOV R0,#+65
\ 0000007A ........ BL send_cmd
\ 0000007E 0028 CMP R0,#+0
\ 00000080 F6D1 BNE ??disk_initialize_4
337 if (Timer) Stat &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */
\ ??disk_initialize_5:
\ 00000082 7078 LDRB R0,[R6, #+1]
\ 00000084 0028 CMP R0,#+0
\ 00000086 03D0 BEQ ??disk_initialize_3
\ 00000088 3078 LDRB R0,[R6, #+0]
\ 0000008A FE21 MOV R1,#+254
\ 0000008C 0140 AND R1,R0
\ 0000008E 3170 STRB R1,[R6, #+0]
338 }
339
340 //AT91F_DBGU_Printk("CMD0 done timer = %i\n", Timer);
341
342 DESELECT(); /* CS = H */
\ ??disk_initialize_3:
\ 00000090 2C60 STR R4,[R5, #+0]
343 rcvr_spi(); /* Idle (Release DO) */
\ 00000092 FF20 MOV R0,#+255
\ 00000094 ........ BL AT91_spi
344
345 AT91_spiSetSpeed(SPI_SCBR_MIN);
\ 00000098 0220 MOV R0,#+2
\ 0000009A ........ BL AT91_spiSetSpeed
346 }
347
348 if (Stat & STA_NOINIT)
\ ??disk_initialize_1:
\ 0000009E 3078 LDRB R0,[R6, #+0]
349 disk_shutdown();
350 return Stat;
\ 000000A0 3078 LDRB R0,[R6, #+0]
\ 000000A2 .... B ?Subroutine18
\ ??disk_initialize_0:
\ 000000A4 04F4FFFF DC32 0xfffff404
\ 000000A8 70F4FFFF DC32 0xfffff470
\ 000000AC 00F4FFFF DC32 0xfffff400
\ 000000B0 10F4FFFF DC32 0xfffff410
\ 000000B4 10FCFFFF DC32 0xfffffc10
\ 000000B8 0000FEFF DC32 0xfffe0000
\ 000000BC 0400FEFF DC32 0xfffe0004
351 }
\ In segment CODE, align 4, keep-with-next
\ ?Subroutine18:
\ 00000000 F0BC POP {R4-R7}
\ 00000002 02BC POP {R1}
\ 00000004 0847 BX R1 ;; return
\ 00000006 C046 NOP
\ ??Subroutine18_0:
\ 00000008 81841E00 DC32 0x1e8481
\ 0000000C ........ DC32 _Stdout
\ 00000010 ........ DC32 `?<Constant "disk read error !">`
\ 00000014 01020000 DC32 0x201
352
353 /*-----------------------*/
354 /* Shutdown */
355 /* (Platform dependent) */
356
357 #if 0
358 DSTATUS disk_shutdown ()
359 {
360 SPCR = 0; /* Disable SPI function */
361 DDRB = 0b11000000; /* Disable drivers */
362 PORTB = 0b10110000;
363 POWER_OFF(); /* Socket power OFF */
364
365 Stat |= STA_NOINIT;
366
367 return Stat;
368 }
369 #endif
370
\ In segment CODE, align 4, keep-with-next
371 DSTATUS disk_shutdown ()
372 {
373 return 0;
\ disk_shutdown:
\ 00000000 0020 MOV R0,#+0
\ 00000002 7047 BX LR ;; return
374 }
375
376
377 /*--------------------*/
378 /* Return Disk Status */
379
\ In segment CODE, align 4, keep-with-next
380 DSTATUS disk_status ()
381 {
382 return Stat;
\ disk_status:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -