flash_sdcard: add flash_sdcard_size to get SD card size

This commit is contained in:
King Kévin 2017-07-01 18:43:58 +02:00
parent 360202c073
commit 22d4dc31f8
2 changed files with 35 additions and 4 deletions

View File

@ -19,6 +19,7 @@
* @note peripherals used: SPI @ref flash_sdcard_spi
* @warning all calls are blocking
* @implements SD Specifications, Part 1, Physical Layer, Simplified Specification, Version 6.00, 10 April 10 2017
* @todo use SPI unidirectional mode and DMA
*/
/* standard libraries */
@ -40,7 +41,9 @@
#define FLASH_SDCARD_SPI 1 /**< SPI peripheral */
/** @} */
/** maximum N_AC value (time between the response token R1 and data block when reading data (see section 7.5.4)
/** if the card has been initialized successfully */
static bool initialized = false;
/** maximum N_AC value (in 8-clock cycles) (time between the response token R1 and data block when reading data (see section 7.5.4)
* @note this is set to N_CR until we can read CSD (see section 7.2.6)
*/
static uint32_t n_ac = 8;
@ -49,6 +52,8 @@ static uint32_t n_ac = 8;
* @note this is important for addressing: for standard capacity cards the address is the byte number, for high capacity cards it is the 512-byte block number
*/
static bool sdsc = false;
/** size of card in bytes */
static uint64_t sdcard_size = 0;
/** table for CRC-7 calculation for the command messages (see section 4.5)
* @note faster than calculating the CRC and doesn't cost a lot of space
@ -222,6 +227,11 @@ static uint8_t flash_sdcard_data_read(uint8_t index, uint32_t argument, uint8_t*
bool flash_sdcard_setup(void)
{
// reset values
initialized = false;
n_ac = 8;
sdcard_size = 0;
// check if card is present
if (!flash_sdcard_card_detect()) {
return false;
@ -314,10 +324,10 @@ bool flash_sdcard_setup(void)
return false;
}
// check if CSD structure version matches capacity (see section 5.3.1)
if ((sdsc && (csd[0]&0xc0)) || (!sdsc && 0x40!=(csd[0]&0xc0))) {
if ((sdsc && (csd[0]>>6)) || (!sdsc && 0==(csd[0]>>6))) {
return false;
}
// we use our set minimum frequency 16 MHz to calculate time
// calculate N_AC value (we use our set minimum frequency 16 MHz to calculate time)
if (sdsc) { // calculate N_AC using TAAC and NSAC
static const float TAAC_UNITS[] = {1E-9, 10E-9, 100E-9, 1E-6, 10E-6, 100E-6, 1E-3, 10E-3}; // (see table 5-5)
static const float TAAC_VALUES[] = {10.0, 1.0, 1.2, 1.3, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 7.0, 8.0}; // (see table 5-5)
@ -326,6 +336,16 @@ bool flash_sdcard_setup(void)
} else { // value is fixed to 100 ms
n_ac=100E-3*16E6/8;
}
// calculate size
if (sdsc) { // see section 5.3.2
uint16_t c_size = (((uint16_t)csd[6]&0x03)<<10)+((uint16_t)csd[7]<<2)+(csd[8]>>6);
uint8_t c_size_mutl = ((csd[9]&0x03)<<1)+((csd[10]&0x80)>>7);
uint8_t read_bl_len = (csd[5]&0x0f);
sdcard_size = ((c_size+1)*(1UL<<(c_size_mutl+2)))*(1UL<<read_bl_len);
} else { // see section 5.3.3
uint32_t c_size = ((uint32_t)(csd[7]&0x3f)<<16)+((uint16_t)csd[8]<<8)+csd[9];
sdcard_size = (c_size+1)*(512<<10);
}
// ensure block length is 512 bytes for SDSC (should be per default) to we match SDHC/SDXC block size
if (sdsc) {
@ -364,5 +384,12 @@ bool flash_sdcard_setup(void)
n_ac = n_ac_back; // restore N_AC
}
return true;
initialized = true;
return initialized;
}
uint64_t flash_sdcard_size(void)
{
return sdcard_size;
}

View File

@ -25,3 +25,7 @@
* @return if card has been initialized correctly
*/
bool flash_sdcard_setup(void);
/** return size of SD card flash memory
* @return size of SD card flash memory in bytes
*/
uint64_t flash_sdcard_size(void);