| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sdmmc_17xx_40xx.c
Go to the documentation of this file.
1 /*
2 * @brief LPC17xx/40xx SDMMC card 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
34 #if !defined(CHIP_LPC175X_6X)
35
36 /*****************************************************************************
37 * Private types/enumerations/variables
38 ****************************************************************************/
39 #define CMD_TIMEOUT (0x10000)
40 #define DATA_TIMEOUT (0x1000000)
41 #define DATA_TIMER_VALUE_R (SDC_TRAN_CLOCK_RATE / 4) // 250ms
42 #define DATA_TIMER_VALUE_W (SDC_TRAN_CLOCK_RATE) // 1000ms
43 #define MS_ACQUIRE_DELAY (100)
45 /*****************************************************************************
46 * Public types/enumerations/variables
47 ****************************************************************************/
48
49 /*****************************************************************************
50 * Private functions
51 ****************************************************************************/
52 /* Send a command to card */
53 STATIC int32_t sendCmd(LPC_SDC_T *pSDC, uint32_t Command, uint32_t Arg, uint32_t timeout)
54 {
55 int32_t ret = SDC_RET_TIMEOUT;
56 uint32_t Status;
57
58 /* Set Command Info */
59 IP_SDC_SetCommand(pSDC, Command, Arg);
60
61 while (timeout) {
62
63 Status = IP_SDC_GetStatus(pSDC);
64
65 /* check if command was sent */
66 if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) {
67 ret = SDC_RET_OK;
68 break;
69 }
70 /* check if response was received */
71 if (Status & SDC_STATUS_CMDRESPEND) {
72 ret = SDC_RET_OK;
73 break;
74 }
75
76 /* check command sending status */
77 if (Status & SDC_STATUS_CMDERR) {
78 if (Status & SDC_STATUS_CMDCRCFAIL) {
79 if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) ||
80 (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) ||
81 (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) {
82 ret = SDC_RET_OK; /* ignore CRC error if it's a resp for SEND_OP_COND or STOP_TRANSMISSION. */
83 break;
84 }
85 }
86 ret = SDC_RET_CMD_FAILED;
87 break;
88 }
89
90 timeout--;
91 }
92
93 IP_SDC_ResetCommand(pSDC);
94
95 return ret;
96 }
97
98 /* Function to send a command to card and get its response (if any)*/
99 STATIC int32_t executeCmd(LPC_SDC_T *pSDC, uint32_t Command, uint32_t Arg, IP_SDC_001_RESP_T *pResp)
100 {
101 int32_t Ret = SDC_RET_FAILED;
102
103 /* Send Command to card */
104 Ret = sendCmd(pSDC, Command, Arg, CMD_TIMEOUT);
105 if (Ret != SDC_RET_OK) {
106 return Ret;
107 }
108
109 /* Get response (if any) */
110 if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) {
111
112 IP_SDC_GetResp(pSDC, pResp);
113
114 /* If the response is not R1, in the response field, the Expected Cmd data
115 won't be the same as the CMD data in SendCmd(). Below four cmds have
116 R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same
117 as the Expected or not. */
118 if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) &&
119 (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) &&
120 (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) &&
121 (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) &&
122 (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) {
123 return SDC_RET_CMD_FAILED;
124 }
125 }
126
127 return SDC_RET_OK;
128 }
129
130 /* Check R1 response, the result is stored in pCheckResult parameter. */
131 /* This function return 1 to exit the command execution, 0 to retry sending command */
132 STATIC int32_t checkR1Response(uint32_t resp, int32_t *pCheckResult)
133 {
134 int32_t Ret = 1;
135
136 if (!(resp & R1_READY_FOR_DATA)) {
137 *pCheckResult = SDC_RET_NOT_READY;
138 Ret = 0;
139 }
140 else if (R1_STATUS(resp)) {
141 *pCheckResult = SDC_RET_FAILED;
142 }
143 else {
144 *pCheckResult = SDC_RET_OK;
145 }
146 return Ret;
147 }
148
149 /* Send APP_CMD to card*/
150 STATIC int32_t sendAppCmd(LPC_SDC_T *pSDC, uint16_t rca)
151
152 {
153 int32_t Ret = SDC_RET_FAILED;
154 IP_SDC_001_RESP_T Response;
155 uint32_t RetryCnt = 20;
156
157 while (RetryCnt > 0) {
158 Ret = executeCmd(pSDC, SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response);
159 if (Ret == SDC_RET_OK) {
160 if (checkR1Response(Response.Data[0], &Ret)) {
161 if (Ret != SDC_RET_OK) {
162 return Ret;
163 }
164 if (Response.Data[0] & R1_APP_CMD) {
165 return SDC_RET_OK;
166 }
167 else {
168 Ret = SDC_RET_FAILED;
169 }
170 }
171 }
172 RetryCnt--;
173 }
174 return SDC_RET_FAILED;
175 }
176
177 /* Send Reset command to card*/
178 STATIC INLINE int32_t cardReset(LPC_SDC_T *pSDC)
179 {
180 return executeCmd(pSDC, SD_GO_IDLE_STATE, 0, NULL);
181 }
182
183 /* Send Interface condition to card*/
184 STATIC int32_t sendIfCond(LPC_SDC_T *pSDC)
185 {
186 int32_t Ret = SDC_RET_FAILED;
187 IP_SDC_001_RESP_T Response;
188 uint32_t RetryCnt = 20;
189
190 while (RetryCnt > 0) {
191 Ret = executeCmd(pSDC, SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN(
192 CMD8_DEF_PATTERN)), &Response);
193 if (Ret == SDC_RET_OK) {
194 if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) &&
195 (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) {
196 return SDC_RET_OK;
197 }
198 return SDC_RET_BAD_PARAMETERS;
199 }
200 RetryCnt--;
201 }
202 return Ret;
203 }
204
205 /* Send Operation condition to card */
206 STATIC int32_t sendOpCond(LPC_SDC_T *pSDC, uint32_t *pOCR)
207 {
208 int32_t Ret = SDC_RET_FAILED;
209 IP_SDC_001_RESP_T Response;
210 uint32_t RetryCnt = 0x200;
211
212 while (RetryCnt > 0) {
213 Ret = executeCmd(pSDC, SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response);
214 if (Ret == SDC_RET_OK) {
215 *pOCR = Response.Data[0];
216 if (*pOCR & SDC_OCR_IDLE) {
217 if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) {
218 return SDC_RET_BAD_PARAMETERS;
219 }
220 return SDC_RET_OK;
221 }
222 }
223 RetryCnt--;
224 }
225 return SDC_RET_FAILED;
226 }
227
228 /* Send ACMD41 command to card.If *Ocr = 0, it gets OCR. Otherwise, it starts initialization card. */
229 /* Open Drain bit must be cleared before calling this function */
230 STATIC int32_t sendAppOpCond(LPC_SDC_T *pSDC, uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS)
231 {
232 int32_t Ret = SDC_RET_FAILED;
233 IP_SDC_001_RESP_T Response;
234 uint32_t Argument;
235 uint32_t RetryCnt = 0x2000; /* The host repeatedly issues ACMD41 for at least 1 second or
236 until the busy bit are set to 1 */
237
238 Argument = ACMD41_OCR(*pOcr);
239 if (hcs) {
240 Argument |= ACMD41_HCS;
241 }
242
243 while (RetryCnt > 0) {
244 Ret = sendAppCmd(pSDC, rca);
245 if (Ret == SDC_RET_OK) {
246 Ret = executeCmd(pSDC, SD_ACMD41_SD_SEND_OP_COND, Argument, &Response);
247 if (Ret == SDC_RET_OK) {
248 if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) {
249 if (*pOcr == 0) {
250 *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]);
251 return SDC_RET_OK;
252 }
253 if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) {
254 return SDC_RET_BAD_PARAMETERS;
255 }
256 *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false;
257 return SDC_RET_OK;
258 }
259 }
260 }
261 else {
262 return Ret;
263 }
264 RetryCnt--;
265 }
266 return SDC_RET_FAILED;
267 }
268
269 /* Get CID */
270 STATIC int32_t getCID(LPC_SDC_T *pSDC, uint32_t *pCID)
271 {
272 int32_t Ret = SDC_RET_FAILED;
273 IP_SDC_001_RESP_T Response;
274 uint32_t RetryCnt = 20;
275
276 while (RetryCnt > 0) {
277 Ret = executeCmd(pSDC, SD_CMD2_ALL_SEND_CID, 0, &Response);
278 if (Ret == SDC_RET_OK) {
279 pCID[3] = Response.Data[0];
280 pCID[2] = Response.Data[1];
281 pCID[1] = Response.Data[2];
282 pCID[0] = Response.Data[3];
283 return SDC_RET_OK;
284 }
285 RetryCnt--;
286 }
287 return Ret;
288 }
289
290 /* Set Addr */
291 STATIC int32_t setAddr(LPC_SDC_T *pSDC, uint16_t addr)
292 {
293 int32_t Ret = SDC_RET_FAILED;
294 IP_SDC_001_RESP_T Response;
295 uint32_t RetryCnt = 20;
296
297 while (RetryCnt > 0) {
298 Ret = executeCmd(pSDC, SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response);
299 if (Ret == SDC_RET_OK) {
300 if (checkR1Response(Response.Data[0], &Ret)) {
301 return Ret;
302 }
303 }
304 RetryCnt--;
305 }
306 return Ret;
307 }
308
309 STATIC int32_t getAddr(LPC_SDC_T *pSDC, uint16_t *pRCA)
310 {
311 int32_t Ret = SDC_RET_FAILED;
312 IP_SDC_001_RESP_T Response;
313 uint32_t RetryCnt = 20;
314
315 *pRCA = 0;
316 while (RetryCnt > 0) {
317 Ret = executeCmd(pSDC, SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response);
318 if (Ret == SDC_RET_OK) {
319 if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) {
320 Ret = SDC_RET_NOT_READY;
321 }
322 else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) {
323 Ret = SDC_RET_ERR_STATE;
324 }
325 else {
326 *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]);
327 return SDC_RET_OK;
328 }
329 }
330 RetryCnt--;
331 }
332 return Ret;
333 }
334
335 STATIC int32_t getCSD(LPC_SDC_T *pSDC, uint16_t rca, uint32_t *pCSD)
336 {
337 int32_t Ret = SDC_RET_FAILED;
338 IP_SDC_001_RESP_T Response;
339 uint32_t RetryCnt = 20;
340
341 while (RetryCnt > 0) {
342 Ret = executeCmd(pSDC, SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response);
343 if (Ret == SDC_RET_OK) {
344 pCSD[3] = Response.Data[0];
345 pCSD[2] = Response.Data[1];
346 pCSD[1] = Response.Data[2];
347 pCSD[0] = Response.Data[3];
348 return Ret;
349 }
350 RetryCnt--;
351 }
352 return Ret;
353 }
354
355 /* Select card*/
356 STATIC int32_t selectCard(LPC_SDC_T *pSDC, uint16_t addr)
357 {
358 int32_t Ret = SDC_RET_FAILED;
359 IP_SDC_001_RESP_T Response;
360 uint32_t RetryCnt = 20;
361
362 while (RetryCnt > 0) {
363 Ret = executeCmd(pSDC, SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response);
364 if (Ret == SDC_RET_OK) {
365 if (checkR1Response(Response.Data[0], &Ret)) {
366 return Ret;
367 }
368 }
369 RetryCnt--;
370 }
371 return Ret;
372 }
373
374 /* Get card status */
375 STATIC int32_t getStatus(LPC_SDC_T *pSDC, uint16_t rca, uint32_t *pStatus)
376 {
377 int32_t Ret = SDC_RET_FAILED;
378 IP_SDC_001_RESP_T Response;
379 uint32_t RetryCnt = 20;
380
381 *pStatus = (uint32_t) -1;
382 while (RetryCnt > 0) {
383 Ret = executeCmd(pSDC, SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response);
384 if (Ret == SDC_RET_OK) {
385 checkR1Response(Response.Data[0], &Ret);
386 *pStatus = Response.Data[0];
387 return Ret;
388 }
389 RetryCnt--;
390 }
391 return Ret;
392 }
393
394 /* Set bus width. */
395 STATIC int32_t getAppStatus(LPC_SDC_T *pSDC, uint16_t rca, uint32_t *pStatus)
396 {
397 int32_t Ret = SDC_RET_FAILED;
398 IP_SDC_001_RESP_T Response;
399 uint8_t RetryCnt = 0x20;
400
401 while (RetryCnt > 0) {
402 Ret = sendAppCmd(pSDC, rca);
403 if (Ret == SDC_RET_OK) {
404 Ret = executeCmd(pSDC, SD_ACMD13_SEND_SD_STATUS, 0, &Response);
405 if (Ret == SDC_RET_OK) {
406 if (checkR1Response(Response.Data[0], &Ret)) {
407 return Ret;
408 }
409 }
410 }
411 RetryCnt--;
412 }
413 return SDC_RET_FAILED;
414 }
415
416 /* Helper function to get a bit field withing multi-word buffer. Used to get
417 fields with-in CSD & EXT-CSD */
418 STATIC uint32_t getBits(LPC_SDC_T *pSDC, int32_t start, int32_t end, uint32_t *data)
419 {
420 uint32_t v;
421 uint32_t i = end >> 5;
422 uint32_t j = start & 0x1f;
423
424 if (i == (start >> 5)) {
425 v = (data[i] >> j);
426 }
427 else {
428 v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
429 }
430
431 return v & ((1 << (end - start + 1)) - 1);
432 }
433
434 /* Function to process the CSD & EXT-CSD of the card */
435 STATIC void processCSD(LPC_SDC_T *pSDC, SDMMC_CARD_T *pCardInfo)
436 {
437 int32_t CSize = 0;
438 int32_t CSizeMult = 0;
439 int32_t Mult = 0;
440
441 /* compute block length based on CSD response */
442 pCardInfo->block_len = 1 << getBits(pSDC, 80, 83, pCardInfo->csd);
443
444 if ((pCardInfo->card_type & CARD_TYPE_HC) && (pCardInfo->card_type & CARD_TYPE_SD)) {
445 /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec an explanation for the calculation of these values */
446 CSize = getBits(pSDC, 48, 63, (uint32_t *) pCardInfo->csd) + 1;
447 pCardInfo->blocknr = CSize << 10; /* 512 byte blocks */
448 }
449 else {
450 /* See section 5.3 of the 4.1 revision of the MMC specs for an explanation for the calculation of these values */
451 CSize = getBits(pSDC, 62, 73, (uint32_t *) pCardInfo->csd);
452 CSizeMult = getBits(pSDC, 47, 49, (uint32_t *) pCardInfo->csd);
453 Mult = 1 << (CSizeMult + 2);
454 pCardInfo->blocknr = (CSize + 1) * Mult;
455
456 /* adjust blocknr to 512/block */
457 if (pCardInfo->block_len > MMC_SECTOR_SIZE) {
458 pCardInfo->blocknr = pCardInfo->blocknr * (pCardInfo->block_len >> 9);
459 }
460 }
461
462 pCardInfo->device_size = pCardInfo->blocknr << 9; /* blocknr * 512 */
463 }
464
465 /* Set bus width. */
466 STATIC int32_t setBusWidth(LPC_SDC_T *pSDC, uint16_t rca, uint8_t width)
467 {
468 int32_t Ret = SDC_RET_FAILED;
469 IP_SDC_001_RESP_T Response;
470 uint8_t RetryCnt = 0x20;
471
472 while (RetryCnt > 0) {
473 Ret = sendAppCmd(pSDC, rca);
474 if (Ret == SDC_RET_OK) {
475 Ret = executeCmd(pSDC, SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response);
476 if (Ret == SDC_RET_OK) {
477 if (checkR1Response(Response.Data[0], &Ret)) {
478 return Ret;
479 }
480 }
481 }
482 RetryCnt--;
483 }
484 return SDC_RET_FAILED;
485 }
486
487 /* Puts current selected card in trans state */
488 STATIC int32_t setTranState(LPC_SDC_T *pSDC, uint16_t rca)
489 {
490 int32_t Ret = 0;
491 uint32_t status = 0;
492 SDMMC_STATE_T state;
493
494 /* get current state of the card */
495 Ret = getStatus(pSDC, rca, &status);
496 if (Ret != SDC_RET_OK) {
497 /* unable to get the card state. So return immediatly. */
498 return Ret;
499 }
500
501 /* check card state in response */
502 state = (SDMMC_STATE_T) R1_CURRENT_STATE(status);
503 switch (state) {
504 case SDMMC_STBY_ST:
505 /* put card in 'Trans' state */
506 Ret = selectCard(pSDC, rca);
507 if (Ret != SDC_RET_OK) {
508 /* unable to put the card in Trans state. So return immediatly. */
509 return Ret;
510 }
511 getStatus(pSDC, rca, &status);
512 if (((SDMMC_STATE_T) R1_CURRENT_STATE(status)) != SDMMC_TRAN_ST) {
513 return SDC_RET_ERR_STATE;
514 }
515 break;
516
517 case SDMMC_TRAN_ST:
518 /*do nothing */
519 break;
520
521 default:
522 /* card shouldn't be in other states so return */
523 return SDC_RET_ERR_STATE;
524 }
525
526 return SDC_RET_OK;
527 }
528
529 /* Set bus width. */
530 STATIC int32_t setblock_length(LPC_SDC_T *pSDC, uint32_t rca, uint32_t block_len)
531 {
532 int32_t Ret = SDC_RET_FAILED;
533 IP_SDC_001_RESP_T Response;
534 uint8_t RetryCnt = 0x20;
535
536 while (RetryCnt > 0) {
537 Ret = executeCmd(pSDC, SD_CMD16_SET_BLOCKLEN, block_len, &Response);
538 if (Ret == SDC_RET_OK) {
539 if (checkR1Response(Response.Data[0], &Ret)) {
540 return Ret;
541 }
542 }
543 RetryCnt--;
544 }
545 return SDC_RET_FAILED;
546 }
547
548 /* Sets card data width and block size */
549 STATIC int32_t setCardParams(LPC_SDC_T *pSDC, SDMMC_CARD_T *pCardInfo)
550 {
551 int32_t Ret;
552
553 Chip_SDC_SetClock(pSDC, SDC_TRAN_CLOCK_RATE);
554 if (pCardInfo->card_type & CARD_TYPE_SD) {
555 IP_SDC_ClockControl(pSDC, SDC_CLOCK_WIDEBUS_MODE, ENABLE);
556 Ret = setBusWidth(pSDC, pCardInfo->rca, ACMD6_BUS_WIDTH_4);
557 if (Ret != SDC_RET_OK) {
558 return Ret;
559 }
560 }
561 else {
562 IP_SDC_ClockControl(pSDC, SDC_CLOCK_WIDEBUS_MODE, DISABLE);
563 }
564
565 /* set block length */
566 Ret = setblock_length(pSDC, pCardInfo->rca, MMC_SECTOR_SIZE);
567 return Ret;
568 }
569
570 STATIC int32_t readBlocks(LPC_SDC_T *pSDC, uint32_t card_type, uint32_t startBlock, uint32_t blockNum)
571 {
572 int32_t Ret = SDC_RET_FAILED;
573 IP_SDC_001_RESP_T Response;
574 uint32_t Command, Argument;
575 uint8_t RetryCnt = 0x20;
576
577 if (blockNum == 1) {
578 Command = SD_CMD17_READ_SINGLE_BLOCK;
579 }
580 else {
581 Command = SD_CMD18_READ_MULTIPLE_BLOCK;
582 }
583
584 /* Select single or multiple read based on number of blocks */
585 /* if high capacity card use block indexing */
586 if (card_type & CARD_TYPE_HC) {
587 Argument = startBlock;
588 }
589 else { /*fix at 512 bytes*/
590 Argument = startBlock << 9;
591 }
592
593 while (RetryCnt > 0) {
594 Ret = executeCmd(pSDC, Command, Argument, &Response);
595 if (Ret == SDC_RET_OK) {
596 if (checkR1Response(Response.Data[0], &Ret)) {
597 return Ret;
598 }
599 }
600 RetryCnt--;
601 }
602 return Ret;
603 }
604
605 STATIC int32_t writeBlocks(LPC_SDC_T *pSDC, uint32_t card_type, uint32_t startBlock, uint32_t blockNum)
606 {
607 int32_t Ret = SDC_RET_FAILED;
608 IP_SDC_001_RESP_T Response;
609 uint32_t Command, Argument;
610 uint8_t RetryCnt = 0x20;
611
612 if (blockNum == 1) {
613 Command = SD_CMD24_WRITE_BLOCK;
614 }
615 else {
616 Command = SD_CMD25_WRITE_MULTIPLE_BLOCK;
617 }
618
619 /* if high capacity card use block indexing */
620 if (card_type & CARD_TYPE_HC) {
621 Argument = startBlock;
622 }
623 else { /*fix at 512 bytes*/
624 Argument = startBlock << 9;
625
626 }
627
628 while (RetryCnt > 0) {
629 Ret = executeCmd(pSDC, Command, Argument, &Response);
630 if (Ret == SDC_RET_OK) {
631 if (checkR1Response(Response.Data[0], &Ret)) {
632 return Ret;
633 }
634 }
635 RetryCnt--;
636 }
637 return Ret;
638 }
639
640 STATIC int32_t stopTranmission(LPC_SDC_T *pSDC, uint32_t rca)
641 {
642 uint32_t Status;
643 int32_t Ret = SDC_RET_FAILED;
644 IP_SDC_001_RESP_T Response;
645 uint32_t RetryCnt = 20;
646
647 Ret = getStatus(pSDC, rca, &Status);
648 if (Ret != SDC_RET_OK) {
649 return SDC_RET_ERR_STATE;
650 }
651
652 if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) {
653 return SDC_RET_OK;
654 }
655
656 if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) &&
657 (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) {
658 return SDC_RET_ERR_STATE;
659 }
660
661 while (RetryCnt > 0) {
662 Ret = executeCmd(pSDC, SD_CMD12_STOP_TRANSMISSION, 0, &Response);
663 if (Ret == SDC_RET_OK) {
664 if (checkR1Response(Response.Data[0], &Ret)) {
665 if (Ret != SDC_RET_OK) {
666 return Ret;
667 }
668 Ret = getStatus(pSDC, rca, &Status);
669 if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) {
670 return SDC_RET_OK;
671 }
672 return SDC_RET_ERR_STATE;
673 }
674 }
675 RetryCnt--;
676 }
677 return Ret;
678 }
679
680 STATIC int32_t Chip_SDMMC_FIFOIRQHandler(LPC_SDC_T *pSDC, uint8_t *txBuf, uint32_t *txCnt,
681 uint8_t *rxBuf, uint32_t *rxCnt)
682 {
683 uint32_t Status;
684 Status = IP_SDC_GetStatus(pSDC);
685
686 if (txBuf ) {
687 if (Status & SDC_STATUS_TXFIFOHALFEMPTY) {
688 if (*txCnt % 64) {
689 IP_SDC_WriteFIFO(pSDC, (uint32_t *) &txBuf[*txCnt], false);
690 }
691 else {
692 IP_SDC_WriteFIFO(pSDC, (uint32_t *) &txBuf[*txCnt], true);
693 }
694 *txCnt += 32;
695 }
696 }
697
698 if (rxBuf ) {
699 if (Status & SDC_STATUS_RXFIFOHALFFULL) {
700 if (*rxCnt % 64) {
701 IP_SDC_ReadFIFO(pSDC, (uint32_t *) &rxBuf[*rxCnt], false);
702 }
703 else {
704 IP_SDC_ReadFIFO(pSDC, (uint32_t *) &rxBuf[*rxCnt], true);
705 }
706 *rxCnt += 32;
707 }
708 }
709
710 IP_SDC_ClearStatus(pSDC, SDC_STATUS_FIFO);
711
712 return 1;
713 }
714
715 /*****************************************************************************
716 * Public functions
717 ****************************************************************************/
718
719 /* SDMMC IRQ handler function */
720 int32_t Chip_SDMMC_IRQHandler(LPC_SDC_T *pSDC, uint8_t *txBuf, uint32_t *txCnt,
721 uint8_t *rxBuf, uint32_t *rxCnt)
722 {
723 uint32_t Status;
724
725 Status = IP_SDC_GetStatus(pSDC);
726
727 if ( Status & SDC_STATUS_DATAERR) {
728 IP_SDC_ClearStatus(pSDC, SDC_STATUS_DATAERR);
729 return -1; /* Data transfer error */
730 }
731
732 if ( Status & SDC_STATUS_DATAEND) {
733 IP_SDC_ClearStatus(pSDC, SDC_STATUS_DATAEND);
734 IP_SDC_SetIntMask(pSDC, 0);
735 return 0;
736 }
737
738 if ( Status & SDC_STATUS_DATABLOCKEND) {
739 IP_SDC_ClearStatus(pSDC, SDC_STATUS_DATABLOCKEND);
740 return 1;
741 }
742
743 if (Status & SDC_STATUS_FIFO) {
744 return Chip_SDMMC_FIFOIRQHandler(pSDC, txBuf, txCnt, rxBuf, rxCnt);
745 }
746
747 return 1;
748 }
749
750 /* Get card's current state (idle, transfer, program, etc.) */
751 SDMMC_STATE_T Chip_SDMMC_GetCardState(LPC_SDC_T *pSDC, SDMMC_CARD_T *pCardInfo)
752 {
753 uint32_t Status;
754 volatile int32_t Ret;
755
756 /* get current state of the card */
757 Ret = getStatus(pSDC, pCardInfo->rca, &Status);
758
759 /* check card state in response */
760 return (SDMMC_STATE_T) R1_CURRENT_STATE(Status);
761 }
762
763 /* Get current card status */
764 uint32_t Chip_SDMMC_GetCardStatus(LPC_SDC_T *pSDC, SDMMC_CARD_T *pCardInfo)
765 {
766 uint32_t Status;
767 getStatus(pSDC, pCardInfo->rca, &Status);
768 return Status;
769 }
770
771 /* Get current sd status */
772 int32_t Chip_SDMMC_GetSDStatus(LPC_SDC_T *pSDC, SDMMC_CARD_T *pCardInfo, uint32_t *pStatus)
773 {
774 int32_t Ret;
775 uint16_t ByteNum = 64;
776 SDMMC_EVENT_T Event;
777 IP_SDC_001_DATA_TRANSFER_T Transfer;
778
779 /* Put to tran state */
780 if (setTranState(pSDC, pCardInfo->rca) != SDC_RET_OK) {
781 return 0;
782 }
783
784 #ifdef SDC_DMA_ENABLE
785 Chip_SDC_SetIntMask(pSDC, SDC_MASK0_DATA | SDC_MASK0_RXDATAERR);
786 Event.DmaChannel = Chip_DMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_SDC);
787 /* DMA Setup */
788 Chip_DMA_Transfer(LPC_GPDMA, Event.DmaChannel,
789 GPDMA_CONN_SDC,
790 (uint32_t) pStatus,
791 GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL,
792 ByteNum);
793 #else
794 Chip_SDC_SetIntMask(SDC_MASK0_DATA | SDC_MASK0_RXDATAERR | SDC_MASK0_RXFIFO);
795
796 Event.Buffer = pStatus;
797 Event.Size = ByteNum;
798 Event.Index = 0;
799 Event.Dir = 1;
800 #endif
801 pCardInfo->evsetup_cb((void *) &Event);
802
803 /* set transfer information */
804 Transfer.BlockNum = 1;
805 Transfer.BlockSize = SDC_BLOCK_SIZE_64; /* 512 bit */
806 Transfer.Dir = SDC_TRANSFER_DIR_FROMCARD;
807 #ifdef SDC_DMA_ENABLE
808 Transfer.DMAUsed = true;
809 #else
810 Transfer.DMAUsed = false;
811 #endif
812 Transfer.Mode = SDC_TRANSFER_MODE_BLOCK;
813 Transfer.Timeout = DATA_TIMER_VALUE_R;
814 IP_SDC_SetDataTransfer(pSDC, &Transfer);
815
816 /* Send ACMD13 command */
817 Ret = getAppStatus(pSDC, pCardInfo->rca, pStatus);
818 if (Ret != SDC_RET_OK) {
819 ByteNum = 0;
820 goto send_end;
821 }
822
823 /* Wait for transfer Finish */
824 if ((pCardInfo->waitfunc_cb()) != 0) {
825 ByteNum = 0;
826 }
827
828 send_end:
829 #ifdef SDC_DMA_ENABLE
830 Chip_DMA_Stop(LPC_GPDMA, Event.DmaChannel);
831 #endif
832 if (Chip_SDMMC_GetCardState(pSDC, pCardInfo) == SDMMC_DATA_ST) {
833 /* Send Stop transmission command */
834 stopTranmission(pSDC, pCardInfo->rca);
835 }
836
837 /*Wait for card enters to tran state*/
838 while ((Chip_SDMMC_GetCardState(pSDC, pCardInfo) != SDMMC_TRAN_ST)) {}
839
840 return ByteNum;
841 }
842
843 /* Function to enumerate the SD/MMC/SDHC/MMC+ cards */
844 int32_t Chip_SDMMC_Acquire(LPC_SDC_T *pSDC, SDMMC_CARD_T *pCardInfo)
845 {
846 int32_t Ret;
847
848 /* Initialize card info */
849 pCardInfo->speed = SDC_TRAN_CLOCK_RATE;
850 pCardInfo->card_type = 0;
851
852 /* During identification phase, the clock should be less than
853 400Khz. Once we pass this phase, the normal clock can be set up
854 to 25Mhz on SD card and 20Mhz on MMC card. */
855 Chip_SDC_SetClock(pSDC, SDC_IDENT_CLOCK_RATE);
856
857 /* Clear Open Drain output control for SD */
858 IP_SDC_PowerControl(pSDC, SDC_POWER_ON, 0);
859
860 /* Card Reset */
861 Ret = cardReset(pSDC);
862 if (Ret != 0) {
863 return Ret;
864 }
865
866 pCardInfo->msdelay_func(MS_ACQUIRE_DELAY);
867
868 /* Send interface operation condiftion */
869 Ret = sendIfCond(pSDC);
870 if (Ret == SDC_RET_BAD_PARAMETERS) {
871 return Ret; /* Non-compatible voltage range or check pattern is not correct */
872
873 }
874 /* Get Card Type */
875 if (Ret == SDC_RET_OK) {/* Ver2.00 or later SD Memory Card*/
876 bool CCS;
877 uint32_t OCR = SDC_OCR_27_36;
878 pCardInfo->card_type |= CARD_TYPE_SD;
879 Ret = sendAppOpCond(pSDC, 0, true, &OCR, &CCS);
880 if (CCS) { /* High Capacity or Extended Capacity SD Memory Card */
881 pCardInfo->card_type |= CARD_TYPE_HC;
882 }
883 }
884 else { /*Ver2.00 or later SD Memory Card(voltage mismatch) or Ver1.X SD Memory Card
885 or not SD Memory Card*/
886 bool CCS;
887 uint32_t OCR = SDC_OCR_27_36;
888 Ret = sendAppOpCond(pSDC, 0, false, &OCR, &CCS);
889 if (Ret == SDC_RET_OK) {
890 pCardInfo->card_type |= CARD_TYPE_SD;
891 }
892 else if (Ret == SDC_RET_BAD_PARAMETERS) {
893 return Ret;
894 }
895 else { /* MMC Card setup */
896 uint32_t OCR;
897 /* Enter to Open Drain mode */
898 IP_SDC_PowerControl(pSDC, SDC_POWER_ON, SDC_PWR_OPENDRAIN);
899 pCardInfo->msdelay_func(MS_ACQUIRE_DELAY);
900 Ret = sendOpCond(pSDC, &OCR);
901 if (Ret != SDC_RET_OK) {
902 return Ret;
903 }
904
905 }
906 }
907
908 /* Read CID */
909 getCID(pSDC, pCardInfo->cid);
910
911 /* RCA send, for SD get RCA */
912 if (pCardInfo->card_type & CARD_TYPE_SD) {
913 getAddr(pSDC, &pCardInfo->rca);
914 }
915 else {
916 pCardInfo->rca = 1;
917 setAddr(pSDC, pCardInfo->rca);
918 IP_SDC_PowerControl(pSDC, SDC_POWER_ON, 0); /* enter to push-pull mode */
919 }
920
921 /* Get CSD */
922 getCSD(pSDC, pCardInfo->rca, pCardInfo->csd);
923
924 /* Compute card size, block size and no. of blocks based on CSD response recived. */
925 if (pCardInfo->cid[0]) {
926 processCSD(pSDC, pCardInfo);
927
928 if (setTranState(pSDC, pCardInfo->rca) != SDC_RET_OK) {
929 return 0;
930 }
931
932 if (Chip_SDMMC_GetCardState(pSDC, pCardInfo) != SDMMC_TRAN_ST) {
933 return 0;
934 }
935
936 if (setCardParams(pSDC, pCardInfo) != 0) {
937 return 0;
938 }
939 }
940
941 return (pCardInfo->cid[0]) ? 1 : 0;
942 }
943
944 /* Performs the read of data from the SD/MMC card */
945 int32_t Chip_SDMMC_ReadBlocks(LPC_SDC_T *pSDC,
946 SDMMC_CARD_T *pCardInfo,
947 void *buffer,
948 int32_t startBlock,
949 int32_t blockNum)
950 {
951 int32_t Ret = SDC_RET_FAILED;
952 IP_SDC_001_DATA_TRANSFER_T Transfer;
953 SDMMC_EVENT_T Event;
954 int32_t ByteNum = blockNum * MMC_SECTOR_SIZE;
955
956 /* if card is not acquired return immediately */
957 if (( startBlock < 0) || ( (startBlock + blockNum) > pCardInfo->blocknr) ) {
958 return 0;
959 }
960
961 /* Put to tran state */
962 if (setTranState(pSDC, pCardInfo->rca) != SDC_RET_OK) {
963 return 0;
964 }
965
966 #ifdef SDC_DMA_ENABLE
967 Chip_SDC_SetIntMask(pSDC, SDC_MASK0_DATA | SDC_MASK0_RXDATAERR);
968 Event.DmaChannel = Chip_DMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_SDC);
969 /* DMA Setup */
970 Chip_DMA_Transfer(LPC_GPDMA, Event.DmaChannel,
971 GPDMA_CONN_SDC,
972 (uint32_t) buffer,
973 GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL,
974 ByteNum);
975 #else
976 Chip_SDC_SetIntMask(SDC_MASK0_DATA | SDC_MASK0_RXDATAERR | SDC_MASK0_RXFIFO);
977
978 Event.Buffer = buffer;
979 Event.Size = ByteNum;
980 Event.Index = 0;
981 Event.Dir = 1;
982 #endif
983 pCardInfo->evsetup_cb((void *) &Event);
984
985 /* set transfer information */
986 Transfer.BlockNum = blockNum;
987 Transfer.BlockSize = SDC_BLOCK_SIZE_512;
988 Transfer.Dir = SDC_TRANSFER_DIR_FROMCARD;
989 #ifdef SDC_DMA_ENABLE
990 Transfer.DMAUsed = true;
991 #else
992 Transfer.DMAUsed = false;
993 #endif
994 Transfer.Mode = SDC_TRANSFER_MODE_BLOCK;
995 Transfer.Timeout = DATA_TIMER_VALUE_R;
996 IP_SDC_SetDataTransfer(pSDC, &Transfer);
997
998 Ret = readBlocks(pSDC, pCardInfo->card_type, startBlock, blockNum);
999 if (Ret != SDC_RET_OK) {
1000 ByteNum = 0;
1001 goto send_end;
1002 }
1003
1004 /* Wait for transfer Finish */
1005 if ((pCardInfo->waitfunc_cb()) != 0) {
1006 ByteNum = 0;
1007 }
1008
1009 send_end:
1010 #ifdef SDC_DMA_ENABLE
1011 Chip_DMA_Stop(LPC_GPDMA, Event.DmaChannel);
1012 #endif
1013
1014 if ((blockNum > 1) || (Chip_SDMMC_GetCardState(pSDC, pCardInfo) == SDMMC_DATA_ST)) {
1015 /* Send Stop transmission command */
1016 stopTranmission(pSDC, pCardInfo->rca);
1017 }
1018
1019 /*Wait for card enter to tran state*/
1020 while (Chip_SDMMC_GetCardState(pSDC, pCardInfo) != SDMMC_TRAN_ST) {}
1021
1022 return ByteNum;
1023 }
1024
1025 /* Performs write of data to the SD/MMC card */
1026 int32_t Chip_SDMMC_WriteBlocks(LPC_SDC_T *pSDC,
1027 SDMMC_CARD_T *pCardInfo,
1028 void *buffer,
1029 int32_t startBlock,
1030 int32_t blockNum)
1031 {
1032 int32_t Ret = SDC_RET_FAILED;
1033 IP_SDC_001_DATA_TRANSFER_T Transfer;
1034 SDMMC_EVENT_T Event;
1035 int32_t ByteNum = blockNum * MMC_SECTOR_SIZE;
1036
1037 /* if card is not acquired return immediately */
1038 if (( startBlock < 0) || ( (startBlock + blockNum) > pCardInfo->blocknr) ) {
1039 return 0;
1040 }
1041
1042 /* Put to tran state */
1043 if (setTranState(pSDC, pCardInfo->rca) != SDC_RET_OK) {
1044 return 0;
1045 }
1046
1047 Ret = writeBlocks(pSDC, pCardInfo->card_type, startBlock, blockNum);
1048 if (Ret != SDC_RET_OK) {
1049 return 0;
1050 }
1051
1052 /*Wait for card enter to rcv state*/
1053 while (Chip_SDMMC_GetCardState(pSDC, pCardInfo) != SDMMC_RCV_ST) {}
1054
1055 #ifdef SDC_DMA_ENABLE
1056 Chip_SDC_SetIntMask(pSDC, SDC_MASK0_DATA | SDC_MASK0_TXDATAERR);
1057
1058 Event.DmaChannel = Chip_DMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_SDC);
1059
1060 /* DMA Setup */
1061 Chip_DMA_Transfer(LPC_GPDMA, Event.DmaChannel,
1062 (uint32_t) buffer,
1063 GPDMA_CONN_SDC,
1064 GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL,
1065 ByteNum);
1066 #else
1067 Chip_SDC_SetIntMask(SDC_MASK0_DATA | SDC_MASK0_TXDATAERR | SDC_MASK0_TXFIFO);
1068 Event.Buffer = buffer;
1069 Event.Size = ByteNum;
1070 Event.Index = 0;
1071 Event.Dir = 0;
1072 #endif
1073 pCardInfo->evsetup_cb((void *) &Event);
1074
1075 /* set transfer information */
1076 Transfer.BlockNum = blockNum;
1077 Transfer.BlockSize = SDC_BLOCK_SIZE_512;
1078 Transfer.Dir = SDC_TRANSFER_DIR_TOCARD;
1079 #ifdef SDC_DMA_ENABLE
1080 Transfer.DMAUsed = true;
1081 #else
1082 Transfer.DMAUsed = false;
1083 #endif
1084 Transfer.Mode = SDC_TRANSFER_MODE_BLOCK;
1085 Transfer.Timeout = DATA_TIMER_VALUE_W;
1086 IP_SDC_SetDataTransfer(pSDC, &Transfer);
1087
1088 /* Wait for transfer done */
1089 if ((pCardInfo->waitfunc_cb()) != 0) {
1090 ByteNum = 0;
1091 }
1092 #ifdef SDC_DMA_ENABLE
1093 Chip_DMA_Stop(LPC_GPDMA, Event.DmaChannel);
1094 #endif
1095 if ((blockNum > 1) || (Chip_SDMMC_GetCardState(pSDC, pCardInfo) == SDMMC_RCV_ST)) {
1096 /* Send Stop transmission command */
1097 stopTranmission(pSDC, pCardInfo->rca);
1098 }
1099
1100 /*Wait for card enter to tran state*/
1101 while (Chip_SDMMC_GetCardState(pSDC, pCardInfo) != SDMMC_TRAN_ST) {}
1102
1103 return ByteNum;
1104 }
1105
1106 #endif /* !defined(CHIP_LPC175X_6X) */