aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-07 13:24:04 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-07 13:24:04 +0000
commit7109dcee27d7fbfa77f1c9b16c934f6ca550f5d5 (patch)
tree038fe570e187e46361449a2e0be98ec7235ffcb3
parentf8c8c48fa989c71ab9b2e26677329ed108a779fb (diff)
downloadChibiOS-7109dcee27d7fbfa77f1c9b16c934f6ca550f5d5.tar.gz
ChibiOS-7109dcee27d7fbfa77f1c9b16c934f6ca550f5d5.tar.bz2
ChibiOS-7109dcee27d7fbfa77f1c9b16c934f6ca550f5d5.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2923 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/hal/include/sdc.h3
-rw-r--r--os/hal/platforms/STM32/sdc_lld.c43
-rw-r--r--os/hal/platforms/STM32/sdc_lld.h6
-rw-r--r--os/hal/src/sdc.c27
4 files changed, 58 insertions, 21 deletions
diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h
index 38b907000..b0d7cfe4a 100644
--- a/os/hal/include/sdc.h
+++ b/os/hal/include/sdc.h
@@ -46,6 +46,7 @@
#define SDC_CMD_STOP_TRANSMISSION 12
#define SDC_CMD_SET_BLOCKLEN 16
#define SDC_CMD_READ_MULTIPLE_BLOCK 18
+#define SDC_CMD_SET_BLOCK_COUNT 23
#define SDC_CMD_WRITE_MULTIPLE_BLOCK 25
#define SDC_CMD_APP_OP_COND 41
#define SDC_CMD_APP_CMD 55
@@ -60,6 +61,8 @@
#define SDC_ACMD41_RETRY 100
+#define SDC_R1_ERROR_MASK 0xFDFFE008
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c
index ae84f812e..78a02028a 100644
--- a/os/hal/platforms/STM32/sdc_lld.c
+++ b/os/hal/platforms/STM32/sdc_lld.c
@@ -205,7 +205,7 @@ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN;
while ((SDIO->STA & SDIO_STA_CMDSENT) == 0)
;
- SDIO->ICR = 0xFFFFFFFF;
+ SDIO->ICR = SDIO_ICR_CMDSENTC;
}
/**
@@ -233,7 +233,7 @@ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
SDIO_STA_CCRCFAIL)) == 0)
;
- SDIO->ICR = 0xFFFFFFFF;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
if ((sta & (SDIO_STA_CTIMEOUT)) != 0)
return TRUE;
*resp = SDIO->RESP1;
@@ -264,7 +264,7 @@ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
SDIO_STA_CCRCFAIL)) == 0)
;
- SDIO->ICR = 0xFFFFFFFF;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
return TRUE;
*resp = SDIO->RESP1;
@@ -297,7 +297,7 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
SDIO_STA_CCRCFAIL)) == 0)
;
- SDIO->ICR = 0xFFFFFFFF;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
return TRUE;
*resp = SDIO->RESP1;
@@ -305,9 +305,10 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
}
/**
- * @brief Data read through the SDIO bus.
+ * @brief Reads one or more blocks.
*
* @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
* @param[out] buf pointer to the read buffer
* @param[in] n number of blocks to read
* @return The operation status.
@@ -317,24 +318,40 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
*
* @notapi
*/
-bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buf, uint32_t n) {
+bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
msg_t msg;
+ uint32_t resp[1];
- chSysLock();
- /* Prepares the DMA channel.*/
+ /* Clearing status.*/
+ SDIO->ICR = 0xFFFFFFFF;
+
+ /* Prepares the DMA channel for reading.*/
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
(STM32_SDC_SDIO_DMA_PRIORITY << 12) |
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
DMA_CCR1_MINC);
+
+ /* Setting up data transfer.
+ Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->DTIMER = STM32_SDC_DATATIMEOUT;
SDIO->DLEN = n;
- /* Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
SDIO->DCTRL = SDIO_DCTRL_RWMOD |
SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_3 |
SDIO_DCTRL_DMAEN |
SDIO_DCTRL_DTEN;
+
/* DMA channel activation.*/
- dmaEnableChannel(&STM32_DMA2, STM32_DMA_CHANNEL_4);
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, n, resp) ||
+ (resp[0] & SDC_R1_ERROR_MASK)) {
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->DCTRL = 0;
+ return TRUE;
+ }
+
chDbgAssert(sdcp->thread == NULL, "sdc_lld_read_blocks(), #1", "not NULL");
sdcp->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
@@ -345,9 +362,10 @@ bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buf, uint32_t n) {
}
/**
- * @brief Data write through the SDIO bus.
+ * @brief Writes one or more blocks.
*
* @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
* @param[out] buf pointer to the write buffer
* @param[in] n number of blocks to write
* @return The operation status.
@@ -357,7 +375,8 @@ bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buf, uint32_t n) {
*
* @notapi
*/
-bool_t sdc_lld_write_blocks(SDCDriver *sdcp, const uint8_t *buf, uint32_t n) {
+bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
return TRUE;
}
diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h
index 3f12dd4fc..702e27d59 100644
--- a/os/hal/platforms/STM32/sdc_lld.h
+++ b/os/hal/platforms/STM32/sdc_lld.h
@@ -184,8 +184,10 @@ extern "C" {
uint32_t *resp);
bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
uint32_t *resp);
- bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buffer, uint32_t n);
- bool_t sdc_lld_write_blocks(SDCDriver *sdcp, const uint8_t *buf, uint32_t n);
+ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n);
+ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
index 3188afb64..1874510a0 100644
--- a/os/hal/src/sdc.c
+++ b/os/hal/src/sdc.c
@@ -211,11 +211,11 @@ 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;
- }
+ }*/
sdcp->state = SDC_ACTIVE;
return FALSE;
@@ -268,20 +268,33 @@ bool_t sdcDisconnect(SDCDriver *sdcp) {
bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
uint8_t *buf, uint32_t n) {
bool_t sts;
- uint32_t resp[1];
+ uint32_t resp[4];
chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead");
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE,
+ "sdcDisconnect(), #1", "invalid state");
+ sdcp->state = SDC_READING;
+ chSysUnlock();
+
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
startblk *= SDC_BLOCK_SIZE;
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK,
- startblk, resp))
+/* if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ (resp[0] & SDC_R1_ERROR_MASK))
return TRUE;
+ if (sdc_lld_send_cmd_long_crc(sdcp, 51, 0, resp))
+ return TRUE;
+
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCK_COUNT, n, resp) ||
+ (resp[0] & SDC_R1_ERROR_MASK))
+ return TRUE;*/
- sts = sdc_lld_read_blocks(sdcp, buf, n);
+ sts = sdc_lld_read(sdcp, startblk, buf, n);
sts = sts || sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION,
0, resp);
+ sdcp->state = SDC_ACTIVE;
return sts;
}
@@ -315,7 +328,7 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
startblk, resp))
return TRUE;
- sts = sdc_lld_write_blocks(sdcp, buf, n);
+ sts = sdc_lld_write(sdcp, startblk, buf, n);
sts = sts || sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION,
0, resp);
return sts;