M480 BSP V3.05.006
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
25#define SDH_BLOCK_SIZE 512ul
26
29/* global variables */
30/* For response R3 (such as ACMD41, CRC-7 is invalid; but SD controller will still */
31/* calculate CRC-7 and get an error result, software should ignore this error and clear SDISR [CRC_IF] flag */
32/* _sd_uR3_CMD is the flag for it. 1 means software should ignore CRC-7 error */
33
34static uint32_t _SDH0_ReferenceClock, _SDH1_ReferenceClock;
35
36#ifdef __ICCARM__
37#pragma data_alignment = 4
38static uint8_t _SDH0_ucSDHCBuffer[512];
39static uint8_t _SDH1_ucSDHCBuffer[512];
40#else
41static uint8_t _SDH0_ucSDHCBuffer[512] __attribute__((aligned(4)));
42static uint8_t _SDH1_ucSDHCBuffer[512] __attribute__((aligned(4)));
43#endif
44
45SDH_INFO_T SD0, SD1;
46
47static int32_t SDH_CheckRB(SDH_T *sdh)
48{
49 uint32_t u32TimeOutCount1, u32TimeOutCount2;
50 SDH_INFO_T *pSD;
51 if (sdh == SDH0)
52 {
53 pSD = &SD0;
54 }
55 else
56 {
57 pSD = &SD1;
58 }
59
60 pSD->i32ErrCode = 0;
61
62 u32TimeOutCount2 = SDH_TIMEOUT_CNT;
63 while(1)
64 {
66 u32TimeOutCount1 = SDH_TIMEOUT_CNT;
68 {
69 if (--u32TimeOutCount1 == 0)
70 {
72 break;
73 }
74 }
76 {
77 break;
78 }
79 if (--u32TimeOutCount2 == 0)
80 {
82 break;
83 }
84 }
85
86 if (pSD->i32ErrCode != 0)
87 return Fail;
88
89 return Successful;
90}
91
92
93uint32_t SDH_SDCommand(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
94{
95 volatile uint32_t buf, val = 0ul;
96 SDH_INFO_T *pSD;
97 uint32_t u32TimeOutCount = SDH_TIMEOUT_CNT;
98
99 if (sdh == SDH0)
100 {
101 pSD = &SD0;
102 }
103 else
104 {
105 pSD = &SD1;
106 }
107
108 pSD->i32ErrCode = 0;
109
110 sdh->CMDARG = uArg;
111 buf = (sdh->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8ul)|(SDH_CTL_COEN_Msk);
112 sdh->CTL = buf;
113
114 while ((sdh->CTL & SDH_CTL_COEN_Msk) == SDH_CTL_COEN_Msk)
115 {
116 if (pSD->IsCardInsert == 0ul)
117 {
118 val = SDH_NO_SD_CARD;
119 }
120 if (--u32TimeOutCount == 0)
121 {
123 break;
124 }
125 }
126
127 if (pSD->i32ErrCode != 0)
128 return Fail;
129
130 return val;
131}
132
133
134uint32_t SDH_SDCmdAndRsp(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t ntickCount)
135{
136 volatile uint32_t buf;
137 SDH_INFO_T *pSD;
138 uint32_t u32TimeOutCount = SDH_TIMEOUT_CNT;
139 int i;
140
141 if (sdh == SDH0)
142 {
143 pSD = &SD0;
144 }
145 else
146 {
147 pSD = &SD1;
148 }
149
150 pSD->i32ErrCode = 0;
151 for (i = 0; i < 0x100; i++);
152
153 sdh->CMDARG = uArg;
154 buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk)) | (ucCmd << 8ul) | (SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk);
155 sdh->CTL = buf;
156
157 if (ntickCount > 0ul)
158 {
159 while ((sdh->CTL & SDH_CTL_RIEN_Msk) == SDH_CTL_RIEN_Msk)
160 {
161 if(ntickCount-- == 0ul)
162 {
163 sdh->CTL |= SDH_CTL_CTLRST_Msk; /* reset SD engine */
164 return 2ul;
165 }
166 if (pSD->IsCardInsert == FALSE)
167 {
168 return SDH_NO_SD_CARD;
169 }
170 }
171 }
172 else
173 {
174 while ((sdh->CTL & SDH_CTL_RIEN_Msk) == SDH_CTL_RIEN_Msk)
175 {
176 if (pSD->IsCardInsert == FALSE)
177 {
178 return SDH_NO_SD_CARD;
179 }
180 if (--u32TimeOutCount == 0)
181 {
183 break;
184 }
185 }
186 }
187
188 if (pSD->i32ErrCode != 0)
189 return Fail;
190
191 if (pSD->R7Flag)
192 {
193 uint32_t tmp0 = 0ul, tmp1= 0ul;
194 tmp1 = sdh->RESP1 & 0xfful;
195 tmp0 = sdh->RESP0 & 0xful;
196 if ((tmp1 != 0x55ul) && (tmp0 != 0x01ul))
197 {
198 pSD->R7Flag = 0ul;
199 return SDH_CMD8_ERROR;
200 }
201 }
202
203 if (!pSD->R3Flag)
204 {
205 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) == SDH_INTSTS_CRC7_Msk) /* check CRC7 */
206 {
207 return Successful;
208 }
209 else
210 {
211 return SDH_CRC7_ERROR;
212 }
213 }
214 else
215 {
216 /* ignore CRC error for R3 case */
217 pSD->R3Flag = 0ul;
219 return Successful;
220 }
221}
222
223
224uint32_t SDH_Swap32(uint32_t val)
225{
226 uint32_t buf;
227
228 buf = val;
229 val <<= 24;
230 val |= (buf<<8) & 0xff0000ul;
231 val |= (buf>>8) & 0xff00ul;
232 val |= (buf>>24)& 0xfful;
233 return val;
234}
235
236/* Get 16 bytes CID or CSD */
237uint32_t SDH_SDCmdAndRsp2(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t puR2ptr[])
238{
239 uint32_t i, buf;
240 uint32_t tmpBuf[5];
241 SDH_INFO_T *pSD;
242 uint32_t u32TimeOutCount = SDH_TIMEOUT_CNT;
243
244 if (sdh == SDH0)
245 {
246 pSD = &SD0;
247 }
248 else
249 {
250 pSD = &SD1;
251 }
252
253 pSD->i32ErrCode = 0;
254
255 sdh->CMDARG = uArg;
256 buf = (sdh->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_R2EN_Msk);
257 sdh->CTL = buf;
258
259 while ((sdh->CTL & SDH_CTL_R2EN_Msk) == SDH_CTL_R2EN_Msk)
260 {
261 if (pSD->IsCardInsert == FALSE)
262 {
263 return SDH_NO_SD_CARD;
264 }
265 if (--u32TimeOutCount == 0)
266 {
268 break;
269 }
270 }
271
273 {
274 for (i=0ul; i<5ul; i++)
275 {
276 tmpBuf[i] = SDH_Swap32(sdh->FB[i]);
277 }
278 for (i=0ul; i<4ul; i++)
279 {
280 puR2ptr[i] = ((tmpBuf[i] & 0x00fffffful)<<8) | ((tmpBuf[i+1ul] & 0xff000000ul)>>24);
281 }
282 }
283 else
284 {
285 return SDH_CRC7_ERROR;
286 }
287
288 if (pSD->i32ErrCode != 0)
289 return Fail;
290
291 return Successful;
292}
293
294
295uint32_t SDH_SDCmdAndRspDataIn(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
296{
297 volatile uint32_t buf;
298 SDH_INFO_T *pSD;
299 uint32_t u32TimeOutCount;
300
301 if (sdh == SDH0)
302 {
303 pSD = &SD0;
304 }
305 else
306 {
307 pSD = &SD1;
308 }
309
310 pSD->i32ErrCode = 0;
311
312 sdh->CMDARG = uArg;
313 buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8ul)|
315
316 sdh->CTL = buf;
317
318 u32TimeOutCount = SDH_TIMEOUT_CNT;
319 while ((sdh->CTL & SDH_CTL_RIEN_Msk) == SDH_CTL_RIEN_Msk)
320 {
321 if (pSD->IsCardInsert == FALSE)
322 {
323 return SDH_NO_SD_CARD;
324 }
325 if (--u32TimeOutCount == 0)
326 {
328 break;
329 }
330 }
331
332 u32TimeOutCount = SDH_TIMEOUT_CNT;
333 while ((sdh->CTL & SDH_CTL_DIEN_Msk) == SDH_CTL_DIEN_Msk)
334 {
335 if (pSD->IsCardInsert == FALSE)
336 {
337 return SDH_NO_SD_CARD;
338 }
339 if (--u32TimeOutCount == 0)
340 {
342 break;
343 }
344 }
345
347 {
348 /* check CRC7 */
349 return SDH_CRC7_ERROR;
350 }
351
353 {
354 /* check CRC16 */
355 return SDH_CRC16_ERROR;
356 }
357 return 0ul;
358}
359
360/* there are 8 bits for divider0, maximum is 256 */
361#define SDH_CLK_DIV0_MAX 256ul
362
363void SDH_Set_clock(SDH_T *sdh, uint32_t sd_clock_khz)
364{
365 uint32_t rate, div1;
366 static uint32_t u32SD_ClkSrc = 0ul, u32SD_PwrCtl = 0ul;
367
368 uint32_t u32RegLockLevel = SYS_IsRegLocked();
369 if (u32RegLockLevel)
370 {
372 }
373
374 /* initial state, clock source use HIRC */
375 if (sd_clock_khz <= 400ul)
376 {
377 u32SD_PwrCtl = CLK->PWRCTL;
378 if ((u32SD_PwrCtl & CLK_PWRCTL_HIRCEN_Msk) != 0x4ul)
379 {
380 CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
381 }
382
383 if (sdh == SDH0)
384 {
385 u32SD_ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_SDH0SEL_Msk);
386 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | CLK_CLKSEL0_SDH0SEL_HIRC;
387 _SDH0_ReferenceClock = (__HIRC / 1000ul);
388 }
389 else
390 {
391 u32SD_ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_SDH1SEL_Msk);
392 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | CLK_CLKSEL0_SDH1SEL_HIRC;
393 _SDH1_ReferenceClock = (__HIRC / 1000ul);
394 }
395 }
396 /* transfer state, clock source use sys_init() */
397 else
398 {
399 CLK->PWRCTL = u32SD_PwrCtl;
400 if (sdh == SDH0)
401 {
402 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | u32SD_ClkSrc;
403 if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HXT)
404 {
405 _SDH0_ReferenceClock = (CLK_GetHXTFreq() / 1000ul);
406 }
407 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HIRC)
408 {
409 _SDH0_ReferenceClock = (__HIRC / 1000ul);
410 }
411 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_PLL)
412 {
413 _SDH0_ReferenceClock = (CLK_GetPLLClockFreq() / 1000ul);
414 }
415 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HCLK)
416 {
417 _SDH0_ReferenceClock = (CLK_GetHCLKFreq() / 1000ul);
418 }
419 }
420 else
421 {
422 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | u32SD_ClkSrc;
423 if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HXT)
424 {
425 _SDH1_ReferenceClock = (CLK_GetHXTFreq() / 1000ul);
426 }
427 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HIRC)
428 {
429 _SDH1_ReferenceClock = (__HIRC / 1000ul);
430 }
431 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_PLL)
432 {
433 _SDH1_ReferenceClock = (CLK_GetPLLClockFreq() / 1000ul);
434 }
435 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HCLK)
436 {
437 _SDH1_ReferenceClock = (CLK_GetHCLKFreq() / 1000ul);
438 }
439 }
440
441 if(sd_clock_khz >= 50000ul)
442 {
443 sd_clock_khz = 50000ul;
444 }
445 }
446 if (sdh == SDH0)
447 {
448 rate = _SDH0_ReferenceClock / sd_clock_khz;
449
450 /* choose slower clock if system clock cannot divisible by wanted clock */
451 if ((_SDH0_ReferenceClock % sd_clock_khz) != 0ul)
452 {
453 rate++;
454 }
455 }
456 else
457 {
458 rate = _SDH1_ReferenceClock / sd_clock_khz;
459
460 /* choose slower clock if system clock cannot divisible by wanted clock */
461 if ((_SDH1_ReferenceClock % sd_clock_khz) != 0ul)
462 {
463 rate++;
464 }
465 }
466
467 if(rate >= SDH_CLK_DIV0_MAX)
468 {
469 rate = SDH_CLK_DIV0_MAX;
470 }
471
472 /*--- calculate the second divider CLKDIV0[SDHOST_N]*/
473 div1 = (rate - 1ul) & 0xFFul;
474
475 /*--- setup register */
476 if (sdh == SDH0)
477 {
478 CLK->CLKDIV0 &= ~CLK_CLKDIV0_SDH0DIV_Msk;
479 CLK->CLKDIV0 |= (div1 << CLK_CLKDIV0_SDH0DIV_Pos);
480 }
481 else
482 {
483 CLK->CLKDIV3 &= ~CLK_CLKDIV3_SDH1DIV_Msk;
484 CLK->CLKDIV3 |= (div1 << CLK_CLKDIV3_SDH1DIV_Pos);
485 }
486
487 if (u32RegLockLevel)
488 {
489 SYS_LockReg();
490 }
491
492 return;
493}
494
495int32_t SDH_CardDetection(SDH_T *sdh)
496{
497 volatile uint32_t i;
498 uint32_t val = TRUE;
499 SDH_INFO_T *pSD;
500
501 if (sdh == SDH0)
502 {
503 pSD = &SD0;
504 }
505 else
506 {
507 pSD = &SD1;
508 }
509
510
511 if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) == SDH_INTEN_CDSRC_Msk) /* Card detect pin from GPIO */
512 {
513 sdh->CTL &= ~SDH_CTL_CLKKEEP_Msk;
514
515 if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk) /* Card remove */
516 {
517 pSD->IsCardInsert = (uint8_t)FALSE;
518 val = FALSE;
519 }
520 else
521 {
522 pSD->IsCardInsert = (uint8_t)TRUE;
523 }
524 }
525 else if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) != SDH_INTEN_CDSRC_Msk)
526 {
527 sdh->CTL |= SDH_CTL_CLKKEEP_Msk;
528
529 for (i = 0ul; i < 5000ul; i++)
530 {
531 __nop();
532 }
533
534 if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk) /* Card insert */
535 {
536 pSD->IsCardInsert = (uint8_t)TRUE;
537 }
538 else
539 {
540 pSD->IsCardInsert = (uint8_t)FALSE;
541 val = FALSE;
542 }
543
544 sdh->CTL &= ~SDH_CTL_CLKKEEP_Msk;
545 }
546
547 return val;
548}
549
550uint32_t SDH_Init(SDH_T *sdh)
551{
552 uint32_t volatile i, status;
553 uint32_t resp;
554 uint32_t CIDBuffer[4];
555 uint32_t volatile u32CmdTimeOut;
556 SDH_INFO_T *pSD;
557 uint32_t u32TimeOutCount;
558
559 if (sdh == SDH0)
560 {
561 pSD = &SD0;
562 }
563 else
564 {
565 pSD = &SD1;
566 }
567
568 pSD->i32ErrCode = 0;
569
570 /* set the clock to 300KHz */
571 SDH_Set_clock(sdh, 300ul);
572
573 /* power ON 74 clock */
575
576 u32TimeOutCount = SDH_TIMEOUT_CNT;
578 {
579 if (pSD->IsCardInsert == FALSE)
580 {
581 return SDH_NO_SD_CARD;
582 }
583 if (--u32TimeOutCount == 0)
584 {
586 break;
587 }
588 }
589
590 SDH_SDCommand(sdh, 0ul, 0ul); /* reset all cards */
591 for (i=0x1000ul; i>0ul; i--)
592 {
593 }
594
595 /* initial SDHC */
596 pSD->R7Flag = 1ul;
597 u32CmdTimeOut = 0xFFFFFul;
598
599 i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
600 if (i == Successful)
601 {
602 /* SD 2.0 */
603 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
604 pSD->R3Flag = 1ul;
605 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 2.7v-3.6v */
606 resp = sdh->RESP0;
607
608 u32TimeOutCount = SDH_TIMEOUT_CNT;
609 while ((resp & 0x00800000ul) != 0x00800000ul) /* check if card is ready */
610 {
611 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
612 pSD->R3Flag = 1ul;
613 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
614 resp = sdh->RESP0;
615 if (--u32TimeOutCount == 0)
616 {
618 break;
619 }
620 }
621 if ((resp & 0x00400000ul) == 0x00400000ul)
622 {
624 }
625 else
626 {
628 }
629 }
630 else
631 {
632 /* SD 1.1 */
633 SDH_SDCommand(sdh, 0ul, 0ul); /* reset all cards */
634 for (i=0x100ul; i>0ul; i--)
635 {
636 }
637
638 i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
639 if (i == 2ul) /* MMC memory */
640 {
641
642 SDH_SDCommand(sdh, 0ul, 0ul); /* reset */
643 for (i=0x100ul; i>0ul; i--)
644 {
645 }
646
647 pSD->R3Flag = 1ul;
648
649 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul) /* eMMC memory */
650 {
651 resp = sdh->RESP0;
652 u32TimeOutCount = SDH_TIMEOUT_CNT;
653 while ((resp & 0x00800000ul) != 0x00800000ul)
654 {
655 /* check if card is ready */
656 pSD->R3Flag = 1ul;
657
658 SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut); /* high voltage */
659 resp = sdh->RESP0;
660
661 if (--u32TimeOutCount == 0)
662 {
664 break;
665 }
666 }
667
668 if ((resp & 0x00400000ul) == 0x00400000ul)
669 {
670 pSD->CardType = SDH_TYPE_EMMC;
671 }
672 else
673 {
674 pSD->CardType = SDH_TYPE_MMC;
675 }
676 }
677 else
678 {
680 return SDH_ERR_DEVICE;
681 }
682 }
683 else if (i == 0ul) /* SD Memory */
684 {
685 pSD->R3Flag = 1ul;
686 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
687 resp = sdh->RESP0;
688 u32TimeOutCount = SDH_TIMEOUT_CNT;
689 while ((resp & 0x00800000ul) != 0x00800000ul) /* check if card is ready */
690 {
691 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
692 pSD->R3Flag = 1ul;
693 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
694 resp = sdh->RESP0;
695 if (--u32TimeOutCount == 0)
696 {
698 break;
699 }
700 }
702 }
703 else
704 {
706 return SDH_INIT_ERROR;
707 }
708 }
709
710 if (pSD->CardType != SDH_TYPE_UNKNOWN)
711 {
712 SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
713 if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
714 {
715 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) != Successful) /* set RCA */
716 {
717 return status;
718 }
719 pSD->RCA = 0x10000ul;
720 }
721 else
722 {
723 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) != Successful) /* get RCA */
724 {
725 return status;
726 }
727 else
728 {
729 pSD->RCA = (sdh->RESP0 << 8) & 0xffff0000;
730 }
731 }
732 }
733
734 if (pSD->i32ErrCode != 0)
735 return Fail;
736
737 return Successful;
738}
739
740
741uint32_t SDH_SwitchToHighSpeed(SDH_T *sdh, SDH_INFO_T *pSD)
742{
743 uint32_t volatile status=0ul;
744 uint16_t current_comsumption, busy_status0;
745 uint32_t u32TimeOutCount = SDH_TIMEOUT_CNT;
746
747 pSD->i32ErrCode = 0;
748
749 sdh->DMASA = (uint32_t)pSD->dmabuf;
750 sdh->BLEN = 63ul;
751
752 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) != Successful)
753 {
754 return Fail;
755 }
756
757 current_comsumption = (uint16_t)(*pSD->dmabuf) << 8;
758 current_comsumption |= (uint16_t)(*(pSD->dmabuf + 1));
759 if (!current_comsumption)
760 {
761 return Fail;
762 }
763
764 busy_status0 = (uint16_t)(*(pSD->dmabuf + 28)) << 8;
765 busy_status0 |= (uint16_t)(*(pSD->dmabuf + 29));
766
767 if (!busy_status0) /* function ready */
768 {
769 sdh->DMASA = (uint32_t)pSD->dmabuf;
770 sdh->BLEN = 63ul; /* 512 bit */
771
772 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) != Successful)
773 {
774 return Fail;
775 }
776
777 /* function change timing: 8 clocks */
778 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
780 {
781 if (--u32TimeOutCount == 0)
782 {
784 break;
785 }
786 }
787
788 if (pSD->i32ErrCode != 0)
789 return Fail;
790
791 current_comsumption = (uint16_t)(*pSD->dmabuf) << 8;
792 current_comsumption |= (uint16_t)(*(pSD->dmabuf + 1));
793 if (!current_comsumption)
794 {
795 return Fail;
796 }
797
798 return Successful;
799 }
800 else
801 {
802 return Fail;
803 }
804}
805
806
807int32_t SDH_SelectCardType(SDH_T *sdh)
808{
809 uint32_t volatile status=0ul;
810 uint32_t param;
811 SDH_INFO_T *pSD;
812 uint32_t u32TimeOutCount;
813
814 if (sdh == SDH0)
815 {
816 pSD = &SD0;
817 }
818 else
819 {
820 pSD = &SD1;
821 }
822
823 pSD->i32ErrCode = 0;
824
825 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
826 {
827 return status;
828 }
829
830 if (SDH_CheckRB(sdh) != Successful)
831 {
832 return SDH_ERR_TIMEOUT;
833 }
834
835 /* if SD card set 4bit */
836 if (pSD->CardType == SDH_TYPE_SD_HIGH)
837 {
838 sdh->DMASA = (uint32_t)pSD->dmabuf;
839 sdh->BLEN = 0x07ul; /* 64 bit */
841 u32TimeOutCount = SDH_TIMEOUT_CNT;
842 while ((sdh->DMACTL & SDH_DMACTL_DMARST_Msk) == 0x2)
843 {
844 if (--u32TimeOutCount == 0)
845 {
847 break;
848 }
849 }
850
851 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
852 {
853 return status;
854 }
855 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
856 {
857 return status;
858 }
859
860 if ((*pSD->dmabuf & 0xful) == 0x2ul)
861 {
862 status = SDH_SwitchToHighSpeed(sdh, pSD);
863 if (status == Successful)
864 {
865 /* divider */
866 SDH_Set_clock(sdh, SDHC_FREQ);
867 }
868 }
869
870 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
871 {
872 return status;
873 }
874 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful) /* set bus width */
875 {
876 return status;
877 }
878
879 sdh->CTL |= SDH_CTL_DBW_Msk;
880 }
881 else if (pSD->CardType == SDH_TYPE_SD_LOW)
882 {
883 sdh->DMASA = (uint32_t)pSD->dmabuf;;
884 sdh->BLEN = 0x07ul;
885
886 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
887 {
888 return status;
889 }
890 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
891 {
892 return status;
893 }
894
895 /* set data bus width. ACMD6 for SD card, SDCR_DBW for host. */
896 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
897 {
898 return status;
899 }
900
901 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful)
902 {
903 return status;
904 }
905
906 sdh->CTL |= SDH_CTL_DBW_Msk;
907 }
908 else if ((pSD->CardType == SDH_TYPE_MMC) ||(pSD->CardType == SDH_TYPE_EMMC))
909 {
910
911 if(pSD->CardType == SDH_TYPE_MMC)
912 {
913 sdh->CTL &= ~SDH_CTL_DBW_Msk;
914 }
915
916 /*--- sent CMD6 to MMC card to set bus width to 4 bits mode */
917 /* set CMD6 argument Access field to 3, Index to 183, Value to 1 (4-bit mode) */
918 param = (3ul << 24) | (183ul << 16) | (1ul << 8);
919 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) != Successful)
920 {
921 return status;
922 }
923 if (SDH_CheckRB(sdh) != Successful)
924 {
925 return SDH_ERR_TIMEOUT;
926 }
927
928 sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
929
930 }
931
932 if ((status = SDH_SDCmdAndRsp(sdh, 16ul, SDH_BLOCK_SIZE, 0ul)) != Successful)
933 {
934 return status;
935 }
936 sdh->BLEN = SDH_BLOCK_SIZE - 1ul;
937
938 SDH_SDCommand(sdh, 7ul, 0ul);
939 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
940 u32TimeOutCount = SDH_TIMEOUT_CNT;
942 {
943 if (--u32TimeOutCount == 0)
944 {
946 break;
947 }
948 }
949
950 if (pSD->i32ErrCode != 0)
951 return Fail;
952
954
955 return Successful;
956}
957
958void SDH_Get_SD_info(SDH_T *sdh)
959{
960 unsigned int R_LEN, C_Size, MULT, size;
961 uint32_t Buffer[4];
962 //unsigned char *ptr;
963 SDH_INFO_T *pSD;
964 uint32_t u32TimeOutCount = SDH_TIMEOUT_CNT;
965
966 if (sdh == SDH0)
967 {
968 pSD = &SD0;
969 }
970 else
971 {
972 pSD = &SD1;
973 }
974
975 pSD->i32ErrCode = 0;
976
977 SDH_SDCmdAndRsp2(sdh, 9ul, pSD->RCA, Buffer);
978
979 if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
980 {
981 /* for MMC/eMMC card */
982 if ((Buffer[0] & 0xc0000000) == 0xc0000000)
983 {
984 /* CSD_STRUCTURE [127:126] is 3 */
985 /* CSD version depend on EXT_CSD register in eMMC v4.4 for card size > 2GB */
986 SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul);
987
988 //ptr = (uint8_t *)((uint32_t)_SDH_ucSDHCBuffer );
989 sdh->DMASA = (uint32_t)pSD->dmabuf;;
990 sdh->BLEN = 511ul; /* read 512 bytes for EXT_CSD */
991
992 if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) == Successful)
993 {
994 SDH_SDCommand(sdh, 7ul, 0ul);
995 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
997 {
998 if (--u32TimeOutCount == 0)
999 {
1001 break;
1002 }
1003 }
1004
1005 pSD->totalSectorN = (uint32_t)(*(pSD->dmabuf+215))<<24;
1006 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+214))<<16;
1007 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+213))<<8;
1008 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+212));
1009 pSD->diskSize = pSD->totalSectorN / 2ul;
1010 }
1011 }
1012 else
1013 {
1014 /* CSD version v1.0/1.1/1.2 in eMMC v4.4 spec for card size <= 2GB */
1015 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1016 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1017 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1018 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1019
1020 pSD->diskSize = size / 1024ul;
1021 pSD->totalSectorN = size / 512ul;
1022 }
1023 }
1024 else
1025 {
1026 if ((Buffer[0] & 0xc0000000) != 0x0ul)
1027 {
1028 C_Size = ((Buffer[1] & 0x0000003ful) << 16) | ((Buffer[2] & 0xffff0000ul) >> 16);
1029 size = (C_Size+1ul) * 512ul; /* Kbytes */
1030
1031 pSD->diskSize = size;
1032 pSD->totalSectorN = size << 1;
1033 }
1034 else
1035 {
1036 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1037 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1038 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1039 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1040
1041 pSD->diskSize = size / 1024ul;
1042 pSD->totalSectorN = size / 512ul;
1043 }
1044 }
1045 pSD->sectorSize = (int)512;
1046}
1047
1048int32_t SDH_ResetCard(SDH_T *sdh)
1049{
1050 int ret;
1051 uint32_t volatile i;
1052 SDH_INFO_T *pSD;
1053 uint32_t u32TimeOutCount;
1054
1055 sdh->GINTEN = 0ul;
1056 sdh->CTL &= ~SDH_CTL_SDNWR_Msk;
1057 sdh->CTL |= 0x09ul << SDH_CTL_SDNWR_Pos; /* set SDNWR = 9 */
1058 sdh->CTL &= ~SDH_CTL_BLKCNT_Msk;
1059 sdh->CTL |= 0x01ul << SDH_CTL_BLKCNT_Pos; /* set BLKCNT = 1 */
1060 sdh->CTL &= ~SDH_CTL_DBW_Msk; /* SD 1-bit data bus */
1061
1062 if (sdh == SDH0)
1063 {
1064 pSD = &SD0;
1065 }
1066 else
1067 {
1068 pSD = &SD1;
1069 }
1070
1071 pSD->i32ErrCode = 0;
1072
1073 /* set the clock to 300KHz */
1074 SDH_Set_clock(sdh, 300ul);
1075
1076 /* power ON 74 clock */
1077 sdh->CTL |= SDH_CTL_CLK74OEN_Msk;
1078
1079 u32TimeOutCount = SDH_TIMEOUT_CNT;
1081 {
1082 if (--u32TimeOutCount == 0)
1083 {
1085 return SDH_ERR_TIMEOUT;
1086 }
1087 }
1088 ret = SDH_SDCommand(sdh, 0ul, 0ul);
1089 for (i=0x1000ul; i>0ul; i--)
1090 {
1091 }
1092 return ret;
1093}
1094
1106void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
1107{
1108 uint32_t u32TimeOutCount;
1109 volatile int i;
1110 SDH_INFO_T *pSD;
1111
1112 if (sdh == SDH0)
1113 {
1114 pSD = &SD0;
1115 }
1116 else
1117 {
1118 pSD = &SD1;
1119 }
1120
1121 pSD->i32ErrCode = 0;
1122
1124 u32TimeOutCount = SDH_TIMEOUT_CNT;
1126 {
1127 if (--u32TimeOutCount == 0)
1128 {
1130 break;
1131 }
1132 }
1133
1135
1137 u32TimeOutCount = SDH_TIMEOUT_CNT;
1139 {
1140 if (--u32TimeOutCount == 0)
1141 {
1143 break;
1144 }
1145 }
1146
1147 if (sdh == SDH0)
1148 {
1149 NVIC_EnableIRQ(SDH0_IRQn);
1150 memset(&SD0, 0, sizeof(SDH_INFO_T));
1151 SD0.dmabuf = _SDH0_ucSDHCBuffer;
1152 }
1153 else if (sdh == SDH1)
1154 {
1155 NVIC_EnableIRQ(SDH1_IRQn);
1156 memset(&SD1, 0, sizeof(SDH_INFO_T));
1157 SD1.dmabuf = _SDH1_ucSDHCBuffer;
1158 }
1159 else
1160 {
1161 }
1162
1163 sdh->GCTL = SDH_GCTL_SDEN_Msk;
1164
1165 if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
1166 {
1167 sdh->INTEN &= ~SDH_INTEN_CDSRC_Msk;
1168 }
1169 else
1170 {
1171 sdh->INTEN |= SDH_INTEN_CDSRC_Msk;
1172 }
1173
1174 for (i = 0; i < 0x100; i++);
1176
1177 if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
1178 {
1179 /* Use polling mode. */
1180 sdh->INTEN &= ~SDH_INTEN_CDIEN_Msk;
1181 }
1182 else
1183 {
1184 sdh->INTEN |= SDH_INTEN_CDIEN_Msk;
1185 }
1186
1187 sdh->CTL |= SDH_CTL_CTLRST_Msk;
1188 u32TimeOutCount = SDH_TIMEOUT_CNT;
1189 while ((sdh->CTL & SDH_CTL_CTLRST_Msk) == SDH_CTL_CTLRST_Msk)
1190 {
1191 if (--u32TimeOutCount == 0)
1192 {
1194 break;
1195 }
1196 }
1197
1198 if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
1199 {
1200 /* Forcefully reset the SD card state to idle to prevent DAT3 voltage in an unexpected level due to transmission terminated. */
1201 SDH_ResetCard(sdh);
1202 }
1203}
1204
1216uint32_t SDH_Probe(SDH_T *sdh)
1217{
1218 uint32_t val;
1219
1220 sdh->GINTEN = 0ul;
1221 sdh->CTL &= ~SDH_CTL_SDNWR_Msk;
1222 sdh->CTL |= 0x09ul << SDH_CTL_SDNWR_Pos; /* set SDNWR = 9 */
1223 sdh->CTL &= ~SDH_CTL_BLKCNT_Msk;
1224 sdh->CTL |= 0x01ul << SDH_CTL_BLKCNT_Pos; /* set BLKCNT = 1 */
1225 sdh->CTL &= ~SDH_CTL_DBW_Msk; /* SD 1-bit data bus */
1226
1227 if(!(SDH_CardDetection(sdh)))
1228 {
1229 return SDH_NO_SD_CARD;
1230 }
1231
1232 if ((val = SDH_Init(sdh)) != 0ul)
1233 {
1234 return val;
1235 }
1236
1237 /* divider */
1238 if ((SD0.CardType == SDH_TYPE_MMC) || (SD1.CardType == SDH_TYPE_MMC))
1239 {
1240 SDH_Set_clock(sdh, MMC_FREQ);
1241 }
1242 else
1243 {
1244 SDH_Set_clock(sdh, SD_FREQ);
1245 }
1246 SDH_Get_SD_info(sdh);
1247
1248 if ((val = SDH_SelectCardType(sdh)) != 0ul)
1249 {
1250 return val;
1251 }
1252
1253 return 0ul;
1254}
1255
1266int32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1267{
1268 uint32_t volatile bIsSendCmd = FALSE, buf;
1269 uint32_t volatile reg;
1270 uint32_t volatile i, loop, status;
1271 uint32_t blksize = SDH_BLOCK_SIZE;
1272 uint32_t u32TimeOutCount;
1273
1274 SDH_INFO_T *pSD;
1275
1276 if (sdh == SDH0)
1277 {
1278 pSD = &SD0;
1279 }
1280 else
1281 {
1282 pSD = &SD1;
1283 }
1284
1285 pSD->i32ErrCode = 0;
1286
1287 if (u32SecCount == 0ul)
1288 {
1289 return SDH_SELECT_ERROR;
1290 }
1291
1292 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
1293 {
1294 return status;
1295 }
1296
1297 if (SDH_CheckRB(sdh) != Successful)
1298 {
1299 return SDH_ERR_TIMEOUT;
1300 }
1301
1302 sdh->BLEN = blksize - 1ul; /* the actual byte count is equal to (SDBLEN+1) */
1303
1304 if ( (pSD->CardType == SDH_TYPE_SD_HIGH) || (pSD->CardType == SDH_TYPE_EMMC) )
1305 {
1306 sdh->CMDARG = u32StartSec;
1307 }
1308 else
1309 {
1310 sdh->CMDARG = u32StartSec * blksize;
1311 }
1312
1313 sdh->DMASA = (uint32_t)pu8BufAddr;
1314
1315 loop = u32SecCount / 255ul;
1316 for (i=0ul; i<loop; i++)
1317 {
1318 pSD->DataReadyFlag = (uint8_t)FALSE;
1319 reg = sdh->CTL & ~SDH_CTL_CMDCODE_Msk;
1320 reg = reg | 0xff0000ul; /* set BLK_CNT to 255 */
1321 if (bIsSendCmd == FALSE)
1322 {
1323 sdh->CTL = reg|(18ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
1324 bIsSendCmd = TRUE;
1325 }
1326 else
1327 {
1328 sdh->CTL = reg | SDH_CTL_DIEN_Msk;
1329 }
1330
1331 u32TimeOutCount = SDH_TIMEOUT_CNT;
1332 while(!pSD->DataReadyFlag)
1333 {
1334 if (pSD->DataReadyFlag)
1335 {
1336 break;
1337 }
1338 if (pSD->IsCardInsert == FALSE)
1339 {
1340 return SDH_NO_SD_CARD;
1341 }
1342 if (--u32TimeOutCount == 0)
1343 {
1345 break;
1346 }
1347 }
1348
1349 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) != SDH_INTSTS_CRC7_Msk) /* check CRC7 */
1350 {
1351 return SDH_CRC7_ERROR;
1352 }
1353
1354 if ((sdh->INTSTS & SDH_INTSTS_CRC16_Msk) != SDH_INTSTS_CRC16_Msk) /* check CRC16 */
1355 {
1356 return SDH_CRC16_ERROR;
1357 }
1358 }
1359
1360 loop = u32SecCount % 255ul;
1361 if (loop != 0ul)
1362 {
1363 pSD->DataReadyFlag = (uint8_t)FALSE;
1364 reg = sdh->CTL & (~SDH_CTL_CMDCODE_Msk);
1365 reg = reg & (~SDH_CTL_BLKCNT_Msk);
1366 reg |= (loop << 16); /* setup SDCR_BLKCNT */
1367
1368 if (bIsSendCmd == FALSE)
1369 {
1370 sdh->CTL = reg|(18ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
1371 bIsSendCmd = TRUE;
1372 }
1373 else
1374 {
1375 sdh->CTL = reg | SDH_CTL_DIEN_Msk;
1376 }
1377
1378 u32TimeOutCount = SDH_TIMEOUT_CNT;
1379 while(!pSD->DataReadyFlag)
1380 {
1381 if (pSD->IsCardInsert == FALSE)
1382 {
1383 return SDH_NO_SD_CARD;
1384 }
1385 if (--u32TimeOutCount == 0)
1386 {
1388 break;
1389 }
1390 }
1391
1392 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) != SDH_INTSTS_CRC7_Msk) /* check CRC7 */
1393 {
1394 return SDH_CRC7_ERROR;
1395 }
1396
1397 if ((sdh->INTSTS & SDH_INTSTS_CRC16_Msk) != SDH_INTSTS_CRC16_Msk) /* check CRC16 */
1398 {
1399 return SDH_CRC16_ERROR;
1400 }
1401 }
1402
1403 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul)) /* stop command */
1404 {
1405 return SDH_CRC7_ERROR;
1406 }
1407
1408 if (SDH_CheckRB(sdh) != Successful)
1409 {
1410 return SDH_ERR_TIMEOUT;
1411 }
1412
1413 SDH_SDCommand(sdh, 7ul, 0ul);
1414 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
1415 u32TimeOutCount = SDH_TIMEOUT_CNT;
1416 while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
1417 {
1418 if (--u32TimeOutCount == 0)
1419 {
1421 break;
1422 }
1423 }
1424
1425 if (pSD->i32ErrCode != 0)
1426 return Fail;
1427
1428 return Successful;
1429}
1430
1431
1446int32_t SDH_Write(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1447{
1448 uint32_t volatile bIsSendCmd = FALSE;
1449 uint32_t volatile reg;
1450 uint32_t volatile i, loop, status;
1451 uint32_t u32TimeOutCount;
1452
1453 SDH_INFO_T *pSD;
1454
1455 if (sdh == SDH0)
1456 {
1457 pSD = &SD0;
1458 }
1459 else
1460 {
1461 pSD = &SD1;
1462 }
1463
1464 pSD->i32ErrCode = 0;
1465
1466 if (u32SecCount == 0ul)
1467 {
1468 return SDH_SELECT_ERROR;
1469 }
1470
1471 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
1472 {
1473 return status;
1474 }
1475
1476 if (SDH_CheckRB(sdh) != Successful)
1477 {
1478 return SDH_ERR_TIMEOUT;
1479 }
1480
1481 /* According to SD Spec v2.0, the write CMD block size MUST be 512, and the start address MUST be 512*n. */
1482 sdh->BLEN = SDH_BLOCK_SIZE - 1ul;
1483
1484 if ((pSD->CardType == SDH_TYPE_SD_HIGH) || (pSD->CardType == SDH_TYPE_EMMC))
1485 {
1486 sdh->CMDARG = u32StartSec;
1487 }
1488 else
1489 {
1490 sdh->CMDARG = u32StartSec * SDH_BLOCK_SIZE; /* set start address for SD CMD */
1491 }
1492
1493 sdh->DMASA = (uint32_t)pu8BufAddr;
1494 loop = u32SecCount / 255ul; /* the maximum block count is 0xFF=255 for register SDCR[BLK_CNT] */
1495 for (i=0ul; i<loop; i++)
1496 {
1497 pSD->DataReadyFlag = (uint8_t)FALSE;
1498 reg = sdh->CTL & 0xff00c080;
1499 reg = reg | 0xff0000ul; /* set BLK_CNT to 0xFF=255 */
1500 if (!bIsSendCmd)
1501 {
1502 sdh->CTL = reg|(25ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
1503 bIsSendCmd = TRUE;
1504 }
1505 else
1506 {
1507 sdh->CTL = reg | SDH_CTL_DOEN_Msk;
1508 }
1509
1510 u32TimeOutCount = SDH_TIMEOUT_CNT;
1511 while(!pSD->DataReadyFlag)
1512 {
1513 if (pSD->IsCardInsert == FALSE)
1514 {
1515 return SDH_NO_SD_CARD;
1516 }
1517 if (--u32TimeOutCount == 0)
1518 {
1520 break;
1521 }
1522 }
1523
1524 if ((sdh->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0ul)
1525 {
1527 return SDH_CRC_ERROR;
1528 }
1529 }
1530
1531 loop = u32SecCount % 255ul;
1532 if (loop != 0ul)
1533 {
1534 pSD->DataReadyFlag = (uint8_t)FALSE;
1535 reg = (sdh->CTL & 0xff00c080) | (loop << 16);
1536 if (!bIsSendCmd)
1537 {
1538 sdh->CTL = reg|(25ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
1539 bIsSendCmd = TRUE;
1540 }
1541 else
1542 {
1543 sdh->CTL = reg | SDH_CTL_DOEN_Msk;
1544 }
1545
1546 u32TimeOutCount = SDH_TIMEOUT_CNT;
1547 while(!pSD->DataReadyFlag)
1548 {
1549 if (pSD->IsCardInsert == FALSE)
1550 {
1551 return SDH_NO_SD_CARD;
1552 }
1553 if (--u32TimeOutCount == 0)
1554 {
1556 break;
1557 }
1558 }
1559
1560 if ((sdh->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0ul)
1561 {
1563 return SDH_CRC_ERROR;
1564 }
1565 }
1567
1568 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul)) /* stop command */
1569 {
1570 return SDH_CRC7_ERROR;
1571 }
1572
1573 if (SDH_CheckRB(sdh) != Successful)
1574 {
1575 return SDH_ERR_TIMEOUT;
1576 }
1577
1578 SDH_SDCommand(sdh, 7ul, 0ul);
1579 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
1580 u32TimeOutCount = SDH_TIMEOUT_CNT;
1581 while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
1582 {
1583 if (--u32TimeOutCount == 0)
1584 {
1586 break;
1587 }
1588 }
1589
1590 if (pSD->i32ErrCode != 0)
1591 return Fail;
1592
1593 return Successful;
1594}
1595 /* end of group SDH_EXPORTED_FUNCTIONS */
1597 /* end of group SDH_Driver */
1599 /* end of group Standard_Driver */
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:1201
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 SDH_INTSTS_CDIF_Msk
Definition: sdh_reg.h:919
#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 SDH_TIMEOUT_CNT
Definition: sdh.h:71
#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_ERR_TIMEOUT
Definition: sdh.h:74
#define SDH_SELECT_ERROR
Definition: sdh.h:53
unsigned int RCA
Definition: sdh.h:88
int32_t i32ErrCode
Definition: sdh.h:93
int32_t SDH_CardDetection(SDH_T *sdh)
uint32_t SDH_Probe(SDH_T *sdh)
This function use to initial SD card.
Definition: sdh.c:1216
unsigned char volatile DataReadyFlag
Definition: sdh.h:86
int32_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:1266
#define SDH_BLOCK_SIZE
Definition: sdh.c:25
int sectorSize
Definition: sdh.h:91
unsigned int diskSize
Definition: sdh.h:90
unsigned char IsCardInsert
Definition: sdh.h:83
unsigned char R3Flag
Definition: sdh.h:84
unsigned int totalSectorN
Definition: sdh.h:89
unsigned char R7Flag
Definition: sdh.h:85
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:1106
unsigned int CardType
Definition: sdh.h:87
int32_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:1446
unsigned char * dmabuf
Definition: sdh.h:92
__STATIC_INLINE void SYS_LockReg(void)
Enable register write-protection function.
Definition: sys.h:1604
uint32_t SYS_IsRegLocked(void)
Check if register is locked nor not.
Definition: sys.c:79
__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:82
#define __HIRC
Definition: system_M480.h:36