summaryrefslogtreecommitdiff
path: root/nuttx/drivers/mmcsd/mmcsd_sdio.h
blob: 0c85912a01cc3ac37222067e469ea86da4cf7f3a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/********************************************************************************************
 * drivers/mmcsd/mmcsd_sdio.h
 *
 *   Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
 *   Author: Gregory Nutt <gnutt@nuttx.org>
 *
 * 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 NuttX nor the names of its 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.
 *
 ********************************************************************************************/

#ifndef __DRIVERS_MMCSD_MMCSD_SDIO_H
#define __DRIVERS_MMCSD_MMCSD_SDIO_H

/********************************************************************************************
 * Included Files
 ********************************************************************************************/

#include <nuttx/config.h>
#include <stdint.h>

/********************************************************************************************
 * Pre-Processor Definitions
 ********************************************************************************************/

/* CMD8 Argument:
 *    [31:12]: Reserved (shall be set to '0')
 *    [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
 *    [7:0]: Check Pattern (recommended 0xaa)
 * CMD8 Response: R7
 */

#define MMCSD_CMD8VOLTAGE_SHIFT     (8)                    /* Bits 8-11: Supply voltage */
#define MMCSD_CMD8VOLTAGE_MASK      ((uint32_t)0x0f << MMCSD_CMD8VOLTAGE_SHIFT)
#  define MMCSD_CMD8VOLTAGE_27      ((uint32_t)0x01 << MMCSD_CMD8VOLTAGE_SHIFT) /* 2.7-3.6V */
#define MMCSD_CMD8ECHO_SHIFT        (0)                    /* Bits 0-7: Check pattern */
#define MMCSD_CMD8ECHO_MASK         ((uint32_t)0xff << MMCSD_CMD8ECHO_SHIFT)
#  define MMCSD_CMD8CHECKPATTERN    ((uint32_t)0xaa << MMCSD_CMD8ECHO_SHIFT)

/* ACMD6 argument */

#define MMCSD_ACMD6_BUSWIDTH_1      ((uint32_t)0)          /* Bus width = 1-bit */
#define MMCSD_ACMD6_BUSWIDTH_4      ((uint32_t)2)          /* Bus width = 4-bit */

/* ACMD41 argument */

#define MMCSD_ACMD41_VOLTAGEWINDOW_34_33 ((uint32_t)1 << 21)
#define MMCSD_ACMD41_VOLTAGEWINDOW_33_32 ((uint32_t)1 << 20)
#define MMCSD_ACMD41_VOLTAGEWINDOW_32_31 ((uint32_t)1 << 19)
#define MMCSD_ACMD41_HIGHCAPACITY   ((uint32_t)1 << 30)
#define MMCSD_ACMD41_STDCAPACITY    ((uint32_t)0)

/* ACMD42 argument */

#define MMCSD_ACMD42_CD_DISCONNECT  ((uint32_t)0)          /* Disconnect card detection logic */
#define MMCSD_ACMD42_CD_CONNECT     ((uint32_t)1)          /* Connect card detection logic */

/* R1 Card Status bit definitions */

#define MMCSD_R1_OUTOFRANGE         ((uint32_t)1 << 31)    /* Bad argument */
#define MMCSD_R1_ADDRESSERROR       ((uint32_t)1 << 30)    /* Bad address */
#define MMCSD_R1_BLOCKLENERROR      ((uint32_t)1 << 29)    /* Bad block length */
#define MMCSD_R1_ERASESEQERROR      ((uint32_t)1 << 28)    /* Erase cmd error */
#define MMCSD_R1_ERASEPARAM         ((uint32_t)1 << 27)    /* Bad write blocks */
#define MMCSD_R1_WPVIOLATION        ((uint32_t)1 << 26)    /* Erase access failure */
#define MMCSD_R1_CARDISLOCKED       ((uint32_t)1 << 25)    /* Card is locked */
#define MMCSD_R1_LOCKUNLOCKFAILED   ((uint32_t)1 << 24)    /* Password error */
#define MMCSD_R1_COMCRCERROR        ((uint32_t)1 << 23)    /* CRC error */
#define MMCSD_R1_ILLEGALCOMMAND     ((uint32_t)1 << 22)    /* Bad command */
#define MMCSD_R1_CARDECCFAILED      ((uint32_t)1 << 21)    /* Failed to correct data */
#define MMCSD_R1_CCERROR            ((uint32_t)1 << 20)    /* Card controller error */
#define MMCSD_R1_ERROR              ((uint32_t)1 << 19)    /* General error */
#define MMCSD_R1_UNDERRUN           ((uint32_t)1 << 18)    /* Underrun (MMC only) */
#define MMCSD_R1_OVERRRUN           ((uint32_t)1 << 17)    /* Overrun (MMC only) */
#define MMCSD_R1_CIDCSDOVERWRITE    ((uint32_t)1 << 16)    /* CID/CSD error */
#define MMCSD_R1_WPERASESKIP        ((uint32_t)1 << 15)    /* Not all erased */
#define MMCSD_R1_CARDECCDISABLED    ((uint32_t)1 << 14)    /* Internal ECC not used */
#define MMCSD_R1_ERASERESET         ((uint32_t)1 << 13)    /* Reset sequence cleared */
#define MMCSD_R1_STATE_SHIFT        (9)                    /* Current card state */
#define MMCSD_R1_STATE_MASK         ((uint32_t)15 << MMCSD_R1_STATE_SHIFT)
                                                           /* Card identification mode states */
#  define MMCSD_R1_STATE_IDLE       ((uint32_t)0 << MMCSD_R1_STATE_SHIFT) /* 0=Idle state */
#  define MMCSD_R1_STATE_READY      ((uint32_t)1 << MMCSD_R1_STATE_SHIFT) /* 1=Ready state */
#  define MMCSD_R1_STATE_IDENT      ((uint32_t)2 << MMCSD_R1_STATE_SHIFT) /* 2=Identification state */
                                                           /* Data transfer states */
#  define MMCSD_R1_STATE_STBY       ((uint32_t)3 << MMCSD_R1_STATE_SHIFT) /* 3=Standby state */
#  define MMCSD_R1_STATE_TRAN       ((uint32_t)4 << MMCSD_R1_STATE_SHIFT) /* 4=Transfer state */
#  define MMCSD_R1_STATE_DATA       ((uint32_t)5 << MMCSD_R1_STATE_SHIFT) /* 5=Sending data state */
#  define MMCSD_R1_STATE_RCV        ((uint32_t)6 << MMCSD_R1_STATE_SHIFT) /* 6=Receiving data state */
#  define MMCSD_R1_STATE_PRG        ((uint32_t)7 << MMCSD_R1_STATE_SHIFT) /* 7=Programming state */
#  define MMCSD_R1_STATE_DIS        ((uint32_t)8 << MMCSD_R1_STATE_SHIFT) /* 8=Disconnect state */
#define MMCSD_R1_READYFORDATA       ((uint32_t)1 << 8)     /* Buffer empty */
#define MMCSD_R1_APPCMD             ((uint32_t)1 << 5)     /* Next CMD is ACMD */
#define MMCSD_R1_AKESEQERROR        ((uint32_t)1 << 3)     /* Authentication error */
#define MMCSD_R1_ERRORMASK          ((uint32_t)0xfdffe008) /* Error mask */

#define IS_STATE(v,s)               ((((uint32_t)v)&MMCSD_R1_STATE_MASK)==(s))

/* R3 (OCR) */

#define MMC_VDD_20_36               ((uint32_t)0x00ffff00) /* VDD voltage 2.0-3.6 */

#define MMCSD_VDD_145_150           ((uint32_t)1 << 0)     /* VDD voltage 1.45 - 1.50 */
#define MMCSD_VDD_150_155           ((uint32_t)1 << 1)     /* VDD voltage 1.50 - 1.55 */
#define MMCSD_VDD_155_160           ((uint32_t)1 << 2)     /* VDD voltage 1.55 - 1.60 */
#define MMCSD_VDD_160_165           ((uint32_t)1 << 3)     /* VDD voltage 1.60 - 1.65 */
#define MMCSD_VDD_165_170           ((uint32_t)1 << 4)     /* VDD voltage 1.65 - 1.70 */
#define MMCSD_VDD_17_18             ((uint32_t)1 << 5)     /* VDD voltage 1.7 - 1.8 */
#define MMCSD_VDD_18_19             ((uint32_t)1 << 6)     /* VDD voltage 1.8 - 1.9 */
#define MMCSD_VDD_19_20             ((uint32_t)1 << 7)     /* VDD voltage 1.9 - 2.0 */
#define MMCSD_VDD_20_21             ((uint32_t)1 << 8)     /* VDD voltage 2.0-2.1 */
#define MMCSD_VDD_21_22             ((uint32_t)1 << 9)     /* VDD voltage 2.1-2.2 */
#define MMCSD_VDD_22_23             ((uint32_t)1 << 10)    /* VDD voltage 2.2-2.3 */
#define MMCSD_VDD_23_24             ((uint32_t)1 << 11)    /* VDD voltage 2.3-2.4 */
#define MMCSD_VDD_24_25             ((uint32_t)1 << 12)    /* VDD voltage 2.4-2.5 */
#define MMCSD_VDD_25_26             ((uint32_t)1 << 13)    /* VDD voltage 2.5-2.6 */
#define MMCSD_VDD_26_27             ((uint32_t)1 << 14)    /* VDD voltage 2.6-2.7 */
#define MMCSD_VDD_27_28             ((uint32_t)1 << 15)    /* VDD voltage 2.7-2.8 */
#define MMCSD_VDD_28_29             ((uint32_t)1 << 16)    /* VDD voltage 2.8-2.9 */
#define MMCSD_VDD_29_30             ((uint32_t)1 << 17)    /* VDD voltage 2.9-3.0 */
#define MMCSD_VDD_30_31             ((uint32_t)1 << 18)    /* VDD voltage 3.0-3.1 */
#define MMCSD_VDD_31_32             ((uint32_t)1 << 19)    /* VDD voltage 3.1-3.2 */
#define MMCSD_VDD_32_33             ((uint32_t)1 << 20)    /* VDD voltage 3.2-3.3 */
#define MMCSD_VDD_33_34             ((uint32_t)1 << 21)    /* VDD voltage 3.3-3.4 */
#define MMCSD_VDD_34_35             ((uint32_t)1 << 22)    /* VDD voltage 3.4-3.5 */
#define MMCSD_VDD_35_36             ((uint32_t)1 << 23)    /* VDD voltage 3.5-3.6 */
#define MMCSD_R3_HIGHCAPACITY       ((uint32_t)1 << 30)    /* true: Card supports block addressing */
#define MMCSD_CARD_BUSY             ((uint32_t)1 << 31)    /* Card power-up busy bit */

/* R6 Card Status bit definitions */

#define MMCSD_R6_RCA_SHIFT          (16)                   /* New published RCA */
#define MMCSD_R6_RCA_MASK           ((uint32_t)0xffff << MMCSD_R6_RCA_SHIFT)
#define MMCSD_R6_COMCRCERROR        ((uint32_t)1 << 15)    /* CRC error */
#define MMCSD_R6_ILLEGALCOMMAND     ((uint32_t)1 << 14)    /* Bad command */
#define MMCSD_R6_ERROR              ((uint32_t)1 << 13)    /* General error */
#define MMCSD_R6_STATE_SHIFT        (9)                    /* Current card state */
#define MMCSD_R6_STATE_MASK         ((uint32_t)15 << MMCSD_R6_STATE_SHIFT)
                                                           /* Card identification mode states */
#  define MMCSD_R6_STATE_IDLE       ((uint32_t)0 << MMCSD_R6_STATE_SHIFT) /* 0=Idle state */
#  define MMCSD_R6_STATE_READY      ((uint32_t)1 << MMCSD_R6_STATE_SHIFT) /* 1=Ready state */
#  define MMCSD_R6_STATE_IDENT      ((uint32_t)2 << MMCSD_R6_STATE_SHIFT) /* 2=Identification state */
                                                           /* Data transfer states */
#  define MMCSD_R6_STATE_STBY       ((uint32_t)3 << MMCSD_R6_STATE_SHIFT) /* 3=Standby state */
#  define MMCSD_R6_STATE_TRAN       ((uint32_t)4 << MMCSD_R6_STATE_SHIFT) /* 4=Transfer state */
#  define MMCSD_R6_STATE_DATA       (5(uint32_t) << MMCSD_R6_STATE_SHIFT) /* 5=Sending data state */
#  define MMCSD_R6_STATE_RCV        ((uint32_t)6 << MMCSD_R6_STATE_SHIFT) /* 6=Receiving data state */
#  define MMCSD_R6_STATE_PRG        ((uint32_t)7 << MMCSD_R6_STATE_SHIFT) /* 7=Programming state */
#  define MMCSD_R6_STATE_DIS        ((uint32_t) << MMCSD_R6_STATE_SHIFT) /* 8=Disconnect state */
#define MMCSD_R6_ERRORMASK          ((uint32_t)0x0000e000)  /* Error mask */

/* SD Configuration Register (SCR) encoding */

#define MMCSD_SCR_BUSWIDTH_1BIT     (1)
#define MMCSD_SCR_BUSWIDTH_2BIT     (2)
#define MMCSD_SCR_BUSWIDTH_4BIT     (4)
#define MMCSD_SCR_BUSWIDTH_8BIT     (8)

/* Last 4 bytes of the 48-bit R7 response */

#define MMCSD_R7VERSION_SHIFT       (28)                   /* Bits 28-31: Command version number */
#define MMCSD_R7VERSION_MASK        ((uint32_t)0x0f << MMCSD_R7VERSION_SHIFT)
#define MMCSD_R7VOLTAGE_SHIFT       (8)                    /* Bits 8-11: Voltage accepted */
#define MMCSD_R7VOLTAGE_MASK        ((uint32_t)0x0f << MMCSD_R7VOLTAGE_SHIFT)
#  define MMCSD_R7VOLTAGE_27        ((uint32_t)0x01 << MMCSD_R7VOLTAGE_SHIFT) /* 2.7-3.6V */
#define MMCSD_R7ECHO_SHIFT          (0)                    /* Bits 0-7: Echoed check pattern */
#define MMCSD_R7ECHO_MASK           ((uint32_t)0xff << MMCSD_R7ECHO_SHIFT)
#  define MMCSD_R7CHECKPATTERN      ((uint32_t)0xaa << MMCSD_R7ECHO_SHIFT)

/********************************************************************************************
 * Public Types
 ********************************************************************************************/

/* Decoded Card Identification (CID) register */

struct mmcsd_cid_s
{
  uint8_t  mid;     /* 127:120  8-bit Manufacturer ID */
  uint16_t oid;     /* 119:104 16-bit OEM/Application ID (ascii) */
  uint8_t  pnm[6];  /* 103:64  40-bit Product Name (ascii) + null terminator */
  uint8_t  prv;     /*  63:56   8-bit Product revision */
  uint32_t psn;     /*  55:24  32-bit Product serial number */
                    /*  23:20   4-bit (reserved) */
  uint16_t mdt;     /*  19:8   12-bit Manufacturing date */
  uint8_t  crc;     /*   7:1    7-bit CRC7 */
                    /*   0:0    1-bit (not used) */
};

/* Decoded Card Specific Data (CSD) register */

struct mmcsd_csd_s
{
  uint8_t csdstructure;        /* 127:126 CSD structure */
  uint8_t mmcspecvers;         /* 125:122 MMC Spec version (MMC only) */

  struct
  {
    uint8_t timeunit;          /*   2:0   Time exponent */
    uint8_t timevalue;         /*   6:3   Time mantissa */
  } taac;                      /* 119:112 Data read access-time-1 */

  uint8_t nsac;                /* 111:104 Data read access-time-2 in CLK cycle(NSAC*100) */

  struct
  {
    uint8_t transferrateunit;  /*   2:0   Rate exponent */
    uint8_t timevalue;         /*   6:3   Rate mantissa */
  } transpeed;                 /* 103:96  Max. data transfer rate */

  uint16_t ccc;                /*  95:84  Card command classes */
  uint8_t readbllen;           /*  83:80  Max. read data block length */
  uint8_t readblpartial;       /*  79:79  Partial blocks for read allowed */
  uint8_t writeblkmisalign;    /*  78:78  Write block misalignment */
  uint8_t readblkmisalign;     /*  77:77  Read block misalignment */
  uint8_t dsrimp;              /*  76:76  DSR implemented */

  union
  {
#ifdef CONFIG_MMCSD_MMCSUPPORT
    struct
    {
      uint16_t csize;          /*  73:62  Device size */
      uint8_t vddrcurrmin;     /*  61:59  Max. read current at Vdd min */
      uint8_t vddrcurrmax;     /*  58:56  Max. read current at Vdd max */
      uint8_t vddwcurrmin;     /*  55:53  Max. write current at Vdd min */
      uint8_t vddwcurrmax;     /*  52:50  Max. write current at Vdd max */
      uint8_t csizemult;       /*  49:47  Device size multiplier */

      union
      {
        struct                 /* MMC system specification version 3.1 */
        {
          uint8_t ergrpsize;   /*  46:42  Erase group size (MMC 3.1) */
          uint8_t ergrpmult;   /*  41:37  Erase group multiplier (MMC 3.1) */
        } mmc31;
        struct                 /* MMC system specification version 2.2 */
        {
          uint8_t sectorsize;  /*  46:42  Erase sector size (MMC 2.2) */
          uint8_t ergrpsize;   /*  41:37  Erase group size (MMC 2.2) */
        } mmc22;
      } er;

      uint8_t mmcwpgrpsize;    /*  36:32  Write protect group size (MMC) */
    } mmc;
#endif
    struct
    {
      uint16_t csize;          /*  73:62  Device size */
      uint8_t vddrcurrmin;     /*  61:59  Max. read current at Vdd min */
      uint8_t vddrcurrmax;     /*  58:56  Max. read current at Vdd max */
      uint8_t vddwcurrmin;     /*  55:53  Max. write current at Vdd min */
      uint8_t vddwcurrmax;     /*  52:50  Max. write current at Vdd max */
      uint8_t csizemult;       /*  49:47  Device size multiplier */
      uint8_t sderblen;        /*  46:46  Erase single block enable (SD) */
      uint8_t sdsectorsize;    /*  45:39  Erase sector size (SD) */
      uint8_t sdwpgrpsize;     /*  38:32  Write protect group size (SD) */
    } sdbyte;

    struct
    {
                               /*  73:70  (reserved) */
      uint32_t csize;          /*  69:48  Device size */
                               /*  47:47  (reserved) */
      uint8_t sderblen;        /*  46:46  Erase single block enable (SD) */
      uint8_t sdsectorsize;    /*  45:39  Erase sector size (SD) */
      uint8_t sdwpgrpsize;     /*  38:32  Write protect group size (SD) */
    } sdblock;
  } u;

  uint8_t wpgrpen;             /*  31:31  Write protect group enable */
  uint8_t mmcdfltecc;          /*  30:29  Manufacturer default ECC (MMC) */
  uint8_t r2wfactor;           /*  28:26  Write speed factor */
  uint8_t writebllen;          /*  25:22  Max. write data block length */
  uint8_t writeblpartial;      /*  21:21  Partial blocks for write allowed */
  uint8_t fileformatgrp;       /*  15:15  File format group */
  uint8_t copy;                /*  14:14  Copy flag (OTP) */
  uint8_t permwriteprotect;    /*  13:13  Permanent write protection */
  uint8_t tmpwriteprotect;     /*  12:12  Temporary write protection */
  uint8_t fileformat;          /*  10:11  File format */
  uint8_t mmcecc;              /*   9:8   ECC (MMC) */
  uint8_t crc;                 /*   7:1   CRC */
                               /*   0:0   Not used */
};

struct mmcsd_scr_s
{
  uint8_t  scrversion;         /* 63:60 Version of SCR structure */
  uint8_t  sdversion;          /* 59:56 SD memory card physical layer version */
  uint8_t  erasestate;         /* 55:55 Data state after erase (1 or 0) */
  uint8_t  security;           /* 54:52 SD security support */
  uint8_t  buswidth;           /* 51:48 DAT bus widthes supported */
                               /* 47:32 SD reserved space */
  uint32_t mfgdata;            /* 31:0  Reserved for manufacturing data */
};

/********************************************************************************************
 * Public Data
 ********************************************************************************************/

#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif

/********************************************************************************************
 * Public Functions
 ********************************************************************************************/


#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __DRIVERS_MMCSD_MMCSD_SDIO_H */