stm32 spi sdcard fatfs

   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 }
posted @ 2012-07-31 14:34  IAmAProgrammer  阅读(2385)  评论(0编辑  收藏  举报