Rev Author Line No. Line
1234 kaklik 1 /*-----------------------------------------------------------------------*/
2 /* MMC/SDC (in SPI mode) control module (C)ChaN, 2006 */
3 /*-----------------------------------------------------------------------*/
4 /* Only rcvr_spi(), xmit_spi(), disk_timerproc(), disk_initialize () and */
5 /* some macros are platform dependent. */
6 /*-----------------------------------------------------------------------*/
7  
8  
9 #include <avr/io.h>
10 #include "diskio.h"
11  
12  
13 /* Definitions for MMC/SDC command */
14 #define CMD0 (0x40+0) /* GO_IDLE_STATE */
15 #define CMD1 (0x40+1) /* SEND_OP_COND */
16 #define CMD8 (0x40+8) /* SEND_IF_COND */
17 #define CMD9 (0x40+9) /* SEND_CSD */
18 #define CMD10 (0x40+10) /* SEND_CID */
19 #define CMD12 (0x40+12) /* STOP_TRANSMISSION */
20 #define CMD16 (0x40+16) /* SET_BLOCKLEN */
21 #define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
22 #define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
23 #define CMD23 (0x40+23) /* SET_BLOCK_COUNT */
24 #define CMD24 (0x40+24) /* WRITE_BLOCK */
25 #define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
26 #define CMD41 (0x40+41) /* SEND_OP_COND (ACMD) */
27 #define CMD55 (0x40+55) /* APP_CMD */
28 #define CMD58 (0x40+58) /* READ_OCR */
29  
30  
31 /* Control signals (Platform dependent) */
32 #define SELECT() PORTB &= ~_BV(PB2) /* MMC CS = L */
33 #define DESELECT() PORTB |= _BV(PB2) /* MMC CS = H */
34  
35 #define SOCKPORT PINB /* Socket contact port */
36 #define SOCKINS 0x01 /* Card detect switch (PB0) */
37  
38  
39  
40 /*--------------------------------------------------------------------------
41  
42 Module Private Functions
43  
44 ---------------------------------------------------------------------------*/
45  
46 static volatile
47 DSTATUS Stat = STA_NOINIT; /* Disk status */
48  
49 static volatile
50 BYTE Timer1, Timer2; /* 100Hz decrement timer */
51  
52 static
53 BYTE CardType; /* b0:MMC, b1:SDC, b2:Block addressing */
54  
55  
56  
57 /*-----------------------------------------------------------------------*/
58 /* Transmit a byte to MMC via SPI (Platform dependent) */
59 /*-----------------------------------------------------------------------*/
60  
61 #define xmit_spi(dat) SPDR=(dat); loop_until_bit_is_set(SPSR,SPIF)
62  
63  
64  
65 /*-----------------------------------------------------------------------*/
66 /* Receive a byte from MMC via SPI (Platform dependent) */
67 /*-----------------------------------------------------------------------*/
68  
69 static
70 BYTE rcvr_spi (void)
71 {
72 SPDR = 0xFF;
73 loop_until_bit_is_set(SPSR, SPIF);
74 return SPDR;
75 }
76  
77 /* Alternative macro to receive data fast */
78 #define rcvr_spi_m(dst) SPDR=0xFF; loop_until_bit_is_set(SPSR,SPIF); *(dst)=SPDR
79  
80  
81  
82 /*-----------------------------------------------------------------------*/
83 /* Wait for card ready */
84 /*-----------------------------------------------------------------------*/
85  
86 static
87 BYTE wait_ready (void)
88 {
89 BYTE res;
90  
91  
92 Timer2 = 50; /* Wait for ready in timeout of 500ms */
93 rcvr_spi();
94 do
95 res = rcvr_spi();
96 while ((res != 0xFF) && Timer2);
97  
98 return res;
99 }
100  
101  
102  
103 /*-----------------------------------------------------------------------*/
104 /* Receive a data packet from MMC */
105 /*-----------------------------------------------------------------------*/
106  
107 static
108 BOOL rcvr_datablock (
109 BYTE *buff, /* Data buffer to store received data */
110 UINT btr /* Byte count (must be even number) */
111 )
112 {
113 BYTE token;
114  
115  
116 Timer1 = 10;
117 do { /* Wait for data packet in timeout of 100ms */
118 token = rcvr_spi();
119 } while ((token == 0xFF) && Timer1);
120 if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */
121  
122 do { /* Receive the data block into buffer */
123 rcvr_spi_m(buff++);
124 rcvr_spi_m(buff++);
125 } while (btr -= 2);
126 rcvr_spi(); /* Discard CRC */
127 rcvr_spi();
128  
129 return TRUE; /* Return with success */
130 }
131  
132  
133  
134 /*-----------------------------------------------------------------------*/
135 /* Send a data packet to MMC */
136 /*-----------------------------------------------------------------------*/
137  
138 #if _READONLY == 0
139 static
140 BOOL xmit_datablock (
141 const BYTE *buff, /* 512 byte data block to be transmitted */
142 BYTE token /* Data/Stop token */
143 )
144 {
145 BYTE resp, wc;
146  
147  
148 if (wait_ready() != 0xFF) return FALSE;
149  
150 xmit_spi(token); /* Xmit data token */
151 if (token != 0xFD) { /* Is data token */
152 wc = 0;
153 do { /* Xmit the 512 byte data block to MMC */
154 xmit_spi(*buff++);
155 xmit_spi(*buff++);
156 } while (--wc);
157 xmit_spi(0xFF); /* CRC (Dummy) */
158 xmit_spi(0xFF);
159 resp = rcvr_spi(); /* Reveive data response */
160 if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
161 return FALSE;
162 }
163  
164 return TRUE;
165 }
166 #endif /* _READONLY */
167  
168  
169  
170 /*-----------------------------------------------------------------------*/
171 /* Send a command packet to MMC */
172 /*-----------------------------------------------------------------------*/
173  
174 static
175 BYTE send_cmd (
176 BYTE cmd, /* Command byte */
177 DWORD arg /* Argument */
178 )
179 {
180 BYTE n, res;
181  
182  
183 if (wait_ready() != 0xFF) return 0xFF;
184  
185 /* Send command packet */
186 xmit_spi(cmd); /* Command */
187 xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
188 xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
189 xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
190 xmit_spi((BYTE)arg); /* Argument[7..0] */
191 n = 0;
192 if (cmd == CMD0) n = 0x95; /* CRC for CMD0(0) */
193 if (cmd == CMD8) n = 0x87; /* CRC for CMD8(0x1AA) */
194 xmit_spi(n);
195  
196 /* Receive command response */
197 if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
198 n = 10; /* Wait for a valid response in timeout of 10 attempts */
199 do
200 res = rcvr_spi();
201 while ((res & 0x80) && --n);
202  
203 return res; /* Return with the response value */
204 }
205  
206  
207  
208  
209 /*--------------------------------------------------------------------------
210  
211 Public Functions
212  
213 ---------------------------------------------------------------------------*/
214  
215  
216 /*-----------------------------------------------------------------------*/
217 /* Initialize Disk Drive */
218 /*-----------------------------------------------------------------------*/
219  
220 DSTATUS disk_initialize (
221 BYTE drv /* Physical drive nmuber (0) */
222 )
223 {
224 BYTE n, ty, ocr[4];
225  
226  
227 if (drv) return STA_NOINIT; /* Supports only single drive */
228 if (Stat & STA_NODISK) return Stat; /* No card in the socket */
229  
230 for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */
231  
232 SELECT(); /* CS = L */
233 ty = 0;
234 if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
235 Timer1 = 100; /* Initialization timeout of 1000 msec */
236 if (send_cmd(CMD8, 0x1AA) == 1) { /* SDC Ver2+ */
237 for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
238 if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
239 do {
240 if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 1UL << 30) == 0) break; /* ACMD41 with HCS bit */
241 } while (Timer1);
242 if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit */
243 for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
244 ty = (ocr[0] & 0x40) ? 6 : 2;
245 }
246 }
247 } else { /* SDC Ver1 or MMC */
248 ty = (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1) ? 2 : 1; /* SDC : MMC */
249 do {
250 if (ty == 2) {
251 if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0) break; /* ACMD41 */
252 } else {
253 if (send_cmd(CMD1, 0) == 0) break; /* CMD1 */
254 }
255 } while (Timer1);
256 if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Select R/W block length */
257 ty = 0;
258 }
259 }
260 CardType = ty;
261 DESELECT(); /* CS = H */
262 rcvr_spi(); /* Idle (Release DO) */
263  
264 if (ty) { /* Initialization succeded */
265 Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
266 } else { /* Initialization failed */
267 Stat |= STA_NOINIT; /* Set STA_NOINIT */
268 }
269  
270 return Stat;
271 }
272  
273  
274  
275 /*-----------------------------------------------------------------------*/
276 /* Get Disk Status */
277 /*-----------------------------------------------------------------------*/
278  
279 DSTATUS disk_status (
280 BYTE drv /* Physical drive nmuber (0) */
281 )
282 {
283 if (drv) return STA_NOINIT; /* Supports only single drive */
284 return Stat;
285 }
286  
287  
288  
289 /*-----------------------------------------------------------------------*/
290 /* Read Sector(s) */
291 /*-----------------------------------------------------------------------*/
292  
293 DRESULT disk_read (
294 BYTE drv, /* Physical drive nmuber (0) */
295 BYTE *buff, /* Pointer to the data buffer to store read data */
296 DWORD sector, /* Start sector number (LBA) */
297 BYTE count /* Sector count (1..255) */
298 )
299 {
300 if (drv || !count) return RES_PARERR;
301 if (Stat & STA_NOINIT) return RES_NOTRDY;
302  
303 if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
304  
305 SELECT(); /* CS = L */
306  
307 if (count == 1) { /* Single block read */
308 if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
309 && rcvr_datablock(buff, 512))
310 count = 0;
311 }
312 else { /* Multiple block read */
313 if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
314 do {
315 if (!rcvr_datablock(buff, 512)) break;
316 buff += 512;
317 } while (--count);
318 send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
319 }
320 }
321  
322 DESELECT(); /* CS = H */
323 rcvr_spi(); /* Idle (Release DO) */
324  
325 return count ? RES_ERROR : RES_OK;
326 }
327  
328  
329  
330 /*-----------------------------------------------------------------------*/
331 /* Write Sector(s) */
332 /*-----------------------------------------------------------------------*/
333  
334 #if _READONLY == 0
335 DRESULT disk_write (
336 BYTE drv, /* Physical drive nmuber (0) */
337 const BYTE *buff, /* Pointer to the data to be written */
338 DWORD sector, /* Start sector number (LBA) */
339 BYTE count /* Sector count (1..255) */
340 )
341 {
342 if (drv || !count) return RES_PARERR;
343 if (Stat & STA_NOINIT) return RES_NOTRDY;
344 if (Stat & STA_PROTECT) return RES_WRPRT;
345  
346 if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
347  
348 SELECT(); /* CS = L */
349  
350 if (count == 1) { /* Single block write */
351 if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
352 && xmit_datablock(buff, 0xFE))
353 count = 0;
354 }
355 else { /* Multiple block write */
356 if (CardType & 2) {
357 send_cmd(CMD55, 0); send_cmd(CMD23, count); /* ACMD23 */
358 }
359 if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
360 do {
361 if (!xmit_datablock(buff, 0xFC)) break;
362 buff += 512;
363 } while (--count);
364 if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
365 count = 1;
366 }
367 }
368  
369 DESELECT(); /* CS = H */
370 rcvr_spi(); /* Idle (Release DO) */
371  
372 return count ? RES_ERROR : RES_OK;
373 }
374 #endif /* _READONLY */
375  
376  
377  
378 /*-----------------------------------------------------------------------*/
379 /* Miscellaneous Functions */
380 /*-----------------------------------------------------------------------*/
381  
382 DRESULT disk_ioctl (
383 BYTE drv, /* Physical drive nmuber (0) */
384 BYTE ctrl, /* Control code */
385 void *buff /* Buffer to send/receive data block */
386 )
387 {
388 DRESULT res;
389 BYTE n, csd[16], *ptr = buff;
390 WORD csize;
391  
392  
393 if (drv) return RES_PARERR;
394  
395 SELECT(); /* CS = L */
396  
397 res = RES_ERROR;
398 switch (ctrl) {
399 case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
400 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
401 if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
402 csize = csd[9] + ((WORD)csd[8] << 8) + 1;
403 *(DWORD*)buff = (DWORD)csize << 10;
404 } else { /* MMC or SDC ver 1.XX */
405 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
406 csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
407 *(DWORD*)buff = (DWORD)csize << (n - 9);
408 }
409 res = RES_OK;
410 }
411 break;
412  
413 case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
414 *(WORD*)buff = 512;
415 res = RES_OK;
416 break;
417  
418 case CTRL_SYNC : /* Make sure that data has been written */
419 if (wait_ready() == 0xFF)
420 res = RES_OK;
421 break;
422  
423 case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
424 if (Stat & STA_NOINIT) return RES_NOTRDY;
425 if ((send_cmd(CMD9, 0) == 0) /* READ_CSD */
426 && rcvr_datablock(ptr, 16))
427 res = RES_OK;
428 break;
429  
430 case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
431 if (Stat & STA_NOINIT) return RES_NOTRDY;
432 if ((send_cmd(CMD10, 0) == 0) /* READ_CID */
433 && rcvr_datablock(ptr, 16))
434 res = RES_OK;
435 break;
436  
437 case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
438 if (Stat & STA_NOINIT) return RES_NOTRDY;
439 if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
440 for (n = 0; n < 4; n++)
441 *ptr++ = rcvr_spi();
442 res = RES_OK;
443 }
444 break;
445  
446 default:
447 res = RES_PARERR;
448 }
449  
450 DESELECT(); /* CS = H */
451 rcvr_spi(); /* Idle (Release DO) */
452  
453 return res;
454 }
455  
456  
457  
458 /*---------------------------------------*/
459 /* Device timer interrupt procedure */
460 /* This must be called in period of 10ms */
461 /* (Platform dependent) */
462  
463 void disk_timerproc (void)
464 {
465 static BYTE pv;
466 BYTE n, s;
467  
468  
469 n = Timer1; /* 100Hz decrement timer */
470 if (n) Timer1 = --n;
471 n = Timer2;
472 if (n) Timer2 = --n;
473  
474 n = pv;
475 pv = SOCKPORT & (SOCKINS); /* Sample socket switch */
476  
477 if (n == pv) { /* Have contacts stabled? */
478 s = Stat;
479 if (pv & SOCKINS) /* INS = H (Socket empty) */
480 s |= (STA_NODISK | STA_NOINIT);
481 else /* INS = L (Card inserted) */
482 s &= ~STA_NODISK;
483  
484 Stat = s;
485 }
486 }
487