1 #ifndef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
2 #define CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
3 //==========================================================================
7 // Define the protocol used for interacting with MMC cards
9 //===========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 2004, 2005 eCosCentric Limited
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //===========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: jlarmour
46 // Usage: Only this package and implementing device drivers should
47 // include this header file.
49 //####DESCRIPTIONEND####
50 //==========================================================================
52 #include <cyg/infra/cyg_type.h> /* Common types */
54 // The MMC command set. A request is a six-byte sequence. First a
55 // single command byte, one of the following with bit 6 (0x40) or'd in
56 // and bit 7 clear as a start bit. Then a four-byte argument, usually
57 // a 32-bit integer most significant byte first. Finally a 7-bit CRC
58 // and a stop bit. In SPI mode the CRC is usually optional, except for
59 // the GO_IDLE_STATE command.
61 // Commands ALL_SEND_CID, SEND_RELATIVE_ADDR, SET_DSR,
62 // SELECT_DESELECT, READ_DATA_UNTIL_STOP, STOP_TRANSMISSION,
63 // GO_INACTIVE, READ_MULTIPLE_BLOCK, WRITE_DATA_UNTIL_STOP,
64 // WRITE_MULTIPLE_BLOCK, and PROGRAM_CID are MMC only, and not
65 // available in SPI mode.
67 // Device drivers may use values with bit 7 set to indicate
68 // driver-specific commands.
70 #define MMC_REQUEST_GO_IDLE_STATE 0x00
71 #define MMC_REQUEST_SEND_OP_COND 0x01
72 #define MMC_REQUEST_ALL_SEND_CID 0x02
73 #define MMC_REQUEST_SEND_RELATIVE_ADDR 0x03
74 #define MMC_REQUEST_SET_DSR 0x04
75 #define MMC_REQUEST_SELECT_DESELECT 0x07
76 #define MMC_REQUEST_SEND_CSD 0x09
77 #define MMC_REQUEST_SEND_CID 0x0A
78 #define MMC_REQUEST_READ_DATA_UNTIL_STOP 0x0B
79 #define MMC_REQUEST_STOP_TRANSMISSION 0x0C
80 #define MMC_REQUEST_SEND_STATUS 0x0D
81 #define MMC_REQUEST_GO_INACTIVE 0x0F
82 #define MMC_REQUEST_SET_BLOCKLEN 0x10
83 #define MMC_REQUEST_READ_SINGLE_BLOCK 0x11
84 #define MMC_REQUEST_READ_MULTIPLE_BLOCK 0x12
85 #define MMC_REQUEST_WRITE_DATA_UNTIL_STOP 0x14
86 #define MMC_REQUEST_WRITE_BLOCK 0x18
87 #define MMC_REQUEST_WRITE_MULTIPLE_BLOCK 0x19
88 #define MMC_REQUEST_PROGRAM_CID 0x1A
89 #define MMC_REQUEST_PROGRAM_CSD 0x1B
90 #define MMC_REQUEST_SET_WRITE_PROT 0x1C
91 #define MMC_REQUEST_CLR_WRITE_PROT 0x1D
92 #define MMC_REQUEST_SEND_WRITE_PROT 0x1E
93 #define MMC_REQUEST_TAG_SECTOR_START 0x20
94 #define MMC_REQUEST_TAG_SECTOR_END 0x21
95 #define MMC_REQUEST_UNTAG_SECTOR 0x22
96 #define MMC_REQUEST_TAG_ERASE_GROUP_START 0x23
97 #define MMC_REQUEST_TAG_ERASE_GROUP_END 0x24
98 #define MMC_REQUEST_UNTAG_ERASE_GROUP 0x25
99 #define MMC_REQUEST_ERASE 0x26
100 #define MMC_REQUEST_LOCK_UNLOCK 0x2A
101 #define MMC_REQUEST_READ_OCR 0x3A
102 #define MMC_REQUEST_CRC_ON_OFF 0x3B
104 // Response formats are different for MMC vs. SPI mode, so are defined
105 // in the appropriate source files.
107 // The CID register is generally treated as an opaque data structure
108 // used only for unique identification of cards.
109 typedef struct mmc_cid_register {
110 cyg_uint8 cid_data[16];
113 #define MMC_CID_REGISTER_MID(_data_) ((_data_)->cid_data[0])
114 #define MMC_CID_REGISTER_OID(_data_) (((_data_)->cid_data[1] << 8) | \
115 ((_data_)->cid_data[2]))
116 #define MMC_CID_REGISTER_PNM(_data_) ((const char*)&((_data_)->cid_data[3]))
117 #define MMC_CID_REGISTER_PRV(_data_) ((_data_)->cid_data[9])
118 #define MMC_CID_REGISTER_PSN(_data_) (((_data_)->cid_data[10] << 24) | \
119 ((_data_)->cid_data[11] << 16) | \
120 ((_data_)->cid_data[12] << 8) | \
121 ((_data_)->cid_data[13]))
122 #define MMC_CID_REGISTER_MDT(_data_) ((_data_)->cid_data[14])
123 #define MMC_CID_REGISTER_CRC(_data_) ((_data_)->cid_data[15] >> 1)
126 // The CSD register is just lots of small bitfields. For now keep it
127 // as an array of 16 bytes and provide macros to read the fields.
128 typedef struct mmc_csd_register {
129 cyg_uint8 csd_data[16];
132 #define MMC_CSD_REGISTER_CSD_STRUCTURE(_data_) (((_data_)->csd_data[0] & 0x00C0) >> 6)
133 #define MMC_CSD_REGISTER_SPEC_VERS(_data_) (((_data_)->csd_data[0] & 0x003C) >> 2)
134 #define MMC_CSD_REGISTER_TAAC_MANTISSA(_data_) (((_data_)->csd_data[1] & 0x0078) >> 3)
135 #define MMC_CSD_REGISTER_TAAC_EXPONENT(_data_) ((_data_)->csd_data[1] & 0x0007)
136 #define MMC_CSD_REGISTER_NSAC(_data_) ((_data_)->csd_data[2])
137 #define MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(_data_) (((_data_)->csd_data[3] & 0x0078) >> 3)
138 #define MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(_data_) ((_data_)->csd_data[3] & 0x0007)
139 #define MMC_CSD_REGISTER_CCC(_data_) (((_data_)->csd_data[4] << 4) | (((_data_)->csd_data[5] & 0x00F0) >> 4))
140 #define MMC_CSD_REGISTER_READ_BL_LEN(_data_) ((_data_)->csd_data[5] & 0x000F)
141 #define MMC_CSD_REGISTER_READ_BL_PARTIAL(_data_) (((_data_)->csd_data[6] & 0x0080) >> 7)
142 #define MMC_CSD_REGISTER_WRITE_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0040) >> 6)
143 #define MMC_CSD_REGISTER_READ_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0020) >> 5)
144 #define MMC_CSD_REGISTER_DSR_IMP(_data_) (((_data_)->csd_data[6] & 0x0010) >> 4)
145 #define MMC_CSD_REGISTER_C_SIZE(_data_) ((((_data_)->csd_data[6] & 0x0003) << 10) | \
146 ((_data_)->csd_data[7] << 2) | \
147 (((_data_)->csd_data[8] & 0x00C0) >> 6))
148 #define MMC_CSD_REGISTER_VDD_R_CURR_MIN(_data_) (((_data_)->csd_data[8] & 0x0038) >> 3)
149 #define MMC_CSD_REGISTER_VDD_R_CURR_MAX(_data_) ((_data_)->csd_data[8] & 0x0007)
150 #define MMC_CSD_REGISTER_VDD_W_CURR_MIN(_data_) (((_data_)->csd_data[9] & 0x00E0) >> 5)
151 #define MMC_CSD_REGISTER_VDD_W_CURR_MAX(_data_) (((_data_)->csd_data[9] & 0x001C) >> 2)
152 #define MMC_CSD_REGISTER_C_SIZE_MULT(_data_) ((((_data_)->csd_data[9] & 0x0003) << 1) | \
153 (((_data_)->csd_data[10] & 0x0080) >> 7))
154 #define MMC_CSD_REGISTER_SECTOR_SIZE(_data_) (((_data_)->csd_data[10] & 0x007C) >> 2)
155 #define MMC_CSD_REGISTER_ERASE_GRP_SIZE(_data_) ((((_data_)->csd_data[10] & 0x0003) << 3) | \
156 (((_data_)->csd_data[11] & 0x00E0) >> 5))
157 #define MMC_CSD_REGISTER_WR_GRP_SIZE(_data_) ((_data_)->csd_data[11] & 0x001F)
158 #define MMC_CSD_REGISTER_WR_GRP_ENABLE(_data_) (((_data_)->csd_data[12] & 0x0080) >> 7)
159 #define MMC_CSD_REGISTER_DEFAULT_ECC(_data_) (((_data_)->csd_data[12] & 0x0060) >> 5)
160 #define MMC_CSD_REGISTER_R2W_FACTOR(_data_) (((_data_)->csd_data[12] & 0x001C) >> 2)
161 #define MMC_CSD_REGISTER_WRITE_BL_LEN(_data_) ((((_data_)->csd_data[12] & 0x0003) << 2) | \
162 (((_data_)->csd_data[13] & 0x00C0) >> 6))
163 #define MMC_CSD_REGISTER_WR_BL_PARTIAL(_data_) (((_data_)->csd_data[13] & 0x0020) >> 5)
164 #define MMC_CSD_REGISTER_FILE_FORMAT_GROUP(_data_) (((_data_)->csd_data[14] & 0x0080) >> 7)
165 #define MMC_CSD_REGISTER_COPY(_data_) (((_data_)->csd_data[14] & 0x0040) >> 6)
166 #define MMC_CSD_REGISTER_PERM_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0020) >> 5)
167 #define MMC_CSD_REGISTER_TMP_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0010) >> 4)
168 #define MMC_CSD_REGISTER_FILE_FORMAT(_data_) (((_data_)->csd_data[14] & 0x000C) >> 2)
169 #define MMC_CSD_REGISTER_ECC(_data_) ((_data_)->csd_data[14] & 0x0003)
170 #define MMC_CSD_REGISTER_CRC(_data_) (((_data_)->csd_data[15] & 0xFE) >> 1)
173 #endif // ifdef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
175 /* EOF mmc_protocol.h */