diff --git a/boards/ST_STM3210E_EVAL/board.c b/boards/ST_STM3210E_EVAL/board.c index b258224f8..a819aaf0f 100644 --- a/boards/ST_STM3210E_EVAL/board.c +++ b/boards/ST_STM3210E_EVAL/board.c @@ -49,6 +49,21 @@ void __early_init(void) { stm32_clock_init(); } +#if HAL_USE_SDC +/* Board-related functions related to the SDC driver.*/ +bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp) { + + (void)sdcp; + return !palReadPad(GPIOF, GPIOF_SD_DETECT); +} + +bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) { + + (void)sdcp; + return FALSE; +} +#endif + /* * Board-specific initialization code. */ diff --git a/demos/ARMCM3-STM32F103ZG-FATFS/main.c b/demos/ARMCM3-STM32F103ZG-FATFS/main.c index a2693badf..8ce90f704 100644 --- a/demos/ARMCM3-STM32F103ZG-FATFS/main.c +++ b/demos/ARMCM3-STM32F103ZG-FATFS/main.c @@ -52,33 +52,6 @@ static unsigned cnt; */ static EventSource inserted_event, removed_event; -/** - * @brief Insertion monitor function. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * - * @notapi - */ -bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp) { - - (void)sdcp; - return !palReadPad(GPIOF, GPIOF_SD_DETECT); -} - -/** - * @brief Protection detection. - * @note Not supported. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * - * @notapi - */ -bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) { - - (void)sdcp; - return FALSE; -} - /** * @brief Insertion monitor timer callback function. * diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 4e5bf0b24..d8de4d936 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -34,9 +34,14 @@ #include "hal_lld.h" +/* Abstract interfaces.*/ #include "io_channel.h" #include "io_block.h" +/* Shared headers.*/ +#include "mmcsd.h" + +/* Layered drivers.*/ #include "tm.h" #include "pal.h" #include "adc.h" @@ -53,6 +58,8 @@ #include "spi.h" #include "uart.h" #include "usb.h" + +/* Complex drivers.*/ #include "mmc_spi.h" #include "serial_usb.h" diff --git a/os/hal/include/io_block.h b/os/hal/include/io_block.h index b12ae4588..2e47eb10a 100644 --- a/os/hal/include/io_block.h +++ b/os/hal/include/io_block.h @@ -192,6 +192,10 @@ typedef struct { * * @param[in] ip pointer to a @p BaseBlockDevice or derived class * + * @return The operation status. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. + * * @api */ #define blkSync(ip) ((ip)->vmt->sync(ip)) @@ -202,6 +206,10 @@ typedef struct { * @param[in] ip pointer to a @p BaseBlockDevice or derived class * @param[out] bdip pointer to a @p BlockDeviceInfo structure * + * @return The operation status. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. + * * @api */ #define blkGetInfo(ip, bdip) ((ip)->vmt->get_info(ip, bdip)) diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h index 1d624aeff..fd2850576 100644 --- a/os/hal/include/mmc_spi.h +++ b/os/hal/include/mmc_spi.h @@ -40,20 +40,6 @@ #define MMC_ACMD41_RETRY 100 #define MMC_WAIT_DATA 10000 -#define MMC_CMDGOIDLE 0 -#define MMC_CMDINIT 1 -#define MMC_CMDINTERFACE_CONDITION 8 -#define MMC_CMDREADCSD 9 -#define MMC_CMDSTOP 12 -#define MMC_CMDSETBLOCKLEN 16 -#define MMC_CMDREAD 17 -#define MMC_CMDREADMULTIPLE 18 -#define MMC_CMDWRITE 24 -#define MMC_CMDWRITEMULTIPLE 25 -#define MMC_CMDAPP 55 -#define MMC_CMDREADOCR 58 -#define MMC_ACMDOPCONDITION 41 - /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -62,13 +48,6 @@ * @name MMC_SPI configuration options * @{ */ -/** - * @brief Block size for MMC transfers. - */ -#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__) -#define MMC_SECTOR_SIZE 512 -#endif - /** * @brief Delays insertions. * @details If enabled this options inserts delays into the MMC waiting @@ -138,9 +117,15 @@ typedef struct { } MMCConfig; /** - * @brief Structure representing a MMC driver. + * @extends MMCSDBlockDevice + * + * @brief Structure representing a MMC/SD over SPI driver. */ typedef struct { + /** + * @brief Virtual Methods Table. + */ + const struct MMCSDBlockDeviceVMT *vmt; /** * @brief Driver state. */ @@ -243,6 +228,8 @@ extern "C" { bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk); bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer); bool_t mmcStopSequentialWrite(MMCDriver *mmcp); + bool_t mmcSync(MMCDriver *mmcp); + bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip); #ifdef __cplusplus } #endif diff --git a/os/hal/include/mmcsd.h b/os/hal/include/mmcsd.h new file mode 100644 index 000000000..fbea45245 --- /dev/null +++ b/os/hal/include/mmcsd.h @@ -0,0 +1,160 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file mmcsd.h + * @brief MMC/SD cards header. + * + * @addtogroup MMCSD + * @{ + */ + +#ifndef _MMCSD_H_ +#define _MMCSD_H_ + +#if HAL_USE_MMC_SPI || HAL_USE_SDC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Fixed block size for MMC/SD block devices. + */ +#define SDMMC_BLOCK_SIZE 512 + +/** + * @brief Mask of error bits in R1 responses. + */ +#define SDMMC_R1_ERROR_MASK 0xFDFFE008 + +/** + * @brief Fixed pattern for CMD8. + */ +#define SDMMC_CMD8_PATTERN 0x000001AA + +/** + * @name SD/MMC status conditions + * @{ + */ +#define SDMMC_STS_IDLE 0 +#define SDMMC_STS_READY 1 +#define SDMMC_STS_IDENT 2 +#define SDMMC_STS_STBY 3 +#define SDMMC_STS_TRAN 4 +#define SDMMC_STS_DATA 5 +#define SDMMC_STS_RCV 6 +#define SDMMC_STS_PRG 7 +#define SDMMC_STS_DIS 8 +/** @} */ + +/** + * @name SD/MMC commands + * @{ + */ +#define SDMMC_CMD_GO_IDLE_STATE 0 +#define SDMMC_CMD_INIT 1 +#define SDMMC_CMD_ALL_SEND_CID 2 +#define SDMMC_CMD_SEND_RELATIVE_ADDR 3 +#define SDMMC_CMD_SET_BUS_WIDTH 6 +#define SDMMC_CMD_SEL_DESEL_CARD 7 +#define SDMMC_CMD_SEND_IF_COND 8 +#define SDMMC_CMD_SEND_CSD 9 +#define SDMMC_CMD_STOP_TRANSMISSION 12 +#define SDMMC_CMD_SEND_STATUS 13 +#define SDMMC_CMD_SET_BLOCKLEN 16 +#define SDMMC_CMD_READ_SINGLE_BLOCK 17 +#define SDMMC_CMD_READ_MULTIPLE_BLOCK 18 +#define SDMMC_CMD_SET_BLOCK_COUNT 23 +#define SDMMC_CMD_WRITE_BLOCK 24 +#define SDMMC_CMD_WRITE_MULTIPLE_BLOCK 25 +#define SDMMC_CMD_APP_OP_COND 41 +#define SDMMC_CMD_LOCK_UNLOCK 42 +#define SDMMC_CMD_APP_CMD 55 +#define SDMMC_CMD_READ_OCR 58 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief @p MMCSDBlockDevice specific methods. + */ +#define _mmcsd_block_device_methods \ + _base_block_device_methods + +/** + * @brief @p MMCSDBlockDevice specific data. + * @note It is empty because @p MMCSDBlockDevice is only an interface + * without implementation. + */ +#define _mmcsd_block_device_data \ + _base_block_device_data + +/** + * @extends BaseBlockDeviceVMT + * + * @brief @p MMCSDBlockDevice virtual methods table. + */ +struct MMCSDBlockDeviceVMT { + _base_block_device_methods +}; + +/** + * @extends BaseBlockDevice + * + * @brief MCC/SD block device class. + * @details This class represents a, block-accessible, MMC/SD device. + */ +typedef struct { + /** @brief Virtual Methods Table.*/ + const struct MMCSDBlockDeviceVMT *vmt; + _mmcsd_block_device_data +} MMCSDBlockDevice; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_MMC_SPI || HAL_USE_MMC_SDC*/ + +#endif /* _MMCSD_H_ */ + +/** @} */ diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 82b083125..20c15c211 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -102,6 +102,7 @@ #define SDC_STARTBIT_ERROR 64 /**< @brief Start bit not detected.*/ #define SDC_OVERFLOW_ERROR 128 /**< @brief Card overflow error. */ #define SDC_UNHANDLED_ERROR 0xFFFFFFFF +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -332,6 +333,8 @@ extern "C" { bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buffer, uint32_t n); sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp); + bool_t sdcSync(SDCDriver *sdcp); + bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip); bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp); #ifdef __cplusplus } diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index cfa36fd25..5d31827b4 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -197,6 +197,10 @@ typedef struct { * @brief Structure representing an SDC driver. */ struct SDCDriver { + /** + * @brief Virtual Methods Table. + */ + const struct MMCSDBlockDeviceVMT *vmt; /** * @brief Driver state. */ diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c index c022e4a68..4fdec3f12 100644 --- a/os/hal/src/mmc_spi.c +++ b/os/hal/src/mmc_spi.c @@ -48,6 +48,28 @@ /* Driver local variables. */ /*===========================================================================*/ +/* Forward declarations required by mmc_vmt.*/ +bool_t mmc_is_inserted(void *instance); +bool_t mmc_is_protected(void *instance); +bool_t mmc_read(void *instance, uint32_t startblk, + uint8_t *buffer, uint32_t n); +bool_t mmc_write(void *instance, uint32_t startblk, + const uint8_t *buffer, uint32_t n); + +/** + * @brief Virtual methods table. + */ +static const struct MMCSDBlockDeviceVMT mmc_vmt = { + mmc_is_inserted, + mmc_is_protected, + (bool_t (*)(void *))mmcConnect, + (bool_t (*)(void *))mmcDisconnect, + mmc_read, + mmc_write, + (bool_t (*)(void *))mmcSync, + (bool_t (*)(void *, BlockDeviceInfo *))mmcGetInfo +}; + /** * @brief Lookup table for CRC-7 ( based on polynomial x^7 + x^3 + 1). */ @@ -80,6 +102,48 @@ static const uint8_t crc7_lookup_table[256] = { /* Driver local functions. */ /*===========================================================================*/ +bool_t mmc_is_inserted(void *instance) { + + return ((MMCDriver *)instance)->is_inserted(); +} + +bool_t mmc_is_protected(void *instance) { + + return ((MMCDriver *)instance)->is_protected(); +} + +bool_t mmc_read(void *instance, uint32_t startblk, + uint8_t *buffer, uint32_t n) { + + if (mmcStartSequentialRead((MMCDriver *)instance, startblk)) + return TRUE; + while (n > 0) { + if (mmcSequentialRead((MMCDriver *)instance, buffer)) + return TRUE; + buffer += SDMMC_BLOCK_SIZE; + n--; + } + if (mmcStopSequentialRead((MMCDriver *)instance)) + return TRUE; + return FALSE; +} + +bool_t mmc_write(void *instance, uint32_t startblk, + const uint8_t *buffer, uint32_t n) { + + if (mmcStartSequentialWrite((MMCDriver *)instance, startblk)) + return TRUE; + while (n > 0) { + if (mmcSequentialWrite((MMCDriver *)instance, buffer)) + return TRUE; + buffer += SDMMC_BLOCK_SIZE; + n--; + } + if (mmcStopSequentialWrite((MMCDriver *)instance)) + return TRUE; + return FALSE; +} + /** * @brief Calculate the MMC standard CRC-7 based on a lookup table. * @@ -321,6 +385,7 @@ void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip, const SPIConfig *lscfg, const SPIConfig *hscfg, mmcquery_t is_protected, mmcquery_t is_inserted) { + mmcp->vmt = &mmc_vmt; mmcp->state = MMC_STOP; mmcp->config = NULL; mmcp->spip = spip; @@ -387,6 +452,7 @@ void mmcStop(MMCDriver *mmcp) { * handler. * * @param[in] mmcp pointer to the @p MMCDriver object + * * @return The operation status. * @retval FALSE the operation succeeded and the driver is now * in the @p MMC_READY state. @@ -411,7 +477,7 @@ bool_t mmcConnect(MMCDriver *mmcp) { /* SPI mode selection.*/ i = 0; while (TRUE) { - if (send_command_R1(mmcp, MMC_CMDGOIDLE, 0) == 0x01) + if (send_command_R1(mmcp, SDMMC_CMD_GO_IDLE_STATE, 0) == 0x01) break; if (++i >= MMC_CMD0_RETRY) return TRUE; @@ -419,20 +485,19 @@ bool_t mmcConnect(MMCDriver *mmcp) { } /* Try to detect if this is a high capacity card and switch to block - * addresses if possible. - * - * This method is based on "How to support SDC Ver2 and high capacity cards" - * by ElmChan. - * - * */ + addresses if possible. + This method is based on "How to support SDC Ver2 and high capacity cards" + by ElmChan.*/ uint8_t r3[4]; - if(send_command_R3(mmcp, MMC_CMDINTERFACE_CONDITION, 0x01AA, r3) != 0x05){ + if (send_command_R3(mmcp, SDMMC_CMD_SEND_IF_COND, + SDMMC_CMD8_PATTERN, r3) != 0x05) { - /* Switch to SDHC mode */ + /* Switch to SDHC mode.*/ i = 0; while (TRUE) { - if ((send_command_R1(mmcp, MMC_CMDAPP, 0) == 0x01) && - (send_command_R3(mmcp, MMC_ACMDOPCONDITION, 0x400001aa, r3) == 0x00)) + if ((send_command_R1(mmcp, SDMMC_CMD_APP_CMD, 0) == 0x01) && + (send_command_R3(mmcp, SDMMC_CMD_APP_OP_COND, + 0x400001aa, r3) == 0x00)) break; if (++i >= MMC_ACMD41_RETRY) @@ -441,17 +506,17 @@ bool_t mmcConnect(MMCDriver *mmcp) { } /* Execute dedicated read on OCR register */ - send_command_R3(mmcp, MMC_CMDREADOCR, 0, r3); + send_command_R3(mmcp, SDMMC_CMD_READ_OCR, 0, r3); - /* Check if CCS is set in response. Card operates in block mode if set */ + /* Check if CCS is set in response. Card operates in block mode if set.*/ if(r3[0] & 0x40) mmcp->block_addresses = TRUE; } - /* Initialization. */ + /* Initialization.*/ i = 0; while (TRUE) { - uint8_t b = send_command_R1(mmcp, MMC_CMDINIT, 0); + uint8_t b = send_command_R1(mmcp, SDMMC_CMD_INIT, 0); if (b == 0x00) break; if (b != 0x01) @@ -461,11 +526,12 @@ bool_t mmcConnect(MMCDriver *mmcp) { chThdSleepMilliseconds(10); } - /* Initialization complete, full speed. */ + /* Initialization complete, full speed.*/ spiStart(mmcp->spip, mmcp->hscfg); /* Setting block size.*/ - if (send_command_R1(mmcp, MMC_CMDSETBLOCKLEN, MMC_SECTOR_SIZE) != 0x00) + if (send_command_R1(mmcp, SDMMC_CMD_SET_BLOCKLEN, + SDMMC_BLOCK_SIZE) != 0x00) return TRUE; /* Transition to MMC_READY state (if not extracted).*/ @@ -490,6 +556,7 @@ bool_t mmcConnect(MMCDriver *mmcp) { * * @param[in] mmcp pointer to the @p MMCDriver object * @return The operation status. + * * @retval FALSE the operation succeeded and the driver is now * in the @p MMC_INSERTED state. * @retval TRUE the operation failed. @@ -525,6 +592,7 @@ bool_t mmcDisconnect(MMCDriver *mmcp) { * * @param[in] mmcp pointer to the @p MMCDriver object * @param[in] startblk first block to read + * * @return The operation status. * @retval FALSE the operation succeeded. * @retval TRUE the operation failed. @@ -547,9 +615,9 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) { spiSelect(mmcp->spip); if(mmcp->block_addresses) - send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk); + send_hdr(mmcp, SDMMC_CMD_READ_MULTIPLE_BLOCK, startblk); else - send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk * MMC_SECTOR_SIZE); + send_hdr(mmcp, SDMMC_CMD_READ_MULTIPLE_BLOCK, startblk * SDMMC_BLOCK_SIZE); if (recvr1(mmcp) != 0x00) { spiUnselect(mmcp->spip); @@ -567,6 +635,7 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) { * * @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 succeeded. * @retval TRUE the operation failed. @@ -588,7 +657,7 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) { for (i = 0; i < MMC_WAIT_DATA; i++) { spiReceive(mmcp->spip, 1, buffer); if (buffer[0] == 0xFE) { - spiReceive(mmcp->spip, MMC_SECTOR_SIZE, buffer); + spiReceive(mmcp->spip, SDMMC_BLOCK_SIZE, buffer); /* CRC ignored. */ spiIgnore(mmcp->spip, 2); return FALSE; @@ -607,6 +676,7 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) { * @brief Stops a sequential read gracefully. * * @param[in] mmcp pointer to the @p MMCDriver object + * * @return The operation status. * @retval FALSE the operation succeeded. * @retval TRUE the operation failed. @@ -614,7 +684,8 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) { * @api */ bool_t mmcStopSequentialRead(MMCDriver *mmcp) { - static const uint8_t stopcmd[] = {0x40 | MMC_CMDSTOP, 0, 0, 0, 0, 1, 0xFF}; + static const uint8_t stopcmd[] = {0x40 | SDMMC_CMD_STOP_TRANSMISSION, + 0, 0, 0, 0, 1, 0xFF}; bool_t result; chDbgCheck(mmcp != NULL, "mmcStopSequentialRead"); @@ -645,6 +716,7 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) { * * @param[in] mmcp pointer to the @p MMCDriver object * @param[in] startblk first block to write + * * @return The operation status. * @retval FALSE the operation succeeded. * @retval TRUE the operation failed. @@ -666,9 +738,10 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) { spiStart(mmcp->spip, mmcp->hscfg); spiSelect(mmcp->spip); if(mmcp->block_addresses) - send_hdr(mmcp, MMC_CMDWRITEMULTIPLE, startblk); + send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK, startblk); else - send_hdr(mmcp, MMC_CMDWRITEMULTIPLE, startblk * MMC_SECTOR_SIZE); + send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK, + startblk * SDMMC_BLOCK_SIZE); if (recvr1(mmcp) != 0x00) { @@ -687,6 +760,7 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) { * * @param[in] mmcp pointer to the @p MMCDriver object * @param[out] buffer pointer to the write buffer + * * @return The operation status. * @retval FALSE the operation succeeded. * @retval TRUE the operation failed. @@ -707,7 +781,7 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) { chSysUnlock(); spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */ - spiSend(mmcp->spip, MMC_SECTOR_SIZE, buffer); /* Data. */ + spiSend(mmcp->spip, SDMMC_BLOCK_SIZE, buffer); /* Data. */ spiIgnore(mmcp->spip, 2); /* CRC ignored. */ spiReceive(mmcp->spip, 1, b); if ((b[0] & 0x1F) == 0x05) { @@ -728,6 +802,7 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) { * @brief Stops a sequential write gracefully. * * @param[in] mmcp pointer to the @p MMCDriver object + * * @return The operation status. * @retval FALSE the operation succeeded. * @retval TRUE the operation failed. @@ -759,6 +834,63 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) { return TRUE; } +/** + * @brief Waits for card idle condition. + * + * @param[in] mmcp pointer to the @p MMCDriver object + * + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed. + * + * @api + */ +bool_t mmcSync(MMCDriver *mmcp) { + + chDbgCheck(mmcp != NULL, "mmcSync"); + + chSysLock(); + if (mmcp->state != MMC_READY) { + chSysUnlock(); + return TRUE; + } + chSysUnlock(); + + sync(mmcp); + + return FALSE; +} + +/** + * @brief Returns the media info. + * + * @param[in] mmcp pointer to the @p MMCDriver object + * @param[out] bdip pointer to a @p BlockDeviceInfo structure + * + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed. + * + * @api + */ +bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) { + + + chDbgCheck((mmcp != NULL) && (bdip != NULL), "mmcGetInfo"); + + chSysLock(); + if (mmcp->state != MMC_READY) { + chSysUnlock(); + return TRUE; + } + chSysUnlock(); + + bdip->blk_num = 0; /* NOTE: To be implemented.*/ + bdip->blk_size = SDMMC_BLOCK_SIZE; + + return FALSE; +} + #endif /* HAL_USE_MMC_SPI */ /** @} */ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 6e9dcabd4..483263776 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -43,6 +43,20 @@ /* Driver local variables. */ /*===========================================================================*/ +/** + * @brief Virtual methods table. + */ +static const struct MMCSDBlockDeviceVMT sdc_vmt = { + (bool_t (*)(void *))sdc_lld_is_card_inserted, + (bool_t (*)(void *))sdc_lld_is_write_protected, + (bool_t (*)(void *))sdcConnect, + (bool_t (*)(void *))sdcDisconnect, + (bool_t (*)(void *, uint32_t, uint8_t *, uint32_t))sdcRead, + (bool_t (*)(void *, uint32_t, const uint8_t *, uint32_t))sdcWrite, + (bool_t (*)(void *))sdcSync, + (bool_t (*)(void *, BlockDeviceInfo *))sdcGetInfo +}; + /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ @@ -147,6 +161,7 @@ void sdcInit(void) { */ void sdcObjectInit(SDCDriver *sdcp) { + sdcp->vmt = &sdc_vmt; sdcp->state = SDC_STOP; sdcp->errors = SDC_NO_ERROR; sdcp->config = NULL; @@ -486,6 +501,63 @@ sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp) { return flags; } +/** + * @brief Waits for card idle condition. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed. + * + * @api + */ +bool_t sdcSync(SDCDriver *sdcp) { + + chDbgCheck(sdcp != NULL, "sdcSync"); + + chSysLock(); + if (sdcp->state != SDC_READY) { + chSysUnlock(); + return TRUE; + } + chSysUnlock(); + + /* TODO: implement.*/ + + return FALSE; +} + +/** + * @brief Returns the media info. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[out] bdip pointer to a @p BlockDeviceInfo structure + * + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed. + * + * @api + */ +bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) { + + + chDbgCheck((sdcp != NULL) && (bdip != NULL), "sdcGetInfo"); + + chSysLock(); + if (sdcp->state != SDC_READY) { + chSysUnlock(); + return TRUE; + } + chSysUnlock(); + + bdip->blk_num = 0; /* NOTE: To be implemented.*/ + bdip->blk_size = SDMMC_BLOCK_SIZE; + + return FALSE; +} + #endif /* HAL_USE_SDC */ /** @} */ diff --git a/readme.txt b/readme.txt index 35d09516a..372a34c74 100644 --- a/readme.txt +++ b/readme.txt @@ -123,13 +123,16 @@ 3484947)(backported to 2.4.1). - FIX: Fixed various minor documentation errors (bug 3484942)(backported to 2.4.1). +- NEW: Added two new functions to the MMC_SPI driver: mmcSync() and + mmc_Get_Info(). Also added the capability to operate through the new + block devices abstract interface. +- NEW: Added an abstract interface for block devices in the HAL. This + abstraction layer is meant to unify the access protocol to the SDC and + MMC_SPI (and potentially others) device drivers. - NEW: Added an abstract interface for serial devices in the HAL. This interface is meant to replace the equivalent class already present in the kernel. access macros are similar except for the prefix, "chn" instead of "chIO". -- NEW: Added an abstract interface for block devices in the HAL. This - abstraction layer is meant to unify the access protocol to the SDC and - MMC_SPI (and potentially others) device drivers. - NEW: Updated the MSP port to work with the latest MSPGCC compiler (4.6.3 LTS 20120406 unpatched), now the old MSPGCC 3.2.3 is no more supported (backported to 2.4.1).