LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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;
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) ||
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)*/
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*/
179 {
180  return executeCmd(pSDC, SD_GO_IDLE_STATE, 0, NULL);
181 }
182 
183 /* Send Interface condition to card*/
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) {
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 
554  if (pCardInfo->card_type & CARD_TYPE_SD) {
556  Ret = setBusWidth(pSDC, pCardInfo->rca, ACMD6_BUS_WIDTH_4);
557  if (Ret != SDC_RET_OK) {
558  return Ret;
559  }
560  }
561  else {
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 {
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 {
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 
641 {
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 {
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 
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 {
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.) */
752 {
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 */
765 {
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;
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
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,
792  ByteNum);
793 #else
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. */
856 
857  /* Clear Open Drain output control for SD */
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 */
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 */
946  SDMMC_CARD_T *pCardInfo,
947  void *buffer,
948  int32_t startBlock,
949  int32_t blockNum)
950 {
951  int32_t Ret = SDC_RET_FAILED;
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
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,
974  ByteNum);
975 #else
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 */
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
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,
1065  ByteNum);
1066 #else
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) */