aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-01 11:14:23 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-01 11:14:23 +0000
commitb33b5201ad65ed0dafb2b9e0a2c40bf06fe27dfc (patch)
tree96e13d5442c4adc6fd8315ec4fff7bdf58722564
parentd5fb75afc4c7203500108fd573f90bfbbd1ac498 (diff)
downloadChibiOS-b33b5201ad65ed0dafb2b9e0a2c40bf06fe27dfc.tar.gz
ChibiOS-b33b5201ad65ed0dafb2b9e0a2c40bf06fe27dfc.tar.bz2
ChibiOS-b33b5201ad65ed0dafb2b9e0a2c40bf06fe27dfc.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2910 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/hal/include/sdc.h8
-rw-r--r--os/hal/platforms/STM32/sdc_lld.h8
-rw-r--r--os/hal/src/sdc.c44
3 files changed, 45 insertions, 15 deletions
diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h
index 027eee2c0..4c43fe505 100644
--- a/os/hal/include/sdc.h
+++ b/os/hal/include/sdc.h
@@ -36,14 +36,18 @@
/*===========================================================================*/
#define SDC_CMD_GO_IDLE_STATE 0
+#define SDC_CMD_ALL_SEND_CID 2
+#define SDC_CMD_SEND_RELATIVE_ADDR 3
+#define SDC_CMD_SEL_DESEL_CARD 7
#define SDC_CMD_SEND_IF_COND 8
+#define SDC_CMD_SEND_CSD 9
#define SDC_CMD_APP_OP_COND 41
#define SDC_CMD_APP_CMD 55
#define SDC_MODE_CARDTYPE_MASK 0xF
-#define SDC_MODE_CARDTYPE_SD 0 /**< Old SD card. */
+#define SDC_MODE_CARDTYPE_SDV11 0 /**< Card is V1.1 compliant. */
#define SDC_MODE_CARDTYPE_SDV20 1 /**< Card is V2.0 compliant. */
-#define SDC_MODE_CARDTYPE_MMC 2 /**< Card is MMC. */
+#define SDC_MODE_CARDTYPE_MMC 2 /**< Card is MMC compliant. */
#define SDC_CMD8_PATTERN 0x000001AA
diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h
index 5f54f3b50..e55205b53 100644
--- a/os/hal/platforms/STM32/sdc_lld.h
+++ b/os/hal/platforms/STM32/sdc_lld.h
@@ -132,6 +132,14 @@ struct SDCDriver {
* @brief Various flags regarding the mounted card.
*/
sdcmode_t cardmode;
+ /**
+ * @brief Card CID.
+ */
+ uint32_t cid[4];
+ /**
+ * @brief Card CSD.
+ */
+ uint32_t csd[4];
/* End of the mandatory fields.*/
};
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
index 7cfac6705..2fd4e7f7b 100644
--- a/os/hal/src/sdc.c
+++ b/os/hal/src/sdc.c
@@ -127,7 +127,7 @@ void sdcStop(SDCDriver *sdcp) {
* @api
*/
bool_t sdcConnect(SDCDriver *sdcp) {
- uint32_t resp;
+ uint32_t resp[1];
chDbgCheck(sdcp != NULL, "sdcConnect");
@@ -136,9 +136,6 @@ bool_t sdcConnect(SDCDriver *sdcp) {
sdcp->state = SDC_INITNG;
chSysUnlock();
- /* Resets card attributes.*/
- sdcp->cardmode = 0;
-
/* Card clock initialization.*/
sdc_lld_start_clk(sdcp);
@@ -147,17 +144,19 @@ bool_t sdcConnect(SDCDriver *sdcp) {
/* V2.0 cards detection.*/
if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND,
- SDC_CMD8_PATTERN, &resp))
- sdcp->cardmode |= SDC_MODE_CARDTYPE_SDV20;
+ SDC_CMD8_PATTERN, resp))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
/* Voltage verification.*/
- if (((resp >> 8) & 0xF) != 1)
+ if (((resp[0] >> 8) & 0xF) != 1)
goto failed;
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, &resp))
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp))
goto failed;
else {
/* MMC or SD detection.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, &resp))
- sdcp->cardmode |= SDC_MODE_CARDTYPE_MMC;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_MMC;
+ else
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV11;
}
if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
@@ -173,17 +172,36 @@ bool_t sdcConnect(SDCDriver *sdcp) {
i = 0;
while (TRUE) {
chThdSleepMilliseconds(10);
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, &resp))
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp))
goto failed;
- if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, &resp))
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, resp))
goto failed;
- if ((resp & 0x80000000) != 0)
+ if ((resp[0] & 0x80000000) != 0)
break;
if (++i >= SDC_ACMD41_RETRY)
goto failed;
}
}
+ /* Reads CID.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_ALL_SEND_CID, 0, sdcp->cid))
+ goto failed;
+
+ /* Asks for the RCA.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR, 0, resp))
+ goto failed;
+
+ /* Reads CSD.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, resp[0], sdcp->csd))
+ goto failed;
+
+ /* Switches to high speed.*/
+ sdc_lld_set_data_clk(sdcp);
+
+ /* Selects the card for operations.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEL_DESEL_CARD, resp[0], resp))
+ goto failed;
+
sdcp->state = SDC_ACTIVE;
return FALSE;
failed: