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 }