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