43 #define CMD_GO_IDLE_STATE 0x00 45 #define CMD_SEND_OP_COND 0x01 47 #define CMD_SEND_IF_COND 0x08 49 #define CMD_SEND_CSD 0x09 51 #define CMD_SEND_CID 0x0a 53 #define CMD_STOP_TRANSMISSION 0x0c 55 #define CMD_SEND_STATUS 0x0d 57 #define CMD_SET_BLOCKLEN 0x10 59 #define CMD_READ_SINGLE_BLOCK 0x11 61 #define CMD_READ_MULTIPLE_BLOCK 0x12 63 #define CMD_WRITE_SINGLE_BLOCK 0x18 65 #define CMD_WRITE_MULTIPLE_BLOCK 0x19 67 #define CMD_PROGRAM_CSD 0x1b 69 #define CMD_SET_WRITE_PROT 0x1c 71 #define CMD_CLR_WRITE_PROT 0x1d 73 #define CMD_SEND_WRITE_PROT 0x1e 75 #define CMD_TAG_SECTOR_START 0x20 77 #define CMD_TAG_SECTOR_END 0x21 79 #define CMD_UNTAG_SECTOR 0x22 81 #define CMD_TAG_ERASE_GROUP_START 0x23 83 #define CMD_TAG_ERASE_GROUP_END 0x24 85 #define CMD_UNTAG_ERASE_GROUP 0x25 87 #define CMD_ERASE 0x26 89 #define CMD_SD_SEND_OP_COND 0x29 91 #define CMD_LOCK_UNLOCK 0x2a 95 #define CMD_READ_OCR 0x3a 97 #define CMD_CRC_ON_OFF 0x3b 101 #define R1_IDLE_STATE 0 102 #define R1_ERASE_RESET 1 103 #define R1_ILL_COMMAND 2 104 #define R1_COM_CRC_ERR 3 105 #define R1_ERASE_SEQ_ERR 4 106 #define R1_ADDR_ERR 5 107 #define R1_PARAM_ERR 6 110 #define R2_CARD_LOCKED 0 111 #define R2_WP_ERASE_SKIP 1 113 #define R2_CARD_ERR 3 114 #define R2_CARD_ECC_FAIL 4 115 #define R2_WP_VIOLATION 5 116 #define R2_INVAL_ERASE 6 117 #define R2_OUT_OF_RANGE 7 118 #define R2_CSD_OVERWRITE 7 119 #define R2_IDLE_STATE (R1_IDLE_STATE + 8) 120 #define R2_ERASE_RESET (R1_ERASE_RESET + 8) 121 #define R2_ILL_COMMAND (R1_ILL_COMMAND + 8) 122 #define R2_COM_CRC_ERR (R1_COM_CRC_ERR + 8) 123 #define R2_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 8) 124 #define R2_ADDR_ERR (R1_ADDR_ERR + 8) 125 #define R2_PARAM_ERR (R1_PARAM_ERR + 8) 127 #define R3_OCR_MASK (0xffffffffUL) 128 #define R3_IDLE_STATE (R1_IDLE_STATE + 32) 129 #define R3_ERASE_RESET (R1_ERASE_RESET + 32) 130 #define R3_ILL_COMMAND (R1_ILL_COMMAND + 32) 131 #define R3_COM_CRC_ERR (R1_COM_CRC_ERR + 32) 132 #define R3_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 32) 133 #define R3_ADDR_ERR (R1_ADDR_ERR + 32) 134 #define R3_PARAM_ERR (R1_PARAM_ERR + 32) 136 #define DR_STATUS_MASK 0x0e 137 #define DR_STATUS_ACCEPTED 0x05 138 #define DR_STATUS_CRC_ERR 0x0a 139 #define DR_STATUS_WRITE_ERR 0x0c 142 #define SD_RAW_SPEC_1 0 143 #define SD_RAW_SPEC_2 1 144 #define SD_RAW_SPEC_SDHC 2 148 static uint8_t raw_block[512];
150 static offset_t raw_block_address;
151 #if SD_RAW_WRITE_BUFFERING 153 static uint8_t raw_block_written;
158 static uint8_t sd_raw_card_type;
183 PORTB.PIN2CTRL = PORT_OPC_WIREDANDPULL_gc;
185 PORTE.DIRSET = PIN4_bm;
194 SD_READER_SPI.CTRL = 0x53;
197 sd_raw_card_type = 0;
204 for ( uint8_t i = 0; i < 10; ++i )
215 for ( uint16_t i = 0;; ++i )
219 if ( response == (1 << R1_IDLE_STATE) )
break;
231 if ( (response & (1 << R1_ILL_COMMAND)) == 0 )
239 sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
247 if ( (response & (1 << R1_ILL_COMMAND)) == 0 )
250 sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
259 for ( uint16_t i = 0;; ++i )
261 if ( sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)) )
265 if ( sd_raw_card_type & (1 << SD_RAW_SPEC_2) ) arg = 0x40000000;
275 if ( (response & (1 << R1_IDLE_STATE)) == 0 )
break;
285 if ( sd_raw_card_type & (1 << SD_RAW_SPEC_2) )
293 if (
sd_raw_rec_byte () & 0x40 ) sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);
312 SD_READER_SPI.CTRL = 0b11010000;
316 raw_block_address = (offset_t) -1;
317 #if SD_RAW_WRITE_BUFFERING 318 raw_block_written = 1;
320 if ( !
sd_raw_read ( 0, raw_block,
sizeof(raw_block) ) )
return 0;
334 return get_pin_available() == 0x00;
345 return get_pin_locked() == 0x00;
358 SD_READER_SPI.DATA = b;
360 while ( !(SD_READER_SPI.STATUS & 0x80) )
366 while(!(SPSR & (1 << SPIF)));
367 SPSR &= ~(1 << SPIF);
383 SD_READER_SPI.DATA = 0xFF;
385 while ( !(SD_READER_SPI.STATUS & 0x80) )
388 return SD_READER_SPI.DATA;
392 while(!(SPSR & (1 << SPIF)));
393 SPSR &= ~(1 << SPIF);
422 case CMD_GO_IDLE_STATE:
425 case CMD_SEND_IF_COND:
434 for ( uint8_t i = 0; i < 10; ++i )
437 if ( response != 0xff )
break;
453 uint8_t
sd_raw_read ( offset_t offset, uint8_t* buffer, uintptr_t length )
455 offset_t block_address;
456 uint16_t block_offset;
457 uint16_t read_length;
461 block_offset = offset & 0x01ff;
462 block_address = offset - block_offset;
463 read_length = 512 - block_offset;
464 if ( read_length > length ) read_length = length;
468 if ( block_address != raw_block_address )
471 #if SD_RAW_WRITE_BUFFERING 480 if (
sd_raw_send_command ( CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address) ) )
495 uint16_t read_to = block_offset + read_length;
496 for(uint16_t i = 0; i < 512; ++i)
499 if(i >= block_offset && i < read_to)
504 uint8_t* cache = raw_block;
505 for ( uint16_t i = 0; i < 512; ++i )
507 raw_block_address = block_address;
509 memcpy ( buffer, raw_block + block_offset, read_length );
510 buffer += read_length;
527 memcpy ( buffer, raw_block + block_offset, read_length );
528 buffer += read_length;
532 length -= read_length;
533 offset += read_length;
563 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 )
565 if ( !buffer || interval == 0 || length < interval || !callback )
return 0;
568 while ( length >= interval )
573 if ( !
sd_raw_read ( offset, buffer, interval ) )
return 0;
574 if ( !callback ( buffer, offset, p ) )
break;
584 uint16_t block_offset;
585 uint16_t read_length;
587 uint8_t finished = 0;
591 block_offset = offset & 0x01ff;
592 read_length = 512 - block_offset;
596 if(
sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? offset / 512 : offset - block_offset)))
609 for(uint16_t i = 0; i < block_offset; ++i)
615 if(read_length < interval || length < interval)
619 for(uint16_t i = 0; i < interval; ++i)
622 if(!callback(buffer, offset + (512 - read_length), p))
628 read_length -= interval;
631 }
while(read_length > 0 && length > 0);
634 while(read_length-- > 0)
641 if(length < interval)
644 offset = offset - block_offset + 512;
658 #if DOXYGEN || SD_RAW_WRITE_SUPPORT 673 uint8_t
sd_raw_write ( offset_t offset,
const uint8_t* buffer, uintptr_t length )
677 offset_t block_address;
678 uint16_t block_offset;
679 uint16_t write_length;
683 block_offset = offset & 0x01ff;
684 block_address = offset - block_offset;
685 write_length = 512 - block_offset;
686 if ( write_length > length ) write_length = length;
691 if ( block_address != raw_block_address )
693 #if SD_RAW_WRITE_BUFFERING 697 if ( block_offset || write_length < 512 )
699 if ( !
sd_raw_read ( block_address, raw_block,
sizeof(raw_block) ) )
return 0;
701 raw_block_address = block_address;
704 if ( buffer != raw_block )
706 memcpy ( raw_block + block_offset, buffer, write_length );
708 #if SD_RAW_WRITE_BUFFERING 709 raw_block_written = 0;
711 if ( length == write_length )
return 1;
720 if (
sd_raw_send_command ( CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address) ) )
733 uint8_t* cache = raw_block;
734 for ( uint16_t i = 0; i < 512; ++i )
749 buffer += write_length;
750 offset += write_length;
751 length -= write_length;
753 #if SD_RAW_WRITE_BUFFERING 754 raw_block_written = 1;
762 #if DOXYGEN || SD_RAW_WRITE_SUPPORT 781 uint8_t
sd_raw_write_interval ( offset_t offset, uint8_t* buffer, uintptr_t length, sd_raw_write_interval_handler_t callback,
void* p )
784 #error "SD_RAW_WRITE_SUPPORT is not supported together with SD_RAW_SAVE_RAM" 787 if ( !buffer || !callback )
return 0;
789 uint8_t endless = (length == 0);
790 while ( endless || length > 0 )
792 uint16_t bytes_to_write = callback ( buffer, offset, p );
793 if ( !bytes_to_write )
break;
794 if ( !endless && bytes_to_write > length )
return 0;
799 if ( !
sd_raw_write ( offset, buffer, bytes_to_write ) )
return 0;
801 offset += bytes_to_write;
802 length -= bytes_to_write;
809 #if DOXYGEN || SD_RAW_WRITE_SUPPORT 824 #if SD_RAW_WRITE_BUFFERING 825 if ( raw_block_written )
return 1;
826 if ( !
sd_raw_write ( raw_block_address, raw_block,
sizeof(raw_block) ) )
return 0;
827 raw_block_written = 1;
852 memset ( info, 0,
sizeof(*info) );
864 for ( uint8_t i = 0; i < 18; ++i )
875 info->
oem[i - 1] = b;
891 info->
serial |= (uint32_t) b << ((12 - i) * 8);
904 uint8_t csd_read_bl_len = 0;
905 uint8_t csd_c_size_mult = 0;
907 uint16_t csd_c_size = 0;
909 uint32_t csd_c_size = 0;
918 for ( uint8_t i = 0; i < 18; ++i )
927 info->
format = (b & 0x0c) >> 2;
932 if ( sd_raw_card_type & (1 << SD_RAW_SPEC_2) )
948 info->
capacity = (offset_t) csd_c_size * 512 * 1024;
957 csd_read_bl_len = b & 0x0f;
960 csd_c_size = b & 0x03;
968 csd_c_size |= b >> 6;
972 csd_c_size_mult = b & 0x03;
973 csd_c_size_mult <<= 1;
976 csd_c_size_mult |= b >> 7;
978 info->
capacity = (uint32_t) csd_c_size << (csd_c_size_mult + csd_read_bl_len + 2);
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)
uint8_t sd_raw_get_info(struct sd_raw_info *info)
uint8_t manufacturing_month
static uint8_t sd_raw_rec_byte()
uint8_t manufacturing_year
XMEGA I/O Port driver header file.
SD-Card Reader Bibliothek von Roland Riegel. MMC/SD/SDHC raw access header (license: GPLv2 or LGPLv2...
uint8_t sd_raw_read(offset_t offset, uint8_t *buffer, uintptr_t length)
uint8_t flag_write_protect
static uint8_t sd_raw_send_command(uint8_t command, uint32_t arg)
uint8_t sd_raw_write_interval(offset_t offset, uint8_t *buffer, uintptr_t length, sd_raw_write_interval_handler_t callback, void *p)
uint8_t flag_write_protect_temp
uint8_t sd_raw_available()
uint8_t sd_raw_write(offset_t offset, const uint8_t *buffer, uintptr_t length)
static void sd_raw_send_byte(uint8_t b)