1 http://cba.si/stuff/fatfs_diskio_sdcard_spi.c
2
3 /*
4 * (c) Domen Puncer, Visionect, d.o.o.
5 * BSD License
6 *
7 * v0.2 add support for SDHC
8 */
9
10 #include <stdio.h>
11 #include "stm32f10x_lib.h"
12
13 /*
14 * Code is split into 3 parts:
15 * - generic SPI code: adapt for your MCU
16 * - sd card code, with crc7 and crc16 calculations
17 * there's lots of it, but it's simple
18 * - fatfs interface. If you use anything else, look here for
19 * interface to SD card code
20 */
21
22 struct hwif
23 {
24 int initialized;
25 int sectors;
26 int erase_sectors;
27 int capabilities;
28 } ;
29
30 typedef struct hwif hwif;
31
32 #define CAP_VER2_00 (1<<0)
33 #define CAP_SDHC (1<<1)
34
35 enum sd_speed
36 {
37 SD_SPEED_INVALID, SD_SPEED_400KHZ, SD_SPEED_25MHZ
38 } ;
39
40 /*** spi functions ***/
41
42 static void spi_set_speed ( enum sd_speed speed );
43
44 /* SD card is connected to SPI1, PA4-7 */
45 #define SPI_SD SPI1
46
47 static void spi_init ( void )
48 {
49 GPIO_InitTypeDef gpio;
50
51 RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA, ENABLE );
52 RCC_APB2PeriphClockCmd ( RCC_APB2Periph_SPI1, ENABLE );
53
54 gpio.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
55 gpio.GPIO_Speed = GPIO_Speed_50MHz;
56 gpio.GPIO_Mode = GPIO_Mode_AF_PP;
57 GPIO_Init ( GPIOA, & gpio );
58
59 gpio.GPIO_Pin = GPIO_Pin_4;
60 gpio.GPIO_Speed = GPIO_Speed_50MHz;
61 gpio.GPIO_Mode = GPIO_Mode_Out_PP;
62 GPIO_Init ( GPIOA, & gpio );
63
64 spi_set_speed ( SD_SPEED_400KHZ );
65 }
66 #define spi_cs_low() do { GPIOA->BRR = GPIO_Pin_4; } while (0)
67 #define spi_cs_high() do { GPIOA->BSRR = GPIO_Pin_4; } while (0)
68
69 static void spi_set_speed ( enum sd_speed speed )
70 {
71 SPI_InitTypeDef spi;
72 int prescaler = SPI_BaudRatePrescaler_128;
73
74 if ( speed == SD_SPEED_400KHZ )
75 {
76 prescaler = SPI_BaudRatePrescaler_128;
77 }
78 else if ( speed == SD_SPEED_25MHZ )
79 {
80 prescaler = SPI_BaudRatePrescaler_2;
81 }
82 /* ^ with /2 APB1 this will be 15mhz/234k at 60mhz
83 * 18/281 at 72. which is ok, 100<x<400khz, and <25mhz */
84
85 SPI_Cmd ( SPI_SD, DISABLE );
86
87 spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
88 spi.SPI_Mode = SPI_Mode_Master;
89 spi.SPI_DataSize = SPI_DataSize_8b;
90 spi.SPI_CPOL = SPI_CPOL_Low;
91 spi.SPI_CPHA = SPI_CPHA_1Edge;
92
93 spi.SPI_NSS = SPI_NSS_Soft;
94 spi.SPI_BaudRatePrescaler = prescaler;
95 spi.SPI_FirstBit = SPI_FirstBit_MSB;
96 spi.SPI_CRCPolynomial = 7;
97 SPI_Init ( SPI_SD, & spi );
98
99 SPI_Cmd ( SPI_SD, ENABLE );
100 }
101
102 static u8 spi_txrx ( u8 data )
103 {
104 /* RXNE always happens after TXE, so if this function is used
105 * we don't need to check for TXE */
106 SPI_SD->DR = data;
107 while ( ( SPI_SD->SR & SPI_I2S_FLAG_RXNE ) == 0 )
108 { ;
109 }
110 return SPI_SD->DR;
111 }
112
113 /* crc helpers */
114 static u8 crc7_one ( u8 t, u8 data )
115 {
116 int i;
117 const u8 g = 0x89;
118
119 t ^= data;
120 for ( i = 0; i < 8; i++ )
121 {
122 if ( t & 0x80 )
123 {
124 t ^= g;
125 }
126 t <<= 1;
127 }
128 return t;
129 }
130
131 u8 crc7 ( const u8 * p, int len )
132 {
133 int j;
134 u8 crc = 0;
135 for ( j = 0; j < len; j++ )
136 {
137 crc = crc7_one ( crc, p[ j ] );
138 }
139
140 return crc >> 1;
141 }
142
143 /* http://www.eagleairaust.com.au/code/crc16.htm */
144 static u16 crc16_ccitt ( u16 crc, u8 ser_data )
145 {
146 crc = ( u8 )( crc >> 8 ) | ( crc << 8 );
147 crc ^= ser_data;
148 crc ^= ( u8 )( crc & 0xff ) >> 4;
149 crc ^= ( crc << 8 ) << 4;
150 crc ^= ( ( crc & 0xff ) << 4 ) << 1;
151
152 return crc;
153 }
154
155 u16 crc16 ( const u8 * p, int len )
156 {
157 int i;
158 u16 crc = 0;
159
160 for ( i = 0; i < len; i++ )
161 {
162 crc = crc16_ccitt ( crc, p[ i ] );
163 }
164
165 return crc;
166 }
167
168 /*** sd functions - on top of spi code ***/
169
170 static void sd_cmd ( u8 cmd, u32 arg )
171 {
172 u8 crc = 0;
173 spi_txrx ( 0x40 | cmd );
174 crc = crc7_one ( crc, 0x40 | cmd );
175 spi_txrx ( arg >> 24 );
176 crc = crc7_one ( crc, arg >> 24 );
177 spi_txrx ( arg >> 16 );
178 crc = crc7_one ( crc, arg >> 16 );
179 spi_txrx ( arg >> 8 );
180 crc = crc7_one ( crc, arg >> 8 );
181 spi_txrx ( arg );
182 crc = crc7_one ( crc, arg );
183 // spi_txrx(0x95); /* crc7, for cmd0 */
184 spi_txrx ( crc | 0x1 ); /* crc7, for cmd0 */
185 }
186
187 static u8 sd_get_r1 ( )
188 {
189 int tries = 1000;
190 u8 r;
191
192 while ( tries-- )
193 {
194 r = spi_txrx ( 0xff );
195 if ( ( r & 0x80 ) == 0 )
196 {
197 return r;
198 }
199 }
200 return 0xff;
201 }
202
203 static u16 sd_get_r2 ( )
204 {
205 int tries = 1000;
206 u16 r;
207
208 while ( tries-- )
209 {
210 r = spi_txrx ( 0xff );
211 if ( ( r & 0x80 ) == 0 )
212 {
213 break;
214 }
215 }
216 if ( tries < 0 )
217 {
218 return 0xff;
219 }
220 r = r << 8 | spi_txrx ( 0xff );
221
222 return r;
223 }
224
225 /*
226 * r1, then 32-bit reply... same format as r3
227 */
228 static u8 sd_get_r7 ( u32 * r7 )
229 {
230 u32 r;
231 r = sd_get_r1 ( );
232 if ( r != 0x01 )
233 {
234 return r;
235 }
236
237 r = spi_txrx ( 0xff ) << 24;
238 r |= spi_txrx ( 0xff ) << 16;
239 r |= spi_txrx ( 0xff ) << 8;
240 r |= spi_txrx ( 0xff );
241
242 *r7 = r;
243 return 0x01;
244 }
245 #define sd_get_r3 sd_get_r7
246
247 static const char * r1_strings[ 7 ] =
248 {
249 "in idle",
250 "erase reset",
251 "illegal command",
252 "communication crc error",
253 "erase sequence error",
254 "address error",
255 "parameter error"
256 } ;
257
258 static void print_r1 ( u8 r )
259 {
260 int i;
261 printf ( "R1: %02x\n", r );
262 for ( i = 0; i < 7; i++ )
263 {
264 if ( r & ( 1 << i ) )
265 {
266 printf ( " %s\n", r1_strings[ i ] );
267 }
268 }
269 }
270
271 static const char * r2_strings[ 15 ] =
272 {
273 "card is locked",
274 "wp erase skip | lock/unlock cmd failed",
275 "error",
276 "CC error",
277 "card ecc failed",
278 "wp violation",
279 "erase param",
280 "out of range | csd overwrite",
281 "in idle state",
282 "erase reset",
283 "illegal command",
284 "com crc error",
285 "erase sequence error",
286 "address error",
287 "parameter error",
288 } ;
289
290 static void print_r2 ( u16 r )
291 {
292 int i;
293 printf ( "R2: %04x\n", r );
294 for ( i = 0; i < 15; i++ )
295 {
296 if ( r & ( 1 << i ) )
297 {
298 printf ( " %s\n", r2_strings[ i ] );
299 }
300 }
301 }
302
303 /* Nec (=Ncr? which is limited to [0,8]) dummy bytes before lowering CS,
304 * as described in sandisk doc, 5.4. */
305 static void sd_nec ( )
306 {
307 int i;
308 for ( i = 0; i < 8; i++ )
309 {
310 spi_txrx ( 0xff );
311 }
312 }
313
314 static int sd_init ( hwif * hw )
315 {
316 int i;
317 int r;
318 u32 r7;
319 u32 r3;
320 int tries;
321
322 hw->capabilities = 0;
323
324 /* start with 100-400 kHz clock */
325 spi_set_speed ( SD_SPEED_400KHZ );
326
327 printf ( "cmd0 - reset.. " );
328 spi_cs_high ( );
329 /* 74+ clocks with CS high */
330 for ( i = 0; i < 10; i++ )
331 {
332 spi_txrx ( 0xff );
333 }
334
335 /* reset */
336 spi_cs_low ( );
337 sd_cmd ( 0, 0 );
338 r = sd_get_r1 ( );
339 sd_nec ( );
340 spi_cs_high ( );
341 if ( r == 0xff )
342 {
343 goto err_spi;
344 }
345 if ( r != 0x01 )
346 {
347 printf ( "fail\n" );
348 print_r1 ( r );
349 goto err;
350 }
351 printf ( "success\n" );
352
353 printf ( "cmd8 - voltage.. " );
354 /* ask about voltage supply */
355 spi_cs_low ( );
356 sd_cmd ( 8, 0x1aa /* VHS = 1 */ );
357 r = sd_get_r7 ( &r7 );
358 sd_nec ( );
359 spi_cs_high ( );
360 hw->capabilities |= CAP_VER2_00;
361 if ( r == 0xff )
362 {
363 goto err_spi;
364 }
365 if ( r == 0x01 )
366 {
367 printf ( "success, SD v2.x\n" );
368 }
369 else if ( r & 0x4 )
370 {
371 hw->capabilities &= ~CAP_VER2_00;
372 printf ( "not implemented, SD v1.x\n" );
373 }
374 else
375 {
376 printf ( "fail\n" );
377 print_r1 ( r );
378 return -2;
379 }
380
381 printf ( "cmd58 - ocr.. " );
382 /* ask about voltage supply */
383 spi_cs_low ( );
384 sd_cmd ( 58, 0 );
385 r = sd_get_r3 ( &r3 );
386 sd_nec ( );
387 spi_cs_high ( );
388 if ( r == 0xff )
389 {
390 goto err_spi;
391 }
392 if ( r != 0x01 && !( r & 0x4 ) )
393 { /* allow it to not be implemented - old cards */
394 printf ( "fail\n" );
395 print_r1 ( r );
396 return -2;
397 }
398 else
399 {
400 int i;
401 for ( i = 4; i <= 23; i++ )
402 {
403 if ( r3 & 1 << i )
404 {
405 break;
406 }
407 }
408 printf ( "Vdd voltage window: %i.%i-", ( 12 + i ) / 10, ( 12 + i ) % 10 );
409 for ( i = 23; i >= 4; i-- )
410 {
411 if ( r3 & 1 << i )
412 {
413 break;
414 }
415 }
416 /* CCS shouldn't be valid here yet */
417 printf ( "%i.%iV, CCS:%li, power up status:%li\n", ( 13 + i ) / 10,
418 ( 13 + i ) % 10, r3 >> 30 & 1, r3 >> 31 );
419 printf ( "success\n" );
420 }
421
422 printf ( "acmd41 - hcs.. " );
423 tries = 1000;
424 u32 hcs = 0;
425 /* say we support SDHC */
426 if ( hw->capabilities & CAP_VER2_00 )
427 {
428 hcs = 1 << 30;
429 }
430
431 /* needs to be polled until in_idle_state becomes 0 */
432 do
433 {
434 /* send we don't support SDHC */
435 spi_cs_low ( );
436 /* next cmd is ACMD */
437 sd_cmd ( 55, 0 );
438 r = sd_get_r1 ( );
439 sd_nec ( );
440 spi_cs_high ( );
441 if ( r == 0xff )
442 {
443 goto err_spi;
444 }
445 /* well... it's probably not idle here, but specs aren't clear */
446 if ( r & 0xfe )
447 {
448 printf ( "fail\n" );
449 print_r1 ( r );
450 goto err;
451 }
452
453 spi_cs_low ( );
454 sd_cmd ( 41, hcs );
455 r = sd_get_r1 ( );
456 sd_nec ( );
457 spi_cs_high ( );
458 if ( r == 0xff )
459 {
460 goto err_spi;
461 }
462 if ( r & 0xfe )
463 {
464 printf ( "fail\n" );
465 print_r1 ( r );
466 goto err;
467 }
468 }
469 while ( r != 0 && tries-- );
470 if ( tries == -1 )
471 {
472 printf ( "timeouted\n" );
473 goto err;
474 }
475 printf ( "success\n" );
476
477 /* Seems after this card is initialized which means bit 0 of R1
478 * will be cleared. Not too sure. */
479
480 if ( hw->capabilities & CAP_VER2_00 )
481 {
482 printf ( "cmd58 - ocr, 2nd time.. " );
483 /* ask about voltage supply */
484 spi_cs_low ( );
485 sd_cmd ( 58, 0 );
486 r = sd_get_r3 ( &r3 );
487 sd_nec ( );
488 spi_cs_high ( );
489 if ( r == 0xff )
490 {
491 goto err_spi;
492 }
493 if ( r & 0xfe )
494 {
495 printf ( "fail\n" );
496 print_r1 ( r );
497 return -2;
498 }
499 else
500 {
501 #if 1
502 int i;
503 for ( i = 4; i <= 23; i++ )
504 {
505 if ( r3 & 1 << i )
506 {
507 break;
508 }
509 }
510 printf ( "Vdd voltage window: %i.%i-", ( 12 + i ) / 10, ( 12 + i ) % 10 );
511 for ( i = 23; i >= 4; i-- )
512 {
513 if ( r3 & 1 << i )
514 {
515 break;
516 }
517 }
518 /* CCS shouldn't be valid here yet */
519 printf ( "%i.%iV, CCS:%li, power up status:%li\n", ( 13 + i ) / 10,
520 ( 13 + i ) % 10, r3 >> 30 & 1, r3 >> 31 );
521 // XXX power up status should be 1 here, since we're finished initializing, but it's not. WHY?
522 // that means CCS is invalid, so we'll set CAP_SDHC later
523 #endif
524 if ( r3 >> 30 & 1 )
525 {
526 hw->capabilities |= CAP_SDHC;
527 }
528
529 printf ( "success\n" );
530 }
531 }
532
533 /* with SDHC block length is fixed to 1024 */
534 if ( ( hw->capabilities & CAP_SDHC ) == 0 )
535 {
536 printf ( "cmd16 - block length.. " );
537 spi_cs_low ( );
538 sd_cmd ( 16, 512 );
539 r = sd_get_r1 ( );
540 sd_nec ( );
541 spi_cs_high ( );
542 if ( r == 0xff )
543 {
544 goto err_spi;
545 }
546 if ( r & 0xfe )
547 {
548 printf ( "fail\n" );
549 print_r1 ( r );
550 goto err;
551 }
552 printf ( "success\n" );
553 }
554
555 printf ( "cmd59 - enable crc.. " );
556 /* crc on */
557 spi_cs_low ( );
558 sd_cmd ( 59, 0 );
559 r = sd_get_r1 ( );
560 sd_nec ( );
561 spi_cs_high ( );
562 if ( r == 0xff )
563 {
564 goto err_spi;
565 }
566 if ( r & 0xfe )
567 {
568 printf ( "fail\n" );
569 print_r1 ( r );
570 goto err;
571 }
572 printf ( "success\n" );
573
574 /* now we can up the clock to <= 25 MHz */
575 spi_set_speed ( SD_SPEED_25MHZ );
576
577 return 0;
578
579 err_spi:
580 printf ( "fail spi\n" );
581 return -1;
582 err:
583 return -2;
584 }
585
586 static int sd_read_status ( hwif * hw )
587 {
588 u16 r2;
589
590 spi_cs_low ( );
591 sd_cmd ( 13, 0 );
592 r2 = sd_get_r2 ( );
593 sd_nec ( );
594 spi_cs_high ( );
595 if ( r2 & 0x8000 )
596 {
597 return -1;
598 }
599 if ( r2 )
600 {
601 print_r2 ( r2 );
602 }
603
604 return 0;
605 }
606
607 /* 0xfe marks data start, then len bytes of data and crc16 */
608 static int sd_get_data ( hwif * hw, u8 * buf, int len )
609 {
610 int tries = 20000;
611 u8 r;
612 u16 _crc16;
613 u16 calc_crc;
614 int i;
615
616 while ( tries-- )
617 {
618 r = spi_txrx ( 0xff );
619 if ( r == 0xfe )
620 {
621 break;
622 }
623 }
624 if ( tries < 0 )
625 {
626 return -1;
627 }
628
629 for ( i = 0; i < len; i++ )
630 {
631 buf[ i ] = spi_txrx ( 0xff );
632 }
633
634 _crc16 = spi_txrx ( 0xff ) << 8;
635 _crc16 |= spi_txrx ( 0xff );
636
637 calc_crc = crc16 ( buf, len );
638 if ( _crc16 != calc_crc )
639 {
640 printf ( "%s, crcs differ: %04x vs. %04x, len:%i\n", __func__, _crc16,
641 calc_crc, len );
642 return -1;
643 }
644
645 return 0;
646 }
647
648 static int sd_put_data ( hwif * hw, const u8 * buf, int len )
649 {
650 u8 r;
651 int tries = 10;
652 u8 b[ 16 ];
653 int bi = 0;
654 u16 crc;
655
656 spi_txrx ( 0xfe ); /* data start */
657
658 while ( len-- )
659 {
660 spi_txrx ( * buf++ );
661 }
662
663 crc = crc16 ( buf, len );
664 /* crc16 */
665 spi_txrx ( crc >> 8 );
666 spi_txrx ( crc );
667
668 /* normally just one dummy read in between... specs don't say how many */
669 while ( tries-- )
670 {
671 b[ bi++ ] = r = spi_txrx ( 0xff );
672 if ( r != 0xff )
673 {
674 break;
675 }
676 }
677 if ( tries < 0 )
678 {
679 return -1;
680 }
681
682 /* poll busy, about 300 reads for 256 MB card */
683 tries = 100000;
684 while ( tries-- )
685 {
686 if ( spi_txrx( 0xff ) == 0xff )
687 {
688 break;
689 }
690 }
691 if ( tries < 0 )
692 {
693 return -2;
694 }
695
696 /* data accepted, WIN */
697 if ( ( r & 0x1f ) == 0x05 )
698 {
699 return 0;
700 }
701
702 return r;
703 }
704
705 static int sd_read_csd ( hwif * hw )
706 {
707 u8 buf[ 16 ];
708 int r;
709 int capacity;
710
711 spi_cs_low ( );
712 sd_cmd ( 9, 0 );
713 r = sd_get_r1 ( );
714 if ( r == 0xff )
715 {
716 spi_cs_high ( );
717 return -1;
718 }
719 if ( r & 0xfe )
720 {
721 spi_cs_high ( );
722 printf ( "%s ", __func__ );
723 print_r1 ( r );
724 return -2;
725 }
726
727 r = sd_get_data ( hw, buf, 16 );
728 sd_nec ( );
729 spi_cs_high ( );
730 if ( r == -1 )
731 {
732 printf ( "failed to get csd\n" );
733 return -3;
734 }
735
736 if ( ( buf[ 0 ] >> 6 ) + 1 == 1 )
737 {
738 /* CSD v1 */
739 printf (
740 "CSD: CSD v%i taac:%02x, nsac:%i, tran:%02x, classes:%02x%x, read_bl_len:%i, " "read_bl_part:%i, write_blk_misalign:%i, read_blk_misalign:%i, dsr_imp:%i, "
741 "c_size:%i, vdd_rmin:%i, vdd_rmax:%i, vdd_wmin:%i, vdd_wmax:%i, " "c_size_mult:%i, erase_blk_en:%i, erase_s_size:%i, "
742 "wp_grp_size:%i, wp_grp_enable:%i, r2w_factor:%i, write_bl_len:%i, write_bl_part:%i, " "filef_gpr:%i, copy:%i, perm_wr_prot:%i, tmp_wr_prot:%i, filef:%i\n"
743 , ( buf[ 0 ] >> 6 ) + 1, buf[ 1 ], buf[ 2 ], buf[ 3 ], buf[ 4 ],
744 buf[ 5 ] >> 4, 1 << ( buf[ 5 ] & 0xf ),
745 /* classes, read_bl_len */ buf[ 6 ] >> 7, ( buf[ 6 ] >> 6 ) & 1,
746 ( buf[ 6 ] >> 5 ) & 1, ( buf[ 6 ] >> 4 ) & 1,
747 ( buf[ 6 ] & 0x3 ) << 10 | buf[ 7 ] << 2 | buf[ 8 ] >> 6,
748 /* c_size */ ( buf[ 8 ] & 0x38 ) >> 3, buf[ 8 ] & 0x07, buf[ 9 ] >> 5,
749 ( buf[ 9 ] >> 2 ) & 0x7,
750 1 << ( 2 + ( ( ( buf[ 9 ] & 3 ) << 1 ) | buf[ 10 ] >> 7 ) ),
751 /* c_size_mult */ ( buf[ 10 ] >> 6 ) & 1,
752 ( ( buf[ 10 ] & 0x3f ) << 1 | buf[ 11 ] >> 7 ) + 1,
753 /* erase sector size */ ( buf[ 11 ] & 0x7f ) + 1,
754 /* write protect group size */ buf[ 12 ] >> 7,
755 1 << ( ( buf[ 12 ] >> 2 ) & 7 ),
756 1 << ( ( buf[ 12 ] & 3 ) << 2 | buf[ 13 ] >> 6 ),
757 /* write_bl_len */ ( buf[ 13 ] >> 5 ) & 1, buf[ 14 ] >> 7,
758 ( buf[ 14 ] >> 6 ) & 1, ( buf[ 14 ] >> 5 ) & 1, ( buf[ 14 ] >> 4 ) & 1,
759 ( buf[ 14 ] >> 2 ) & 3 /* file format */ );
760
761 capacity = ( ( ( buf[ 6 ] & 0x3 ) << 10 | buf[ 7 ] << 2 | buf[ 8 ] >> 6 ) +
762 1 ) << ( 2 + ( ( ( buf[ 9 ] & 3 ) << 1 ) | buf[ 10 ] >> 7 ) ) <<
763 ( ( buf[ 5 ] & 0xf ) - 9 );
764 /* ^ = (c_size+1) * 2**(c_size_mult+2) * 2**(read_bl_len-9) */
765
766 }
767 else
768 {
769 /* CSD v2 */
770 /* this means the card is HC */
771 hw->capabilities |= CAP_SDHC;
772
773 printf (
774 "CSD: CSD v%i taac:%02x, nsac:%i, tran:%02x, classes:%02x%x, read_bl_len:%i, " "read_bl_part:%i, write_blk_misalign:%i, read_blk_misalign:%i, dsr_imp:%i, "
775 "c_size:%i, erase_blk_en:%i, erase_s_size:%i, " "wp_grp_size:%i, wp_grp_enable:%i, r2w_factor:%i, write_bl_len:%i, write_bl_part:%i, "
776 "filef_gpr:%i, copy:%i, perm_wr_prot:%i, tmp_wr_prot:%i, filef:%i\n",
777 ( buf[ 0 ] >> 6 ) + 1, buf[ 1 ], buf[ 2 ], buf[ 3 ], buf[ 4 ],
778 buf[ 5 ] >> 4, 1 << ( buf[ 5 ] & 0xf ),
779 /* classes, read_bl_len */ buf[ 6 ] >> 7, ( buf[ 6 ] >> 6 ) & 1,
780 ( buf[ 6 ] >> 5 ) & 1, ( buf[ 6 ] >> 4 ) & 1,
781 buf[ 7 ] << 16 | buf[ 8 ] << 8 | buf[ 9 ],
782 /* c_size */ ( buf[ 10 ] >> 6 ) & 1,
783 ( ( buf[ 10 ] & 0x3f ) << 1 | buf[ 11 ] >> 7 ) + 1,
784 /* erase sector size */ ( buf[ 11 ] & 0x7f ) + 1,
785 /* write protect group size */ buf[ 12 ] >> 7,
786 1 << ( ( buf[ 12 ] >> 2 ) & 7 ),
787 1 << ( ( buf[ 12 ] & 3 ) << 2 | buf[ 13 ] >> 6 ),
788 /* write_bl_len */ ( buf[ 13 ] >> 5 ) & 1, buf[ 14 ] >> 7,
789 ( buf[ 14 ] >> 6 ) & 1, ( buf[ 14 ] >> 5 ) & 1, ( buf[ 14 ] >> 4 ) & 1,
790 ( buf[ 14 ] >> 2 ) & 3 /* file format */ );
791
792 capacity = buf[ 7 ] << 16 | buf[ 8 ] << 8 | buf[ 9 ]; /* in 512 kB */
793 capacity *= 1024; /* in 512 B sectors */
794
795 }
796
797 printf ( "capacity = %i kB\n", capacity / 2 );
798 hw->sectors = capacity;
799
800 /* if erase_blk_en = 0, then only this many sectors can be erased at once
801 * this is NOT yet tested */
802 hw->erase_sectors = 1;
803 if ( ( ( buf[ 10 ] >> 6 ) & 1 ) == 0 )
804 {
805 hw->erase_sectors = ( ( buf[ 10 ] & 0x3f ) << 1 | buf[ 11 ] >> 7 ) + 1;
806 }
807
808 return 0;
809 }
810
811 static int sd_read_cid ( hwif * hw )
812 {
813 u8 buf[ 16 ];
814 int r;
815
816 spi_cs_low ( );
817 sd_cmd ( 10, 0 );
818 r = sd_get_r1 ( );
819 if ( r == 0xff )
820 {
821 spi_cs_high ( );
822 return -1;
823 }
824 if ( r & 0xfe )
825 {
826 spi_cs_high ( );
827 printf ( "%s ", __func__ );
828 print_r1 ( r );
829 return -2;
830 }
831
832 r = sd_get_data ( hw, buf, 16 );
833 sd_nec ( );
834 spi_cs_high ( );
835 if ( r == -1 )
836 {
837 printf ( "failed to get cid\n" );
838 return -3;
839 }
840
841 printf (
842 "CID: mid:%x, oid:%c%c, pnm:%c%c%c%c%c, prv:%i.%i, psn:%02x%02x%02x%02x, mdt:%i/%i\n",
843 buf[ 0 ], buf[ 1 ], buf[ 2 ], /* mid, oid */ buf[ 3 ], buf[ 4 ], buf[ 5 ],
844 buf[ 6 ], buf[ 7 ], /* pnm */ buf[ 8 ] >> 4, buf[ 8 ] & 0xf,
845 /* prv */ buf[ 9 ], buf[ 10 ], buf[ 11 ], buf[ 12 ],
846 /* psn */ 2000 + ( buf[ 13 ] << 4 | buf[ 14 ] >> 4 ),
847 1 + ( buf[ 14 ] & 0xf ) );
848
849 return 0;
850 }
851
852 static int sd_readsector ( hwif * hw, u32 address, u8 * buf )
853 {
854 int r;
855
856 spi_cs_low ( );
857 if ( hw->capabilities & CAP_SDHC )
858 {
859 sd_cmd ( 17, address );
860 } /* read single block */
861 else
862 {
863 sd_cmd ( 17, address * 512 );
864 } /* read single block */
865
866 r = sd_get_r1 ( );
867 if ( r == 0xff )
868 {
869 spi_cs_high ( );
870 r = -1;
871 goto fail;
872 }
873 if ( r & 0xfe )
874 {
875 spi_cs_high ( );
876 printf ( "%s\n", __func__ );
877 print_r1 ( r );
878 r = -2;
879 goto fail;
880 }
881
882 r = sd_get_data ( hw, buf, 512 );
883 sd_nec ( );
884 spi_cs_high ( );
885 if ( r == -1 )
886 {
887 r = -3;
888 goto fail;
889 }
890
891 return 0;
892 fail:
893 printf ( "failed to read sector %li, err:%i\n", address, r );
894 return r;
895 }
896
897 static int sd_writesector ( hwif * hw, u32 address, const u8 * buf )
898 {
899 int r;
900
901 spi_cs_low ( );
902 if ( hw->capabilities & CAP_SDHC )
903 {
904 sd_cmd ( 24, address );
905 } /* write block */
906 else
907 {
908 sd_cmd ( 24, address * 512 );
909 } /* write block */
910
911 r = sd_get_r1 ( );
912 if ( r == 0xff )
913 {
914 spi_cs_high ( );
915 r = -1;
916 goto fail;
917 }
918 if ( r & 0xfe )
919 {
920 spi_cs_high ( );
921 printf ( "%s\n", __func__ );
922 print_r1 ( r );
923 r = -2;
924 goto fail;
925 }
926
927 spi_txrx ( 0xff ); /* Nwr (>= 1) high bytes */
928 r = sd_put_data ( hw, buf, 512 );
929 sd_nec ( );
930 spi_cs_high ( );
931 if ( r != 0 )
932 {
933 printf ( "sd_put_data returned: %i\n", r );
934 r = -3;
935 goto fail;
936 }
937
938 /* efsl code is weird shit, 0 is error in there?
939 * not that it's properly handled or anything,
940 * and the return type is char, fucking efsl */
941 return 0;
942 fail:
943 printf ( "failed to write sector %li, err:%i\n", address, r );
944 return r;
945 }
946
947 /*** public API - on top of sd/spi code ***/
948
949 int hwif_init ( hwif * hw )
950 {
951 int tries = 10;
952
953 if ( hw->initialized )
954 {
955 return 0;
956 }
957
958 spi_init ( );
959
960 while ( tries-- )
961 {
962 if ( sd_init( hw ) == 0 )
963 {
964 break;
965 }
966 }
967 if ( tries == -1 )
968 {
969 return -1;
970 }
971
972 /* read status register */
973 sd_read_status ( hw );
974
975 sd_read_cid ( hw );
976 if ( sd_read_csd( hw ) != 0 )
977 {
978 return -1;
979 }
980
981 hw->initialized = 1;
982 return 0;
983 }
984
985 int sd_read ( hwif * hw, u32 address, u8 * buf )
986 {
987 int r;
988 int tries = 10;
989
990 r = sd_readsector ( hw, address, buf );
991
992 while ( r < 0 && tries-- )
993 {
994 if ( sd_init( hw ) != 0 )
995 {
996 continue;
997 }
998
999 /* read status register */
1000 sd_read_status ( hw );
1001
1002 r = sd_readsector ( hw, address, buf );
1003 }
1004 if ( tries == -1 )
1005 {
1006 printf ( "%s: couldn't read sector %li\n", __func__, address );
1007 }
1008
1009 return r;
1010 }
1011
1012 int sd_write ( hwif * hw, u32 address, const u8 * buf )
1013 {
1014 int r;
1015 int tries = 10;
1016
1017 r = sd_writesector ( hw, address, buf );
1018
1019 while ( r < 0 && tries-- )
1020 {
1021 if ( sd_init( hw ) != 0 )
1022 {
1023 continue;
1024 }
1025
1026 /* read status register */
1027 sd_read_status ( hw );
1028
1029 r = sd_writesector ( hw, address, buf );
1030 }
1031 if ( tries == -1 )
1032 {
1033 printf ( "%s: couldn't write sector %li\n", __func__, address );
1034 }
1035
1036 return r;
1037 }
1038
1039 /*** fatfs code that uses the public API ***/
1040
1041 #include "diskio.h"
1042
1043 hwif hw;
1044
1045 DSTATUS disk_initialize ( BYTE drv )
1046 {
1047 if ( hwif_init( &hw ) == 0 )
1048 {
1049 return 0;
1050 }
1051
1052 return STA_NOINIT;
1053 }
1054
1055 DSTATUS disk_status ( BYTE drv )
1056 {
1057 if ( hw.initialized )
1058 {
1059 return 0;
1060 }
1061
1062 return STA_NOINIT;
1063 }
1064
1065 DRESULT disk_read ( BYTE drv, BYTE * buff, DWORD sector, BYTE count )
1066 {
1067 int i;
1068
1069 for ( i = 0; i < count; i++ )
1070 {
1071 if ( sd_read( &hw, sector + i, buff + 512 * i ) != 0 )
1072 {
1073 return RES_ERROR;
1074 }
1075 }
1076
1077 return RES_OK;
1078 }
1079
1080 #if _READONLY == 0
1081
1082 DRESULT disk_write ( BYTE drv, const BYTE * buff, DWORD sector, BYTE count )
1083 {
1084 int i;
1085
1086 for ( i = 0; i < count; i++ )
1087 {
1088 if ( sd_write( &hw, sector + i, buff + 512 * i ) != 0 )
1089 {
1090 return RES_ERROR;
1091 }
1092 }
1093
1094 return RES_OK;
1095 }
1096 #endif /* _READONLY */
1097
1098 DRESULT disk_ioctl ( BYTE drv, BYTE ctrl, void * buff )
1099 {
1100 switch ( ctrl )
1101 {
1102 case CTRL_SYNC:
1103 return RES_OK;
1104 case GET_SECTOR_SIZE:
1105 *( WORD * )buff = 512;
1106 return RES_OK;
1107 case GET_SECTOR_COUNT:
1108 *( DWORD* )buff = hw.sectors;
1109 return RES_OK;
1110 case GET_BLOCK_SIZE:
1111 *( DWORD* )buff = hw.erase_sectors;
1112 return RES_OK;
1113 }
1114 return RES_PARERR;
1115 }
1116
1117 /*
1118 * FAT filestamp format:
1119 * [31:25] - year - 1980
1120 * [24:21] - month 1..12
1121 * [20:16] - day 1..31
1122 * [15:11] - hour 0..23
1123 * [10:5] - minute 0..59
1124 * [4:0] - second/2 0..29
1125 * so... midnight 2009 is 0x3a000000
1126 */
1127 DWORD get_fattime ( )
1128 {
1129 int time = RTC_GetCounter ( );
1130 int y, m, d;
1131 epoch_days_to_date ( time / DAY_SECONDS, & y, & m, & d );
1132 time %= DAY_SECONDS;
1133 return ( y - 1980 ) << 25 | m << 21 | d << 16 | ( time / 3600 ) << 11 |
1134 ( time / 60 % 60 ) << 5 | ( time / 2 % 30 );
1135 }