cancel
Showing results for 
Search instead for 
Did you mean: 

SDHC and SDXC ?

antonius
Senior
Posted on April 20, 2014 at 05:22

Guys,

I tried to read SDHC 8Gb with SDIO and it works fine, but when I change into 64Gb SDXC, it doesn't work ?

Do you have any ideas what the cause is ?

When I tried with SPI and Atmega controller and SPI , they're all working properly.

Thanks
17 REPLIES 17
Posted on April 20, 2014 at 06:08

Do you have any ideas what the cause is ?

Well my list of probable issues would by the driver, the commands it uses, and the block/byte addressing methods employed, and the file system, the 64GB card likely doesn't use FAT32.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on April 20, 2014 at 13:55

I used FAT32 for 64 Gb and it works fine on atmega MCU with SPI, and I'm still using FAT32 for STM32 with SDIO interface, I'll see the driver....

I'm using FATFs for STM32......

antonius
Senior
Posted on April 20, 2014 at 13:58

I tested with 1Gb and it doesn't work too....strange..

antonius
Senior
Posted on April 21, 2014 at 03:51

Probably from here ?

What's HCLK ? is it 72MHz ? I have 8MHz external Crystal * @brief SDIO Intialization Frequency (400KHz max) */ #define SDIO_INIT_CLK_DIV ((uint8_t)0xB2) //#define SDIO_INIT_CLK_DIV ((uint8_t)0xB5)


/*!< Power ON Sequence -----------------------------------------------------*/

/*!< Configure the SDIO peripheral */

/*!< SDIOCLK = HCLK, SDIO_CK = HCLK/(2 + SDIO_INIT_CLK_DIV) */

/*!< SDIO_CK for initialization should not exceed 400 KHz */ 

SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;

SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;

SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;

SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;

SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;

SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;

SDIO_Init(&SDIO_InitStructure);

antonius
Senior
Posted on April 21, 2014 at 04:02

Complete power on function


PowerON(void)

{

SD_Error errorstatus = SD_OK;

uint32_t response = 0, count = 0, validvoltage = 0;

uint32_t SDType = SD_STD_CAPACITY;


/*!< 
Power
ON Sequence -----------------------------------------------------*/

/*!< Configure the SDIO peripheral */

/*!< 
SDIOCLK
= 
HCLK
, 
SDIO_CK
= 
HCLK
/(2 + SDIO_INIT_CLK_DIV) */

/*!< SDIO_CK for initialization should not exceed 400 KHz */ 

SDIO_InitStructure.SDIO_ClockDiv
= 
SDIO_INIT_CLK_DIV
;

SDIO_InitStructure.SDIO_ClockEdge
= 
SDIO_ClockEdge_Rising
;

SDIO_InitStructure.SDIO_ClockBypass
= 
SDIO_ClockBypass_Disable
;

SDIO_InitStructure.SDIO_ClockPowerSave
= 
SDIO_ClockPowerSave_Disable
;

SDIO_InitStructure.SDIO_BusWide
= 
SDIO_BusWide_1b
;

SDIO_InitStructure.SDIO_HardwareFlowControl
= 
SDIO_HardwareFlowControl_Disable
;

SDIO_Init(&SDIO_InitStructure);


/*!< Set Power State to ON */

SDIO_SetPowerState(SDIO_PowerState_ON);


/*!< Enable SDIO Clock */

SDIO_ClockCmd(ENABLE);


/*!< CMD0: GO_IDLE_STATE ---------------------------------------------------*/

/*!< No CMD response required */

SDIO_CmdInitStructure.SDIO_Argument
= 
0x0
;

SDIO_CmdInitStructure.SDIO_CmdIndex
= 
SD_CMD_GO_IDLE_STATE
;

SDIO_CmdInitStructure.SDIO_Response
= 
SDIO_Response_No
;

SDIO_CmdInitStructure.SDIO_Wait
= 
SDIO_Wait_No
;

SDIO_CmdInitStructure.SDIO_CPSM
= 
SDIO_CPSM_Enable
;

SDIO_SendCommand(&SDIO_CmdInitStructure);


errorstatus
= 
CmdError
();


if (errorstatus != SD_OK)

{

/*!< CMD Response TimeOut (wait for CMDSENT flag) */

return(errorstatus);

}


/*!< CMD8: SEND_IF_COND ----------------------------------------------------*/

/*!< Send CMD8 to verify SD card interface operating condition */

/*!< Argument: - [31:12]: Reserved (shall be set to '0')

- [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)

- [7:0]: Check Pattern (recommended 0xAA) */

/*!< CMD Response: R7 */

SDIO_CmdInitStructure.SDIO_Argument
= 
SD_CHECK_PATTERN
;

SDIO_CmdInitStructure.SDIO_CmdIndex
= 
SDIO_SEND_IF_COND
;

SDIO_CmdInitStructure.SDIO_Response
= 
SDIO_Response_Short
;

SDIO_CmdInitStructure.SDIO_Wait
= 
SDIO_Wait_No
;

SDIO_CmdInitStructure.SDIO_CPSM
= 
SDIO_CPSM_Enable
;

SDIO_SendCommand(&SDIO_CmdInitStructure);


errorstatus
= 
CmdResp7Error
();


if (errorstatus == SD_OK)

{

CardType
= 
SDIO_STD_CAPACITY_SD_CARD_V2_0
; /*!< SD Card 2.0 */

SDType
= 
SD_HIGH_CAPACITY
;


}

else

{

/*!< CMD55 */

SDIO_CmdInitStructure.SDIO_Argument
= 
0x00
;

SDIO_CmdInitStructure.SDIO_CmdIndex
= 
SD_CMD_APP_CMD
;

SDIO_CmdInitStructure.SDIO_Response
= 
SDIO_Response_Short
;

SDIO_CmdInitStructure.SDIO_Wait
= 
SDIO_Wait_No
;

SDIO_CmdInitStructure.SDIO_CPSM
= 
SDIO_CPSM_Enable
;

SDIO_SendCommand(&SDIO_CmdInitStructure);

errorstatus
= 
CmdResp1Error
(SD_CMD_APP_CMD);

}

/*!< CMD55 */

SDIO_CmdInitStructure.SDIO_Argument
= 
0x00
;

SDIO_CmdInitStructure.SDIO_CmdIndex
= 
SD_CMD_APP_CMD
;

SDIO_CmdInitStructure.SDIO_Response
= 
SDIO_Response_Short
;

SDIO_CmdInitStructure.SDIO_Wait
= 
SDIO_Wait_No
;

SDIO_CmdInitStructure.SDIO_CPSM
= 
SDIO_CPSM_Enable
;

SDIO_SendCommand(&SDIO_CmdInitStructure);

errorstatus
= 
CmdResp1Error
(SD_CMD_APP_CMD);


/*!< If errorstatus is Command TimeOut, it is a MMC card */

/*!< If errorstatus is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch)

or SD card 1.x */

if (errorstatus == SD_OK)

{

/*!< SD CARD */

/*!< Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */

while ((!validvoltage) && (count < SD_MAX_VOLT_TRIAL))

{


/*!< SEND CMD55 APP_CMD with RCA as 0 */

SDIO_CmdInitStructure.SDIO_Argument
= 
0x00
;

SDIO_CmdInitStructure.SDIO_CmdIndex
= 
SD_CMD_APP_CMD
;

SDIO_CmdInitStructure.SDIO_Response
= 
SDIO_Response_Short
;

SDIO_CmdInitStructure.SDIO_Wait
= 
SDIO_Wait_No
;

SDIO_CmdInitStructure.SDIO_CPSM
= 
SDIO_CPSM_Enable
;

SDIO_SendCommand(&SDIO_CmdInitStructure);


errorstatus
= 
CmdResp1Error
(SD_CMD_APP_CMD);


if (errorstatus != SD_OK)

{

return(errorstatus);

}

SDIO_CmdInitStructure.SDIO_Argument
= 
SD_VOLTAGE_WINDOW_SD
| SDType;

SDIO_CmdInitStructure.SDIO_CmdIndex
= 
SD_CMD_SD_APP_OP_COND
;

SDIO_CmdInitStructure.SDIO_Response
= 
SDIO_Response_Short
;

SDIO_CmdInitStructure.SDIO_Wait
= 
SDIO_Wait_No
;

SDIO_CmdInitStructure.SDIO_CPSM
= 
SDIO_CPSM_Enable
;

SDIO_SendCommand(&SDIO_CmdInitStructure);


errorstatus
= 
CmdResp3Error
();

if (errorstatus != SD_OK)

{

return(errorstatus);

}


response
= 
SDIO_GetResponse
(SDIO_RESP1);

validvoltage = (((response >> 31) == 1) ? 1 : 0);

count++;

}

if (count >= SD_MAX_VOLT_TRIAL)

{

errorstatus = SD_INVALID_VOLTRANGE;

return(errorstatus);

}


if (response &= SD_HIGH_CAPACITY)

{

CardType = SDIO_HIGH_CAPACITY_SD_CARD;

}


}/*!< else MMC Card */


return(errorstatus);

}

antonius
Senior
Posted on April 21, 2014 at 04:03

anything missing / broken ? thanks

antonius
Senior
Posted on April 21, 2014 at 04:45

I tried on :

#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x3)

and it's working on 64GB sdcard but there're some noises on the picture (256 colors), dot dot noise with random position...

but with 0x3, it's not stable on 8Gb, stop in the middle.....don't know why ?
Posted on April 21, 2014 at 05:07

Yes, if the PLL is clocking at 72 MHz, then HCLK is there.

When first configuring the card a 400 KHz SPI rate is used, after the performance has been determined, it switches up to higher speeds or 4-bits. I'd expect a Ultra/SDXC type card to work at pretty high speeds. Programming a value of 0 would get a 36 MHz clock.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 21, 2014 at 05:19

Different cards have different maximal frequencies, 14.4 MHz doesn't seem that high, a lot of cards are rated at 25 or 50 MHz, as I recall, but that does require a considered implementation with short consistent track lengths, effective grounding and guarding.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..