aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-05-10 15:07:40 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-05-10 15:07:40 +0000
commiteba4b7056128ae85402984fb03882a5a9eb88213 (patch)
treed306aef73012c2d08a0fff678bf20826eae1d656 /os
parentb1653c7b3cac9131127bc12190e1fa89dd8c7ec1 (diff)
downloadChibiOS-eba4b7056128ae85402984fb03882a5a9eb88213.tar.gz
ChibiOS-eba4b7056128ae85402984fb03882a5a9eb88213.tar.bz2
ChibiOS-eba4b7056128ae85402984fb03882a5a9eb88213.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4182 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/mmc_spi.h4
-rw-r--r--os/hal/platforms/STM32/sdc_lld.c2
-rw-r--r--os/hal/src/mmc_spi.c59
-rw-r--r--os/hal/src/mmcsd.c6
4 files changed, 65 insertions, 6 deletions
diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h
index a5812e399..a1a33c72d 100644
--- a/os/hal/include/mmc_spi.h
+++ b/os/hal/include/mmc_spi.h
@@ -157,6 +157,10 @@ typedef struct {
* @brief Addresses use blocks instead of bytes.
*/
bool_t block_addresses;
+ /**
+ * @brief Total number of blocks in card.
+ */
+ uint32_t capacity;
} MMCDriver;
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c
index 14752c049..f618d7776 100644
--- a/os/hal/platforms/STM32/sdc_lld.c
+++ b/os/hal/platforms/STM32/sdc_lld.c
@@ -578,7 +578,7 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
sdc_lld_collect_errors(sdcp);
return CH_FAILED;
}
- /* save bytes in reverse order because MSB in response comes first */
+ /* Save bytes in reverse order because MSB in response comes first.*/
*resp++ = SDIO->RESP4;
*resp++ = SDIO->RESP3;
*resp++ = SDIO->RESP2;
diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c
index dad837613..a4ce608e3 100644
--- a/os/hal/src/mmc_spi.c
+++ b/os/hal/src/mmc_spi.c
@@ -310,7 +310,7 @@ static uint8_t send_command_R1(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
static uint8_t send_command_R3(MMCDriver *mmcp, uint8_t cmd, uint32_t arg,
uint8_t *response) {
uint8_t r1;
-
+
spiSelect(mmcp->config->spip);
send_hdr(mmcp, cmd, arg);
r1 = recvr3(mmcp, response);
@@ -319,6 +319,53 @@ static uint8_t send_command_R3(MMCDriver *mmcp, uint8_t cmd, uint32_t arg,
}
/**
+ * @brief Reads the CSD.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ * @param[out] csd pointer to the CSD buffer
+ *
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed.
+ *
+ * @notapi
+ */
+static bool_t read_CSD(MMCDriver *mmcp, uint32_t csd[4]) {
+ unsigned i;
+ uint8_t *bp, buf[16];
+
+ spiSelect(mmcp->config->spip);
+ send_hdr(mmcp, MMCSD_CMD_SEND_CSD, 0);
+ if (recvr1(mmcp) != 0x00) {
+ spiUnselect(mmcp->config->spip);
+ return TRUE;
+ }
+
+ /* Wait for data availability.*/
+ for (i = 0; i < MMC_WAIT_DATA; i++) {
+ spiReceive(mmcp->config->spip, 1, buf);
+ if (buf[0] == 0xFE) {
+ uint32_t *wp;
+
+ spiReceive(mmcp->config->spip, 16, buf);
+ bp = buf;
+ for (wp = &csd[3]; wp >= csd; wp--) {
+ *wp = ((uint32_t)bp[0] << 24) | ((uint32_t)bp[1] << 16) |
+ ((uint32_t)bp[2] << 8) | (uint32_t)bp[3];
+ bp += 4;
+ }
+
+ /* CRC ignored then end of transaction. */
+ spiIgnore(mmcp->config->spip, 2);
+ spiUnselect(mmcp->config->spip);
+
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
* @brief Waits that the card reaches an idle state.
*
* @param[in] mmcp pointer to the @p MMCDriver object
@@ -444,6 +491,7 @@ void mmcStop(MMCDriver *mmcp) {
bool_t mmcConnect(MMCDriver *mmcp) {
unsigned i;
bool_t result;
+ uint32_t csd[4];
chDbgCheck(mmcp != NULL, "mmcConnect");
@@ -515,6 +563,13 @@ bool_t mmcConnect(MMCDriver *mmcp) {
MMCSD_BLOCK_SIZE) != 0x00)
return TRUE;
+ /* Determine capacity.*/
+ if (read_CSD(mmcp, csd))
+ return TRUE;
+ mmcp->capacity = mmcsdGetCapacity(csd);
+ if (mmcp->capacity == 0)
+ return TRUE;
+
/* Transition to MMC_READY state (if not extracted).*/
chSysLock();
if (mmcp->state == MMC_INSERTED) {
@@ -866,7 +921,7 @@ bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) {
}
chSysUnlock();
- bdip->blk_num = 0; /* NOTE: To be implemented.*/
+ bdip->blk_num = mmcp->capacity;
bdip->blk_size = MMCSD_BLOCK_SIZE;
return FALSE;
diff --git a/os/hal/src/mmcsd.c b/os/hal/src/mmcsd.c
index 88f8a5505..44a552cbd 100644
--- a/os/hal/src/mmcsd.c
+++ b/os/hal/src/mmcsd.c
@@ -58,7 +58,7 @@ static uint32_t mmcsd_get_slice(uint32_t *data, uint32_t end, uint32_t start) {
chDbgCheck(end >= start, "sdc_get_slice");
- while ((start - 32 * word) > 31){
+ while ((start - 32 * word) > 31) {
word++;
data++;
}
@@ -66,12 +66,12 @@ static uint32_t mmcsd_get_slice(uint32_t *data, uint32_t end, uint32_t start) {
end -= 32 * word;
start -= 32 * word;
- if (end < 31){
+ if (end < 31) {
/* Value lays in one word.*/
mask = (1 << (end - start + 1)) - 1;
return (*data >> start) & mask;
}
- else{
+ else {
/* Value spread on separate words.*/
uint32_t lsb, msb;
lsb = *data >> start;