From 60c6d531d4b6b5c5d3d78c4337d267d3fe315c7c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 12 Aug 2013 16:44:22 +0000 Subject: Ported MMC_SPI. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6145 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/hal.h | 6 +- os/hal/include/hal_ioblock.h | 269 +++++++++++++++++++++++++++++++++++++++++ os/hal/include/hal_mmcsd.h | 279 +++++++++++++++++++++++++++++++++++++++++++ os/hal/include/mmc_spi.h | 199 ++++++++++++++++++++++++++++++ 4 files changed, 750 insertions(+), 3 deletions(-) create mode 100644 os/hal/include/hal_ioblock.h create mode 100644 os/hal/include/hal_mmcsd.h create mode 100644 os/hal/include/mmc_spi.h (limited to 'os/hal/include') diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 81cf25571..0ab5ee37b 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -38,8 +38,8 @@ /* Abstract interfaces.*/ #include "hal_streams.h" #include "hal_channels.h" -//#include "io_block.h" -//#include "mmcsd.h" +#include "hal_ioblock.h" +#include "hal_mmcsd.h" /* Shared headers.*/ #include "hal_queues.h" @@ -63,7 +63,7 @@ //#include "usb.h" /* Complex drivers.*/ -//#include "mmc_spi.h" +#include "mmc_spi.h" //#include "serial_usb.h" /*===========================================================================*/ diff --git a/os/hal/include/hal_ioblock.h b/os/hal/include/hal_ioblock.h new file mode 100644 index 000000000..e0ef360f3 --- /dev/null +++ b/os/hal/include/hal_ioblock.h @@ -0,0 +1,269 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 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 hal_ioblock.h + * @brief I/O block devices access. + * @details This header defines an abstract interface useful to access generic + * I/O block devices in a standardized way. + * + * @addtogroup IO_BLOCK + * @details This module defines an abstract interface for accessing generic + * block devices.
+ * Note that no code is present, just abstract interfaces-like + * structures, you should look at the system as to a set of + * abstract C++ classes (even if written in C). This system + * has then advantage to make the access to block devices + * independent from the implementation logic. + * @{ + */ + +#ifndef _HAL_IOBLOCK_H_ +#define _HAL_IOBLOCK_H_ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + BLK_UNINIT = 0, /**< Not initialized. */ + BLK_STOP = 1, /**< Stopped. */ + BLK_ACTIVE = 2, /**< Interface active. */ + BLK_CONNECTING = 3, /**< Connection in progress. */ + BLK_DISCONNECTING = 4, /**< Disconnection in progress. */ + BLK_READY = 5, /**< Device ready. */ + BLK_READING = 6, /**< Read operation in progress. */ + BLK_WRITING = 7, /**< Write operation in progress. */ + BLK_SYNCING = 8 /**< Sync. operation in progress. */ +} blkstate_t; + +/** + * @brief Block device info. + */ +typedef struct { + uint32_t blk_size; /**< @brief Block size in bytes. */ + uint32_t blk_num; /**< @brief Total number of blocks. */ +} BlockDeviceInfo; + +/** + * @brief @p BaseBlockDevice specific methods. + */ +#define _base_block_device_methods \ + /* Removable media detection.*/ \ + bool (*is_inserted)(void *instance); \ + /* Removable write protection detection.*/ \ + bool (*is_protected)(void *instance); \ + /* Connection to the block device.*/ \ + bool (*connect)(void *instance); \ + /* Disconnection from the block device.*/ \ + bool (*disconnect)(void *instance); \ + /* Reads one or more blocks.*/ \ + bool (*read)(void *instance, uint32_t startblk, \ + uint8_t *buffer, uint32_t n); \ + /* Writes one or more blocks.*/ \ + bool (*write)(void *instance, uint32_t startblk, \ + const uint8_t *buffer, uint32_t n); \ + /* Write operations synchronization.*/ \ + bool (*sync)(void *instance); \ + /* Obtains info about the media.*/ \ + bool (*get_info)(void *instance, BlockDeviceInfo *bdip); + +/** + * @brief @p BaseBlockDevice specific data. + */ +#define _base_block_device_data \ + /* Driver state.*/ \ + blkstate_t state; + +/** + * @brief @p BaseBlockDevice virtual methods table. + */ +struct BaseBlockDeviceVMT { + _base_block_device_methods +}; + +/** + * @brief Base block device class. + * @details This class represents a generic, block-accessible, device. + */ +typedef struct { + /** @brief Virtual Methods Table.*/ + const struct BaseBlockDeviceVMT *vmt; + _base_block_device_data +} BaseBlockDevice; + +/** + * @name Macro Functions (BaseBlockDevice) + * @{ + */ +/** + * @brief Returns the driver state. + * @note Can be called in ISR context. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The driver state. + * + * @special + */ +#define blkGetDriverState(ip) ((ip)->state) + +/** + * @brief Determines if the device is transferring data. + * @note Can be called in ISR context. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The driver state. + * @retval FALSE the device is not transferring data. + * @retval TRUE the device not transferring data. + * + * @special + */ +#define blkIsTransferring(ip) ((((ip)->state) == BLK_CONNECTING) || \ + (((ip)->state) == BLK_DISCONNECTING) || \ + (((ip)->state) == BLK_READING) || \ + (((ip)->state) == BLK_WRITING)) + +/** + * @brief Returns the media insertion status. + * @note On some implementations this function can only be called if the + * device is not transferring data. + * The function @p blkIsTransferring() should be used before calling + * this function. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The media state. + * @retval FALSE media not inserted. + * @retval TRUE media inserted. + * + * @api + */ +#define blkIsInserted(ip) ((ip)->vmt->is_inserted(ip)) + +/** + * @brief Returns the media write protection status. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The media state. + * @retval FALSE writable media. + * @retval TRUE non writable media. + * + * @api + */ +#define blkIsWriteProtected(ip) ((ip)->vmt->is_protected(ip)) + +/** + * @brief Performs the initialization procedure on the block device. + * @details This function should be performed before I/O operations can be + * attempted on the block device and after insertion has been + * confirmed using @p blkIsInserted(). + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The operation status. + * @retval CH_SUCCESS operation succeeded. + * @retval CH_FAILED operation failed. + * + * @api + */ +#define blkConnect(ip) ((ip)->vmt->connect(ip)) + +/** + * @brief Terminates operations on the block device. + * @details This operation safely terminates operations on the block device. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The operation status. + * @retval CH_SUCCESS operation succeeded. + * @retval CH_FAILED operation failed. + * + * @api + */ +#define blkDisconnect(ip) ((ip)->vmt->disconnect(ip)) + +/** + * @brief Reads one or more blocks. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer + * @param[in] n number of blocks to read + * + * @return The operation status. + * @retval CH_SUCCESS operation succeeded. + * @retval CH_FAILED operation failed. + * + * @api + */ +#define blkRead(ip, startblk, buf, n) \ + ((ip)->vmt->read(ip, startblk, buf, n)) + +/** + * @brief Writes one or more blocks. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer + * @param[in] n number of blocks to write + * + * @return The operation status. + * @retval CH_SUCCESS operation succeeded. + * @retval CH_FAILED operation failed. + * + * @api + */ +#define blkWrite(ip, startblk, buf, n) \ + ((ip)->vmt->write(ip, startblk, buf, n)) + +/** + * @brief Ensures write synchronization. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The operation status. + * @retval CH_SUCCESS operation succeeded. + * @retval CH_FAILED operation failed. + * + * @api + */ +#define blkSync(ip) ((ip)->vmt->sync(ip)) + +/** + * @brief Returns a media information structure. + * + * @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 CH_SUCCESS operation succeeded. + * @retval CH_FAILED operation failed. + * + * @api + */ +#define blkGetInfo(ip, bdip) ((ip)->vmt->get_info(ip, bdip)) + +/** @} */ + +#endif /* _HAL_IOBLOCK_H_ */ + +/** @} */ diff --git a/os/hal/include/hal_mmcsd.h b/os/hal/include/hal_mmcsd.h new file mode 100644 index 000000000..09a789549 --- /dev/null +++ b/os/hal/include/hal_mmcsd.h @@ -0,0 +1,279 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 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 hal_mmcsd.h + * @brief MMC/SD cards common header. + * @details This header defines an abstract interface useful to access MMC/SD + * I/O block devices in a standardized way. + * + * @addtogroup MMCSD + * @{ + */ + +#ifndef _HAL_MMCSD_H_ +#define _HAL_MMCSD_H_ + +#if HAL_USE_MMC_SPI || HAL_USE_SDC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Fixed block size for MMC/SD block devices. + */ +#define MMCSD_BLOCK_SIZE 512 + +/** + * @brief Mask of error bits in R1 responses. + */ +#define MMCSD_R1_ERROR_MASK 0xFDFFE008 + +/** + * @brief Fixed pattern for CMD8. + */ +#define MMCSD_CMD8_PATTERN 0x000001AA + +/** + * @name SD/MMC status conditions + * @{ + */ +#define MMCSD_STS_IDLE 0 +#define MMCSD_STS_READY 1 +#define MMCSD_STS_IDENT 2 +#define MMCSD_STS_STBY 3 +#define MMCSD_STS_TRAN 4 +#define MMCSD_STS_DATA 5 +#define MMCSD_STS_RCV 6 +#define MMCSD_STS_PRG 7 +#define MMCSD_STS_DIS 8 +/** @} */ + +/** + * @name SD/MMC commands + * @{ + */ +#define MMCSD_CMD_GO_IDLE_STATE 0 +#define MMCSD_CMD_INIT 1 +#define MMCSD_CMD_ALL_SEND_CID 2 +#define MMCSD_CMD_SEND_RELATIVE_ADDR 3 +#define MMCSD_CMD_SET_BUS_WIDTH 6 +#define MMCSD_CMD_SEL_DESEL_CARD 7 +#define MMCSD_CMD_SEND_IF_COND 8 +#define MMCSD_CMD_SEND_CSD 9 +#define MMCSD_CMD_SEND_CID 10 +#define MMCSD_CMD_STOP_TRANSMISSION 12 +#define MMCSD_CMD_SEND_STATUS 13 +#define MMCSD_CMD_SET_BLOCKLEN 16 +#define MMCSD_CMD_READ_SINGLE_BLOCK 17 +#define MMCSD_CMD_READ_MULTIPLE_BLOCK 18 +#define MMCSD_CMD_SET_BLOCK_COUNT 23 +#define MMCSD_CMD_WRITE_BLOCK 24 +#define MMCSD_CMD_WRITE_MULTIPLE_BLOCK 25 +#define MMCSD_CMD_ERASE_RW_BLK_START 32 +#define MMCSD_CMD_ERASE_RW_BLK_END 33 +#define MMCSD_CMD_ERASE 38 +#define MMCSD_CMD_APP_OP_COND 41 +#define MMCSD_CMD_LOCK_UNLOCK 42 +#define MMCSD_CMD_APP_CMD 55 +#define MMCSD_CMD_READ_OCR 58 +/** @} */ + +/** + * @name CSD record offsets + */ +/** + * @brief Slice position of values in CSD register. + */ +/* CSD version 2.0 */ +#define MMCSD_CSD_20_CRC_SLICE 7,1 +#define MMCSD_CSD_20_FILE_FORMAT_SLICE 11,10 +#define MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE 12,12 +#define MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE 13,13 +#define MMCSD_CSD_20_COPY_SLICE 14,14 +#define MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE 15,15 +#define MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE 21,21 +#define MMCSD_CSD_20_WRITE_BL_LEN_SLICE 25,12 +#define MMCSD_CSD_20_R2W_FACTOR_SLICE 28,26 +#define MMCSD_CSD_20_WP_GRP_ENABLE_SLICE 31,31 +#define MMCSD_CSD_20_WP_GRP_SIZE_SLICE 38,32 +#define MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE 45,39 +#define MMCSD_CSD_20_ERASE_BLK_EN_SLICE 46,46 +#define MMCSD_CSD_20_C_SIZE_SLICE 69,48 +#define MMCSD_CSD_20_DSR_IMP_SLICE 76,76 +#define MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE 77,77 +#define MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE 78,78 +#define MMCSD_CSD_20_READ_BL_PARTIAL_SLICE 79,79 +#define MMCSD_CSD_20_READ_BL_LEN_SLICE 83,80 +#define MMCSD_CSD_20_CCC_SLICE 95,84 +#define MMCSD_CSD_20_TRANS_SPEED_SLICE 103,96 +#define MMCSD_CSD_20_NSAC_SLICE 111,104 +#define MMCSD_CSD_20_TAAC_SLICE 119,112 +#define MMCSD_CSD_20_STRUCTURE_SLICE 127,126 + +/* CSD version 1.0 */ +#define MMCSD_CSD_10_CRC_SLICE MMCSD_CSD_20_CRC_SLICE +#define MMCSD_CSD_10_FILE_FORMAT_SLICE MMCSD_CSD_20_FILE_FORMAT_SLICE +#define MMCSD_CSD_10_TMP_WRITE_PROTECT_SLICE MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE +#define MMCSD_CSD_10_PERM_WRITE_PROTECT_SLICE MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE +#define MMCSD_CSD_10_COPY_SLICE MMCSD_CSD_20_COPY_SLICE +#define MMCSD_CSD_10_FILE_FORMAT_GRP_SLICE MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE +#define MMCSD_CSD_10_WRITE_BL_PARTIAL_SLICE MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE +#define MMCSD_CSD_10_WRITE_BL_LEN_SLICE MMCSD_CSD_20_WRITE_BL_LEN_SLICE +#define MMCSD_CSD_10_R2W_FACTOR_SLICE MMCSD_CSD_20_R2W_FACTOR_SLICE +#define MMCSD_CSD_10_WP_GRP_ENABLE_SLICE MMCSD_CSD_20_WP_GRP_ENABLE_SLICE +#define MMCSD_CSD_10_WP_GRP_SIZE_SLICE MMCSD_CSD_20_WP_GRP_SIZE_SLICE +#define MMCSD_CSD_10_ERASE_SECTOR_SIZE_SLICE MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE +#define MMCSD_CSD_10_ERASE_BLK_EN_SLICE MMCSD_CSD_20_ERASE_BLK_EN_SLICE +#define MMCSD_CSD_10_C_SIZE_MULT_SLICE 49,47 +#define MMCSD_CSD_10_VDD_W_CURR_MAX_SLICE 52,50 +#define MMCSD_CSD_10_VDD_W_CURR_MIN_SLICE 55,53 +#define MMCSD_CSD_10_VDD_R_CURR_MAX_SLICE 58,56 +#define MMCSD_CSD_10_VDD_R_CURR_MIX_SLICE 61,59 +#define MMCSD_CSD_10_C_SIZE_SLICE 73,62 +#define MMCSD_CSD_10_DSR_IMP_SLICE MMCSD_CSD_20_DSR_IMP_SLICE +#define MMCSD_CSD_10_READ_BLK_MISALIGN_SLICE MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE +#define MMCSD_CSD_10_WRITE_BLK_MISALIGN_SLICE MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE +#define MMCSD_CSD_10_READ_BL_PARTIAL_SLICE MMCSD_CSD_20_READ_BL_PARTIAL_SLICE +#define MMCSD_CSD_10_READ_BL_LEN_SLICE 83, 80 +#define MMCSD_CSD_10_CCC_SLICE MMCSD_CSD_20_CCC_SLICE +#define MMCSD_CSD_10_TRANS_SPEED_SLICE MMCSD_CSD_20_TRANS_SPEED_SLICE +#define MMCSD_CSD_10_NSAC_SLICE MMCSD_CSD_20_NSAC_SLICE +#define MMCSD_CSD_10_TAAC_SLICE MMCSD_CSD_20_TAAC_SLICE +#define MMCSD_CSD_10_STRUCTURE_SLICE MMCSD_CSD_20_STRUCTURE_SLICE +/** @} */ + +/*===========================================================================*/ +/* 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 \ + /* Card CID.*/ \ + uint32_t cid[4]; \ + /* Card CSD.*/ \ + uint32_t csd[4]; \ + /* Total number of blocks in card.*/ \ + uint32_t capacity; + +/** + * @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. */ +/*===========================================================================*/ + +/** + * @name R1 response utilities + * @{ + */ +/** + * @brief Evaluates to @p TRUE if the R1 response contains error flags. + * + * @param[in] r1 the r1 response + */ +#define MMCSD_R1_ERROR(r1) (((r1) & MMCSD_R1_ERROR_MASK) != 0) + +/** + * @brief Returns the status field of an R1 response. + * + * @param[in] r1 the r1 response + */ +#define MMCSD_R1_STS(r1) (((r1) >> 9) & 15) + +/** + * @brief Evaluates to @p TRUE if the R1 response indicates a locked card. + * + * @param[in] r1 the r1 response + */ +#define MMCSD_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1) +/** @} */ + +/** + * @name Macro Functions + * @{ + */ +/** + * @brief Returns the card capacity in blocks. + * + * @param[in] ip pointer to a @p MMCSDBlockDevice or derived class + * + * @return The card capacity. + * + * @api + */ +#define mmcsdGetCardCapacity(ip) ((ip)->capacity) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + uint32_t mmcsdGetCapacity(uint32_t csd[4]); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_MMC_SPI || HAL_USE_MMC_SDC*/ + +#endif /* _HAL_MMCSD_H_ */ + +/** @} */ diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h new file mode 100644 index 000000000..9f51f7e2b --- /dev/null +++ b/os/hal/include/mmc_spi.h @@ -0,0 +1,199 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 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 mmc_spi.h + * @brief MMC over SPI driver header. + * + * @addtogroup MMC_SPI + * @{ + */ + +#ifndef _MMC_SPI_H_ +#define _MMC_SPI_H_ + +#if HAL_USE_MMC_SPI || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +#define MMC_CMD0_RETRY 10 +#define MMC_CMD1_RETRY 100 +#define MMC_ACMD41_RETRY 100 +#define MMC_WAIT_DATA 10000 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name MMC_SPI configuration options + * @{ + */ +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !HAL_USE_SPI || !SPI_USE_WAIT +#error "MMC_SPI driver requires HAL_USE_SPI and SPI_USE_WAIT" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief MMC/SD over SPI driver configuration structure. + */ +typedef struct { + /** + * @brief SPI driver associated to this MMC driver. + */ + SPIDriver *spip; + /** + * @brief SPI low speed configuration used during initialization. + */ + const SPIConfig *lscfg; + /** + * @brief SPI high speed configuration used during transfers. + */ + const SPIConfig *hscfg; +} MMCConfig; + +/** + * @brief @p MMCDriver specific methods. + */ +#define _mmc_driver_methods \ + _mmcsd_block_device_methods + +/** + * @extends MMCSDBlockDeviceVMT + * + * @brief @p MMCDriver virtual methods table. + */ +struct MMCDriverVMT { + _mmc_driver_methods +}; + +/** + * @extends MMCSDBlockDevice + * + * @brief Structure representing a MMC/SD over SPI driver. + */ +typedef struct { + /** + * @brief Virtual Methods Table. + */ + const struct MMCDriverVMT *vmt; + _mmcsd_block_device_data + /** + * @brief Current configuration data. + */ + const MMCConfig *config; + /*** + * @brief Addresses use blocks instead of bytes. + */ + bool block_addresses; +} MMCDriver; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Macro Functions + * @{ + */ +/** + * @brief Returns the card insertion status. + * @note This macro wraps a low level function named + * @p sdc_lld_is_card_inserted(), this function must be + * provided by the application because it is not part of the + * SDC driver. + * + * @param[in] mmcp pointer to the @p MMCDriver object + * @return The card state. + * @retval FALSE card not inserted. + * @retval TRUE card inserted. + * + * @api + */ +#define mmcIsCardInserted(mmcp) mmc_lld_is_card_inserted(mmcp) + +/** + * @brief Returns the write protect status. + * + * @param[in] mmcp pointer to the @p MMCDriver object + * @return The card state. + * @retval FALSE card not inserted. + * @retval TRUE card inserted. + * + * @api + */ +#define mmcIsWriteProtected(mmcp) mmc_lld_is_write_protected(mmcp) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void mmcInit(void); + void mmcObjectInit(MMCDriver *mmcp); + void mmcStart(MMCDriver *mmcp, const MMCConfig *config); + void mmcStop(MMCDriver *mmcp); + bool mmcConnect(MMCDriver *mmcp); + bool mmcDisconnect(MMCDriver *mmcp); + bool mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk); + bool mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer); + bool mmcStopSequentialRead(MMCDriver *mmcp); + bool mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk); + bool mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer); + bool mmcStopSequentialWrite(MMCDriver *mmcp); + bool mmcSync(MMCDriver *mmcp); + bool mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip); + bool mmcErase(MMCDriver *mmcp, uint32_t startblk, uint32_t endblk); + bool mmc_lld_is_card_inserted(MMCDriver *mmcp); + bool mmc_lld_is_write_protected(MMCDriver *mmcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_MMC_SPI */ + +#endif /* _MMC_SPI_H_ */ + +/** @} */ -- cgit v1.2.3