aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src/sdc.c
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-01 09:10:22 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-01 09:10:22 +0000
commit40c7b22bf43d795d9e6822f67907a1665aa6d7b6 (patch)
treef2b67a5fcdb85a4ef348c7fbe29184b76b316433 /os/hal/src/sdc.c
parentdd9cac5ffa29031b1175bb750e587a20362f5276 (diff)
downloadChibiOS-40c7b22bf43d795d9e6822f67907a1665aa6d7b6.tar.gz
ChibiOS-40c7b22bf43d795d9e6822f67907a1665aa6d7b6.tar.bz2
ChibiOS-40c7b22bf43d795d9e6822f67907a1665aa6d7b6.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2908 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src/sdc.c')
-rw-r--r--os/hal/src/sdc.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
index b64dcf9c5..07f25aa65 100644
--- a/os/hal/src/sdc.c
+++ b/os/hal/src/sdc.c
@@ -127,6 +127,7 @@ void sdcStop(SDCDriver *sdcp) {
* @api
*/
bool_t sdcConnect(SDCDriver *sdcp) {
+ uint32_t resp;
chDbgCheck(sdcp != NULL, "sdcConnect");
@@ -135,12 +136,60 @@ bool_t sdcConnect(SDCDriver *sdcp) {
sdcp->state = SDC_INITNG;
chSysUnlock();
+ /* Resets card attributes.*/
+ sdcp->cardmode = 0;
+
+ /* Card clock initialization.*/
sdc_lld_start_clk(sdcp);
+ /* Enforces the initial card state.*/
sdc_lld_send_cmd_none(sdcp, SDC_CMD_GO_IDLE_STATE, 0);
+ /* V2.0 cards detection.*/
+ if (!sdc_lld_send_cmd_short(sdcp, SDC_CMD_SEND_IF_COND,
+ SDC_CMD8_PATTERN, &resp))
+ sdcp->cardmode |= SDC_MODE_CARDTYPE_SDV20;
+ /* Voltage verification.*/
+ if (((resp >> 8) & 0xF) != 1)
+ goto failed;
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_CMD, 0, &resp))
+ goto failed;
+ else {
+ /* MMC or SD detection.*/
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_CMD, 0, &resp))
+ sdcp->cardmode |= SDC_MODE_CARDTYPE_MMC;
+ }
+
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
+ }
+ else {
+ uint32_t ocr = 0x80100000;
+ unsigned i;
+
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_SDV20)
+ ocr |= 0x40000000;
+
+ /* SD-type initialization. */
+ i = 0;
+ while (TRUE) {
+ chThdSleepMilliseconds(10);
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_CMD, 0, &resp))
+ goto failed;
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, &resp))
+ goto failed;
+ if ((resp & 0x80000000) != 0)
+ break;
+ if (++i >= SDC_ACMD41_RETRY)
+ goto failed;
+ }
+ }
+
sdcp->state = SDC_ACTIVE;
return FALSE;
+failed:
+ sdc_lld_stop_clk(sdcp);
+ sdcp->state = SDC_READY;
+ return TRUE;
}
/**