LPCOpen Platform for LPC18XX/43XX microcontrollers: C:/w/lpcopen_docs/software/lpc_core/lpc_chip/chip_18xx_43xx/sdmmc_18xx_43xx.c Source File

| LPCOpen Platform for LPC18XX/43XX microcontrollers 18XX43XX LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

sdmmc_18xx_43xx.c
Go to the documentation of this file.
1 /*
2 * @brief LPC18xx/43xx SD/SDIO driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include "chip.h"
33 #include "string.h"
34
35 /*****************************************************************************
36 * Private types/enumerations/variables
37 ****************************************************************************/
38
39 /* Global instance of the current card */
40 static mci_card_struct *g_card_info;
41
42 /* Helper definition: all SD error conditions in the status word */
43 #define SD_INT_ERROR (MCI_INT_RESP_ERR | MCI_INT_RCRC | MCI_INT_DCRC | \
44 MCI_INT_RTO | MCI_INT_DTO | MCI_INT_HTO | MCI_INT_FRUN | MCI_INT_HLE | \
45 MCI_INT_SBE | MCI_INT_EBE)
46
47 /*****************************************************************************
48 * Public types/enumerations/variables
49 ****************************************************************************/
50
51 /*****************************************************************************
52 * Private functions
53 ****************************************************************************/
54
55 /* Function to execute a command */
56 static int32_t sdmmc_execute_command(LPC_SDMMC_T *pSDMMC, uint32_t cmd, uint32_t arg, uint32_t wait_status)
57 {
58 int32_t step = (cmd & CMD_BIT_APP) ? 2 : 1;
59 int32_t status = 0;
60 uint32_t cmd_reg = 0;
61
62 if (!wait_status) {
63 wait_status = (cmd & CMD_MASK_RESP) ? MCI_INT_CMD_DONE : MCI_INT_DATA_OVER;
64 }
65
66 /* Clear the interrupts & FIFOs*/
67 if (cmd & CMD_BIT_DATA) {
68 Chip_SDIF_SetClearIntFifo(pSDMMC);
69 }
70
71 /* also check error conditions */
72 wait_status |= MCI_INT_EBE | MCI_INT_SBE | MCI_INT_HLE | MCI_INT_RTO | MCI_INT_RCRC | MCI_INT_RESP_ERR;
73 if (wait_status & MCI_INT_DATA_OVER) {
74 wait_status |= MCI_INT_FRUN | MCI_INT_HTO | MCI_INT_DTO | MCI_INT_DCRC;
75 }
76
77 while (step) {
78 Chip_SDIF_SetClock(pSDMMC, Chip_Clock_GetBaseClocktHz(CLK_BASE_SDIO), g_card_info->card_info.speed);
79
80 /* Clear the interrupts */
81 Chip_SDIF_ClrIntStatus(pSDMMC, 0xFFFFFFFF);
82
83 g_card_info->card_info.evsetup_cb((void *) &wait_status);
84
85 switch (step) {
86 case 1: /* Execute command */
87 cmd_reg = ((cmd & CMD_MASK_CMD) >> CMD_SHIFT_CMD) |
88 ((cmd & CMD_BIT_INIT) ? MCI_CMD_INIT : 0) |
89 ((cmd & CMD_BIT_DATA) ? (MCI_CMD_DAT_EXP | MCI_CMD_PRV_DAT_WAIT) : 0) |
90 (((cmd & CMD_MASK_RESP) == CMD_RESP_R2) ? MCI_CMD_RESP_LONG : 0) |
91 ((cmd & CMD_MASK_RESP) ? MCI_CMD_RESP_EXP : 0) |
92 ((cmd & CMD_BIT_WRITE) ? MCI_CMD_DAT_WR : 0) |
93 ((cmd & CMD_BIT_STREAM) ? MCI_CMD_STRM_MODE : 0) |
94 ((cmd & CMD_BIT_BUSY) ? MCI_CMD_STOP : 0) |
95 ((cmd & CMD_BIT_AUTO_STOP) ? MCI_CMD_SEND_STOP : 0) |
96 MCI_CMD_START;
97
98 /* wait for previos data finsh for select/deselect commands */
99 if (((cmd & CMD_MASK_CMD) >> CMD_SHIFT_CMD) == MMC_SELECT_CARD) {
100 cmd_reg |= MCI_CMD_PRV_DAT_WAIT;
101 }
102
103 /* wait for command to be accepted by CIU */
104 if (Chip_SDIF_SendCmd(pSDMMC, cmd_reg, arg) == 0) {
105 --step;
106 }
107 break;
108
109 case 0:
110 return 0;
111
112 case 2: /* APP prefix */
113 cmd_reg = MMC_APP_CMD | MCI_CMD_RESP_EXP |
114 ((cmd & CMD_BIT_INIT) ? MCI_CMD_INIT : 0) |
115 MCI_CMD_START;
116
117 if (Chip_SDIF_SendCmd(pSDMMC, cmd_reg, g_card_info->card_info.rca << 16) == 0) {
118 --step;
119 }
120 break;
121 }
122
123 /* wait for command response */
124 status = g_card_info->card_info.waitfunc_cb();
125
126 /* We return an error if there is a timeout, even if we've fetched a response */
127 if (status & SD_INT_ERROR) {
128 return status;
129 }
130
131 if (status & MCI_INT_CMD_DONE) {
132 switch (cmd & CMD_MASK_RESP) {
133 case 0:
134 break;
135
136 case CMD_RESP_R1:
137 case CMD_RESP_R3:
138 case CMD_RESP_R2:
139 Chip_SDIF_GetResponse(pSDMMC, &g_card_info->card_info.response[0]);
140 break;
141 }
142 }
143 }
144
145 return 0;
146 }
147
148 /* Checks whether card is acquired properly or not */
149 static int32_t prv_card_acquired(void)
150 {
151 return g_card_info->card_info.cid[0] != 0;
152 }
153
154 /* Helper function to get a bit field withing multi-word buffer. Used to get
155 fields with-in CSD & EXT-CSD */
156 static uint32_t prv_get_bits(int32_t start, int32_t end, uint32_t *data)
157 {
158 uint32_t v;
159 uint32_t i = end >> 5;
160 uint32_t j = start & 0x1f;
161
162 if (i == (start >> 5)) {
163 v = (data[i] >> j);
164 }
165 else {
166 v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
167 }
168
169 return v & ((1 << (end - start + 1)) - 1);
170 }
171
172 /* Function to process the CSD & EXT-CSD of the card */
173 static void prv_process_csd(LPC_SDMMC_T *pSDMMC)
174 {
175 int32_t status = 0;
176 int32_t c_size = 0;
177 int32_t c_size_mult = 0;
178 int32_t mult = 0;
179
180 /* compute block length based on CSD response */
181 g_card_info->card_info.block_len = 1 << prv_get_bits(80, 83, g_card_info->card_info.csd);
182
183 if ((g_card_info->card_info.card_type & CARD_TYPE_HC) && (g_card_info->card_info.card_type & CARD_TYPE_SD)) {
184 /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec an explanation for the calculation of these values */
185 c_size = prv_get_bits(48, 63, (uint32_t *) g_card_info->card_info.csd) + 1;
186 g_card_info->card_info.blocknr = c_size << 10; /* 512 byte blocks */
187 }
188 else {
189 /* See section 5.3 of the 4.1 revision of the MMC specs for an explanation for the calculation of these values */
190 c_size = prv_get_bits(62, 73, (uint32_t *) g_card_info->card_info.csd);
191 c_size_mult = prv_get_bits(47, 49, (uint32_t *) g_card_info->card_info.csd);
192 mult = 1 << (c_size_mult + 2);
193 g_card_info->card_info.blocknr = (c_size + 1) * mult;
194
195 /* adjust blocknr to 512/block */
196 if (g_card_info->card_info.block_len > MMC_SECTOR_SIZE) {
197 g_card_info->card_info.blocknr = g_card_info->card_info.blocknr * (g_card_info->card_info.block_len >> 9);
198 }
199
200 /* get extended CSD for newer MMC cards CSD spec >= 4.0*/
201 if (((g_card_info->card_info.card_type & CARD_TYPE_SD) == 0) &&
202 (prv_get_bits(122, 125, (uint32_t *) g_card_info->card_info.csd) >= 4)) {
203 /* put card in trans state */
204 status = sdmmc_execute_command(pSDMMC, CMD_SELECT_CARD, g_card_info->card_info.rca << 16, 0);
205
206 /* set block size and byte count */
207 Chip_SDIF_SetBlkSizeByteCnt(pSDMMC, MMC_SECTOR_SIZE);
208
209 /* send EXT_CSD command */
210 Chip_SDIF_DmaSetup(pSDMMC,
211 &g_card_info->sdif_dev,
212 (uint32_t) g_card_info->card_info.ext_csd,
213 MMC_SECTOR_SIZE);
214
215 status = sdmmc_execute_command(pSDMMC, CMD_SEND_EXT_CSD, 0, 0 | MCI_INT_DATA_OVER);
216 if ((status & SD_INT_ERROR) == 0) {
217 /* check EXT_CSD_VER is greater than 1.1 */
218 if ((g_card_info->card_info.ext_csd[48] & 0xFF) > 1) {
219 g_card_info->card_info.blocknr = g_card_info->card_info.ext_csd[53];/* bytes 212:215 represent sec count */
220
221 }
222 /* switch to 52MHz clock if card type is set to 1 or else set to 26MHz */
223 if ((g_card_info->card_info.ext_csd[49] & 0xFF) == 1) {
224 /* for type 1 MMC cards high speed is 52MHz */
225 g_card_info->card_info.speed = MMC_HIGH_BUS_MAX_CLOCK;
226 }
227 else {
228 /* for type 0 MMC cards high speed is 26MHz */
229 g_card_info->card_info.speed = MMC_LOW_BUS_MAX_CLOCK;
230 }
231 }
232 }
233 }
234
235 g_card_info->card_info.device_size = (uint64_t) g_card_info->card_info.blocknr << 9; /* blocknr * 512 */
236 }
237
238 /* Puts current selected card in trans state */
239 static int32_t prv_set_trans_state(LPC_SDMMC_T *pSDMMC)
240 {
241 uint32_t status;
242
243 /* get current state of the card */
244 status = sdmmc_execute_command(pSDMMC, CMD_SEND_STATUS, g_card_info->card_info.rca << 16, 0);
245 if (status & MCI_INT_RTO) {
246 /* unable to get the card state. So return immediatly. */
247 return -1;
248 }
249
250 /* check card state in response */
251 status = R1_CURRENT_STATE(g_card_info->card_info.response[0]);
252 switch (status) {
253 case SDMMC_STBY_ST:
254 /* put card in 'Trans' state */
255 status = sdmmc_execute_command(pSDMMC, CMD_SELECT_CARD, g_card_info->card_info.rca << 16, 0);
256 if (status != 0) {
257 /* unable to put the card in Trans state. So return immediatly. */
258 return -1;
259 }
260 break;
261
262 case SDMMC_TRAN_ST:
263 /*do nothing */
264 break;
265
266 default:
267 /* card shouldn't be in other states so return */
268 return -1;
269 }
270
271 return 0;
272 }
273
274 /* Sets card data width and block size */
275 static int32_t prv_set_card_params(LPC_SDMMC_T *pSDMMC)
276 {
277 int32_t status;
278
279 #if SDIO_BUS_WIDTH > 1
280 if (g_card_info->card_info.card_type & CARD_TYPE_SD) {
281 status = sdmmc_execute_command(pSDMMC, CMD_SD_SET_WIDTH, 2, 0);
282 if (status != 0) {
283 return -1;
284 }
285
286 /* if positive response */
287 Chip_SDIF_SetCardType(pSDMMC, MCI_CTYPE_4BIT);
288 }
289 #elif SDIO_BUS_WIDTH > 4
290 #error 8-bit mode not supported yet!
291 #endif
292
293 /* set block length */
294 Chip_SDIF_SetBlkSize(pSDMMC, MMC_SECTOR_SIZE);
295 status = sdmmc_execute_command(pSDMMC, CMD_SET_BLOCKLEN, MMC_SECTOR_SIZE, 0);
296 if (status != 0) {
297 return -1;
298 }
299
300 return 0;
301 }
302
303 /*****************************************************************************
304 * Public functions
305 ****************************************************************************/
306 /* Get card's current state (idle, transfer, program, etc.) */
307 int32_t Chip_SDMMC_GetState(LPC_SDMMC_T *pSDMMC)
308 {
309 uint32_t status;
310
311 /* get current state of the card */
312 status = sdmmc_execute_command(pSDMMC, CMD_SEND_STATUS, g_card_info->card_info.rca << 16, 0);
313 if (status & MCI_INT_RTO) {
314 return -1;
315 }
316
317 /* check card state in response */
318 return (int32_t) R1_CURRENT_STATE(g_card_info->card_info.response[0]);
319 }
320
321 /* Function to enumerate the SD/MMC/SDHC/MMC+ cards */
322 uint32_t Chip_SDMMC_Acquire(LPC_SDMMC_T *pSDMMC, mci_card_struct *pcardinfo)
323 {
324 int32_t status;
325 int32_t tries = 0;
326 uint32_t ocr = OCR_VOLTAGE_RANGE_MSK;
327 uint32_t r;
328 int32_t state = 0;
329 uint32_t command = 0;
330
331 g_card_info = pcardinfo;
332
333 /* clear card type */
334 Chip_SDIF_SetCardType(pSDMMC, 0);
335
336 /* set high speed for the card as 20MHz */
337 g_card_info->card_info.speed = MMC_MAX_CLOCK;
338
339 status = sdmmc_execute_command(pSDMMC, CMD_IDLE, 0, MCI_INT_CMD_DONE);
340
341 while (state < 100) {
342 switch (state) {
343 case 0: /* Setup for SD */
344 /* check if it is SDHC card */
345 status = sdmmc_execute_command(pSDMMC, CMD_SD_SEND_IF_COND, SD_SEND_IF_ARG, 0);
346 if (!(status & MCI_INT_RTO)) {
347 /* check response has same echo pattern */
348 if ((g_card_info->card_info.response[0] & SD_SEND_IF_ECHO_MSK) == SD_SEND_IF_RESP) {
349 ocr |= OCR_HC_CCS;
350 }
351 }
352
353 ++state;
354 command = CMD_SD_OP_COND;
355 tries = INIT_OP_RETRIES;
356
357 /* assume SD card */
358 g_card_info->card_info.card_type |= CARD_TYPE_SD;
359 g_card_info->card_info.speed = SD_MAX_CLOCK;
360 break;
361
362 case 10: /* Setup for MMC */
363 /* start fresh for MMC crds */
364 g_card_info->card_info.card_type &= ~CARD_TYPE_SD;
365 status = sdmmc_execute_command(pSDMMC, CMD_IDLE, 0, MCI_INT_CMD_DONE);
366 command = CMD_MMC_OP_COND;
367 tries = INIT_OP_RETRIES;
368 ocr |= OCR_HC_CCS;
369 ++state;
370
371 /* for MMC cards high speed is 20MHz */
372 g_card_info->card_info.speed = MMC_MAX_CLOCK;
373 break;
374
375 case 1:
376 case 11:
377 status = sdmmc_execute_command(pSDMMC, command, 0, 0);
378 if (status & MCI_INT_RTO) {
379 state += 9; /* Mode unavailable */
380 }
381 else {
382 ++state;
383 }
384 break;
385
386 case 2: /* Initial OCR check */
387 case 12:
388 ocr = g_card_info->card_info.response[0] | (ocr & OCR_HC_CCS);
389 if (ocr & OCR_ALL_READY) {
390 ++state;
391 }
392 else {
393 state += 2;
394 }
395 break;
396
397 case 3: /* Initial wait for OCR clear */
398 case 13:
399 while ((ocr & OCR_ALL_READY) && --tries > 0) {
400 g_card_info->card_info.msdelay_func(MS_ACQUIRE_DELAY);
401 status = sdmmc_execute_command(pSDMMC, command, 0, 0);
402 ocr = g_card_info->card_info.response[0] | (ocr & OCR_HC_CCS);
403 }
404 if (ocr & OCR_ALL_READY) {
405 state += 7;
406 }
407 else {
408 ++state;
409 }
410 break;
411
412 case 14:
413 /* for MMC cards set high capacity bit */
414 ocr |= OCR_HC_CCS;
415
416 case 4: /* Assign OCR */
417 tries = SET_OP_RETRIES;
418 ocr &= OCR_VOLTAGE_RANGE_MSK | OCR_HC_CCS; /* Mask for the bits we care about */
419 do {
420 g_card_info->card_info.msdelay_func(MS_ACQUIRE_DELAY);
421 status = sdmmc_execute_command(pSDMMC, command, ocr, 0);
422 r = g_card_info->card_info.response[0];
423 } while (!(r & OCR_ALL_READY) && --tries > 0);
424
425 if (r & OCR_ALL_READY) {
426 /* is it high capacity card */
427 g_card_info->card_info.card_type |= (r & OCR_HC_CCS);
428 ++state;
429 }
430 else {
431 state += 6;
432 }
433 break;
434
435 case 5: /* CID polling */
436 case 15:
437 status = sdmmc_execute_command(pSDMMC, CMD_ALL_SEND_CID, 0, 0);
438 memcpy(&g_card_info->card_info.cid, &g_card_info->card_info.response[0], 16);
439 ++state;
440 break;
441
442 case 6: /* RCA send, for SD get RCA */
443 status = sdmmc_execute_command(pSDMMC, CMD_SD_SEND_RCA, 0, 0);
444 g_card_info->card_info.rca = (g_card_info->card_info.response[0]) >> 16;
445 ++state;
446 break;
447
448 case 16: /* RCA assignment for MMC set to 1 */
449 g_card_info->card_info.rca = 1;
450 status = sdmmc_execute_command(pSDMMC, CMD_MMC_SET_RCA, g_card_info->card_info.rca << 16, 0);
451 ++state;
452 break;
453
454 case 7:
455 case 17:
456 status = sdmmc_execute_command(pSDMMC, CMD_SEND_CSD, g_card_info->card_info.rca << 16, 0);
457 memcpy(&g_card_info->card_info.csd, &g_card_info->card_info.response[0], 16);
458 state = 100;
459 break;
460
461 default:
462 state += 100; /* break from while loop */
463 break;
464 }
465 }
466
467 /* Compute card size, block size and no. of blocks based on CSD response recived. */
468 if (prv_card_acquired()) {
469 prv_process_csd(pSDMMC);
470
471 /* Setup card data width and block size (once) */
472 if (prv_set_trans_state(pSDMMC) != 0) {
473 return 0;
474 }
475 if (prv_set_card_params(pSDMMC) != 0) {
476 return 0;
477 }
478 }
479
480 return prv_card_acquired();
481 }
482
483 /* Get the device size of SD/MMC card (after enumeration) */
484 uint64_t Chip_SDMMC_GetDeviceSize(LPC_SDMMC_T *pSDMMC)
485 {
486 return g_card_info->card_info.device_size;
487 }
488
489 /* Get the number of blocks in SD/MMC card (after enumeration) */
490 int32_t Chip_SDMMC_GetDeviceBlocks(LPC_SDMMC_T *pSDMMC)
491 {
492 return g_card_info->card_info.blocknr;
493 }
494
495 /* Performs the read of data from the SD/MMC card */
496 int32_t Chip_SDMMC_ReadBlocks(LPC_SDMMC_T *pSDMMC, void *buffer, int32_t start_block, int32_t num_blocks)
497 {
498 int32_t cbRead = (num_blocks) * MMC_SECTOR_SIZE;
499 int32_t status = 0;
500 int32_t index;
501
502 /* if card is not acquired return immediately */
503 if (( start_block < 0) || ( (start_block + num_blocks) > g_card_info->card_info.blocknr) ) {
504 return 0;
505 }
506
507 /* put card in trans state */
508 if (prv_set_trans_state(pSDMMC) != 0) {
509 return 0;
510 }
511
512 /* set number of bytes to read */
513 Chip_SDIF_SetByteCnt(pSDMMC, cbRead);
514
515 /* if high capacity card use block indexing */
516 if (g_card_info->card_info.card_type & CARD_TYPE_HC) {
517 index = start_block;
518 }
519 else { /*fix at 512 bytes*/
520 index = start_block << 9; // \* g_card_info->card_info.block_len;
521
522 }
523 Chip_SDIF_DmaSetup(pSDMMC, &g_card_info->sdif_dev, (uint32_t) buffer, cbRead);
524
525 /* Select single or multiple read based on number of blocks */
526 if (num_blocks == 1) {
527 status = sdmmc_execute_command(pSDMMC, CMD_READ_SINGLE, index, 0 | MCI_INT_DATA_OVER);
528 }
529 else {
530 status = sdmmc_execute_command(pSDMMC, CMD_READ_MULTIPLE, index, 0 | MCI_INT_DATA_OVER);
531 }
532
533 if (status != 0) {
534 cbRead = 0;
535 }
536 /*Wait for card program to finish*/
537 while (Chip_SDMMC_GetState(pSDMMC) != SDMMC_TRAN_ST) {}
538
539 return cbRead;
540 }
541
542 /* Performs write of data to the SD/MMC card */
543 int32_t Chip_SDMMC_WriteBlocks(LPC_SDMMC_T *pSDMMC, void *buffer, int32_t start_block, int32_t num_blocks)
544 {
545 int32_t cbWrote = num_blocks * MMC_SECTOR_SIZE;
546 int32_t status;
547 int32_t index;
548
549 /* if card is not acquired return immediately */
550 if (( start_block < 0) || ( (start_block + num_blocks) > g_card_info->card_info.blocknr) ) {
551 return 0;
552 }
553
554 /*Wait for card program to finish*/
555 while (Chip_SDMMC_GetState(pSDMMC) != SDMMC_TRAN_ST) {}
556
557 /* put card in trans state */
558 if (prv_set_trans_state(pSDMMC) != 0) {
559 return 0;
560 }
561
562 /* set number of bytes to write */
563 Chip_SDIF_SetByteCnt(pSDMMC, cbWrote);
564
565 /* if high capacity card use block indexing */
566 if (g_card_info->card_info.card_type & CARD_TYPE_HC) {
567 index = start_block;
568 }
569 else { /*fix at 512 bytes*/
570 index = start_block << 9; // * g_card_info->card_info.block_len;
571
572 }
573
574 Chip_SDIF_DmaSetup(pSDMMC, &g_card_info->sdif_dev, (uint32_t) buffer, cbWrote);
575
576 /* Select single or multiple write based on number of blocks */
577 if (num_blocks == 1) {
578 status = sdmmc_execute_command(pSDMMC, CMD_WRITE_SINGLE, index, 0 | MCI_INT_DATA_OVER);
579 }
580 else {
581 status = sdmmc_execute_command(pSDMMC, CMD_WRITE_MULTIPLE, index, 0 | MCI_INT_DATA_OVER);
582 }
583
584 /*Wait for card program to finish*/
585 while (Chip_SDMMC_GetState(pSDMMC) != SDMMC_TRAN_ST) {}
586
587 if (status != 0) {
588 cbWrote = 0;
589 }
590
591 return cbWrote;
592 }