aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-11-14 14:57:32 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-11-14 14:57:32 +0000
commit0da2b9d0d87312b9fd50f368689be8f870055542 (patch)
treedf18c81a1eedd89b8ba993d42b43540c70bf1b49 /os
parent174b6a1ba2483ab226bb8e7279f9a3b6535be308 (diff)
downloadChibiOS-0da2b9d0d87312b9fd50f368689be8f870055542.tar.gz
ChibiOS-0da2b9d0d87312b9fd50f368689be8f870055542.tar.bz2
ChibiOS-0da2b9d0d87312b9fd50f368689be8f870055542.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1291 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/io/mmc_spi.c67
-rw-r--r--os/io/mmc_spi.h1
2 files changed, 67 insertions, 1 deletions
diff --git a/os/io/mmc_spi.c b/os/io/mmc_spi.c
index 517291814..d3370ea8c 100644
--- a/os/io/mmc_spi.c
+++ b/os/io/mmc_spi.c
@@ -143,6 +143,26 @@ static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
return r1;
}
+/**
+ * @brief Waits that the card reaches an idle state.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ */
+static void sync(MMCDriver *mmcp) {
+ uint8_t buf[1];
+
+ spiSelect(mmcp->mmc_spip);
+ while (TRUE) {
+ spiReceive(mmcp->mmc_spip, 1, buf);
+ if (buf[0] == 0xFF)
+ break;
+#ifdef MMC_NICE_WAITING
+ chThdSleep(1); /* Trying to be nice with the other threads.*/
+#endif
+ }
+ spiUnselect(mmcp->mmc_spip);
+}
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -302,6 +322,38 @@ bool_t mmcConnect(MMCDriver *mmcp) {
}
/**
+ * @brief Brings the driver in a state safe for card removal.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ * @return The operation status.
+ * @retval FALSE the operation was successful and the driver is now
+ * in the @p MMC_INSERTED state.
+ * @retval TRUE the operation failed.
+ */
+bool_t mmcDisconnect(MMCDriver *mmcp) {
+
+ chDbgCheck(mmcp != NULL, "mmcConnect");
+
+ chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
+ (mmcp->mmc_state != MMC_STOP),
+ "mmcDisconnect(), #1",
+ "invalid state");
+ switch (mmcp->mmc_state) {
+ case MMC_READY:
+ /* Wait for the pending write operations to complete.*/
+ sync(mmcp);
+ chSysLock();
+ if (mmcp->mmc_state == MMC_READY)
+ mmcp->mmc_state = MMC_INSERTED;
+ chSysUnlock();
+ case MMC_INSERTED:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+/**
* @brief Starts a sequential read.
*
* @param[in] mmcp pointer to the @p MMCDriver object
@@ -455,6 +507,8 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
* @retval TRUE the operation failed.
*/
bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
+ static const uint8_t start[] = {0xFF, 0xFC};
+ uint8_t b[1];
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
@@ -465,8 +519,19 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
}
chSysUnlock();
- /**/
+ spiSend(mmcp->mmc_spip, sizeof(start), start); /* Data prologue. */
+ spiSend(mmcp->mmc_spip, MMC_BLOCK_SIZE, buffer); /* Data. */
+ spiIgnore(mmcp->mmc_spip, 2); /* CRC ignored. */
+ spiReceive(mmcp->mmc_spip, 1, b);
+ if ((b[0] & 0x1F) == 0x05)
+ return FALSE;
+ /* Error.*/
+ spiUnselect(mmcp->mmc_spip);
+ chSysLock();
+ if (mmcp->mmc_state == MMC_WRITING)
+ mmcp->mmc_state = MMC_READY;
+ chSysUnlock();
return TRUE;
}
diff --git a/os/io/mmc_spi.h b/os/io/mmc_spi.h
index e89f17117..717f80b84 100644
--- a/os/io/mmc_spi.h
+++ b/os/io/mmc_spi.h
@@ -178,6 +178,7 @@ extern "C" {
void mmcStart(MMCDriver *mmcp, const MMCConfig *config);
void mmcStop(MMCDriver *mmcp);
bool_t mmcConnect(MMCDriver *mmcp);
+ bool_t mmcDisconnect(MMCDriver *mmcp);
bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk);
bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer);
bool_t mmcStopSequentialRead(MMCDriver *mmcp);