00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <string.h>
00012 #include <avr/io.h>
00013 #include "sd_raw.h"
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #define CMD_GO_IDLE_STATE 0x00
00045
00046 #define CMD_SEND_OP_COND 0x01
00047
00048 #define CMD_SEND_IF_COND 0x08
00049
00050 #define CMD_SEND_CSD 0x09
00051
00052 #define CMD_SEND_CID 0x0a
00053
00054 #define CMD_STOP_TRANSMISSION 0x0c
00055
00056 #define CMD_SEND_STATUS 0x0d
00057
00058 #define CMD_SET_BLOCKLEN 0x10
00059
00060 #define CMD_READ_SINGLE_BLOCK 0x11
00061
00062 #define CMD_READ_MULTIPLE_BLOCK 0x12
00063
00064 #define CMD_WRITE_SINGLE_BLOCK 0x18
00065
00066 #define CMD_WRITE_MULTIPLE_BLOCK 0x19
00067
00068 #define CMD_PROGRAM_CSD 0x1b
00069
00070 #define CMD_SET_WRITE_PROT 0x1c
00071
00072 #define CMD_CLR_WRITE_PROT 0x1d
00073
00074 #define CMD_SEND_WRITE_PROT 0x1e
00075
00076 #define CMD_TAG_SECTOR_START 0x20
00077
00078 #define CMD_TAG_SECTOR_END 0x21
00079
00080 #define CMD_UNTAG_SECTOR 0x22
00081
00082 #define CMD_TAG_ERASE_GROUP_START 0x23
00083
00084 #define CMD_TAG_ERASE_GROUP_END 0x24
00085
00086 #define CMD_UNTAG_ERASE_GROUP 0x25
00087
00088 #define CMD_ERASE 0x26
00089
00090 #define CMD_SD_SEND_OP_COND 0x29
00091
00092 #define CMD_LOCK_UNLOCK 0x2a
00093
00094 #define CMD_APP 0x37
00095
00096 #define CMD_READ_OCR 0x3a
00097
00098 #define CMD_CRC_ON_OFF 0x3b
00099
00100
00101
00102 #define R1_IDLE_STATE 0
00103 #define R1_ERASE_RESET 1
00104 #define R1_ILL_COMMAND 2
00105 #define R1_COM_CRC_ERR 3
00106 #define R1_ERASE_SEQ_ERR 4
00107 #define R1_ADDR_ERR 5
00108 #define R1_PARAM_ERR 6
00109
00110
00111 #define R2_CARD_LOCKED 0
00112 #define R2_WP_ERASE_SKIP 1
00113 #define R2_ERR 2
00114 #define R2_CARD_ERR 3
00115 #define R2_CARD_ECC_FAIL 4
00116 #define R2_WP_VIOLATION 5
00117 #define R2_INVAL_ERASE 6
00118 #define R2_OUT_OF_RANGE 7
00119 #define R2_CSD_OVERWRITE 7
00120 #define R2_IDLE_STATE (R1_IDLE_STATE + 8)
00121 #define R2_ERASE_RESET (R1_ERASE_RESET + 8)
00122 #define R2_ILL_COMMAND (R1_ILL_COMMAND + 8)
00123 #define R2_COM_CRC_ERR (R1_COM_CRC_ERR + 8)
00124 #define R2_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 8)
00125 #define R2_ADDR_ERR (R1_ADDR_ERR + 8)
00126 #define R2_PARAM_ERR (R1_PARAM_ERR + 8)
00127
00128 #define R3_OCR_MASK (0xffffffffUL)
00129 #define R3_IDLE_STATE (R1_IDLE_STATE + 32)
00130 #define R3_ERASE_RESET (R1_ERASE_RESET + 32)
00131 #define R3_ILL_COMMAND (R1_ILL_COMMAND + 32)
00132 #define R3_COM_CRC_ERR (R1_COM_CRC_ERR + 32)
00133 #define R3_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 32)
00134 #define R3_ADDR_ERR (R1_ADDR_ERR + 32)
00135 #define R3_PARAM_ERR (R1_PARAM_ERR + 32)
00136
00137 #define DR_STATUS_MASK 0x0e
00138 #define DR_STATUS_ACCEPTED 0x05
00139 #define DR_STATUS_CRC_ERR 0x0a
00140 #define DR_STATUS_WRITE_ERR 0x0c
00141
00142
00143 #define SD_RAW_SPEC_1 0
00144 #define SD_RAW_SPEC_2 1
00145 #define SD_RAW_SPEC_SDHC 2
00146
00147 #if !SD_RAW_SAVE_RAM
00148
00149 static uint8_t raw_block[512];
00150
00151 static offset_t raw_block_address;
00152 #if SD_RAW_WRITE_BUFFERING
00153
00154 static uint8_t raw_block_written;
00155 #endif
00156 #endif
00157
00158
00159 static uint8_t sd_raw_card_type;
00160
00161
00162 static void sd_raw_send_byte(uint8_t b);
00163 static uint8_t sd_raw_rec_byte();
00164 static uint8_t sd_raw_send_command(uint8_t command, uint32_t arg);
00165
00166
00167
00168
00169
00170
00171
00172
00173 uint8_t sd_raw_init()
00174 {
00175
00176 configure_pin_available();
00177
00178
00179
00180
00181
00182
00183 SPCR = (0 << SPIE) |
00184 (1 << SPE) |
00185 (0 << DORD) |
00186 (1 << MSTR) |
00187 (0 << CPOL) |
00188 (0 << CPHA) |
00189 (1 << SPR1) |
00190 (1 << SPR0);
00191 SPSR &= ~(1 << SPI2X);
00192
00193
00194 configure_pin_mosi();
00195 configure_pin_sck();
00196 configure_pin_ss();
00197 configure_pin_miso();
00198
00199
00200
00201
00202
00203 sd_raw_card_type = 0;
00204
00205
00206
00207
00208
00209 uint16_t i=0;
00210
00211 for(i = 0; i < 10; ++i)
00212 {
00213
00214 sd_raw_rec_byte();
00215 }
00216
00217
00218 select_card();
00219
00220
00221 uint8_t response;
00222 for( i = 0; ; ++i)
00223 {
00224 response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
00225 if(response == (1 << R1_IDLE_STATE))
00226 break;
00227
00228 if(i == 0x1ff)
00229 {
00230 unselect_card();
00231 return 0;
00232 }
00233 }
00234
00235 #if SD_RAW_SDHC
00236
00237 response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 | 0xaa );
00238 if((response & (1 << R1_ILL_COMMAND)) == 0)
00239 {
00240 sd_raw_rec_byte();
00241 sd_raw_rec_byte();
00242 if((sd_raw_rec_byte() & 0x01) == 0)
00243 return 0;
00244 if(sd_raw_rec_byte() != 0xaa)
00245 return 0;
00246
00247
00248 sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
00249 }
00250 else
00251 #endif
00252 {
00253
00254 sd_raw_send_command(CMD_APP, 0);
00255 response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0);
00256 if((response & (1 << R1_ILL_COMMAND)) == 0)
00257 {
00258
00259 sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
00260 }
00261 else
00262 {
00263
00264 }
00265 }
00266
00267
00268 for( i = 0; ; ++i)
00269 {
00270 if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)))
00271 {
00272 uint32_t arg = 0;
00273 #if SD_RAW_SDHC
00274 if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
00275 arg = 0x40000000;
00276 #endif
00277 sd_raw_send_command(CMD_APP, 0);
00278 response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg);
00279 }
00280 else
00281 {
00282 response = sd_raw_send_command(CMD_SEND_OP_COND, 0);
00283 }
00284
00285 if((response & (1 << R1_IDLE_STATE)) == 0)
00286 break;
00287
00288 if(i == 0x7fff)
00289 {
00290 unselect_card();
00291 return 0;
00292 }
00293 }
00294
00295 #if SD_RAW_SDHC
00296 if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
00297 {
00298 if(sd_raw_send_command(CMD_READ_OCR, 0))
00299 {
00300 unselect_card();
00301 return 0;
00302 }
00303
00304 if(sd_raw_rec_byte() & 0x40)
00305 sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);
00306
00307 sd_raw_rec_byte();
00308 sd_raw_rec_byte();
00309 sd_raw_rec_byte();
00310 }
00311 #endif
00312
00313
00314 if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512))
00315 {
00316 unselect_card();
00317 return 0;
00318 }
00319
00320
00321 unselect_card();
00322
00323
00324 SPCR &= ~((1 << SPR1) | (1 << SPR0));
00325 SPSR |= (1 << SPI2X);
00326
00327 #if !SD_RAW_SAVE_RAM
00328
00329 raw_block_address = (offset_t) -1;
00330 #if SD_RAW_WRITE_BUFFERING
00331 raw_block_written = 1;
00332 #endif
00333 if(!sd_raw_read(0, raw_block, sizeof(raw_block)))
00334 return 0;
00335 #endif
00336
00337 return 1;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346 uint8_t sd_raw_available()
00347 {
00348 return get_pin_available() == 0x00;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357 uint8_t sd_raw_locked()
00358 {
00359 return get_pin_locked() == 0x00;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369 void sd_raw_send_byte(uint8_t b)
00370 {
00371 SPDR = b;
00372
00373 while(!(SPSR & (1 << SPIF)));
00374 SPSR &= ~(1 << SPIF);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 uint8_t sd_raw_rec_byte()
00385 {
00386
00387 SPDR = 0xff;
00388 while(!(SPSR & (1 << SPIF)));
00389 SPSR &= ~(1 << SPIF);
00390
00391 return SPDR;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 uint8_t sd_raw_send_command(uint8_t command, uint32_t arg)
00403 {
00404 uint8_t response;
00405
00406
00407 sd_raw_rec_byte();
00408
00409
00410 sd_raw_send_byte(0x40 | command);
00411 sd_raw_send_byte((arg >> 24) & 0xff);
00412 sd_raw_send_byte((arg >> 16) & 0xff);
00413 sd_raw_send_byte((arg >> 8) & 0xff);
00414 sd_raw_send_byte((arg >> 0) & 0xff);
00415 switch(command)
00416 {
00417 case CMD_GO_IDLE_STATE:
00418 sd_raw_send_byte(0x95);
00419 break;
00420 case CMD_SEND_IF_COND:
00421 sd_raw_send_byte(0x87);
00422 break;
00423 default:
00424 sd_raw_send_byte(0xff);
00425 break;
00426 }
00427
00428
00429 uint8_t i=0;
00430 for( i = 0; i < 10; ++i)
00431 {
00432 response = sd_raw_rec_byte();
00433 if(response != 0xff)
00434 break;
00435 }
00436
00437 return response;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 uint8_t sd_raw_read(offset_t offset, uint8_t* buffer, uintptr_t length)
00451 {
00452 offset_t block_address;
00453 uint16_t block_offset;
00454 uint16_t read_length;
00455 uint16_t i=0;
00456
00457 while(length > 0)
00458 {
00459
00460 block_offset = offset & 0x01ff;
00461 block_address = offset - block_offset;
00462 read_length = 512 - block_offset;
00463 if(read_length > length)
00464 read_length = length;
00465
00466 #if !SD_RAW_SAVE_RAM
00467
00468 if(block_address != raw_block_address)
00469 #endif
00470 {
00471 #if SD_RAW_WRITE_BUFFERING
00472 if(!sd_raw_sync())
00473 return 0;
00474 #endif
00475
00476
00477 select_card();
00478
00479
00480 #if SD_RAW_SDHC
00481 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
00482 #else
00483 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address))
00484 #endif
00485 {
00486 unselect_card();
00487 return 0;
00488 }
00489
00490
00491 while(sd_raw_rec_byte() != 0xfe);
00492
00493 #if SD_RAW_SAVE_RAM
00494
00495 uint16_t read_to = block_offset + read_length;
00496 for( i = 0; i < 512; ++i)
00497 {
00498 uint8_t b = sd_raw_rec_byte();
00499 if(i >= block_offset && i < read_to)
00500 *buffer++ = b;
00501 }
00502 #else
00503
00504 uint8_t* cache = raw_block;
00505 for( i = 0; i < 512; ++i)
00506 *cache++ = sd_raw_rec_byte();
00507 raw_block_address = block_address;
00508
00509 memcpy(buffer, raw_block + block_offset, read_length);
00510 buffer += read_length;
00511 #endif
00512
00513
00514 sd_raw_rec_byte();
00515 sd_raw_rec_byte();
00516
00517
00518 unselect_card();
00519
00520
00521 sd_raw_rec_byte();
00522 }
00523 #if !SD_RAW_SAVE_RAM
00524 else
00525 {
00526
00527 memcpy(buffer, raw_block + block_offset, read_length);
00528 buffer += read_length;
00529 }
00530 #endif
00531
00532 length -= read_length;
00533 offset += read_length;
00534 }
00535
00536 return 1;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 uint8_t sd_raw_read_interval(offset_t offset, uint8_t* buffer, uintptr_t interval, uintptr_t length, sd_raw_read_interval_handler_t callback, void* p)
00564 {
00565 if(!buffer || interval == 0 || length < interval || !callback)
00566 return 0;
00567
00568 #if !SD_RAW_SAVE_RAM
00569 while(length >= interval)
00570 {
00571
00572
00573
00574 if(!sd_raw_read(offset, buffer, interval))
00575 return 0;
00576 if(!callback(buffer, offset, p))
00577 break;
00578 offset += interval;
00579 length -= interval;
00580 }
00581
00582 return 1;
00583 #else
00584
00585 select_card();
00586
00587 uint16_t block_offset;
00588 uint16_t read_length;
00589 uint8_t* buffer_cur;
00590 uint8_t finished = 0;
00591 uint16_t i=0;
00592
00593 do
00594 {
00595
00596 block_offset = offset & 0x01ff;
00597 read_length = 512 - block_offset;
00598
00599
00600 #if SD_RAW_SDHC
00601 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? offset / 512 : offset - block_offset)))
00602 #else
00603 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, offset - block_offset))
00604 #endif
00605 {
00606 unselect_card();
00607 return 0;
00608 }
00609
00610
00611 while(sd_raw_rec_byte() != 0xfe);
00612
00613
00614 for( i = 0; i < block_offset; ++i)
00615 sd_raw_rec_byte();
00616
00617
00618 do
00619 {
00620 if(read_length < interval || length < interval)
00621 break;
00622
00623 buffer_cur = buffer;
00624 for( i = 0; i < interval; ++i)
00625 *buffer_cur++ = sd_raw_rec_byte();
00626
00627 if(!callback(buffer, offset + (512 - read_length), p))
00628 {
00629 finished = 1;
00630 break;
00631 }
00632
00633 read_length -= interval;
00634 length -= interval;
00635
00636 } while(read_length > 0 && length > 0);
00637
00638
00639 while(read_length-- > 0)
00640 sd_raw_rec_byte();
00641
00642
00643 sd_raw_rec_byte();
00644 sd_raw_rec_byte();
00645
00646 if(length < interval)
00647 break;
00648
00649 offset = offset - block_offset + 512;
00650
00651 } while(!finished);
00652
00653
00654 unselect_card();
00655
00656
00657 sd_raw_rec_byte();
00658
00659 return 1;
00660 #endif
00661 }
00662
00663 #if DOXYGEN || SD_RAW_WRITE_SUPPORT
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 uint8_t sd_raw_write(offset_t offset, const uint8_t* buffer, uintptr_t length)
00679 {
00680
00681
00682
00683 offset_t block_address;
00684 uint16_t block_offset;
00685 uint16_t write_length;
00686 uint16_t i=0;
00687
00688 while(length > 0)
00689 {
00690
00691 block_offset = offset & 0x01ff;
00692 block_address = offset - block_offset;
00693 write_length = 512 - block_offset;
00694 if(write_length > length)
00695 write_length = length;
00696
00697
00698
00699
00700 if(block_address != raw_block_address)
00701 {
00702 #if SD_RAW_WRITE_BUFFERING
00703 if(!sd_raw_sync())
00704 return 0;
00705 #endif
00706
00707 if(block_offset || write_length < 512)
00708 {
00709 if(!sd_raw_read(block_address, raw_block, sizeof(raw_block))){
00710 return 0;
00711 }
00712 }
00713 raw_block_address = block_address;
00714 }
00715
00716 if(buffer != raw_block)
00717 {
00718 memcpy(raw_block + block_offset, buffer, write_length);
00719
00720 #if SD_RAW_WRITE_BUFFERING
00721 raw_block_written = 0;
00722
00723 if(length == write_length){
00724 return 1;
00725 }
00726 #endif
00727 }
00728
00729
00730 select_card();
00731
00732
00733 #if SD_RAW_SDHC
00734 if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
00735 #else
00736 if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address))
00737 #endif
00738 {
00739 unselect_card();
00740 return 0;
00741 }
00742
00743
00744 sd_raw_send_byte(0xfe);
00745
00746
00747 uint8_t* cache = raw_block;
00748 for( i = 0; i < 512; ++i)
00749 sd_raw_send_byte(*cache++);
00750
00751
00752 sd_raw_send_byte(0xff);
00753 sd_raw_send_byte(0xff);
00754
00755
00756 while(sd_raw_rec_byte() != 0xff);
00757 sd_raw_rec_byte();
00758
00759
00760 unselect_card();
00761
00762 buffer += write_length;
00763 offset += write_length;
00764 length -= write_length;
00765
00766 #if SD_RAW_WRITE_BUFFERING
00767 raw_block_written = 1;
00768 #endif
00769 }
00770 return 1;
00771 }
00772 #endif
00773
00774 #if DOXYGEN || SD_RAW_WRITE_SUPPORT
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 uint8_t sd_raw_write_interval(offset_t offset, uint8_t* buffer, uintptr_t length, sd_raw_write_interval_handler_t callback, void* p)
00794 {
00795 #if SD_RAW_SAVE_RAM
00796 #error "SD_RAW_WRITE_SUPPORT is not supported together with SD_RAW_SAVE_RAM"
00797 #endif
00798
00799 if(!buffer || !callback)
00800 return 0;
00801
00802 uint8_t endless = (length == 0);
00803 while(endless || length > 0)
00804 {
00805 uint16_t bytes_to_write = callback(buffer, offset, p);
00806 if(!bytes_to_write)
00807 break;
00808 if(!endless && bytes_to_write > length)
00809 return 0;
00810
00811
00812
00813
00814 if(!sd_raw_write(offset, buffer, bytes_to_write))
00815 return 0;
00816
00817 offset += bytes_to_write;
00818 length -= bytes_to_write;
00819 }
00820
00821 return 1;
00822 }
00823 #endif
00824
00825 #if DOXYGEN || SD_RAW_WRITE_SUPPORT
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 uint8_t sd_raw_sync()
00839 {
00840 #if SD_RAW_WRITE_BUFFERING
00841 if(raw_block_written)
00842 return 1;
00843 if(!sd_raw_write(raw_block_address, raw_block, sizeof(raw_block)))
00844 return 0;
00845 raw_block_written = 1;
00846 #endif
00847 return 1;
00848 }
00849 #endif
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 uint8_t sd_raw_get_info(struct sd_raw_info* info)
00867 {
00868 uint16_t i=0;
00869
00870
00871
00872
00873 if(!info )
00874 return 0;
00875
00876 memset(info, 0, sizeof(*info));
00877
00878 select_card();
00879
00880
00881 if(sd_raw_send_command(CMD_SEND_CID, 0))
00882 {
00883 unselect_card();
00884 return 0;
00885 }
00886 while(sd_raw_rec_byte() != 0xfe);
00887 for( i = 0; i < 18; ++i)
00888 {
00889 uint8_t b = sd_raw_rec_byte();
00890
00891 switch(i)
00892 {
00893 case 0:
00894 info->manufacturer = b;
00895 break;
00896 case 1:
00897 case 2:
00898 info->oem[i - 1] = b;
00899 break;
00900 case 3:
00901 case 4:
00902 case 5:
00903 case 6:
00904 case 7:
00905 info->product[i - 3] = b;
00906 break;
00907 case 8:
00908 info->revision = b;
00909 break;
00910 case 9:
00911 case 10:
00912 case 11:
00913 case 12:
00914 info->serial |= (uint32_t) b << ((12 - i) * 8);
00915 break;
00916 case 13:
00917 info->manufacturing_year = b << 4;
00918 break;
00919 case 14:
00920 info->manufacturing_year |= b >> 4;
00921 info->manufacturing_month = b & 0x0f;
00922 break;
00923 }
00924 }
00925
00926
00927 uint8_t csd_read_bl_len = 0;
00928 uint8_t csd_c_size_mult = 0;
00929 #if SD_RAW_SDHC
00930 uint16_t csd_c_size = 0;
00931 #else
00932 uint32_t csd_c_size = 0;
00933 #endif
00934 if(sd_raw_send_command(CMD_SEND_CSD, 0))
00935 {
00936 unselect_card();
00937 return 0;
00938 }
00939 while(sd_raw_rec_byte() != 0xfe);
00940 for( i = 0; i < 18; ++i)
00941 {
00942 uint8_t b = sd_raw_rec_byte();
00943
00944 if(i == 14)
00945 {
00946 if(b & 0x40)
00947 info->flag_copy = 1;
00948 if(b & 0x20)
00949 info->flag_write_protect = 1;
00950 if(b & 0x10)
00951 info->flag_write_protect_temp = 1;
00952 info->format = (b & 0x0c) >> 2;
00953 }
00954 else
00955 {
00956 #if SD_RAW_SDHC
00957 if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
00958 {
00959 switch(i)
00960 {
00961 case 7:
00962 b &= 0x3f;
00963 case 8:
00964 case 9:
00965 csd_c_size <<= 8;
00966 csd_c_size |= b;
00967 break;
00968 }
00969 if(i == 9)
00970 {
00971 ++csd_c_size;
00972 info->capacity = (offset_t) csd_c_size * 512 * 1024;
00973 }
00974 }
00975 else
00976 #endif
00977 {
00978 switch(i)
00979 {
00980 case 5:
00981 csd_read_bl_len = b & 0x0f;
00982 break;
00983 case 6:
00984 csd_c_size = b & 0x03;
00985 csd_c_size <<= 8;
00986 break;
00987 case 7:
00988 csd_c_size |= b;
00989 csd_c_size <<= 2;
00990 break;
00991 case 8:
00992 csd_c_size |= b >> 6;
00993 ++csd_c_size;
00994 break;
00995 case 9:
00996 csd_c_size_mult = b & 0x03;
00997 csd_c_size_mult <<= 1;
00998 break;
00999 case 10:
01000 csd_c_size_mult |= b >> 7;
01001
01002 info->capacity = (uint32_t) csd_c_size << (csd_c_size_mult + csd_read_bl_len + 2);
01003
01004 break;
01005 }
01006 }
01007 }
01008 }
01009
01010 unselect_card();
01011
01012 return 1;
01013 }
01014