aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/sdc.h1
-rw-r--r--os/hal/platforms/STM32/sdc_lld.h4
-rw-r--r--os/hal/src/sdc.c20
3 files changed, 18 insertions, 7 deletions
diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h
index b0d7cfe4a..56ee267e1 100644
--- a/os/hal/include/sdc.h
+++ b/os/hal/include/sdc.h
@@ -40,6 +40,7 @@
#define SDC_CMD_GO_IDLE_STATE 0
#define SDC_CMD_ALL_SEND_CID 2
#define SDC_CMD_SEND_RELATIVE_ADDR 3
+#define SDC_CMD_SET_BUS_WIDTH 6
#define SDC_CMD_SEL_DESEL_CARD 7
#define SDC_CMD_SEND_IF_COND 8
#define SDC_CMD_SEND_CSD 9
diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h
index 702e27d59..96639eb39 100644
--- a/os/hal/platforms/STM32/sdc_lld.h
+++ b/os/hal/platforms/STM32/sdc_lld.h
@@ -148,6 +148,10 @@ struct SDCDriver {
* @brief Card CSD.
*/
uint32_t csd[4];
+ /**
+ * @brief Card RCA.
+ */
+ uint32_t rca;
/* End of the mandatory fields.*/
/**
* @brief Tthread waiting for I/O completion IRQ.
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
index 42b7cd903..334caec0d 100644
--- a/os/hal/src/sdc.c
+++ b/os/hal/src/sdc.c
@@ -173,7 +173,7 @@ bool_t sdcConnect(SDCDriver *sdcp) {
while (TRUE) {
chThdSleepMilliseconds(10);
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))
goto failed;
if ((resp[0] & 0x80000000) != 0) {
@@ -191,18 +191,18 @@ bool_t sdcConnect(SDCDriver *sdcp) {
goto failed;
/* Asks for the RCA.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR, 0, resp))
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR, 0, &sdcp->rca))
goto failed;
/* Reads CSD.*/
- if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, resp[0], sdcp->csd))
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, sdcp->rca, 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))
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEL_DESEL_CARD, sdcp->rca, resp))
goto failed;
/* Block length fixed at 512 bytes.*/
@@ -211,11 +211,17 @@ bool_t sdcConnect(SDCDriver *sdcp) {
goto failed;
/* Switches to wide bus mode.*/
-/* switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) {
+ switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) {
case SDC_MODE_CARDTYPE_SDV11:
case SDC_MODE_CARDTYPE_SDV20:
- SDIO->CLKCR |= SDIO_CLKCR_WIDBUS_0;
- }*/
+ sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT);
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, sdcp->rca, resp) ||
+ (resp[0] & SDC_R1_ERROR_MASK))
+ goto failed;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) ||
+ (resp[0] & SDC_R1_ERROR_MASK))
+ goto failed;
+ }
sdcp->state = SDC_ACTIVE;
return FALSE;