#ifndef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H #define CYGONCE_DEVS_DISK_MMC_PROTOCOL_H //========================================================================== // // mmc_protocol.h // // Define the protocol used for interacting with MMC cards // //=========================================================================== // ####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 2004, 2005 Free Software Foundation, Inc. // // eCos 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 2 or (at your option) any later // version. // // eCos 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 eCos; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // As a special exception, if other files instantiate templates or use // macros or inline functions from this file, or you compile this file // and link it with other works to produce a work based on this file, // this file does not by itself cause the resulting work to be covered by // the GNU General Public License. However the source code for this file // must still be made available in accordance with section (3) of the GNU // General Public License v2. // // This exception does not invalidate any other reasons why a work based // on this file might be covered by the GNU General Public License. // ------------------------------------------- // ####ECOSGPLCOPYRIGHTEND#### //=========================================================================== //#####DESCRIPTIONBEGIN#### // // Author: bartv // Contributors: jlarmour // Date: 2004-04-25 // Usage: Only this package and implementing device drivers should // include this header file. // //####DESCRIPTIONEND#### //========================================================================== #include /* Common types */ // The MMC command set. A request is a six-byte sequence. First a // single command byte, one of the following with bit 6 (0x40) or'd in // and bit 7 clear as a start bit. Then a four-byte argument, usually // a 32-bit integer most significant byte first. Finally a 7-bit CRC // and a stop bit. In SPI mode the CRC is usually optional, except for // the GO_IDLE_STATE command. // // Commands ALL_SEND_CID, SEND_RELATIVE_ADDR, SET_DSR, // SELECT_DESELECT, READ_DATA_UNTIL_STOP, STOP_TRANSMISSION, // GO_INACTIVE, READ_MULTIPLE_BLOCK, WRITE_DATA_UNTIL_STOP, // WRITE_MULTIPLE_BLOCK, and PROGRAM_CID are MMC only, and not // available in SPI mode. // // Device drivers may use values with bit 7 set to indicate // driver-specific commands. #define MMC_REQUEST_GO_IDLE_STATE 0x00 #define MMC_REQUEST_SEND_OP_COND 0x01 #define MMC_REQUEST_ALL_SEND_CID 0x02 #define MMC_REQUEST_SEND_RELATIVE_ADDR 0x03 #define MMC_REQUEST_SET_DSR 0x04 #define MMC_REQUEST_SELECT_DESELECT 0x07 #define MMC_REQUEST_SEND_CSD 0x09 #define MMC_REQUEST_SEND_CID 0x0A #define MMC_REQUEST_READ_DATA_UNTIL_STOP 0x0B #define MMC_REQUEST_STOP_TRANSMISSION 0x0C #define MMC_REQUEST_SEND_STATUS 0x0D #define MMC_REQUEST_GO_INACTIVE 0x0F #define MMC_REQUEST_SET_BLOCKLEN 0x10 #define MMC_REQUEST_READ_SINGLE_BLOCK 0x11 #define MMC_REQUEST_READ_MULTIPLE_BLOCK 0x12 #define MMC_REQUEST_WRITE_DATA_UNTIL_STOP 0x14 #define MMC_REQUEST_WRITE_BLOCK 0x18 #define MMC_REQUEST_WRITE_MULTIPLE_BLOCK 0x19 #define MMC_REQUEST_PROGRAM_CID 0x1A #define MMC_REQUEST_PROGRAM_CSD 0x1B #define MMC_REQUEST_SET_WRITE_PROT 0x1C #define MMC_REQUEST_CLR_WRITE_PROT 0x1D #define MMC_REQUEST_SEND_WRITE_PROT 0x1E #define MMC_REQUEST_TAG_SECTOR_START 0x20 #define MMC_REQUEST_TAG_SECTOR_END 0x21 #define MMC_REQUEST_UNTAG_SECTOR 0x22 #define MMC_REQUEST_TAG_ERASE_GROUP_START 0x23 #define MMC_REQUEST_TAG_ERASE_GROUP_END 0x24 #define MMC_REQUEST_UNTAG_ERASE_GROUP 0x25 #define MMC_REQUEST_ERASE 0x26 #define MMC_REQUEST_LOCK_UNLOCK 0x2A #define MMC_REQUEST_READ_OCR 0x3A #define MMC_REQUEST_CRC_ON_OFF 0x3B // SD V2.x specific commands #define SD_REQUEST_SEND_IF_COND 8 #define SD_REQUEST_SD_SEND_OP_COND 41 #define SD_REQUEST_APP_CMD 55 // Response formats are different for MMC vs. SPI mode, so are defined // in the appropriate source files. // SD V2.x specific responses #define SD_ARGUMENT_HCS ( 1 << 30 ) // The CID register is generally treated as an opaque data structure // used only for unique identification of cards. typedef struct mmc_cid_register { cyg_uint8 cid_data[16]; } mmc_cid_register; #define MMC_CID_REGISTER_MID(_data_) ((_data_)->cid_data[0]) #define MMC_CID_REGISTER_OID(_data_) (((_data_)->cid_data[1] << 8) | \ ((_data_)->cid_data[2])) #define MMC_CID_REGISTER_PNM(_data_) ((const char*)&((_data_)->cid_data[3])) #define MMC_CID_REGISTER_PRV(_data_) ((_data_)->cid_data[9]) #define MMC_CID_REGISTER_PSN(_data_) (((_data_)->cid_data[10] << 24) | \ ((_data_)->cid_data[11] << 16) | \ ((_data_)->cid_data[12] << 8) | \ ((_data_)->cid_data[13])) #define MMC_CID_REGISTER_MDT(_data_) ((_data_)->cid_data[14]) #define MMC_CID_REGISTER_CRC(_data_) ((_data_)->cid_data[15] >> 1) // The CSD register is just lots of small bitfields. For now keep it // as an array of 16 bytes and provide macros to read the fields. typedef struct mmc_csd_register { cyg_uint8 csd_data[16]; } mmc_csd_register; #define MMC_CSD_REGISTER_CSD_STRUCTURE(_data_) (((_data_)->csd_data[0] & 0x00C0) >> 6) #define MMC_CSD_REGISTER_SPEC_VERS(_data_) (((_data_)->csd_data[0] & 0x003C) >> 2) #define MMC_CSD_REGISTER_TAAC_MANTISSA(_data_) (((_data_)->csd_data[1] & 0x0078) >> 3) #define MMC_CSD_REGISTER_TAAC_EXPONENT(_data_) ((_data_)->csd_data[1] & 0x0007) #define MMC_CSD_REGISTER_NSAC(_data_) ((_data_)->csd_data[2]) #define MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(_data_) (((_data_)->csd_data[3] & 0x0078) >> 3) #define MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(_data_) ((_data_)->csd_data[3] & 0x0007) #define MMC_CSD_REGISTER_CCC(_data_) (((_data_)->csd_data[4] << 4) | (((_data_)->csd_data[5] & 0x00F0) >> 4)) #define MMC_CSD_REGISTER_READ_BL_LEN(_data_) ((_data_)->csd_data[5] & 0x000F) #define MMC_CSD_REGISTER_READ_BL_PARTIAL(_data_) (((_data_)->csd_data[6] & 0x0080) >> 7) #define MMC_CSD_REGISTER_WRITE_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0040) >> 6) #define MMC_CSD_REGISTER_READ_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0020) >> 5) #define MMC_CSD_REGISTER_DSR_IMP(_data_) (((_data_)->csd_data[6] & 0x0010) >> 4) #define MMC_CSD_REGISTER_C_SIZE(_data_) ((((_data_)->csd_data[6] & 0x0003) << 10) | \ ((_data_)->csd_data[7] << 2) | \ (((_data_)->csd_data[8] & 0x00C0) >> 6)) #define MMC_CSD_REGISTER_VDD_R_CURR_MIN(_data_) (((_data_)->csd_data[8] & 0x0038) >> 3) #define MMC_CSD_REGISTER_VDD_R_CURR_MAX(_data_) ((_data_)->csd_data[8] & 0x0007) #define MMC_CSD_REGISTER_VDD_W_CURR_MIN(_data_) (((_data_)->csd_data[9] & 0x00E0) >> 5) #define MMC_CSD_REGISTER_VDD_W_CURR_MAX(_data_) (((_data_)->csd_data[9] & 0x001C) >> 2) #define MMC_CSD_REGISTER_C_SIZE_MULT(_data_) ((((_data_)->csd_data[9] & 0x0003) << 1) | \ (((_data_)->csd_data[10] & 0x0080) >> 7)) #define MMC_CSD_REGISTER_SECTOR_SIZE(_data_) (((_data_)->csd_data[10] & 0x007C) >> 2) #define MMC_CSD_REGISTER_ERASE_GRP_SIZE(_data_) ((((_data_)->csd_data[10] & 0x0003) << 3) | \ (((_data_)->csd_data[11] & 0x00E0) >> 5)) #define MMC_CSD_REGISTER_WR_GRP_SIZE(_data_) ((_data_)->csd_data[11] & 0x001F) #define MMC_CSD_REGISTER_WR_GRP_ENABLE(_data_) (((_data_)->csd_data[12] & 0x0080) >> 7) #define MMC_CSD_REGISTER_DEFAULT_ECC(_data_) (((_data_)->csd_data[12] & 0x0060) >> 5) #define MMC_CSD_REGISTER_R2W_FACTOR(_data_) (((_data_)->csd_data[12] & 0x001C) >> 2) #define MMC_CSD_REGISTER_WRITE_BL_LEN(_data_) ((((_data_)->csd_data[12] & 0x0003) << 2) | \ (((_data_)->csd_data[13] & 0x00C0) >> 6)) #define MMC_CSD_REGISTER_WR_BL_PARTIAL(_data_) (((_data_)->csd_data[13] & 0x0020) >> 5) #define MMC_CSD_REGISTER_FILE_FORMAT_GROUP(_data_) (((_data_)->csd_data[14] & 0x0080) >> 7) #define MMC_CSD_REGISTER_COPY(_data_) (((_data_)->csd_data[14] & 0x0040) >> 6) #define MMC_CSD_REGISTER_PERM_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0020) >> 5) #define MMC_CSD_REGISTER_TMP_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0010) >> 4) #define MMC_CSD_REGISTER_FILE_FORMAT(_data_) (((_data_)->csd_data[14] & 0x000C) >> 2) #define MMC_CSD_REGISTER_ECC(_data_) ((_data_)->csd_data[14] & 0x0003) #define MMC_CSD_REGISTER_CRC(_data_) (((_data_)->csd_data[15] & 0xFE) >> 1) // CSD V2.x structure #define SD_CSD_V2_REGISTER_C_SIZE(_data_) ((((_data_)->csd_data[7] & 0x007f) << 16) | \ ((_data_)->csd_data[8] << 8) | \ ((_data_)->csd_data[9] )) // OCR typedef struct sd_ocr_register { cyg_uint8 ocr_data[4]; } sd_ocr_register_t; #define SD_OCR_REGISTER_POWER_UP(_data_) (((_data_)->ocr_data[0] & 0x80) >> 7) // CCS bit denotes Standard (0) or High/Extended (1) capacity #define SD_OCR_REGISTER_CCS(_data_) (((_data_)->ocr_data[0] & 0x40) >> 6) #endif // ifdef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H /* EOF mmc_protocol.h */