aboutsummaryrefslogtreecommitdiffstats
path: root/os/io
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-11-08 18:36:55 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-11-08 18:36:55 +0000
commit85cf8d37b5923dfa3e324c0e13e5e4d6efb884df (patch)
tree936b2ed16d977f8737c7c3a09e5dfdc93399690f /os/io
parent0eb3b39e5e66fca98864b6724534ba65740d2473 (diff)
downloadChibiOS-85cf8d37b5923dfa3e324c0e13e5e4d6efb884df.tar.gz
ChibiOS-85cf8d37b5923dfa3e324c0e13e5e4d6efb884df.tar.bz2
ChibiOS-85cf8d37b5923dfa3e324c0e13e5e4d6efb884df.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1277 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/io')
-rw-r--r--os/io/mmc_spi.c156
-rw-r--r--os/io/mmc_spi.h17
2 files changed, 141 insertions, 32 deletions
diff --git a/os/io/mmc_spi.c b/os/io/mmc_spi.c
index ae29c4d34..20d7162ec 100644
--- a/os/io/mmc_spi.c
+++ b/os/io/mmc_spi.c
@@ -237,9 +237,9 @@ void mmcStop(MMCDriver *mmcp) {
if (mmcp->mmc_state != MMC_STOP) {
mmcp->mmc_state = MMC_STOP;
chVTResetI(&mmcp->mmc_vt);
- spiStop(mmcp->mmc_spip);
}
chSysUnlock();
+ spiStop(mmcp->mmc_spip);
}
/**
@@ -257,37 +257,143 @@ void mmcStop(MMCDriver *mmcp) {
* in the @p MMC_READY state.
* @retval TRUE the operation failed.
*/
-bool_t mmcOpen(MMCDriver *mmcp) {
+bool_t mmcConnect(MMCDriver *mmcp) {
unsigned i;
- /* Slow clock mode and 128 clock pulses.*/
- spiStart(mmcp->mmc_spip, mmcp->mmc_lscfg);
+ chDbgCheck(mmcp != NULL, "mmcConnect");
- /* SPI mode selection.*/
- i = 0;
- while (TRUE) {
- if (send_command(mmcp, MMC_CMDGOIDLE, 0) == 0x01)
- break;
- if (++i >= MMC_CMD0_RETRY)
- return TRUE;
- chThdSleepMilliseconds(10);
+ chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
+ (mmcp->mmc_state != MMC_STOP),
+ "mmcConnect(), #1",
+ "invalid state");
+
+ if (mmcp->mmc_state == MMC_INSERTED) {
+ /* Slow clock mode and 128 clock pulses.*/
+ spiStart(mmcp->mmc_spip, mmcp->mmc_lscfg);
+
+ /* SPI mode selection.*/
+ i = 0;
+ while (TRUE) {
+ if (send_command(mmcp, MMC_CMDGOIDLE, 0) == 0x01)
+ break;
+ if (++i >= MMC_CMD0_RETRY)
+ return TRUE;
+ chThdSleepMilliseconds(10);
+ }
+
+ /* Initialization. */
+ i = 0;
+ while (TRUE) {
+ uint8_t b = send_command(mmcp, MMC_CMDINIT, 0);
+ if (b == 0x00)
+ break;
+ if (b != 0x01)
+ return TRUE;
+ if (++i >= MMC_CMD1_RETRY)
+ return TRUE;
+ chThdSleepMilliseconds(10);
+ }
+
+ /* Initialization complete, full speed. */
+ spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
+ mmcp->mmc_state = MMC_READY;
+ return FALSE;
}
+ if (mmcp->mmc_state == MMC_READY)
+ return FALSE;
+ /* Any other state is invalid.*/
+ return TRUE;
+}
- /* Initialization. */
- i = 0;
- while (TRUE) {
- uint8_t b = send_command(mmcp, MMC_CMDINIT, 0);
- if (b == 0x00)
- break;
- if (b != 0x01)
- return TRUE;
- if (++i >= MMC_CMD1_RETRY)
- return TRUE;
- chThdSleepMilliseconds(10);
+/**
+ * @brief Starts a sequential read.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ * @param[in] startblk first block to read
+ *
+ * @return The operation status.
+ * @retval FALSE the operation was successful.
+ * @retval TRUE the operation failed.
+ */
+bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
+
+ chDbgCheck(mmcp != NULL, "mmcStartSequentialRead");
+
+ chSysLock();
+ if (mmcp->mmc_state != MMC_READY) {
+ chSysUnlock();
+ return TRUE;
+ }
+ mmcp->mmc_state = MMC_RUNNING;
+ chSysUnlock();
+
+ spiSelect(mmcp->mmc_spip);
+ send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk << 9);
+ if (recvr1() != 0x00) {
+ spiUnselect(mmcp->mmc_spip);
+ chSysLock();
+ if (mmcp->mmc_state == MMC_RUNNING)
+ mmcp->mmc_state = MMC_READY;
+ chSysUnlock();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * @brief Reads a block within a sequential read operation.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ * @param[out] buffer pointer to the read buffer
+ *
+ * @return The operation status.
+ * @retval FALSE the operation was successful.
+ * @retval TRUE the operation failed.
+ */
+bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
+ int i;
+ uint8_t ignored[2];
+
+ chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
+
+ if (mmcp->mmc_state != MMC_RUNNING)
+ return TRUE;
+
+ for (i = 0; i < MMC_WAIT_DATA; i++) {
+ spiReceive(mmcp->mmc_spip, 1, buf);
+ if (buf[0] == 0xFE) {
+ spiReceive(mmcp->mmc_spip, 512, buf);
+ /* CRC ignored. */
+ spiReceive(mmcp->mmc_spip, 2, ignored);
+ return FALSE;
+ }
}
+ /* Timeout.*/
+ spiUnselect(mmcp->mmc_spip);
+ chSysLock();
+ if (mmcp->mmc_state == MMC_RUNNING)
+ mmcp->mmc_state = MMC_READY;
+ chSysUnlock();
+ return TRUE;
+}
+
+/**
+ * @brief Stops a sequential read gracefully.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ *
+ * @return The operation status.
+ * @retval FALSE the operation was successful.
+ * @retval TRUE the operation failed.
+ */
+bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
+
+ chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
+
+ if (mmcp->mmc_state != MMC_RUNNING)
+ return TRUE;
- /* Initialization complete, full speed. */
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
+ mmcp->mmc_state = MMC_READY;
return FALSE;
}
diff --git a/os/io/mmc_spi.h b/os/io/mmc_spi.h
index 00f0e617b..538f46430 100644
--- a/os/io/mmc_spi.h
+++ b/os/io/mmc_spi.h
@@ -83,12 +83,12 @@
* @brief Driver state machine possible states.
*/
typedef enum {
- MMC_UNINIT = 0, /**< @brief Not initialized. *///!< MMC_UNINIT
- MMC_STOP = 1, /**< @brief Stopped. *///!< MMC_STOP
- MMC_WAIT = 2, /**< @brief Waiting card. *///!< MMC_WAIT
- MMC_INSERTED = 3, /**< @brief Card inserted. *///!< MMC_INSERTED
- MMC_READY = 4, /**< @brief Card ready. *///!< MMC_READY
- MMC_RUNNING = 5 /**< @brief Reading or writing. *///!< MMC_RUNNING
+ MMC_UNINIT = 0, /**< @brief Not initialized. */
+ MMC_STOP = 1, /**< @brief Stopped. */
+ MMC_WAIT = 2, /**< @brief Waiting card. */
+ MMC_INSERTED = 3, /**< @brief Card inserted. */
+ MMC_READY = 4, /**< @brief Card ready. */
+ MMC_RUNNING = 5 /**< @brief Reading or writing. */
} mmcstate_t;
/**
@@ -168,7 +168,10 @@ extern "C" {
mmcquery_t is_protected, mmcquery_t is_inserted);
void mmcStart(MMCDriver *mmcp, const MMCConfig *config);
void mmcStop(MMCDriver *mmcp);
- bool_t mmcOpen(MMCDriver *mmcp);
+ bool_t mmcConnect(MMCDriver *mmcp);
+ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk);
+ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer);
+ bool_t mmcStopSequentialRead(MMCDriver *mmcp);
#ifdef __cplusplus
}
#endif