]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/mmc.c
Multidrive support for mmc.c (1. step)
[z180-stamp.git] / avr / mmc.c
1 /*-----------------------------------------------------------------------*/
2 /* MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2007 */
3 /*-----------------------------------------------------------------------*/
4 /* Only spi_rcvr(), spi_xmit(), disk_timerproc() and some macros */
5 /* are platform dependent. */
6 /*-----------------------------------------------------------------------*/
7
8 #include "common.h"
9 #include <stdbool.h>
10 #include "timer.h"
11 #include "spi.h"
12 #include "diskio.h"
13 //#include "debug.h"
14
15
16 /* Port Controls (Platform dependent) */
17 /* SD card socket connections */
18
19 #define SD_CD_1 SBIT(PORTG,3) /* Card detect switch */
20 #define SD_CD_1_IN SBIT(PING,3)
21 #define SD_CD_1_DDR SBIT(DDRG,3)
22
23 //#define SD_WP_1 SBIT(PORTG,5) /* Write protect switch */
24 #define SD_WP_1_IN SBIT(PING,5)
25 #define SD_WP_1_DDR SBIT(DDRG,5)
26
27 #define SD_CS_1 SBIT(PORTG,4) /* Chip select pin */
28 #define SD_CS_1_IN SBIT(PING,4)
29 #define SD_CS_1_DDR SBIT(DDRG,4)
30
31
32 #define FCLK_SLOW() SPISetMMCInitClock() /* Set slow clock (100k-400k) */
33 #define FCLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */
34
35
36 /*--------------------------------------------------------------------------
37 Definitions for MMC/SDC command
38 ---------------------------------------------------------------------------*/
39
40 #define CMD0 (0) /* GO_IDLE_STATE */
41 #define CMD1 (1) /* SEND_OP_COND (MMC) */
42 #define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
43 #define CMD8 (8) /* SEND_IF_COND */
44 #define CMD9 (9) /* SEND_CSD */
45 #define CMD10 (10) /* SEND_CID */
46 #define CMD12 (12) /* STOP_TRANSMISSION */
47 #define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
48 #define CMD16 (16) /* SET_BLOCKLEN */
49 #define CMD17 (17) /* READ_SINGLE_BLOCK */
50 #define CMD18 (18) /* READ_MULTIPLE_BLOCK */
51 #define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
52 #define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
53 #define CMD24 (24) /* WRITE_BLOCK */
54 #define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
55 #define CMD55 (55) /* APP_CMD */
56 #define CMD58 (58) /* READ_OCR */
57
58
59 /*--------------------------------------------------------------------------
60
61 Module Private Functions
62
63 ---------------------------------------------------------------------------*/
64
65 struct sdsock_stat_s {
66 volatile DSTATUS stat; /* Disk/socket status */
67 BYTE CardType; /* Card type flags */
68 };
69
70 static
71 struct sdsock_stat_s
72 socket[2] = {
73 {.stat=STA_NOINIT},
74 {.stat=STA_NOINIT}
75 };
76
77 /*-----------------------------------------------------------------------*/
78 /* Wait for card ready */
79 /*-----------------------------------------------------------------------*/
80
81 static
82 int wait_ready (void) /* 1:OK, 0:Timeout */
83 {
84 uint32_t to = get_timer(0);
85
86 /* Wait for ready in timeout of 500ms */
87 do {
88 if (spi_rcvr() == 0xFF) {
89 return 1;
90 }
91 } while (get_timer(to) < 500);
92
93 return 0;
94 }
95
96 /*-----------------------------------------------------------------------*/
97 /* Deselect the card and release SPI bus */
98 /*-----------------------------------------------------------------------*/
99
100 static
101 void deselect (void)
102 {
103 // debug("*** enter deselect()\n");
104 SD_CS_1 = 1;
105 /* Dummy clock (TODO: force DO hi-z for multiple slave SPI) */
106 spi_rcvr();
107 // debug("*** exit deselect()\n");
108 }
109
110
111
112 /*-----------------------------------------------------------------------*/
113 /* Select the card and wait for ready */
114 /*-----------------------------------------------------------------------*/
115
116 static
117 int select (void) /* 1:Successful, 0:Timeout */
118 {
119 // debug("*** enter select()\n");
120 SD_CS_1 = 0;
121 /* Dummy clock (force DO enabled) */
122 spi_rcvr();
123
124 if (wait_ready()) {
125 // debug("*** exit select() == 1\n");
126 return 1; /* OK */
127 }
128 deselect();
129 // debug("*** exit select() == 0\n");
130
131 return 0; /* Timeout */
132 }
133
134 /*-----------------------------------------------------------------------*/
135 /* Power Control (Platform dependent) */
136 /*-----------------------------------------------------------------------*/
137 /* When the target system does not support socket power control, there */
138 /* is nothing to do in these functions and chk_power always returns 1. */
139
140 static
141 void power_on(void)
142 {
143 // debug("*** enter power_on()\n");
144
145 #ifdef SD_PWR_1
146 SD_PWR_1_DDR = 1; /* Turns on PWR pin as output */
147 SD_PWR_1 = 0; /* Drives PWR pin high */
148
149 for (uint32_t to = get_timer(0); get_timer(to) < 30;)
150 ; /* Wait for 30ms */
151 #endif
152
153 #ifdef SD_CD_1
154 /* Card detect, input with pullup */
155 SD_CD_1_DDR = 0;
156 SD_CD_1 = 1;
157 #endif
158 #ifdef SD_WP_1
159 SD_WP_1_DDR = 0;
160 SD_WP_1 = 1;
161 #endif
162 SD_CS_1 = 1;
163 SD_CS_1_DDR = 1;
164
165 // debug("*** exit power_on()\n");
166 }
167
168 static
169 void power_off (void)
170 {
171 // debug("*** enter power_off()\n");
172 select(); /* Wait for card ready */
173 deselect();
174
175 #ifdef SD_PWR_1
176 SD_PWR_1 = 1; /* Socket power OFF */
177 #endif
178 socket[0].stat |= STA_NOINIT;
179 // debug("*** exit power_off()\n");
180 }
181
182 #if 0
183 static
184 int chk_power(void) /* Socket power state: 0=off, 1=on */
185 {
186 #ifdef SD_PWR_1
187 return SD_PWR_1 == 0;
188 #else
189 return 1;
190 #endif /* SD_PWR_PIN */
191 }
192 #endif
193
194 /*-----------------------------------------------------------------------*/
195 /* Receive a data packet from MMC */
196 /*-----------------------------------------------------------------------*/
197
198 static
199 int rcvr_datablock (
200 BYTE *buff, /* Data buffer to store received data */
201 UINT btr /* Byte count (must be multiple of 4) */
202 ) {
203 BYTE token, tmp;
204 uint32_t to = get_timer(0);
205
206 /* Wait for data packet in timeout of 200ms */
207 do {
208 token = spi_rcvr();
209 } while ((token == 0xFF) && get_timer(to) < 200);
210 if(token != 0xFE) return 0; /* If not valid data token, retutn with error */
211
212 tmp = spi_rcvr(); /* shift in first byte */
213 spi_write(0xff); /* start shift in next byte */
214 while (--btr) {
215 *buff++ = tmp;
216 asm volatile (""::"r"(buff), "r"(btr));
217 spi_wait();
218 tmp = SPDR;
219 spi_write(0xff);
220 }
221 *buff = tmp; /* store last byte in buffer while SPI module shifts in crc part1 */
222 spi_wait();
223 spi_rcvr(); /* second crc */
224
225 return 1; /* Return with success */
226 }
227
228 /*-----------------------------------------------------------------------*/
229 /* Send a data packet to MMC */
230 /*-----------------------------------------------------------------------*/
231
232 #if _USE_WRITE
233 static
234 int xmit_datablock (
235 const BYTE *buff, /* 512 byte data block to be transmitted */
236 BYTE token /* Data/Stop token */
237 )
238 {
239 BYTE resp, tmp;
240 UINT btr;
241
242 if (!wait_ready()) return 0;
243
244 spi_write(token); /* Xmit data token */
245 if (token != 0xFD) { /* Is data token */
246 btr = 512;
247 do {
248 tmp = *buff++;
249 spi_wait();
250 spi_write(tmp);
251 }while (--btr);
252 spi_wait();
253 spi_xmit(0xff); /* CRC (Dummy) */
254 spi_xmit(0xff);
255 resp = spi_rcvr(); /* Reveive data response */
256 return ((resp & 0x1F) != 0x05) ? 0 : 1; /* If not accepted, return with error */
257 }
258
259 spi_wait();
260 return 1;
261 }
262 #endif /* _USE_WRITE */
263
264 /*-----------------------------------------------------------------------*/
265 /* Send a command packet to MMC */
266 /*-----------------------------------------------------------------------*/
267
268 static
269 BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */
270 BYTE cmd, /* Command index */
271 DWORD arg /* Argument */
272 ) {
273 union {
274 DWORD as32;
275 BYTE as8[4];
276 } argtmp;
277 BYTE n, res;
278
279 // debug("*** send_cmd( %.2x )\n", cmd);
280
281 if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
282 cmd &= 0x7F;
283 res = send_cmd(CMD55, 0);
284 if (res > 1)
285 return res;
286 }
287
288 /* Select the card and wait for ready except to stop multiple block read */
289 if (cmd != CMD12) {
290 deselect();
291 if (!select())
292 return 0xFF;
293 }
294
295 /* Send command packet */
296 spi_xmit(0x40 | cmd); /* Start + Command index */
297 argtmp.as32 = arg;
298 spi_xmit(argtmp.as8[3]); /* Argument[31..24] */
299 spi_xmit(argtmp.as8[2]); /* Argument[23..16] */
300 spi_xmit(argtmp.as8[1]); /* Argument[15..8] */
301 spi_xmit(argtmp.as8[0]); /* Argument[7..0] */
302
303 n = 0x01; /* Dummy CRC + Stop */
304 if (cmd == CMD0)
305 n = 0x95; /* Valid CRC for CMD0(0) */
306 if (cmd == CMD8)
307 n = 0x87; /* Valid CRC for CMD8(0x1AA) */
308 spi_xmit(n);
309
310 /* Receive command response */
311 if (cmd == CMD12)
312 spi_rcvr(); /* Skip a stuff byte when stop reading */
313 n = 10; /* Wait for a valid response in timeout of 10 attempts */
314 do
315 res = spi_rcvr();
316 while ((res & 0x80) && --n);
317
318 return res; /* Return with the response value */
319 }
320
321 /*--------------------------------------------------------------------------
322
323 Public Functions
324
325 ---------------------------------------------------------------------------*/
326
327 /*-----------------------------------------------------------------------*/
328 /* Initialize Disk Drive */
329 /*-----------------------------------------------------------------------*/
330
331 #define MMC_INIT_TO 1000 /* 1s */
332
333 DSTATUS disk_initialize (
334 BYTE drv /* Physical drive nmuber (0) */
335 )
336 {
337 BYTE n, cmd, ty, ocr[4];
338
339 if (drv)
340 return STA_NOINIT; /* Supports only single drive */
341 if (socket[drv].stat & STA_NODISK)
342 return socket[drv].stat; /* No card in the socket */
343
344 power_on(); /* Force socket power on */
345 FCLK_SLOW();
346 for (n = 10; n; n--)
347 spi_rcvr(); /* 80 dummy clocks */
348
349 ty = 0;
350 if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
351 /* Init timeout timer */
352 uint32_t timer = get_timer(0);
353
354 if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */
355 for (n = 0; n < 4; n++) ocr[n] = spi_rcvr(); /* Get trailing return value of R7 resp */
356 if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
357 while (get_timer(timer) < MMC_INIT_TO && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
358 if (get_timer(timer) < MMC_INIT_TO && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
359 for (n = 0; n < 4; n++) ocr[n] = spi_rcvr();
360 ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 */
361 }
362 }
363 } else { /* SDv1 or MMCv3 */
364 if (send_cmd(ACMD41, 0) <= 1) {
365 ty = CT_SD1; cmd = ACMD41; /* SDv1 */
366 } else {
367 ty = CT_MMC; cmd = CMD1; /* MMCv3 */
368 }
369
370 /* Wait for leaving idle state */
371 while (get_timer(timer) < MMC_INIT_TO && send_cmd(cmd, 0));
372
373 /* Set R/W block length to 512 */
374 if (!(get_timer(timer) < MMC_INIT_TO) || send_cmd(CMD16, 512) != 0)
375 ty = 0;
376 }
377 }
378 socket[drv].CardType = ty;
379 deselect();
380
381 if (ty) { /* Initialization succeded */
382 socket[drv].stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
383 FCLK_FAST();
384 } else { /* Initialization failed */
385 power_off();
386 }
387
388 return socket[drv].stat;
389 }
390
391 /*-----------------------------------------------------------------------*/
392 /* Get Disk Status */
393 /*-----------------------------------------------------------------------*/
394
395 DSTATUS disk_status (
396 BYTE drv /* Physical drive nmuber (0) */
397 )
398 {
399 if (drv) return STA_NOINIT; /* Supports only single drive */
400 return socket[drv].stat;
401 }
402
403 /*-----------------------------------------------------------------------*/
404 /* Read Sector(s) */
405 /*-----------------------------------------------------------------------*/
406
407 DRESULT disk_read (
408 BYTE drv, /* Physical drive nmuber (0) */
409 BYTE *buff, /* Pointer to the data buffer to store read data */
410 DWORD sector, /* Start sector number (LBA) */
411 UINT count /* Sector count (1..255) */
412 )
413 {
414 BYTE cmd;
415
416 if (drv || !count) return RES_PARERR;
417 if (socket[drv].stat & STA_NOINIT) return RES_NOTRDY;
418
419 if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
420
421 cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
422 if (send_cmd(cmd, sector) == 0) {
423 do {
424 if (!rcvr_datablock(buff, 512))
425 break;
426 buff += 512;
427 } while (--count);
428 if (cmd == CMD18)
429 send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
430 }
431 deselect();
432
433 return count ? RES_ERROR : RES_OK;
434 }
435
436 /*-----------------------------------------------------------------------*/
437 /* Write Sector(s) */
438 /*-----------------------------------------------------------------------*/
439
440 #if _USE_WRITE
441 DRESULT disk_write (
442 BYTE drv, /* Physical drive nmuber (0) */
443 const BYTE *buff, /* Pointer to the data to be written */
444 DWORD sector, /* Start sector number (LBA) */
445 UINT count /* Sector count (1..255) */
446 )
447 {
448 if (drv || !count) return RES_PARERR;
449 if (socket[drv].stat & STA_NOINIT) return RES_NOTRDY;
450 if (socket[drv].stat & STA_PROTECT) return RES_WRPRT;
451
452 if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
453
454 if (count == 1) { /* Single block write */
455 if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
456 && xmit_datablock(buff, 0xFE))
457 count = 0;
458 }
459 else { /* Multiple block write */
460 if (socket[drv].CardType & CT_SDC) send_cmd(ACMD23, count);
461 if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
462 do {
463 if (!xmit_datablock(buff, 0xFC)) break;
464 buff += 512;
465 }while (--count);
466 if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
467 count = 1;
468 }
469 }
470 deselect();
471
472 return count ? RES_ERROR : RES_OK;
473 }
474 #endif /* _USE_WRITE */
475
476 /*-----------------------------------------------------------------------*/
477 /* Miscellaneous Functions */
478 /*-----------------------------------------------------------------------*/
479
480 #if _USE_IOCTL
481 DRESULT disk_ioctl (
482 BYTE drv, /* Physical drive nmuber (0) */
483 BYTE cmd, /* Control code */
484 void *buff /* Buffer to send/receive control data */
485 )
486 {
487 DRESULT res;
488 BYTE n, csd[16], *ptr = buff;
489 DWORD csize;
490
491 if (drv)
492 return RES_PARERR;
493
494 res = RES_ERROR;
495
496 if (socket[drv].stat & STA_NOINIT) return RES_NOTRDY;
497
498 switch (cmd) {
499 case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */
500 if (select())
501 res = RES_OK;
502 break;
503
504 case GET_SECTOR_COUNT: /* Get number of sectors on the disk (DWORD) */
505 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
506 if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
507 csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
508 *(DWORD*)buff = csize << 10;
509 } else { /* SDC ver 1.XX or MMC*/
510 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
511 csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
512 *(DWORD*)buff = csize << (n - 9);
513 }
514 res = RES_OK;
515 }
516 break;
517
518 case GET_BLOCK_SIZE: /* Get erase block size in unit of sector (DWORD) */
519 if (socket[drv].CardType & CT_SD2) { /* SDv2? */
520 if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
521 spi_rcvr();
522 if (rcvr_datablock(csd, 16)) { /* Read partial block */
523 for (n = 64 - 16; n; n--)
524 spi_rcvr(); /* Purge trailing data */
525 *(DWORD*) buff = 16UL << (csd[10] >> 4);
526 res = RES_OK;
527 }
528 }
529 } else { /* SDv1 or MMCv3 */
530 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
531 if (socket[drv].CardType & CT_SD1) { /* SDv1 */
532 *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
533 } else { /* MMCv3 */
534 *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
535 }
536 res = RES_OK;
537 }
538 }
539 break;
540
541 /* Following commands are never used by FatFs module */
542
543 case MMC_GET_TYPE: /* Get card type flags (1 byte) */
544 *ptr = socket[drv].CardType;
545 res = RES_OK;
546 break;
547
548 case MMC_GET_CSD: /* Receive CSD as a data block (16 bytes) */
549 if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
550 && rcvr_datablock(ptr, 16))
551 res = RES_OK;
552 break;
553
554 case MMC_GET_CID: /* Receive CID as a data block (16 bytes) */
555 if (send_cmd(CMD10, 0) == 0 /* READ_CID */
556 && rcvr_datablock(ptr, 16))
557 res = RES_OK;
558 break;
559
560 case MMC_GET_OCR: /* Receive OCR as an R3 resp (4 bytes) */
561 if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
562 for (n = 4; n; n--)
563 *ptr++ = spi_rcvr();
564 res = RES_OK;
565 }
566 break;
567
568 case MMC_GET_SDSTAT: /* Receive SD status as a data block (64 bytes) */
569 if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
570 spi_rcvr();
571 if (rcvr_datablock(ptr, 64))
572 res = RES_OK;
573 }
574 break;
575
576 case CTRL_POWER_OFF : /* Power off */
577 power_off();
578 socket[drv].stat |= STA_NOINIT;
579 res = RES_OK;
580 break;
581
582 default:
583 res = RES_PARERR;
584 }
585
586 deselect();
587
588 return res;
589 }
590 #endif /* _USE_IOCTL */
591
592 /*-----------------------------------------------------------------------*/
593 /* Device Timer Interrupt Procedure (Platform dependent) */
594 /*-----------------------------------------------------------------------*/
595 /* This function must be called in period of 10ms */
596
597 void disk_timerproc (void)
598 {
599 BYTE s;
600
601 s = socket[0].stat;
602
603 #ifdef SD_WP_1
604 if (SD_WP_1_IN == 0) /* Write protected */
605 s |= STA_PROTECT;
606 else /* Write enabled */
607 s &= ~STA_PROTECT;
608 #endif
609
610 #ifdef SD_CD_1
611 if (SD_CD_1_IN == 0) /* Card inserted */
612 s &= ~STA_NODISK;
613 else /* Socket empty */
614 s |= (STA_NODISK | STA_NOINIT);
615 #endif
616
617 socket[0].stat = s; /* Update MMC status */
618 }