git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2910 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2011-05-01 11:14:23 +00:00
parent d5fb75afc4
commit b33b5201ad
3 changed files with 45 additions and 15 deletions

View File

@ -36,14 +36,18 @@
/*===========================================================================*/ /*===========================================================================*/
#define SDC_CMD_GO_IDLE_STATE 0 #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_IF_COND 8
#define SDC_CMD_SEND_CSD 9
#define SDC_CMD_APP_OP_COND 41 #define SDC_CMD_APP_OP_COND 41
#define SDC_CMD_APP_CMD 55 #define SDC_CMD_APP_CMD 55
#define SDC_MODE_CARDTYPE_MASK 0xF #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_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 #define SDC_CMD8_PATTERN 0x000001AA

View File

@ -132,6 +132,14 @@ struct SDCDriver {
* @brief Various flags regarding the mounted card. * @brief Various flags regarding the mounted card.
*/ */
sdcmode_t cardmode; sdcmode_t cardmode;
/**
* @brief Card CID.
*/
uint32_t cid[4];
/**
* @brief Card CSD.
*/
uint32_t csd[4];
/* End of the mandatory fields.*/ /* End of the mandatory fields.*/
}; };

View File

@ -127,7 +127,7 @@ void sdcStop(SDCDriver *sdcp) {
* @api * @api
*/ */
bool_t sdcConnect(SDCDriver *sdcp) { bool_t sdcConnect(SDCDriver *sdcp) {
uint32_t resp; uint32_t resp[1];
chDbgCheck(sdcp != NULL, "sdcConnect"); chDbgCheck(sdcp != NULL, "sdcConnect");
@ -136,9 +136,6 @@ bool_t sdcConnect(SDCDriver *sdcp) {
sdcp->state = SDC_INITNG; sdcp->state = SDC_INITNG;
chSysUnlock(); chSysUnlock();
/* Resets card attributes.*/
sdcp->cardmode = 0;
/* Card clock initialization.*/ /* Card clock initialization.*/
sdc_lld_start_clk(sdcp); sdc_lld_start_clk(sdcp);
@ -147,17 +144,19 @@ bool_t sdcConnect(SDCDriver *sdcp) {
/* V2.0 cards detection.*/ /* V2.0 cards detection.*/
if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND, if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND,
SDC_CMD8_PATTERN, &resp)) SDC_CMD8_PATTERN, resp))
sdcp->cardmode |= SDC_MODE_CARDTYPE_SDV20; sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
/* Voltage verification.*/ /* Voltage verification.*/
if (((resp >> 8) & 0xF) != 1) if (((resp[0] >> 8) & 0xF) != 1)
goto failed; 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; goto failed;
else { else {
/* MMC or SD detection.*/ /* MMC or SD detection.*/
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))
sdcp->cardmode |= SDC_MODE_CARDTYPE_MMC; sdcp->cardmode = SDC_MODE_CARDTYPE_MMC;
else
sdcp->cardmode = SDC_MODE_CARDTYPE_SDV11;
} }
if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) { if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
@ -173,17 +172,36 @@ bool_t sdcConnect(SDCDriver *sdcp) {
i = 0; i = 0;
while (TRUE) { while (TRUE) {
chThdSleepMilliseconds(10); 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; 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; goto failed;
if ((resp & 0x80000000) != 0) if ((resp[0] & 0x80000000) != 0)
break; break;
if (++i >= SDC_ACMD41_RETRY) if (++i >= SDC_ACMD41_RETRY)
goto failed; 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; sdcp->state = SDC_ACTIVE;
return FALSE; return FALSE;
failed: failed: