From b33b5201ad65ed0dafb2b9e0a2c40bf06fe27dfc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 1 May 2011 11:14:23 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2910 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 8 ++++++-- os/hal/platforms/STM32/sdc_lld.h | 8 ++++++++ os/hal/src/sdc.c | 44 ++++++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 15 deletions(-) (limited to 'os') 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: -- cgit v1.2.3