#ifndef _DEV_MMCARD_H_ #define _DEV_MMCARD_H_ /* * Copyright (C) 2005 by egnite Software GmbH. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * For additional information see http://www.ethernut.de/ */ /*! * \file dev/mmcard.h * \brief Header file for basic multimedia card driver. * * \verbatim * * $Log$ * Revision 1.5 2008/10/03 11:28:58 haraldkipp * Corrected and modified initialization of MultiMedia and SD Cards. * * Revision 1.4 2008/08/11 06:59:59 haraldkipp * BSD types replaced by stdint types (feature request #1282721). * * Revision 1.3 2006/10/08 16:48:09 haraldkipp * Documentation fixed * * Revision 1.2 2006/09/05 12:34:55 haraldkipp * Added commands for native MMC interface. * * Revision 1.1 2006/01/05 16:32:10 haraldkipp * First check-in. * * * \endverbatim */ #include #include /*! * \addtogroup xgMmCard */ /*@{*/ #define NUTMC_SF_CD 0x01 #define NUTMC_SF_WP 0x02 #define NUTMC_SF_HC 0x04 #define NUTMC_SF_ILL 0x80 #define NUTMC_IND_OFF 0 #define NUTMC_IND_READ 1 #define NUTMC_IND_WRITE 2 #define NUTMC_IND_ERROR 4 /*! * \brief Memory card support structure. */ typedef struct _MEMCARDSUPP { /*! \brief Status change flag. */ uint8_t mcs_cf; /*! \brief Socket status. */ uint8_t mcs_sf; /*! \brief Status reset. */ int (*mcs_reset) (NUTDEVICE *); /*! \brief Set activity indicator. */ void (*mcs_act) (int); /*! \brief Power up or down. */ int (*mcs_power) (int); } MEMCARDSUPP; /*! * \brief Low level access information structure. */ typedef struct _MMCIFC { /*! Initialize the card. */ int (*mmcifc_in) (void); /*! Read received byte and transmit a new one. */ uint8_t(*mmcifc_io) (uint8_t); /*! Select or deselect the card. */ int (*mmcifc_cs) (int); /*! Query card detect. */ int (*mmcifc_cd) (void); /*! Query write protect. */ int (*mmcifc_wp) (void); /*! Set addressing mode. */ int (*mmcifc_sm) (int); /*! Get addressing mode. */ int (*mmcifc_gm) (void); } MMCIFC; #define MMCMD_HOST 0x40 #define MMCMD_RESET_CRC 0x95 #define MMCMD_IF_COND_CRC 0x87 /*! * \brief Addressing mode selection flags * SD-HC uses byte addressing, SD-normal uses block addressing */ #define MMC_BLOCK_MODE 0 // access card in block mode, #define MMC_BYTE_MODE 1 // acces card using byte-addresses iso sector addresses /*! \brief Reset card to idle state. * * In idle state the card will not accept any other commands than * MMCMD_SEND_OP_COND or MMCMD_READ_OCR. */ #define MMCMD_GO_IDLE_STATE 0 /*! \brief Activate card's initialization process. */ #define MMCMD_SEND_OP_COND 1 /*! \brief Send operation condition register. * * Queries the operation condition register content from all cards, which * are in idle state. */ #define MMCMD_ALL_SEND_CID 2 /*! \brief Assign relative card address. */ #define MMCMD_SEND_RELATIVE_ADDR 3 /*! \brief Assign relative card address. */ #define MMCMD_SELECT_CARD 7 /*! \brief negociate operating voltage (mandatory for 2.0). */ // TODO: Double command? Same as extcsd? #define MMCMD_SEND_IF_COND 8 /*! \brief Query card's extended CSD. */ #define MMCMD_SEND_EXTCSD 8 /*! \brief Query card's CSD. */ #define MMCMD_SEND_CSD 9 /*! \brief Query card's CID. */ #define MMCMD_SEND_CID 10 /*! \brief Stop multiple block transmission. */ #define MMCMD_STOP_TRANSMISSION 12 /*! \brief Query card's status register. */ #define MMCMD_SEND_STATUS 13 /*! \brief Select block length for following read/write commands. */ #define MMCMD_SET_BLOCKLEN 16 /*! \brief Initiate single block read. */ #define MMCMD_READ_SINGLE_BLOCK 17 /*! \brief Initiate continuous block read. */ #define MMCMD_READ_MULTIPLE_BLOCK 18 /*! \brief Initiate single block write. */ #define MMCMD_WRITE_BLOCK 24 /*! \brief Initiate continuous block write. */ #define MMCMD_WRITE_MULTIPLE_BLOCK 25 /*! \brief Initiate programming of programmable CSD bits. */ #define MMCMD_PROGRAM_CSD 27 /*! \brief Enable card's optional write protection. */ #define MMCMD_SET_WRITE_PROTECT 28 /*! \brief Disable card's write protection. */ #define MMCMD_CLR_WRITE_PROTECT 29 /*! \brief Query card's write protect status. */ #define MMCMD_SEND_WRITE_PROTECT 30 /*! \brief Set address of the first erase group. */ #define MMCMD_TAG_ERASE_GROUP_START 35 /*! \brief Set address of the last erase group. */ #define MMCMD_TAG_ERASE_GROUP_END 36 /*! \brief Erase previously selected sectors. */ #define MMCMD_ERASE 38 /*! \brief Activate SD card's initialization process. */ #define MMCMD_SEND_APP_OP_COND 41 /*! \brief Set/clear password or lock/unlock the card. */ #define MMCMD_LOCK_UNLOCK 42 /*! \brief Application command follows. */ #define MMCMD_SEND_APP_CMD 55 /*! \brief Query card's operating condition register. */ #define MMCMD_READ_OCR 58 /*! \brief Enable or disable CRC mode. * * In SPI mode CRC is disabled by default. */ #define MMCMD_CRC_ON_OFF 59 /*! \brief Card is idle. */ #define MMR1_IDLE_STATE 0x00 /*! \brief Card is busy. */ #define MMR1_NOT_IDLE 0x01 /*! \brief Erase sequence was cleared before execution. */ #define MMR1_ERASE_RESET 0x02 /*! \brief Illegal command code detected. */ #define MMR1_ILLEGAL_COMMAND 0x04 /*! \brief Bad command CRC detected. */ #define MMR1_COM_CRC_ERROR 0x08 /*! \brief Bad erase sequence. */ #define MMR1_ERASE_SEQ_ERROR 0x10 /*! \brief Misaligned address did not match block length. */ #define MMR1_ADDRESS_ERROR 0x20 /*! \brief Command parameter is out of range. */ #define MMR1_PARAMETER_ERROR 0x40 /*! \brief Card is locked. */ #define MMR2_CARD_LOCKED 0x01 /*! \brief Erasing write protected sector or password error. */ #define MMR2_WP_ERASE_SKIP 0x02 /*! \brief General or unknown error occured. */ #define MMR2_ERROR 0x04 /*! \brief Internal card controller error. */ #define MMR2_CC_ERROR 0x08 /*! \brief Bad internal ECC. */ #define MMR2_ECC_FAILED 0x10 /*! \brief Failed to write to protected block. */ #define MMR2_WP_VIOLATION 0x20 /*! \brief Invalid erase parameter. */ #define MMR2_ERASE_PARAMETER 0x40 /*! \brief Command parameter is out of range. */ #define MMR2_OUT_OF_RANGE 0x80 #define MMCSR_OUT_OF_RANGE 0x80000000 #define MMCSR_ADDRESS_ERROR 0x40000000 #define MMCSR_BLOCK_LEN_ERROR 0x20000000 #define MMCSR_ERASE_SEQ_ERROR 0x10000000 #define MMCSR_ERASE_PARAM 0x08000000 #define MMCSR_WP_VIOLATION 0x04000000 #define MMCSR_COM_CRC_ERROR 0x00800000 #define MMCSR_ILLEGAL_COMMAND 0x00400000 #define MMCSR_ERROR 0x00080000 #define MMCSR_CIDCSD_OVERWRITE 0x00010000 #define MMCSR_WP_ERASE_SKIP 0x00008000 #define MMCSR_CARD_ECC_DISABLED 0x00004000 #define MMCSR_ERASE_RESET 0x00002000 #define MMCSR_STATE_MASK 0x00001E00 #define MMCSR_READY_FOR_DATA 0x00000100 #define MMCSR_IS_IDLE 0x00000000 #define MMCSR_IS_READY 0x00000200 #define MMCSR_IS_IDENT 0x00000400 #define MMCSR_IS_STBY 0x00000600 #define MMCSR_IS_TRAN 0x00000800 #define MMCSR_IS_DATA 0x00000A00 #define MMCSR_IS_RCV 0x00000C00 #define MMCSR_IS_PRG 0x00000E00 #define MMCSR_IS_DIS 0x00001000 #define MMDR_ACCEPTED #define MMDR_CRC_ERROR #define MMDR_WRITE_ERROR #define MMCERR_TIMEOUT 0x00000001 #define MMCOP_NBUSY 0x80000000 /*! \brief Number of bytes in the CID register. */ #define MMCARD_CIDR_SIZE 16 /*! \brief Number of bytes in the CSD register. */ #define MMCARD_CSDR_SIZE 16 /*! \brief Number of bytes in the operating condition register. */ #define MMCARD_OCR_SIZE 32 /*! * \name Voltage Ranges */ /*@{*/ #define MMCARD_165_195V 0x00000080 #define MMCARD_20_21V 0x00000100 #define MMCARD_21_22V 0x00000200 #define MMCARD_22_23V 0x00000400 #define MMCARD_23_24V 0x00000800 #define MMCARD_24_25V 0x00001000 #define MMCARD_25_26V 0x00002000 #define MMCARD_26_27V 0x00004000 #define MMCARD_27_28V 0x00008000 #define MMCARD_28_29V 0x00010000 #define MMCARD_29_30V 0x00020000 #define MMCARD_30_31V 0x00040000 #define MMCARD_31_32V 0x00080000 #define MMCARD_32_33V 0x00100000 #define MMCARD_33_34V 0x00200000 #define MMCARD_34_35V 0x00400000 #define MMCARD_35_36V 0x00800000 /*@}*/ /*! * \name Control Codes */ /*@{*/ /*! \brief Retrieve card status. */ #define MMCARD_GETSTATUS 0x2001 /*! \brief Retrieve operation condition register. */ #define MMCARD_GETOCR 0x2002 /*! \brief Retrieve card identification. */ #define MMCARD_GETCID 0x2003 /*! \brief Retrieve card specific data. */ #define MMCARD_GETCSD 0x2004 /*! \brief Retrieve extended card specific data. */ #define MMCARD_GETEXTCSD 0x2005 /*@}*/ /*! * \brief Multimedia card identification register. */ typedef struct NUT_PACKED_TYPE _MMC_CID { /*! \brief Manufacturer identifier. */ uint8_t mmcid_mid; /*! \brief OEM/Application identifier. */ uint16_t mmcid_oid; /*! \brief Product name. */ uint8_t mmcid_pnm[6]; /*! \brief Product revision. */ uint8_t mmcid_rev; /*! \brief Serial number. */ uint32_t mmcid_psn; /*! \brief Manufacturing date code. */ uint8_t mmcid_mdt; /*! \brief CRC7 checksum. */ uint8_t mmcid_crc; } MMC_CID; /*! * \brief Multimedia card identification register. */ typedef struct NUT_PACKED_TYPE _MMC_CSD { /*! \brief Card specification. */ uint8_t mmcsd_spec; /*! \brief Data read access time. */ uint8_t mmcsd_taac; /*! \brief Data read access time 2. */ uint8_t mmcsd_nsac; /*! \brief Maximum data transfer rate. */ uint8_t mmcsd_speed; /*! \brief Card command classes and max. read block length. */ uint8_t mmcsd_ccc_bl[2]; /*! \brief Read-only fields. * * - [0] 0..1 Device size bits 10..11. * - [0] 2..3 Reserved. * - [0] 4 DSR implemented. * - [0] 5 Read block misalignment. * - [0] 6 Write block misalignment. * - [0] 7 Partial blocks for read allowed. * - [1] 0..7 Device size bits 2..9. * - [2] 0..2 Max. read current at VDD max. * - [2] 3..5 Max. read current at VDD min. * - [2] 6..7 Device size bits 0..1. * - [3] 0..1 Device size multiplier bits 1..2. * - [3] 2..4 Max. write current at VDD max. * - [3] 5..7 Max. write current at VDD min. * - [4] 0..1 Erase group size multiplier bits 3..4. * - [4] 2..6 Erase group size. * - [4] 7 Device size multiplier bit 0. * - [5] 0..4 Write protect group size. * - [5] 5..7 Erase group size multiplier bits 0..2. * - [6] 0..1 Max. write data block length bits 2..3. * - [6] 2..4 Read to write speed factor. * - [6] 5..6 Reserved. * - [6] 7 Write protect group enable. * - [7] 0 Content protection application. * - [7] 1..4 Reserved. * - [7] 5 Partial blocks for write allowed. * - [7] 6..7 Max. write data block length bits 0..1. */ uint8_t mmcsd_rfld[8]; /*! \brief Programmable field. */ uint8_t mmcsd_pfld; /*! \brief Checksum. */ uint8_t mmcsd_crc; } MMC_CSD; /*@}*/ extern int MmCardDevInit(NUTDEVICE * dev); extern int MmCardIOCtl(NUTDEVICE * dev, int req, void *conf); extern int MmCardBlockRead(NUTFILE * nfp, void *buffer, int len); extern int MmCardBlockWrite(NUTFILE * nfp, const void *buffer, int len); #ifdef __HARVARD_ARCH__ extern int MmCardBlockWrite_P(NUTFILE * nfp, PGM_P buffer, int len); #endif extern NUTFILE *MmCardMount(NUTDEVICE * dev, const char *name, int mode, int acc); extern int MmCardUnmount(NUTFILE * nfp); extern int SpiMmcInit(NUTDEVICE * dev); extern int SpiMmcIOCtl(NUTDEVICE * dev, int req, void *conf); extern int SpiMmcBlockRead(NUTFILE * nfp, void *buffer, int num); extern int SpiMmcBlockWrite(NUTFILE * nfp, const void *buffer, int num); #ifdef __HARVARD_ARCH__ extern int SpiMmcBlockWrite_P(NUTFILE * nfp, PGM_P buffer, int len); #endif extern NUTFILE *SpiMmcMount(NUTDEVICE * dev, const char *name, int mode, int acc); extern int SpiMmcUnmount(NUTFILE * nfp); #endif