*/
#include <string.h>
+#include <avr/pgmspace.h>
#include <avr/io.h>
#include "sd_raw.h"
+#include <uart.h>
+
/**
* \addtogroup sd_raw MMC/SD/SDHC card raw access
*
/* private helper functions */
static void sd_raw_send_byte(uint8_t b);
-static uint8_t sd_raw_rec_byte();
+static uint8_t sd_raw_rec_byte(void);
static uint8_t sd_raw_send_command(uint8_t command, uint32_t arg);
/**
*
* \returns 0 on failure, 1 on success.
*/
-uint8_t sd_raw_init()
+uint8_t sd_raw_init(void)
{
/* enable inputs for reading card status */
configure_pin_available();
/* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
- (1 << SPE) | /* SPI Enable */
- (0 << DORD) | /* Data Order: MSB first */
- (1 << MSTR) | /* Master mode */
- (0 << CPOL) | /* Clock Polarity: SCK low when idle */
- (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
- (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
- (1 << SPR0);
+ (1 << SPE) | /* SPI Enable */
+ (0 << DORD) | /* Data Order: MSB first */
+ (1 << MSTR) | /* Master mode */
+ (0 << CPOL) | /* Clock Polarity: SCK low when idle */
+ (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
+ (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
+ (1 << SPR0);
SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */
/* initialization procedure */
sd_raw_card_type = 0;
-
+
if(!sd_raw_available())
- return 0;
+ return 0;
/* card needs 74 cycles minimum to start up */
for(uint8_t i = 0; i < 10; ++i)
{
- /* wait 8 clock cycles */
- sd_raw_rec_byte();
+ /* wait 8 clock cycles */
+ sd_raw_rec_byte();
}
/* address card */
uint8_t response;
for(uint16_t i = 0; ; ++i)
{
- response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
- if(response == (1 << R1_IDLE_STATE))
- break;
-
- if(i == 0x1ff)
- {
- unselect_card();
- return 0;
- }
+ response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
+ if(response == (1 << R1_IDLE_STATE))
+ break;
+
+ if(i == 0x1ff)
+ {
+ unselect_card();
+ return 0;
+ }
}
#if SD_RAW_SDHC
response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 /* 2.7V - 3.6V */ | 0xaa /* test pattern */);
if((response & (1 << R1_ILL_COMMAND)) == 0)
{
- sd_raw_rec_byte();
- sd_raw_rec_byte();
- if((sd_raw_rec_byte() & 0x01) == 0)
- return 0; /* card operation voltage range doesn't match */
- if(sd_raw_rec_byte() != 0xaa)
- return 0; /* wrong test pattern */
-
- /* card conforms to SD 2 card specification */
- sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
+ sd_raw_rec_byte();
+ sd_raw_rec_byte();
+ if((sd_raw_rec_byte() & 0x01) == 0)
+ return 0; /* card operation voltage range doesn't match */
+ if(sd_raw_rec_byte() != 0xaa)
+ return 0; /* wrong test pattern */
+
+ /* card conforms to SD 2 card specification */
+ sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
}
else
#endif
{
- /* determine SD/MMC card type */
- sd_raw_send_command(CMD_APP, 0);
- response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0);
- if((response & (1 << R1_ILL_COMMAND)) == 0)
- {
- /* card conforms to SD 1 card specification */
- sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
- }
- else
- {
- /* MMC card */
- }
+ /* determine SD/MMC card type */
+ sd_raw_send_command(CMD_APP, 0);
+ response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0);
+ if((response & (1 << R1_ILL_COMMAND)) == 0)
+ {
+ /* card conforms to SD 1 card specification */
+ sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
+ }
+ else
+ {
+ /* MMC card */
+ }
}
/* wait for card to get ready */
for(uint16_t i = 0; ; ++i)
{
- if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)))
- {
- uint32_t arg = 0;
+ if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)))
+ {
+ uint32_t arg = 0;
#if SD_RAW_SDHC
- if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
- arg = 0x40000000;
+ if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
+ arg = 0x40000000;
#endif
- sd_raw_send_command(CMD_APP, 0);
- response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg);
- }
- else
- {
- response = sd_raw_send_command(CMD_SEND_OP_COND, 0);
- }
-
- if((response & (1 << R1_IDLE_STATE)) == 0)
- break;
-
- if(i == 0x7fff)
- {
- unselect_card();
- return 0;
- }
+ sd_raw_send_command(CMD_APP, 0);
+ response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg);
+ }
+ else
+ {
+ response = sd_raw_send_command(CMD_SEND_OP_COND, 0);
+ }
+
+ if((response & (1 << R1_IDLE_STATE)) == 0)
+ break;
+
+ if(i == 0x7fff)
+ {
+ unselect_card();
+ return 0;
+ }
}
#if SD_RAW_SDHC
if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
{
- if(sd_raw_send_command(CMD_READ_OCR, 0))
- {
- unselect_card();
- return 0;
- }
-
- if(sd_raw_rec_byte() & 0x40)
- sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);
-
- sd_raw_rec_byte();
- sd_raw_rec_byte();
- sd_raw_rec_byte();
+ if(sd_raw_send_command(CMD_READ_OCR, 0))
+ {
+ unselect_card();
+ return 0;
+ }
+
+ if(sd_raw_rec_byte() & 0x40)
+ sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);
+
+ sd_raw_rec_byte();
+ sd_raw_rec_byte();
+ sd_raw_rec_byte();
}
#endif
/* set block size to 512 bytes */
if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512))
{
- unselect_card();
- return 0;
+ unselect_card();
+ return 0;
}
/* deaddress card */
raw_block_written = 1;
#endif
if(!sd_raw_read(0, raw_block, sizeof(raw_block)))
- return 0;
+ return 0;
#endif
return 1;
sd_raw_send_byte((arg >> 0) & 0xff);
switch(command)
{
- case CMD_GO_IDLE_STATE:
- sd_raw_send_byte(0x95);
- break;
- case CMD_SEND_IF_COND:
- sd_raw_send_byte(0x87);
- break;
- default:
- sd_raw_send_byte(0xff);
- break;
+ case CMD_GO_IDLE_STATE:
+ sd_raw_send_byte(0x95);
+ break;
+ case CMD_SEND_IF_COND:
+ sd_raw_send_byte(0x87);
+ break;
+ default:
+ sd_raw_send_byte(0xff);
+ break;
}
-
+
/* receive response */
for(uint8_t i = 0; i < 10; ++i)
{
- response = sd_raw_rec_byte();
- if(response != 0xff)
- break;
+ response = sd_raw_rec_byte();
+ if(response != 0xff)
+ break;
}
return response;
uint16_t read_length;
while(length > 0)
{
- /* determine byte count to read at once */
- block_offset = offset & 0x01ff;
- block_address = offset - block_offset;
- read_length = 512 - block_offset; /* read up to block border */
- if(read_length > length)
- read_length = length;
-
+ /* determine byte count to read at once */
+ block_offset = offset & 0x01ff;
+ block_address = offset - block_offset;
+ read_length = 512 - block_offset; /* read up to block border */
+ if(read_length > length)
+ read_length = length;
+
#if !SD_RAW_SAVE_RAM
- /* check if the requested data is cached */
- if(block_address != raw_block_address)
+ /* check if the requested data is cached */
+ if(block_address != raw_block_address)
#endif
- {
+ {
#if SD_RAW_WRITE_BUFFERING
- if(!sd_raw_sync())
- return 0;
+ if(!sd_raw_sync())
+ return 0;
#endif
- /* address card */
- select_card();
+ /* address card */
+ select_card();
- /* send single block request */
+ /* send single block request */
#if SD_RAW_SDHC
- if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
+ if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
#else
- if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address))
+ if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address))
#endif
- {
- unselect_card();
- return 0;
- }
+ {
+ unselect_card();
+ return 0;
+ }
- /* wait for data block (start byte 0xfe) */
- while(sd_raw_rec_byte() != 0xfe);
+ /* wait for data block (start byte 0xfe) */
+ while(sd_raw_rec_byte() != 0xfe);
#if SD_RAW_SAVE_RAM
- /* read byte block */
- uint16_t read_to = block_offset + read_length;
- for(uint16_t i = 0; i < 512; ++i)
- {
- uint8_t b = sd_raw_rec_byte();
- if(i >= block_offset && i < read_to)
- *buffer++ = b;
- }
+ /* read byte block */
+ uint16_t read_to = block_offset + read_length;
+ for(uint16_t i = 0; i < 512; ++i)
+ {
+ uint8_t b = sd_raw_rec_byte();
+ if(i >= block_offset && i < read_to)
+ *buffer++ = b;
+ }
#else
- /* read byte block */
- uint8_t* cache = raw_block;
- for(uint16_t i = 0; i < 512; ++i)
- *cache++ = sd_raw_rec_byte();
- raw_block_address = block_address;
-
- memcpy(buffer, raw_block + block_offset, read_length);
- buffer += read_length;
+ /* read byte block */
+ uint8_t* cache = raw_block;
+ for(uint16_t i = 0; i < 512; ++i)
+ *cache++ = sd_raw_rec_byte();
+ raw_block_address = block_address;
+
+ memcpy(buffer, raw_block + block_offset, read_length);
+ buffer += read_length;
#endif
-
- /* read crc16 */
- sd_raw_rec_byte();
- sd_raw_rec_byte();
-
- /* deaddress card */
- unselect_card();
-
- /* let card some time to finish */
- sd_raw_rec_byte();
- }
+
+ /* read crc16 */
+ sd_raw_rec_byte();
+ sd_raw_rec_byte();
+
+ /* deaddress card */
+ unselect_card();
+
+ /* let card some time to finish */
+ sd_raw_rec_byte();
+ }
#if !SD_RAW_SAVE_RAM
- else
- {
- /* use cached data */
- memcpy(buffer, raw_block + block_offset, read_length);
- buffer += read_length;
- }
+ else
+ {
+ /* use cached data */
+ memcpy(buffer, raw_block + block_offset, read_length);
+ buffer += read_length;
+ }
#endif
- length -= read_length;
- offset += read_length;
+ length -= read_length;
+ offset += read_length;
}
return 1;
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)
{
if(!buffer || interval == 0 || length < interval || !callback)
- return 0;
+ return 0;
#if !SD_RAW_SAVE_RAM
while(length >= interval)
{
- /* as reading is now buffered, we directly
- * hand over the request to sd_raw_read()
- */
- if(!sd_raw_read(offset, buffer, interval))
- return 0;
- if(!callback(buffer, offset, p))
- break;
- offset += interval;
- length -= interval;
+ /* as reading is now buffered, we directly
+ * hand over the request to sd_raw_read()
+ */
+ if(!sd_raw_read(offset, buffer, interval))
+ return 0;
+ if(!callback(buffer, offset, p))
+ break;
+ offset += interval;
+ length -= interval;
}
return 1;
uint8_t finished = 0;
do
{
- /* determine byte count to read at once */
- block_offset = offset & 0x01ff;
- read_length = 512 - block_offset;
-
- /* send single block request */
+ /* determine byte count to read at once */
+ block_offset = offset & 0x01ff;
+ read_length = 512 - block_offset;
+
+ /* send single block request */
#if SD_RAW_SDHC
- if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? offset / 512 : offset - block_offset)))
+ if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? offset / 512 : offset - block_offset)))
#else
- if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, offset - block_offset))
+ if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, offset - block_offset))
#endif
- {
- unselect_card();
- return 0;
- }
-
- /* wait for data block (start byte 0xfe) */
- while(sd_raw_rec_byte() != 0xfe);
-
- /* read up to the data of interest */
- for(uint16_t i = 0; i < block_offset; ++i)
- sd_raw_rec_byte();
-
- /* read interval bytes of data and execute the callback */
- do
- {
- if(read_length < interval || length < interval)
- break;
-
- buffer_cur = buffer;
- for(uint16_t i = 0; i < interval; ++i)
- *buffer_cur++ = sd_raw_rec_byte();
-
- if(!callback(buffer, offset + (512 - read_length), p))
- {
- finished = 1;
- break;
- }
-
- read_length -= interval;
- length -= interval;
-
- } while(read_length > 0 && length > 0);
-
- /* read rest of data block */
- while(read_length-- > 0)
- sd_raw_rec_byte();
-
- /* read crc16 */
- sd_raw_rec_byte();
- sd_raw_rec_byte();
-
- if(length < interval)
- break;
-
- offset = offset - block_offset + 512;
+ {
+ unselect_card();
+ return 0;
+ }
+
+ /* wait for data block (start byte 0xfe) */
+ while(sd_raw_rec_byte() != 0xfe);
+
+ /* read up to the data of interest */
+ for(uint16_t i = 0; i < block_offset; ++i)
+ sd_raw_rec_byte();
+
+ /* read interval bytes of data and execute the callback */
+ do
+ {
+ if(read_length < interval || length < interval)
+ break;
+
+ buffer_cur = buffer;
+ for(uint16_t i = 0; i < interval; ++i)
+ *buffer_cur++ = sd_raw_rec_byte();
+
+ if(!callback(buffer, offset + (512 - read_length), p))
+ {
+ finished = 1;
+ break;
+ }
+
+ read_length -= interval;
+ length -= interval;
+
+ } while(read_length > 0 && length > 0);
+
+ /* read rest of data block */
+ while(read_length-- > 0)
+ sd_raw_rec_byte();
+
+ /* read crc16 */
+ sd_raw_rec_byte();
+ sd_raw_rec_byte();
+
+ if(length < interval)
+ break;
+
+ offset = offset - block_offset + 512;
} while(!finished);
-
+
/* deaddress card */
unselect_card();
uint8_t sd_raw_write(offset_t offset, const uint8_t* buffer, uintptr_t length)
{
if(sd_raw_locked())
- return 0;
+ return 0;
offset_t block_address;
uint16_t block_offset;
uint16_t write_length;
while(length > 0)
{
- /* determine byte count to write at once */
- block_offset = offset & 0x01ff;
- block_address = offset - block_offset;
- write_length = 512 - block_offset; /* write up to block border */
- if(write_length > length)
- write_length = length;
-
- /* Merge the data to write with the content of the block.
- * Use the cached block if available.
- */
- if(block_address != raw_block_address)
- {
+ /* determine byte count to write at once */
+ block_offset = offset & 0x01ff;
+ block_address = offset - block_offset;
+ write_length = 512 - block_offset; /* write up to block border */
+ if(write_length > length)
+ write_length = length;
+
+ /* Merge the data to write with the content of the block.
+ * Use the cached block if available.
+ */
+ if(block_address != raw_block_address)
+ {
#if SD_RAW_WRITE_BUFFERING
- if(!sd_raw_sync())
- return 0;
+ if(!sd_raw_sync())
+ return 0;
#endif
- if(block_offset || write_length < 512)
- {
- if(!sd_raw_read(block_address, raw_block, sizeof(raw_block)))
- return 0;
- }
- raw_block_address = block_address;
- }
+ if(block_offset || write_length < 512)
+ {
+ if(!sd_raw_read(block_address, raw_block, sizeof(raw_block)))
+ return 0;
+ }
+ raw_block_address = block_address;
+ }
- if(buffer != raw_block)
- {
- memcpy(raw_block + block_offset, buffer, write_length);
+ if(buffer != raw_block)
+ {
+ memcpy(raw_block + block_offset, buffer, write_length);
#if SD_RAW_WRITE_BUFFERING
- raw_block_written = 0;
+ raw_block_written = 0;
- if(length == write_length)
- return 1;
+ if(length == write_length)
+ return 1;
#endif
- }
+ }
- /* address card */
- select_card();
+ /* address card */
+ select_card();
- /* send single block request */
+ /* send single block request */
#if SD_RAW_SDHC
- if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
+ if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
#else
- if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address))
+ if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address))
#endif
- {
- unselect_card();
- return 0;
- }
+ {
+ unselect_card();
+ return 0;
+ }
- /* send start byte */
- sd_raw_send_byte(0xfe);
+ /* send start byte */
+ sd_raw_send_byte(0xfe);
- /* write byte block */
- uint8_t* cache = raw_block;
- for(uint16_t i = 0; i < 512; ++i)
- sd_raw_send_byte(*cache++);
+ /* write byte block */
+ uint8_t* cache = raw_block;
+ for(uint16_t i = 0; i < 512; ++i)
+ sd_raw_send_byte(*cache++);
- /* write dummy crc16 */
- sd_raw_send_byte(0xff);
- sd_raw_send_byte(0xff);
+ /* write dummy crc16 */
+ sd_raw_send_byte(0xff);
+ sd_raw_send_byte(0xff);
- /* wait while card is busy */
- while(sd_raw_rec_byte() != 0xff);
- sd_raw_rec_byte();
+ /* wait while card is busy */
+ while(sd_raw_rec_byte() != 0xff);
+ sd_raw_rec_byte();
- /* deaddress card */
- unselect_card();
+ /* deaddress card */
+ unselect_card();
- buffer += write_length;
- offset += write_length;
- length -= write_length;
+ buffer += write_length;
+ offset += write_length;
+ length -= write_length;
#if SD_RAW_WRITE_BUFFERING
- raw_block_written = 1;
+ raw_block_written = 1;
#endif
}
#endif
if(!buffer || !callback)
- return 0;
+ return 0;
uint8_t endless = (length == 0);
while(endless || length > 0)
{
- uint16_t bytes_to_write = callback(buffer, offset, p);
- if(!bytes_to_write)
- break;
- if(!endless && bytes_to_write > length)
- return 0;
-
- /* as writing is always buffered, we directly
- * hand over the request to sd_raw_write()
- */
- if(!sd_raw_write(offset, buffer, bytes_to_write))
- return 0;
-
- offset += bytes_to_write;
- length -= bytes_to_write;
+ uint16_t bytes_to_write = callback(buffer, offset, p);
+ if(!bytes_to_write)
+ break;
+ if(!endless && bytes_to_write > length)
+ return 0;
+
+ /* as writing is always buffered, we directly
+ * hand over the request to sd_raw_write()
+ */
+ if(!sd_raw_write(offset, buffer, bytes_to_write))
+ return 0;
+
+ offset += bytes_to_write;
+ length -= bytes_to_write;
}
return 1;
{
#if SD_RAW_WRITE_BUFFERING
if(raw_block_written)
- return 1;
+ return 1;
if(!sd_raw_write(raw_block_address, raw_block, sizeof(raw_block)))
- return 0;
+ return 0;
raw_block_written = 1;
#endif
return 1;
uint8_t sd_raw_get_info(struct sd_raw_info* info)
{
if(!info || !sd_raw_available())
- return 0;
+ return 0;
memset(info, 0, sizeof(*info));
/* read cid register */
if(sd_raw_send_command(CMD_SEND_CID, 0))
{
- unselect_card();
- return 0;
+ unselect_card();
+ return 0;
}
while(sd_raw_rec_byte() != 0xfe);
for(uint8_t i = 0; i < 18; ++i)
{
- uint8_t b = sd_raw_rec_byte();
-
- switch(i)
- {
- case 0:
- info->manufacturer = b;
- break;
- case 1:
- case 2:
- info->oem[i - 1] = b;
- break;
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- info->product[i - 3] = b;
- break;
- case 8:
- info->revision = b;
- break;
- case 9:
- case 10:
- case 11:
- case 12:
- info->serial |= (uint32_t) b << ((12 - i) * 8);
- break;
- case 13:
- info->manufacturing_year = b << 4;
- break;
- case 14:
- info->manufacturing_year |= b >> 4;
- info->manufacturing_month = b & 0x0f;
- break;
- }
+ uint8_t b = sd_raw_rec_byte();
+
+ switch(i)
+ {
+ case 0:
+ info->manufacturer = b;
+ break;
+ case 1:
+ case 2:
+ info->oem[i - 1] = b;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ info->product[i - 3] = b;
+ break;
+ case 8:
+ info->revision = b;
+ break;
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ info->serial |= (uint32_t) b << ((12 - i) * 8);
+ break;
+ case 13:
+ info->manufacturing_year = b << 4;
+ break;
+ case 14:
+ info->manufacturing_year |= b >> 4;
+ info->manufacturing_month = b & 0x0f;
+ break;
+ }
}
/* read csd register */
uint8_t csd_structure = 0;
if(sd_raw_send_command(CMD_SEND_CSD, 0))
{
- unselect_card();
- return 0;
+ unselect_card();
+ return 0;
}
while(sd_raw_rec_byte() != 0xfe);
for(uint8_t i = 0; i < 18; ++i)
{
- uint8_t b = sd_raw_rec_byte();
-
- if(i == 0)
- {
- csd_structure = b >> 6;
- }
- else if(i == 14)
- {
- if(b & 0x40)
- info->flag_copy = 1;
- if(b & 0x20)
- info->flag_write_protect = 1;
- if(b & 0x10)
- info->flag_write_protect_temp = 1;
- info->format = (b & 0x0c) >> 2;
- }
- else
- {
+ uint8_t b = sd_raw_rec_byte();
+
+ if(i == 0)
+ {
+ csd_structure = b >> 6;
+ (void)csd_structure;
+ }
+ else if(i == 14)
+ {
+ if(b & 0x40)
+ info->flag_copy = 1;
+ if(b & 0x20)
+ info->flag_write_protect = 1;
+ if(b & 0x10)
+ info->flag_write_protect_temp = 1;
+ info->format = (b & 0x0c) >> 2;
+ }
+ else
+ {
#if SD_RAW_SDHC
- if(csd_structure == 0x01)
- {
- switch(i)
- {
- case 7:
- b &= 0x3f;
- case 8:
- case 9:
- csd_c_size <<= 8;
- csd_c_size |= b;
- break;
- }
- if(i == 9)
- {
- ++csd_c_size;
- info->capacity = (offset_t) csd_c_size * 512 * 1024;
- }
- }
- else if(csd_structure == 0x00)
+ if(csd_structure == 0x01)
+ {
+ switch(i)
+ {
+ case 7:
+ b &= 0x3f;
+ case 8:
+ case 9:
+ csd_c_size <<= 8;
+ csd_c_size |= b;
+ break;
+ }
+ if(i == 9)
+ {
+ ++csd_c_size;
+ info->capacity = (offset_t) csd_c_size * 512 * 1024;
+ }
+ }
+ else if(csd_structure == 0x00)
#endif
- {
- switch(i)
- {
- case 5:
- csd_read_bl_len = b & 0x0f;
- break;
- case 6:
- csd_c_size = b & 0x03;
- csd_c_size <<= 8;
- break;
- case 7:
- csd_c_size |= b;
- csd_c_size <<= 2;
- break;
- case 8:
- csd_c_size |= b >> 6;
- ++csd_c_size;
- break;
- case 9:
- csd_c_size_mult = b & 0x03;
- csd_c_size_mult <<= 1;
- break;
- case 10:
- csd_c_size_mult |= b >> 7;
-
- info->capacity = (uint32_t) csd_c_size << (csd_c_size_mult + csd_read_bl_len + 2);
- break;
- }
- }
- }
+ {
+ switch(i)
+ {
+ case 5:
+ csd_read_bl_len = b & 0x0f;
+ break;
+ case 6:
+ csd_c_size = b & 0x03;
+ csd_c_size <<= 8;
+ break;
+ case 7:
+ csd_c_size |= b;
+ csd_c_size <<= 2;
+ break;
+ case 8:
+ csd_c_size |= b >> 6;
+ ++csd_c_size;
+ break;
+ case 9:
+ csd_c_size_mult = b & 0x03;
+ csd_c_size_mult <<= 1;
+ break;
+ case 10:
+ csd_c_size_mult |= b >> 7;
+
+ info->capacity = (uint32_t) csd_c_size << (csd_c_size_mult + csd_read_bl_len + 2);
+ break;
+ }
+ }
+ }
}
unselect_card();