From 70e33302eba298105eda45752b09915626d163fd Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 8 Nov 2009 11:55:28 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1275 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/io/mmc_spi.c | 49 ++++++++++++++++++++++++++++++++++++++++------ os/io/mmc_spi.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 96 insertions(+), 13 deletions(-) (limited to 'os') diff --git a/os/io/mmc_spi.c b/os/io/mmc_spi.c index 75162c193..3c1b63cc7 100644 --- a/os/io/mmc_spi.c +++ b/os/io/mmc_spi.c @@ -28,6 +28,37 @@ #include #include +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +void tmrfunc(void *p) { + MMCDriver *mmcp = p; + + if (mmcp->mmc_cnt > 0) { + if (mmcp->mmc_is_inserted()) { + if (--mmcp->mmc_cnt == 0) { + mmcp->mmc_state = MMC_INSERTED; + chEvtBroadcastI(&mmcp->mmc_inserted_event); + } + } + else + mmcp->mmc_cnt = MMC_POLLING_INTERVAL; + } + else { + if (!mmcp->mmc_is_inserted()) { + mmcp->mmc_state = MMC_WAIT; + mmcp->mmc_cnt = MMC_POLLING_INTERVAL; + chEvtBroadcastI(&mmcp->mmc_removed_event); + } + } + chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + /** * @brief MMC over SPI driver initialization. */ @@ -51,6 +82,8 @@ void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip, mmcp->mmc_hscfg = hscfg; mmcp->mmc_is_protected = is_protected; mmcp->mmc_is_inserted = is_inserted; + chEvtInit(&mmcp->mmc_inserted_event); + chEvtInit(&mmcp->mmc_removed_event); } /** @@ -64,11 +97,11 @@ void mmcStart(MMCDriver *mmcp, const MMCConfig *config) { chDbgCheck((mmcp != NULL) && (config != NULL), "mmcStart"); chSysLock(); - chDbgAssert((mmcp->mmc_state == MMC_STOP) || (mmcp->mmc_state == MMC_READY), - "mmcStart(), #1", - "invalid state"); + chDbgAssert(mmcp->mmc_state == MMC_STOP, "mmcStart(), #1", "invalid state"); mmcp->mmc_config = config; - mmcp->mmc_state = MMC_READY; + mmcp->mmc_state = MMC_WAIT; + mmcp->mmc_cnt = MMC_POLLING_INTERVAL; + chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp); chSysUnlock(); } @@ -82,10 +115,14 @@ void mmcStop(MMCDriver *mmcp) { chDbgCheck(mmcp != NULL, "mmcStop"); chSysLock(); - chDbgAssert((mmcp->mmc_state == MMC_STOP) || (mmcp->mmc_state == MMC_READY), + chDbgAssert((mmcp->mmc_state != MMC_UNINIT) && + (mmcp->mmc_state != MMC_RUNNING), "mmcStop(), #1", "invalid state"); - mmcp->mmc_state = MMC_STOP; + if (mmcp->mmc_state == MMC_READY) { + mmcp->mmc_state = MMC_STOP; + chVTResetI(&mmcp->mmc_vt); + } chSysUnlock(); } diff --git a/os/io/mmc_spi.h b/os/io/mmc_spi.h index 258962f6f..afe8946d1 100644 --- a/os/io/mmc_spi.h +++ b/os/io/mmc_spi.h @@ -27,15 +27,48 @@ #ifndef _MMC_SPI_H_ #define _MMC_SPI_H_ +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Number of positive insertion queries before generating the + * insertion event. + */ +#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__) +#define MMC_POLLING_INTERVAL 10 +#endif + +/** + * @brief Interval, in milliseconds, between insertion queries. + */ +#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__) +#define MMC_POLLING_DELAY 10 +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + /** * @brief Driver state machine possible states. */ typedef enum { MMC_UNINIT = 0, /**< @brief Not initialized. */ MMC_STOP = 1, /**< @brief Stopped. */ - MMC_READY = 2 /**< @brief Ready. */ + 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; +/** + * @brief Function used to query some hardware status bits. + * + * @return The status. + */ +typedef bool_t (*mmcquery_t)(void); + /** * @brief Driver configuration structure. */ @@ -75,14 +108,27 @@ typedef struct { * @brief Insertion status query function. */ mmcquery_t mmc_is_inserted; + /** + * @brief Card insertion event source. + */ + EventSource mmc_inserted_event; + /** + * @brief Card removal event source. + */ + EventSource mmc_removed_event; + /** + * @brief MMC insertion polling timer. + */ + VirtualTimer mmc_vt; + /** + * @brief Insertion counter. + */ + uint_fast8_t mmc_cnt; } MMCDriver; -/** - * @brief Function used to query some hardware status bits. - * - * @return The status. - */ -typedef bool_t (*mmcquery_t)(void); +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ #ifdef __cplusplus extern "C" { -- cgit v1.2.3