M480 BSP V3.05.005
The Board Support Package for M480 Series
sdh.c
Go to the documentation of this file.
1/**************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include "NuMicro.h"
13
26#define SDH_BLOCK_SIZE 512ul
27
30/* global variables */
31/* For response R3 (such as ACMD41, CRC-7 is invalid; but SD controller will still */
32/* calculate CRC-7 and get an error result, software should ignore this error and clear SDISR [CRC_IF] flag */
33/* _sd_uR3_CMD is the flag for it. 1 means software should ignore CRC-7 error */
34
35static uint32_t _SDH0_ReferenceClock, _SDH1_ReferenceClock;
36
37#ifdef __ICCARM__
38#pragma data_alignment = 4
39static uint8_t _SDH0_ucSDHCBuffer[512];
40static uint8_t _SDH1_ucSDHCBuffer[512];
41#else
42static uint8_t _SDH0_ucSDHCBuffer[512] __attribute__((aligned(4)));
43static uint8_t _SDH1_ucSDHCBuffer[512] __attribute__((aligned(4)));
44#endif
45
46SDH_INFO_T SD0, SD1;
47
48uint32_t SDH_CheckRB(SDH_T *sdh)
49{
50 SDH_INFO_T *pSD;
51
52 if (sdh == SDH0)
53 {
54 pSD = &SD0;
55 }
56 else
57 {
58 pSD = &SD1;
59 }
60
61 while(1)
62 {
65 {
66 }
68 {
69 return Successful;
70 }
71 if (pSD->IsCardInsert == FALSE)
72 {
73 return SDH_NO_SD_CARD;
74 }
75 }
76}
77
78
79uint32_t SDH_SDCommand(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
80{
81 volatile uint32_t buf, val = 0ul;
82 SDH_INFO_T *pSD;
83
84 if (sdh == SDH0)
85 {
86 pSD = &SD0;
87 }
88 else
89 {
90 pSD = &SD1;
91 }
92
93 sdh->CMDARG = uArg;
94 buf = (sdh->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8ul)|(SDH_CTL_COEN_Msk);
95 sdh->CTL = buf;
96
97 while ((sdh->CTL & SDH_CTL_COEN_Msk) == SDH_CTL_COEN_Msk)
98 {
99 if (pSD->IsCardInsert == 0ul)
100 {
101 val = SDH_NO_SD_CARD;
102 }
103 }
104 return val;
105}
106
107
108uint32_t SDH_SDCmdAndRsp(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t ntickCount)
109{
110 volatile uint32_t buf;
111 SDH_INFO_T *pSD;
112
113 if (sdh == SDH0)
114 {
115 pSD = &SD0;
116 }
117 else
118 {
119 pSD = &SD1;
120 }
121
122 sdh->CMDARG = uArg;
123 buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk)) | (ucCmd << 8ul) | (SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk);
124 sdh->CTL = buf;
125
126 if (ntickCount > 0ul)
127 {
128 while ((sdh->CTL & SDH_CTL_RIEN_Msk) == SDH_CTL_RIEN_Msk)
129 {
130 if(ntickCount-- == 0ul)
131 {
132 sdh->CTL |= SDH_CTL_CTLRST_Msk; /* reset SD engine */
133 return 2ul;
134 }
135 if (pSD->IsCardInsert == FALSE)
136 {
137 return SDH_NO_SD_CARD;
138 }
139 if (sdh->INTSTS & SDH_INTSTS_CDSTS_Msk)
140 {
141 return SDH_NO_SD_CARD;
142 }
143 }
144 }
145 else
146 {
147 while ((sdh->CTL & SDH_CTL_RIEN_Msk) == SDH_CTL_RIEN_Msk)
148 {
149 if (pSD->IsCardInsert == FALSE)
150 {
151 return SDH_NO_SD_CARD;
152 }
153 if (sdh->INTSTS & SDH_INTSTS_CDSTS_Msk)
154 {
155 return SDH_NO_SD_CARD;
156 }
157 }
158 }
159
160 if (pSD->R7Flag)
161 {
162 uint32_t tmp0 = 0ul, tmp1= 0ul;
163 tmp1 = sdh->RESP1 & 0xfful;
164 tmp0 = sdh->RESP0 & 0xful;
165 if ((tmp1 != 0x55ul) && (tmp0 != 0x01ul))
166 {
167 pSD->R7Flag = 0ul;
168 return SDH_CMD8_ERROR;
169 }
170 }
171
172 if (!pSD->R3Flag)
173 {
174 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) == SDH_INTSTS_CRC7_Msk) /* check CRC7 */
175 {
176 return Successful;
177 }
178 else
179 {
180 return SDH_CRC7_ERROR;
181 }
182 }
183 else
184 {
185 /* ignore CRC error for R3 case */
186 pSD->R3Flag = 0ul;
188 return Successful;
189 }
190}
191
192
193uint32_t SDH_Swap32(uint32_t val)
194{
195 uint32_t buf;
196
197 buf = val;
198 val <<= 24;
199 val |= (buf<<8) & 0xff0000ul;
200 val |= (buf>>8) & 0xff00ul;
201 val |= (buf>>24)& 0xfful;
202 return val;
203}
204
205/* Get 16 bytes CID or CSD */
206uint32_t SDH_SDCmdAndRsp2(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t puR2ptr[])
207{
208 uint32_t i, buf;
209 uint32_t tmpBuf[5];
210 SDH_INFO_T *pSD;
211
212 if (sdh == SDH0)
213 {
214 pSD = &SD0;
215 }
216 else
217 {
218 pSD = &SD1;
219 }
220
221 sdh->CMDARG = uArg;
222 buf = (sdh->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_R2EN_Msk);
223 sdh->CTL = buf;
224
225 while ((sdh->CTL & SDH_CTL_R2EN_Msk) == SDH_CTL_R2EN_Msk)
226 {
227 if (pSD->IsCardInsert == FALSE)
228 {
229 return SDH_NO_SD_CARD;
230 }
231 if (sdh->INTSTS & SDH_INTSTS_CDSTS_Msk)
232 {
233 return SDH_NO_SD_CARD;
234 }
235 }
236
238 {
239 for (i=0ul; i<5ul; i++)
240 {
241 tmpBuf[i] = SDH_Swap32(sdh->FB[i]);
242 }
243 for (i=0ul; i<4ul; i++)
244 {
245 puR2ptr[i] = ((tmpBuf[i] & 0x00fffffful)<<8) | ((tmpBuf[i+1ul] & 0xff000000ul)>>24);
246 }
247 }
248 else
249 {
250 return SDH_CRC7_ERROR;
251 }
252 return Successful;
253}
254
255
256uint32_t SDH_SDCmdAndRspDataIn(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
257{
258 volatile uint32_t buf;
259 SDH_INFO_T *pSD;
260
261 if (sdh == SDH0)
262 {
263 pSD = &SD0;
264 }
265 else
266 {
267 pSD = &SD1;
268 }
269
270 sdh->CMDARG = uArg;
271 buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8ul)|
273
274 sdh->CTL = buf;
275
276 while ((sdh->CTL & SDH_CTL_RIEN_Msk) == SDH_CTL_RIEN_Msk)
277 {
278 if (pSD->IsCardInsert == FALSE)
279 {
280 return SDH_NO_SD_CARD;
281 }
282 if (sdh->INTSTS & SDH_INTSTS_CDSTS_Msk)
283 {
284 return SDH_NO_SD_CARD;
285 }
286 }
287
288 while ((sdh->CTL & SDH_CTL_DIEN_Msk) == SDH_CTL_DIEN_Msk)
289 {
290 if (pSD->IsCardInsert == FALSE)
291 {
292 return SDH_NO_SD_CARD;
293 }
294 if (sdh->INTSTS & SDH_INTSTS_CDSTS_Msk)
295 {
296 return SDH_NO_SD_CARD;
297 }
298 }
299
301 {
302 /* check CRC7 */
303 return SDH_CRC7_ERROR;
304 }
305
307 {
308 /* check CRC16 */
309 return SDH_CRC16_ERROR;
310 }
311 return 0ul;
312}
313
314/* there are 8 bits for divider0, maximum is 256 */
315#define SDH_CLK_DIV0_MAX 256ul
316
317void SDH_Set_clock(SDH_T *sdh, uint32_t sd_clock_khz)
318{
319 uint32_t rate, div1;
320 static uint32_t u32SD_ClkSrc = 0ul, u32SD_PwrCtl = 0ul;
321
323
324 /* initial state, clock source use HIRC */
325 if (sd_clock_khz <= 400ul)
326 {
327 u32SD_PwrCtl = CLK->PWRCTL;
328 if ((u32SD_PwrCtl & CLK_PWRCTL_HIRCEN_Msk) != 0x4ul)
329 {
330 CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
331 }
332
333 if (sdh == SDH0)
334 {
335 u32SD_ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_SDH0SEL_Msk);
336 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | CLK_CLKSEL0_SDH0SEL_HIRC;
337 _SDH0_ReferenceClock = (__HIRC / 1000ul);
338 }
339 else
340 {
341 u32SD_ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_SDH1SEL_Msk);
342 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | CLK_CLKSEL0_SDH1SEL_HIRC;
343 _SDH1_ReferenceClock = (__HIRC / 1000ul);
344 }
345 }
346 /* transfer state, clock source use sys_init() */
347 else
348 {
349 CLK->PWRCTL = u32SD_PwrCtl;
350 if (sdh == SDH0)
351 {
352 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | u32SD_ClkSrc;
353 if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HXT)
354 {
355 _SDH0_ReferenceClock = (CLK_GetHXTFreq() / 1000ul);
356 }
357 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HIRC)
358 {
359 _SDH0_ReferenceClock = (__HIRC / 1000ul);
360 }
361 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_PLL)
362 {
363 _SDH0_ReferenceClock = (CLK_GetPLLClockFreq() / 1000ul);
364 }
365 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HCLK)
366 {
367 _SDH0_ReferenceClock = (CLK_GetHCLKFreq() / 1000ul);
368 }
369 }
370 else
371 {
372 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | u32SD_ClkSrc;
373 if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HXT)
374 {
375 _SDH1_ReferenceClock = (CLK_GetHXTFreq() / 1000ul);
376 }
377 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HIRC)
378 {
379 _SDH1_ReferenceClock = (__HIRC / 1000ul);
380 }
381 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_PLL)
382 {
383 _SDH1_ReferenceClock = (CLK_GetPLLClockFreq() / 1000ul);
384 }
385 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HCLK)
386 {
387 _SDH1_ReferenceClock = (CLK_GetHCLKFreq() / 1000ul);
388 }
389 }
390
391 if(sd_clock_khz >= 50000ul)
392 {
393 sd_clock_khz = 50000ul;
394 }
395 }
396 if (sdh == SDH0)
397 {
398 rate = _SDH0_ReferenceClock / sd_clock_khz;
399
400 /* choose slower clock if system clock cannot divisible by wanted clock */
401 if ((_SDH0_ReferenceClock % sd_clock_khz) != 0ul)
402 {
403 rate++;
404 }
405 }
406 else
407 {
408 rate = _SDH1_ReferenceClock / sd_clock_khz;
409
410 /* choose slower clock if system clock cannot divisible by wanted clock */
411 if ((_SDH1_ReferenceClock % sd_clock_khz) != 0ul)
412 {
413 rate++;
414 }
415 }
416
417 if(rate >= SDH_CLK_DIV0_MAX)
418 {
419 rate = SDH_CLK_DIV0_MAX;
420 }
421
422 /*--- calculate the second divider CLKDIV0[SDHOST_N]*/
423 div1 = (rate - 1ul) & 0xFFul;
424
425 /*--- setup register */
426 if (sdh == SDH0)
427 {
428 CLK->CLKDIV0 &= ~CLK_CLKDIV0_SDH0DIV_Msk;
429 CLK->CLKDIV0 |= (div1 << CLK_CLKDIV0_SDH0DIV_Pos);
430 }
431 else
432 {
433 CLK->CLKDIV3 &= ~CLK_CLKDIV3_SDH1DIV_Msk;
434 CLK->CLKDIV3 |= (div1 << CLK_CLKDIV3_SDH1DIV_Pos);
435 }
436 return;
437}
438
439uint32_t SDH_CardDetection(SDH_T *sdh)
440{
441 uint32_t i, val = TRUE;
442 SDH_INFO_T *pSD;
443
444 if (sdh == SDH0)
445 {
446 pSD = &SD0;
447 }
448 else
449 {
450 pSD = &SD1;
451 }
452
453
454 if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) == SDH_INTEN_CDSRC_Msk) /* Card detect pin from GPIO */
455 {
456 if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk) /* Card remove */
457 {
458 pSD->IsCardInsert = (uint8_t)FALSE;
459 val = FALSE;
460 }
461 else
462 {
463 pSD->IsCardInsert = (uint8_t)TRUE;
464 }
465 }
466 else if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) != SDH_INTEN_CDSRC_Msk)
467 {
468 sdh->CTL |= SDH_CTL_CLKKEEP_Msk;
469 for(i= 0ul; i < 5000ul; i++)
470 {
471 }
472
473 if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk) /* Card insert */
474 {
475 pSD->IsCardInsert = (uint8_t)TRUE;
476 }
477 else
478 {
479 pSD->IsCardInsert = (uint8_t)FALSE;
480 val = FALSE;
481 }
482
483 sdh->CTL &= ~SDH_CTL_CLKKEEP_Msk;
484 }
485
486 return val;
487}
488
489uint32_t SDH_Init(SDH_T *sdh)
490{
491 uint32_t volatile i, status;
492 uint32_t resp;
493 uint32_t CIDBuffer[4];
494 uint32_t volatile u32CmdTimeOut;
495 SDH_INFO_T *pSD;
496
497 if (sdh == SDH0)
498 {
499 pSD = &SD0;
500 }
501 else
502 {
503 pSD = &SD1;
504 }
505
506 /* set the clock to 300KHz */
507 SDH_Set_clock(sdh, 300ul);
508
509 /* power ON 74 clock */
511
513 {
514 if (pSD->IsCardInsert == FALSE)
515 {
516 return SDH_NO_SD_CARD;
517 }
518 }
519
520 SDH_SDCommand(sdh, 0ul, 0ul); /* reset all cards */
521 for (i=0x1000ul; i>0ul; i--)
522 {
523 }
524
525 /* initial SDHC */
526 pSD->R7Flag = 1ul;
527 u32CmdTimeOut = 0xFFFFFul;
528
529 i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
530 if (i == Successful)
531 {
532 /* SD 2.0 */
533 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
534 pSD->R3Flag = 1ul;
535 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 2.7v-3.6v */
536 resp = sdh->RESP0;
537
538 while ((resp & 0x00800000ul) != 0x00800000ul) /* check if card is ready */
539 {
540 if (SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut) == SDH_NO_SD_CARD)
541 return SDH_NO_SD_CARD;
542 pSD->R3Flag = 1ul;
543 if (SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut) == SDH_NO_SD_CARD) /* 3.0v-3.4v */
544 return SDH_NO_SD_CARD;
545 resp = sdh->RESP0;
546 }
547 if ((resp & 0x00400000ul) == 0x00400000ul)
548 {
550 }
551 else
552 {
554 }
555 }
556 else
557 {
558 /* SD 1.1 */
559 SDH_SDCommand(sdh, 0ul, 0ul); /* reset all cards */
560 for (i=0x100ul; i>0ul; i--)
561 {
562 }
563
564 i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
565 if (i == 2ul) /* MMC memory */
566 {
567
568 SDH_SDCommand(sdh, 0ul, 0ul); /* reset */
569 for (i=0x100ul; i>0ul; i--)
570 {
571 }
572
573 pSD->R3Flag = 1ul;
574
575 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul) /* eMMC memory */
576 {
577 resp = sdh->RESP0;
578 while ((resp & 0x00800000ul) != 0x00800000ul)
579 {
580 /* check if card is ready */
581 pSD->R3Flag = 1ul;
582
583 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) == SDH_NO_SD_CARD) /* high voltage */
584 return SDH_NO_SD_CARD;
585 resp = sdh->RESP0;
586 }
587
588 if ((resp & 0x00400000ul) == 0x00400000ul)
589 {
590 pSD->CardType = SDH_TYPE_EMMC;
591 }
592 else
593 {
594 pSD->CardType = SDH_TYPE_MMC;
595 }
596 }
597 else
598 {
600 return SDH_ERR_DEVICE;
601 }
602 }
603 else if (i == 0ul) /* SD Memory */
604 {
605 pSD->R3Flag = 1ul;
606 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
607 resp = sdh->RESP0;
608 while ((resp & 0x00800000ul) != 0x00800000ul) /* check if card is ready */
609 {
610 if (SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut) == SDH_NO_SD_CARD)
611 return SDH_NO_SD_CARD;
612 pSD->R3Flag = 1ul;
613 if (SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut) == SDH_NO_SD_CARD) /* 3.0v-3.4v */
614 return SDH_NO_SD_CARD;
615 resp = sdh->RESP0;
616 }
618 }
619 else
620 {
622 return SDH_INIT_ERROR;
623 }
624 }
625
626 if (pSD->CardType != SDH_TYPE_UNKNOWN)
627 {
628 SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
629 if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
630 {
631 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) != Successful) /* set RCA */
632 {
633 return status;
634 }
635 pSD->RCA = 0x10000ul;
636 }
637 else
638 {
639 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) != Successful) /* get RCA */
640 {
641 return status;
642 }
643 else
644 {
645 pSD->RCA = (sdh->RESP0 << 8) & 0xffff0000;
646 }
647 }
648 }
649 return Successful;
650}
651
652
653uint32_t SDH_SwitchToHighSpeed(SDH_T *sdh, SDH_INFO_T *pSD)
654{
655 uint32_t volatile status=0ul;
656 uint16_t current_comsumption, busy_status0;
657
658 sdh->DMASA = (uint32_t)pSD->dmabuf;
659 sdh->BLEN = 63ul;
660
661 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) != Successful)
662 {
663 return Fail;
664 }
665
666 current_comsumption = (uint16_t)(*pSD->dmabuf) << 8;
667 current_comsumption |= (uint16_t)(*(pSD->dmabuf + 1));
668 if (!current_comsumption)
669 {
670 return Fail;
671 }
672
673 busy_status0 = (uint16_t)(*(pSD->dmabuf + 28)) << 8;
674 busy_status0 |= (uint16_t)(*(pSD->dmabuf + 29));
675
676 if (!busy_status0) /* function ready */
677 {
678 sdh->DMASA = (uint32_t)pSD->dmabuf;
679 sdh->BLEN = 63ul; /* 512 bit */
680
681 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) != Successful)
682 {
683 return Fail;
684 }
685
686 /* function change timing: 8 clocks */
687 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
689 {
690 if (pSD->IsCardInsert == FALSE)
691 {
692 return SDH_NO_SD_CARD;
693 }
694 }
695
696 current_comsumption = (uint16_t)(*pSD->dmabuf) << 8;
697 current_comsumption |= (uint16_t)(*(pSD->dmabuf + 1));
698 if (!current_comsumption)
699 {
700 return Fail;
701 }
702
703 return Successful;
704 }
705 else
706 {
707 return Fail;
708 }
709}
710
711
712uint32_t SDH_SelectCardType(SDH_T *sdh)
713{
714 uint32_t volatile status=0ul;
715 uint32_t param;
716 SDH_INFO_T *pSD;
717
718 if (sdh == SDH0)
719 {
720 pSD = &SD0;
721 }
722 else
723 {
724 pSD = &SD1;
725 }
726
727 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
728 {
729 return status;
730 }
731
732 if ((status = SDH_CheckRB(sdh)) != Successful)
733 {
734 return status;
735 }
736
737 /* if SD card set 4bit */
738 if (pSD->CardType == SDH_TYPE_SD_HIGH)
739 {
740 sdh->DMASA = (uint32_t)pSD->dmabuf;
741 sdh->BLEN = 0x07ul; /* 64 bit */
743 while ((sdh->DMACTL & SDH_DMACTL_DMARST_Msk) == 0x2);
744
745 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
746 {
747 return status;
748 }
749 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
750 {
751 return status;
752 }
753
754 if ((*pSD->dmabuf & 0xful) == 0x2ul)
755 {
756 status = SDH_SwitchToHighSpeed(sdh, pSD);
757 if (status == Successful)
758 {
759 /* divider */
760 SDH_Set_clock(sdh, SDHC_FREQ);
761 }
762 }
763
764 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
765 {
766 return status;
767 }
768 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful) /* set bus width */
769 {
770 return status;
771 }
772
773 sdh->CTL |= SDH_CTL_DBW_Msk;
774 }
775 else if (pSD->CardType == SDH_TYPE_SD_LOW)
776 {
777 sdh->DMASA = (uint32_t)pSD->dmabuf;;
778 sdh->BLEN = 0x07ul;
779
780 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
781 {
782 return status;
783 }
784 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
785 {
786 return status;
787 }
788
789 /* set data bus width. ACMD6 for SD card, SDCR_DBW for host. */
790 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
791 {
792 return status;
793 }
794
795 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful)
796 {
797 return status;
798 }
799
800 sdh->CTL |= SDH_CTL_DBW_Msk;
801 }
802 else if ((pSD->CardType == SDH_TYPE_MMC) ||(pSD->CardType == SDH_TYPE_EMMC))
803 {
804
805 if(pSD->CardType == SDH_TYPE_MMC)
806 {
807 sdh->CTL &= ~SDH_CTL_DBW_Msk;
808 }
809
810 /*--- sent CMD6 to MMC card to set bus width to 4 bits mode */
811 /* set CMD6 argument Access field to 3, Index to 183, Value to 1 (4-bit mode) */
812 param = (3ul << 24) | (183ul << 16) | (1ul << 8);
813 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) != Successful)
814 {
815 return status;
816 }
817 if ((status = SDH_CheckRB(sdh)) != Successful)
818 {
819 return status;
820 }
821
822 sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
823
824 }
825
826 if ((status = SDH_SDCmdAndRsp(sdh, 16ul, SDH_BLOCK_SIZE, 0ul)) != Successful)
827 {
828 return status;
829 }
830 sdh->BLEN = SDH_BLOCK_SIZE - 1ul;
831
832 SDH_SDCommand(sdh, 7ul, 0ul);
833 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
835 {
836 if (pSD->IsCardInsert == FALSE)
837 {
838 return SDH_NO_SD_CARD;
839 }
840 }
841
843
844 return Successful;
845}
846
847int32_t SDH_Get_SD_info(SDH_T *sdh)
848{
849 unsigned int R_LEN, C_Size, MULT, size;
850 uint32_t Buffer[4];
851 //unsigned char *ptr;
852 SDH_INFO_T *pSD;
853
854 if (sdh == SDH0)
855 {
856 pSD = &SD0;
857 }
858 else
859 {
860 pSD = &SD1;
861 }
862
863 SDH_SDCmdAndRsp2(sdh, 9ul, pSD->RCA, Buffer);
864
865 if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
866 {
867 /* for MMC/eMMC card */
868 if ((Buffer[0] & 0xc0000000) == 0xc0000000)
869 {
870 /* CSD_STRUCTURE [127:126] is 3 */
871 /* CSD version depend on EXT_CSD register in eMMC v4.4 for card size > 2GB */
872 SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul);
873
874 //ptr = (uint8_t *)((uint32_t)_SDH_ucSDHCBuffer );
875 sdh->DMASA = (uint32_t)pSD->dmabuf;;
876 sdh->BLEN = 511ul; /* read 512 bytes for EXT_CSD */
877
878 if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) == Successful)
879 {
880 SDH_SDCommand(sdh, 7ul, 0ul);
881 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
883 {
884 if (pSD->IsCardInsert == FALSE)
885 {
886 return SDH_NO_SD_CARD;
887 }
888 }
889
890 pSD->totalSectorN = (uint32_t)(*(pSD->dmabuf+215))<<24;
891 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+214))<<16;
892 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+213))<<8;
893 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+212));
894 pSD->diskSize = pSD->totalSectorN / 2ul;
895 }
896 }
897 else
898 {
899 /* CSD version v1.0/1.1/1.2 in eMMC v4.4 spec for card size <= 2GB */
900 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
901 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
902 MULT = (Buffer[2] & 0x00038000ul) >> 15;
903 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
904
905 pSD->diskSize = size / 1024ul;
906 pSD->totalSectorN = size / 512ul;
907 }
908 }
909 else
910 {
911 if ((Buffer[0] & 0xc0000000) != 0x0ul)
912 {
913 C_Size = ((Buffer[1] & 0x0000003ful) << 16) | ((Buffer[2] & 0xffff0000ul) >> 16);
914 size = (C_Size+1ul) * 512ul; /* Kbytes */
915
916 pSD->diskSize = size;
917 pSD->totalSectorN = size << 1;
918 }
919 else
920 {
921 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
922 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
923 MULT = (Buffer[2] & 0x00038000ul) >> 15;
924 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
925
926 pSD->diskSize = size / 1024ul;
927 pSD->totalSectorN = size / 512ul;
928 }
929 }
930 pSD->sectorSize = (int)512;
931 return Successful;
932}
933
945void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
946{
949 {
950 }
951
953
956 {
957 }
958
959 if (sdh == SDH0)
960 {
961 NVIC_EnableIRQ(SDH0_IRQn);
962 memset(&SD0, 0, sizeof(SDH_INFO_T));
963 SD0.dmabuf = _SDH0_ucSDHCBuffer;
964 }
965 else if (sdh == SDH1)
966 {
967 NVIC_EnableIRQ(SDH1_IRQn);
968 memset(&SD1, 0, sizeof(SDH_INFO_T));
969 SD1.dmabuf = _SDH1_ucSDHCBuffer;
970 }
971 else
972 {
973 }
974
975 sdh->GCTL = SDH_GCTL_SDEN_Msk;
976
977 if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
978 {
979 sdh->INTEN &= ~SDH_INTEN_CDSRC_Msk;
980 }
981 else
982 {
984 }
986
987 sdh->CTL |= SDH_CTL_CTLRST_Msk;
988 while ((sdh->CTL & SDH_CTL_CTLRST_Msk) == SDH_CTL_CTLRST_Msk)
989 {
990 }
991}
992
1008uint32_t SDH_Probe(SDH_T *sdh)
1009{
1010 uint32_t val;
1011
1012 sdh->GINTEN = 0ul;
1013 sdh->CTL &= ~SDH_CTL_SDNWR_Msk;
1014 sdh->CTL |= 0x09ul << SDH_CTL_SDNWR_Pos; /* set SDNWR = 9 */
1015 sdh->CTL &= ~SDH_CTL_BLKCNT_Msk;
1016 sdh->CTL |= 0x01ul << SDH_CTL_BLKCNT_Pos; /* set BLKCNT = 1 */
1017 sdh->CTL &= ~SDH_CTL_DBW_Msk; /* SD 1-bit data bus */
1018
1019 if(!(SDH_CardDetection(sdh)))
1020 {
1021 return SDH_NO_SD_CARD;
1022 }
1023
1024 if ((val = SDH_Init(sdh)) != 0ul)
1025 {
1026 return val;
1027 }
1028
1029 /* divider */
1030 if ((SD0.CardType == SDH_TYPE_MMC) || (SD1.CardType == SDH_TYPE_MMC))
1031 {
1032 SDH_Set_clock(sdh, MMC_FREQ);
1033 }
1034 else
1035 {
1036 SDH_Set_clock(sdh, SD_FREQ);
1037 }
1038 if (SDH_Get_SD_info(sdh) != 0)
1039 return SDH_NO_SD_CARD;
1040
1041 if ((val = SDH_SelectCardType(sdh)) != 0ul)
1042 {
1043 return val;
1044 }
1045
1046 return 0ul;
1047}
1048
1059uint32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1060{
1061 uint32_t volatile bIsSendCmd = FALSE, buf;
1062 uint32_t volatile reg;
1063 uint32_t volatile i, loop, status;
1064 uint32_t blksize = SDH_BLOCK_SIZE;
1065
1066 SDH_INFO_T *pSD;
1067 if (sdh == SDH0)
1068 {
1069 pSD = &SD0;
1070 }
1071 else
1072 {
1073 pSD = &SD1;
1074 }
1075
1076 if (u32SecCount == 0ul)
1077 {
1078 return SDH_SELECT_ERROR;
1079 }
1080
1081 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
1082 {
1083 return status;
1084 }
1085 if ((status = SDH_CheckRB(sdh)) != Successful)
1086 {
1087 return status;
1088 }
1089
1090 sdh->BLEN = blksize - 1ul; /* the actual byte count is equal to (SDBLEN+1) */
1091
1092 if ( (pSD->CardType == SDH_TYPE_SD_HIGH) || (pSD->CardType == SDH_TYPE_EMMC) )
1093 {
1094 sdh->CMDARG = u32StartSec;
1095 }
1096 else
1097 {
1098 sdh->CMDARG = u32StartSec * blksize;
1099 }
1100
1101 sdh->DMASA = (uint32_t)pu8BufAddr;
1102
1103 loop = u32SecCount / 255ul;
1104 for (i=0ul; i<loop; i++)
1105 {
1106 pSD->DataReadyFlag = (uint8_t)FALSE;
1107 reg = sdh->CTL & ~SDH_CTL_CMDCODE_Msk;
1108 reg = reg | 0xff0000ul; /* set BLK_CNT to 255 */
1109 if (bIsSendCmd == FALSE)
1110 {
1111 sdh->CTL = reg|(18ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
1112 bIsSendCmd = TRUE;
1113 }
1114 else
1115 {
1116 sdh->CTL = reg | SDH_CTL_DIEN_Msk;
1117 }
1118
1119 while(!pSD->DataReadyFlag)
1120 {
1121 if (pSD->IsCardInsert == FALSE)
1122 {
1123 return SDH_NO_SD_CARD;
1124 }
1125 }
1126
1127 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) != SDH_INTSTS_CRC7_Msk) /* check CRC7 */
1128 {
1129 return SDH_CRC7_ERROR;
1130 }
1131
1132 if ((sdh->INTSTS & SDH_INTSTS_CRC16_Msk) != SDH_INTSTS_CRC16_Msk) /* check CRC16 */
1133 {
1134 return SDH_CRC16_ERROR;
1135 }
1136 }
1137
1138 loop = u32SecCount % 255ul;
1139 if (loop != 0ul)
1140 {
1141 pSD->DataReadyFlag = (uint8_t)FALSE;
1142 reg = sdh->CTL & (~SDH_CTL_CMDCODE_Msk);
1143 reg = reg & (~SDH_CTL_BLKCNT_Msk);
1144 reg |= (loop << 16); /* setup SDCR_BLKCNT */
1145
1146 if (bIsSendCmd == FALSE)
1147 {
1148 sdh->CTL = reg|(18ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
1149 bIsSendCmd = TRUE;
1150 }
1151 else
1152 {
1153 sdh->CTL = reg | SDH_CTL_DIEN_Msk;
1154 }
1155
1156 while(!pSD->DataReadyFlag)
1157 {
1158 if (pSD->IsCardInsert == FALSE)
1159 {
1160 return SDH_NO_SD_CARD;
1161 }
1162 }
1163
1164 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) != SDH_INTSTS_CRC7_Msk) /* check CRC7 */
1165 {
1166 return SDH_CRC7_ERROR;
1167 }
1168
1169 if ((sdh->INTSTS & SDH_INTSTS_CRC16_Msk) != SDH_INTSTS_CRC16_Msk) /* check CRC16 */
1170 {
1171 return SDH_CRC16_ERROR;
1172 }
1173 }
1174
1175 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul)) /* stop command */
1176 {
1177 return SDH_CRC7_ERROR;
1178 }
1179 if ((status = SDH_CheckRB(sdh)) != Successful)
1180 {
1181 return status;
1182 }
1183
1184 SDH_SDCommand(sdh, 7ul, 0ul);
1185 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
1186 while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
1187 {
1188 if (pSD->IsCardInsert == FALSE)
1189 {
1190 return SDH_NO_SD_CARD;
1191 }
1192 }
1193
1194 return Successful;
1195}
1196
1197
1212uint32_t SDH_Write(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1213{
1214 uint32_t volatile bIsSendCmd = FALSE;
1215 uint32_t volatile reg;
1216 uint32_t volatile i, loop, status;
1217
1218 SDH_INFO_T *pSD;
1219
1220 if (sdh == SDH0)
1221 {
1222 pSD = &SD0;
1223 }
1224 else
1225 {
1226 pSD = &SD1;
1227 }
1228
1229 if (u32SecCount == 0ul)
1230 {
1231 return SDH_SELECT_ERROR;
1232 }
1233
1234 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
1235 {
1236 return status;
1237 }
1238
1239 if ((status = SDH_CheckRB(sdh)) != Successful)
1240 {
1241 return status;
1242 }
1243
1244 /* According to SD Spec v2.0, the write CMD block size MUST be 512, and the start address MUST be 512*n. */
1245 sdh->BLEN = SDH_BLOCK_SIZE - 1ul;
1246
1247 if ((pSD->CardType == SDH_TYPE_SD_HIGH) || (pSD->CardType == SDH_TYPE_EMMC))
1248 {
1249 sdh->CMDARG = u32StartSec;
1250 }
1251 else
1252 {
1253 sdh->CMDARG = u32StartSec * SDH_BLOCK_SIZE; /* set start address for SD CMD */
1254 }
1255
1256 sdh->DMASA = (uint32_t)pu8BufAddr;
1257 loop = u32SecCount / 255ul; /* the maximum block count is 0xFF=255 for register SDCR[BLK_CNT] */
1258 for (i=0ul; i<loop; i++)
1259 {
1260 pSD->DataReadyFlag = (uint8_t)FALSE;
1261 reg = sdh->CTL & 0xff00c080;
1262 reg = reg | 0xff0000ul; /* set BLK_CNT to 0xFF=255 */
1263 if (!bIsSendCmd)
1264 {
1265 sdh->CTL = reg|(25ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
1266 bIsSendCmd = TRUE;
1267 }
1268 else
1269 {
1270 sdh->CTL = reg | SDH_CTL_DOEN_Msk;
1271 }
1272
1273 while(!pSD->DataReadyFlag)
1274 {
1275 if (pSD->IsCardInsert == FALSE)
1276 {
1277 return SDH_NO_SD_CARD;
1278 }
1279 }
1280
1281 if ((sdh->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0ul)
1282 {
1284 return SDH_CRC_ERROR;
1285 }
1286 }
1287
1288 loop = u32SecCount % 255ul;
1289 if (loop != 0ul)
1290 {
1291 pSD->DataReadyFlag = (uint8_t)FALSE;
1292 reg = (sdh->CTL & 0xff00c080) | (loop << 16);
1293 if (!bIsSendCmd)
1294 {
1295 sdh->CTL = reg|(25ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
1296 bIsSendCmd = TRUE;
1297 }
1298 else
1299 {
1300 sdh->CTL = reg | SDH_CTL_DOEN_Msk;
1301 }
1302
1303 while(!pSD->DataReadyFlag)
1304 {
1305 if (pSD->IsCardInsert == FALSE)
1306 {
1307 return SDH_NO_SD_CARD;
1308 }
1309 }
1310
1311 if ((sdh->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0ul)
1312 {
1314 return SDH_CRC_ERROR;
1315 }
1316 }
1318
1319 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul)) /* stop command */
1320 {
1321 return SDH_CRC7_ERROR;
1322 }
1323 if ((status = SDH_CheckRB(sdh)) != Successful)
1324 {
1325 return status;
1326 }
1327
1328 SDH_SDCommand(sdh, 7ul, 0ul);
1329 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
1330 while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
1331 {
1332 if (pSD->IsCardInsert == FALSE)
1333 {
1334 return SDH_NO_SD_CARD;
1335 }
1336 }
1337
1338 return Successful;
1339}
1340 /* end of group SDH_EXPORTED_FUNCTIONS */
1342 /* end of group SDH_Driver */
1344 /* end of group Standard_Driver */
1346
1347/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
1348
1349
1350
1351
1352
1353
1354
1355
void *__dso_handle __attribute__((weak))
Definition: _syscalls.c:35
NuMicro peripheral access layer header file.
#define CLK_CLKSEL0_SDH0SEL_HCLK
Definition: clk.h:81
#define CLK_CLKSEL0_SDH1SEL_PLL
Definition: clk.h:84
#define CLK_CLKSEL0_SDH0SEL_HXT
Definition: clk.h:78
#define CLK_CLKSEL0_SDH0SEL_HIRC
Definition: clk.h:80
#define CLK_CLKSEL0_SDH0SEL_PLL
Definition: clk.h:79
#define CLK_CLKSEL0_SDH1SEL_HXT
Definition: clk.h:83
#define CLK_CLKSEL0_SDH1SEL_HIRC
Definition: clk.h:85
#define CLK_CLKSEL0_SDH1SEL_HCLK
Definition: clk.h:86
uint32_t CLK_GetHCLKFreq(void)
Get HCLK frequency.
Definition: clk.c:246
uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
Definition: clk.c:1197
uint32_t CLK_GetHXTFreq(void)
Get external high speed crystal clock frequency.
Definition: clk.c:122
@ SDH0_IRQn
Definition: M480.h:144
@ SDH1_IRQn
Definition: M480.h:166
#define TRUE
Boolean true, define to use in API parameters or return value.
Definition: M480.h:608
#define FALSE
Boolean false, define to use in API parameters or return value.
Definition: M480.h:609
#define SDH0
Definition: M480.h:392
#define CLK
Definition: M480.h:368
#define SDH1
Definition: M480.h:393
#define SDH_DMACTL_DMAEN_Msk
Definition: sdh_reg.h:793
#define SDH_CTL_COEN_Msk
Definition: sdh_reg.h:838
#define SDH_CTL_SDNWR_Pos
Definition: sdh_reg.h:873
#define SDH_CTL_R2EN_Msk
Definition: sdh_reg.h:850
#define SDH_CTL_CLK8OEN_Msk
Definition: sdh_reg.h:856
#define SDH_CTL_DBW_Msk
Definition: sdh_reg.h:868
#define SDH_GCTL_GCTLRST_Msk
Definition: sdh_reg.h:826
#define CLK_CLKSEL0_SDH1SEL_Msk
Definition: clk_reg.h:2523
#define SDH_CTL_RIEN_Msk
Definition: sdh_reg.h:841
#define SDH_INTSTS_CDSTS_Msk
Definition: sdh_reg.h:928
#define SDH_INTSTS_DAT0STS_Msk
Definition: sdh_reg.h:916
#define CLK_PWRCTL_HIRCEN_Msk
Definition: clk_reg.h:2283
#define CLK_CLKSEL0_SDH0SEL_Msk
Definition: clk_reg.h:2520
#define SDH_INTEN_CDSRC_Msk
Definition: sdh_reg.h:898
#define SDH_CTL_CLK74OEN_Msk
Definition: sdh_reg.h:853
#define SDH_DMACTL_DMARST_Msk
Definition: sdh_reg.h:796
#define SDH_CTL_BLKCNT_Pos
Definition: sdh_reg.h:870
#define SDH_GCTL_SDEN_Msk
Definition: sdh_reg.h:829
#define CLK_CLKDIV0_SDH0DIV_Pos
Definition: clk_reg.h:2630
#define SDH_INTSTS_CRC7_Msk
Definition: sdh_reg.h:907
#define SDH_INTEN_CDIEN_Msk
Definition: sdh_reg.h:886
#define SDH_INTSTS_CRC16_Msk
Definition: sdh_reg.h:910
#define SDH_CTL_DOEN_Msk
Definition: sdh_reg.h:847
#define SDH_CTL_DIEN_Msk
Definition: sdh_reg.h:844
#define SDH_INTEN_BLKDIEN_Msk
Definition: sdh_reg.h:880
#define SDH_INTSTS_CRCIF_Msk
Definition: sdh_reg.h:904
#define SDH_CTL_CLKKEEP_Msk
Definition: sdh_reg.h:859
#define CLK_CLKDIV3_SDH1DIV_Pos
Definition: clk_reg.h:2657
#define SDH_CTL_CTLRST_Msk
Definition: sdh_reg.h:865
#define SDH_NO_SD_CARD
Definition: sdh.h:50
#define SD_FREQ
Definition: sdh.h:62
#define Successful
Definition: sdh.h:39
#define SDH_TYPE_EMMC
Definition: sdh.h:47
#define SDH_CRC16_ERROR
Definition: sdh.h:57
#define SDH_TYPE_MMC
Definition: sdh.h:46
#define SDH_CRC_ERROR
Definition: sdh.h:58
#define SDH_TYPE_SD_LOW
Definition: sdh.h:45
#define SDH_INIT_ERROR
Definition: sdh.h:55
#define SDH_CMD8_ERROR
Definition: sdh.h:59
#define SDH_TYPE_SD_HIGH
Definition: sdh.h:44
#define SDH_TYPE_UNKNOWN
Definition: sdh.h:43
#define SDH_ERR_DEVICE
Definition: sdh.h:51
#define SDH_CRC7_ERROR
Definition: sdh.h:56
#define Fail
Definition: sdh.h:40
#define CardDetect_From_DAT3
Definition: sdh.h:68
#define SDHC_FREQ
Definition: sdh.h:63
#define MMC_FREQ
Definition: sdh.h:61
#define SDH_SELECT_ERROR
Definition: sdh.h:53
unsigned int RCA
Definition: sdh.h:82
uint32_t SDH_Probe(SDH_T *sdh)
This function use to initial SD card.
Definition: sdh.c:1008
unsigned char volatile DataReadyFlag
Definition: sdh.h:80
#define SDH_BLOCK_SIZE
Definition: sdh.c:26
uint32_t SDH_Write(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
This function use to write data to SD card.
Definition: sdh.c:1212
int sectorSize
Definition: sdh.h:85
unsigned int diskSize
Definition: sdh.h:84
unsigned char IsCardInsert
Definition: sdh.h:77
unsigned char R3Flag
Definition: sdh.h:78
unsigned int totalSectorN
Definition: sdh.h:83
unsigned char R7Flag
Definition: sdh.h:79
void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
This function use to reset SD function and select card detection source and pin.
Definition: sdh.c:945
uint32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
This function use to read data from SD card.
Definition: sdh.c:1059
unsigned int CardType
Definition: sdh.h:81
unsigned char * dmabuf
Definition: sdh.h:86
uint32_t SDH_CardDetection(SDH_T *sdh)
__STATIC_INLINE void SYS_UnlockReg(void)
Disable register write-protection function.
Definition: sys.h:1586
Definition: sdh_reg.h:27
__IO uint32_t DMASA
Definition: sdh_reg.h:762
__IO uint32_t CTL
Definition: sdh_reg.h:775
__IO uint32_t GINTEN
Definition: sdh_reg.h:770
__IO uint32_t CMDARG
Definition: sdh_reg.h:776
__IO uint32_t INTEN
Definition: sdh_reg.h:777
__IO uint32_t INTSTS
Definition: sdh_reg.h:778
__IO uint32_t GCTL
Definition: sdh_reg.h:769
__IO uint32_t FB[32]
Definition: sdh_reg.h:754
__I uint32_t RESP0
Definition: sdh_reg.h:779
__I uint32_t RESP1
Definition: sdh_reg.h:780
__IO uint32_t DMACTL
Definition: sdh_reg.h:758
__IO uint32_t BLEN
Definition: sdh_reg.h:781
Definition: sdh.h:76
#define __HIRC
Definition: system_M480.h:36