M480 BSP V3.0.7000
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;
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 if ((CLK->PWRCTL & CLK_PWRCTL_HIRCEN_Msk) != 0x4ul)
378 {
379 CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
380 }
381
382 if (sdh == SDH0)
383 {
384 u32SD_ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_SDH0SEL_Msk);
385 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | CLK_CLKSEL0_SDH0SEL_HIRC;
386 _SDH0_ReferenceClock = (__HIRC / 1000ul);
387 }
388 else
389 {
390 u32SD_ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_SDH1SEL_Msk);
391 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | CLK_CLKSEL0_SDH1SEL_HIRC;
392 _SDH1_ReferenceClock = (__HIRC / 1000ul);
393 }
394 }
395 /* transfer state, clock source use sys_init() */
396 else
397 {
398 if (sdh == SDH0)
399 {
400 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | u32SD_ClkSrc;
401 if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HXT)
402 {
403 _SDH0_ReferenceClock = (CLK_GetHXTFreq() / 1000ul);
404 }
405 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HIRC)
406 {
407 _SDH0_ReferenceClock = (__HIRC / 1000ul);
408 }
409 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_PLL)
410 {
411 _SDH0_ReferenceClock = (CLK_GetPLLClockFreq() / 1000ul);
412 }
413 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH0SEL_HCLK)
414 {
415 _SDH0_ReferenceClock = (CLK_GetHCLKFreq() / 1000ul);
416 }
417 }
418 else
419 {
420 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | u32SD_ClkSrc;
421 if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HXT)
422 {
423 _SDH1_ReferenceClock = (CLK_GetHXTFreq() / 1000ul);
424 }
425 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HIRC)
426 {
427 _SDH1_ReferenceClock = (__HIRC / 1000ul);
428 }
429 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_PLL)
430 {
431 _SDH1_ReferenceClock = (CLK_GetPLLClockFreq() / 1000ul);
432 }
433 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDH1SEL_HCLK)
434 {
435 _SDH1_ReferenceClock = (CLK_GetHCLKFreq() / 1000ul);
436 }
437 }
438
439 if(sd_clock_khz >= 50000ul)
440 {
441 sd_clock_khz = 50000ul;
442 }
443 }
444 if (sdh == SDH0)
445 {
446 rate = _SDH0_ReferenceClock / sd_clock_khz;
447
448 /* choose slower clock if system clock cannot divisible by wanted clock */
449 if ((_SDH0_ReferenceClock % sd_clock_khz) != 0ul)
450 {
451 rate++;
452 }
453 }
454 else
455 {
456 rate = _SDH1_ReferenceClock / sd_clock_khz;
457
458 /* choose slower clock if system clock cannot divisible by wanted clock */
459 if ((_SDH1_ReferenceClock % sd_clock_khz) != 0ul)
460 {
461 rate++;
462 }
463 }
464
465 if(rate >= SDH_CLK_DIV0_MAX)
466 {
467 rate = SDH_CLK_DIV0_MAX;
468 }
469
470 /*--- calculate the second divider CLKDIV0[SDHOST_N]*/
471 div1 = (rate - 1ul) & 0xFFul;
472
473 /*--- setup register */
474 if (sdh == SDH0)
475 {
476 CLK->CLKDIV0 &= ~CLK_CLKDIV0_SDH0DIV_Msk;
477 CLK->CLKDIV0 |= (div1 << CLK_CLKDIV0_SDH0DIV_Pos);
478 }
479 else
480 {
481 CLK->CLKDIV3 &= ~CLK_CLKDIV3_SDH1DIV_Msk;
482 CLK->CLKDIV3 |= (div1 << CLK_CLKDIV3_SDH1DIV_Pos);
483 }
484
485 if (u32RegLockLevel)
486 {
487 SYS_LockReg();
488 }
489
490 return;
491}
492
493int32_t SDH_CardDetection(SDH_T *sdh)
494{
495 volatile uint32_t i;
496 uint32_t val = TRUE;
497 SDH_INFO_T *pSD;
498
499 if (sdh == SDH0)
500 {
501 pSD = &SD0;
502 }
503 else
504 {
505 pSD = &SD1;
506 }
507
508
509 if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) == SDH_INTEN_CDSRC_Msk) /* Card detect pin from GPIO */
510 {
511 sdh->CTL &= ~SDH_CTL_CLKKEEP_Msk;
512
513 if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk) /* Card remove */
514 {
515 pSD->IsCardInsert = (uint8_t)FALSE;
516 val = FALSE;
517 }
518 else
519 {
520 pSD->IsCardInsert = (uint8_t)TRUE;
521 }
522 }
523 else if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) != SDH_INTEN_CDSRC_Msk)
524 {
525 sdh->CTL |= SDH_CTL_CLKKEEP_Msk;
526
527 for (i = 0ul; i < 5000ul; i++)
528 {
529 __NOP();
530 }
531
532 if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk) /* Card insert */
533 {
534 pSD->IsCardInsert = (uint8_t)TRUE;
535 }
536 else
537 {
538 pSD->IsCardInsert = (uint8_t)FALSE;
539 val = FALSE;
540 }
541
542 sdh->CTL &= ~SDH_CTL_CLKKEEP_Msk;
543 }
544
545 return val;
546}
547
548uint32_t SDH_Init(SDH_T *sdh)
549{
550 uint32_t volatile i, status;
551 uint32_t resp;
552 uint32_t CIDBuffer[4];
553 uint32_t volatile u32CmdTimeOut;
554 SDH_INFO_T *pSD;
555 uint32_t u32TimeOutCount;
556
557 if (sdh == SDH0)
558 {
559 pSD = &SD0;
560 }
561 else
562 {
563 pSD = &SD1;
564 }
565
566 pSD->i32ErrCode = 0;
567
568 /* set the clock to 300KHz */
569 SDH_Set_clock(sdh, 300ul);
570
571 /* power ON 74 clock */
573
574 u32TimeOutCount = SDH_TIMEOUT_CNT;
576 {
577 if (pSD->IsCardInsert == FALSE)
578 {
579 return SDH_NO_SD_CARD;
580 }
581 if (--u32TimeOutCount == 0)
582 {
584 break;
585 }
586 }
587
588 SDH_SDCommand(sdh, 0ul, 0ul); /* reset all cards */
589 for (i=0x1000ul; i>0ul; i--)
590 {
591 }
592
593 /* initial SDHC */
594 pSD->R7Flag = 1ul;
595 u32CmdTimeOut = 0xFFFFFul;
596
597 i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
598 if (i == Successful)
599 {
600 /* SD 2.0 */
601 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
602 pSD->R3Flag = 1ul;
603 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 2.7v-3.6v */
604 resp = sdh->RESP0;
605
606 u32TimeOutCount = SDH_TIMEOUT_CNT;
607 while ((resp & 0x00800000ul) != 0x00800000ul) /* check if card is ready */
608 {
609 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
610 pSD->R3Flag = 1ul;
611 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
612 resp = sdh->RESP0;
613 if (--u32TimeOutCount == 0)
614 {
616 break;
617 }
618 }
619 if ((resp & 0x00400000ul) == 0x00400000ul)
620 {
622 }
623 else
624 {
626 }
627 }
628 else
629 {
630 /* SD 1.1 */
631 SDH_SDCommand(sdh, 0ul, 0ul); /* reset all cards */
632 for (i=0x100ul; i>0ul; i--)
633 {
634 }
635
636 i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
637 if (i == 2ul) /* MMC memory */
638 {
639
640 SDH_SDCommand(sdh, 0ul, 0ul); /* reset */
641 for (i=0x100ul; i>0ul; i--)
642 {
643 }
644
645 pSD->R3Flag = 1ul;
646
647 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul) /* eMMC memory */
648 {
649 resp = sdh->RESP0;
650 u32TimeOutCount = SDH_TIMEOUT_CNT;
651 while ((resp & 0x00800000ul) != 0x00800000ul)
652 {
653 /* check if card is ready */
654 pSD->R3Flag = 1ul;
655
656 SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut); /* high voltage */
657 resp = sdh->RESP0;
658
659 if (--u32TimeOutCount == 0)
660 {
662 break;
663 }
664 }
665
666 if ((resp & 0x00400000ul) == 0x00400000ul)
667 {
668 pSD->CardType = SDH_TYPE_EMMC;
669 }
670 else
671 {
672 pSD->CardType = SDH_TYPE_MMC;
673 }
674 }
675 else
676 {
678 return SDH_ERR_DEVICE;
679 }
680 }
681 else if (i == 0ul) /* SD Memory */
682 {
683 pSD->R3Flag = 1ul;
684 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
685 resp = sdh->RESP0;
686 u32TimeOutCount = SDH_TIMEOUT_CNT;
687 while ((resp & 0x00800000ul) != 0x00800000ul) /* check if card is ready */
688 {
689 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
690 pSD->R3Flag = 1ul;
691 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
692 resp = sdh->RESP0;
693 if (--u32TimeOutCount == 0)
694 {
696 break;
697 }
698 }
700 }
701 else
702 {
704 return SDH_INIT_ERROR;
705 }
706 }
707
708 if (pSD->CardType != SDH_TYPE_UNKNOWN)
709 {
710 SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
711 if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
712 {
713 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) != Successful) /* set RCA */
714 {
715 return status;
716 }
717 pSD->RCA = 0x10000ul;
718 }
719 else
720 {
721 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) != Successful) /* get RCA */
722 {
723 return status;
724 }
725 else
726 {
727 pSD->RCA = (sdh->RESP0 << 8) & 0xffff0000;
728 }
729 }
730 }
731
732 if (pSD->i32ErrCode != 0)
733 return Fail;
734
735 return Successful;
736}
737
738
739uint32_t SDH_SwitchToHighSpeed(SDH_T *sdh, SDH_INFO_T *pSD)
740{
741 uint32_t volatile status=0ul;
742 uint16_t current_comsumption, busy_status0;
743 uint32_t u32TimeOutCount = SDH_TIMEOUT_CNT;
744
745 pSD->i32ErrCode = 0;
746
747 sdh->DMASA = (uint32_t)pSD->dmabuf;
748 sdh->BLEN = 63ul;
749
750 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) != Successful)
751 {
752 return Fail;
753 }
754
755 current_comsumption = (uint16_t)(*pSD->dmabuf) << 8;
756 current_comsumption |= (uint16_t)(*(pSD->dmabuf + 1));
757 if (!current_comsumption)
758 {
759 return Fail;
760 }
761
762 busy_status0 = (uint16_t)(*(pSD->dmabuf + 28)) << 8;
763 busy_status0 |= (uint16_t)(*(pSD->dmabuf + 29));
764
765 if (!busy_status0) /* function ready */
766 {
767 sdh->DMASA = (uint32_t)pSD->dmabuf;
768 sdh->BLEN = 63ul; /* 512 bit */
769
770 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) != Successful)
771 {
772 return Fail;
773 }
774
775 /* function change timing: 8 clocks */
776 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
778 {
779 if (--u32TimeOutCount == 0)
780 {
782 break;
783 }
784 }
785
786 if (pSD->i32ErrCode != 0)
787 return Fail;
788
789 current_comsumption = (uint16_t)(*pSD->dmabuf) << 8;
790 current_comsumption |= (uint16_t)(*(pSD->dmabuf + 1));
791 if (!current_comsumption)
792 {
793 return Fail;
794 }
795
796 return Successful;
797 }
798 else
799 {
800 return Fail;
801 }
802}
803
804
805int32_t SDH_SelectCardType(SDH_T *sdh)
806{
807 uint32_t volatile status=0ul;
808 uint32_t param;
809 SDH_INFO_T *pSD;
810 uint32_t u32TimeOutCount;
811
812 if (sdh == SDH0)
813 {
814 pSD = &SD0;
815 }
816 else
817 {
818 pSD = &SD1;
819 }
820
821 pSD->i32ErrCode = 0;
822
823 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
824 {
825 return status;
826 }
827
828 if (SDH_CheckRB(sdh) != Successful)
829 {
830 return SDH_ERR_TIMEOUT;
831 }
832
833 /* if SD card set 4bit */
834 if (pSD->CardType == SDH_TYPE_SD_HIGH)
835 {
836 sdh->DMASA = (uint32_t)pSD->dmabuf;
837 sdh->BLEN = 0x07ul; /* 64 bit */
839 u32TimeOutCount = SDH_TIMEOUT_CNT;
840 while ((sdh->DMACTL & SDH_DMACTL_DMARST_Msk) == 0x2)
841 {
842 if (--u32TimeOutCount == 0)
843 {
845 break;
846 }
847 }
848
849 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
850 {
851 return status;
852 }
853 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
854 {
855 return status;
856 }
857
858 if ((*pSD->dmabuf & 0xful) == 0x2ul)
859 {
860 status = SDH_SwitchToHighSpeed(sdh, pSD);
861 if (status == Successful)
862 {
863 /* divider */
864 SDH_Set_clock(sdh, SDHC_FREQ);
865 }
866 }
867
868 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
869 {
870 return status;
871 }
872 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful) /* set bus width */
873 {
874 return status;
875 }
876
877 sdh->CTL |= SDH_CTL_DBW_Msk;
878 }
879 else if (pSD->CardType == SDH_TYPE_SD_LOW)
880 {
881 sdh->DMASA = (uint32_t)pSD->dmabuf;;
882 sdh->BLEN = 0x07ul;
883
884 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
885 {
886 return status;
887 }
888 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
889 {
890 return status;
891 }
892
893 /* set data bus width. ACMD6 for SD card, SDCR_DBW for host. */
894 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
895 {
896 return status;
897 }
898
899 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful)
900 {
901 return status;
902 }
903
904 sdh->CTL |= SDH_CTL_DBW_Msk;
905 }
906 else if ((pSD->CardType == SDH_TYPE_MMC) ||(pSD->CardType == SDH_TYPE_EMMC))
907 {
908
909 if(pSD->CardType == SDH_TYPE_MMC)
910 {
911 sdh->CTL &= ~SDH_CTL_DBW_Msk;
912 }
913
914 /*--- sent CMD6 to MMC card to set bus width to 4 bits mode */
915 /* set CMD6 argument Access field to 3, Index to 183, Value to 1 (4-bit mode) */
916 param = (3ul << 24) | (183ul << 16) | (1ul << 8);
917 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) != Successful)
918 {
919 return status;
920 }
921 if (SDH_CheckRB(sdh) != Successful)
922 {
923 return SDH_ERR_TIMEOUT;
924 }
925
926 sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
927
928 }
929
930 if ((status = SDH_SDCmdAndRsp(sdh, 16ul, SDH_BLOCK_SIZE, 0ul)) != Successful)
931 {
932 return status;
933 }
934 sdh->BLEN = SDH_BLOCK_SIZE - 1ul;
935
936 SDH_SDCommand(sdh, 7ul, 0ul);
937 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
938 u32TimeOutCount = SDH_TIMEOUT_CNT;
940 {
941 if (--u32TimeOutCount == 0)
942 {
944 break;
945 }
946 }
947
948 if (pSD->i32ErrCode != 0)
949 return Fail;
950
952
953 return Successful;
954}
955
956void SDH_Get_SD_info(SDH_T *sdh)
957{
958 unsigned int R_LEN, C_Size, MULT, size;
959 uint32_t Buffer[4];
960 //unsigned char *ptr;
961 SDH_INFO_T *pSD;
962 uint32_t u32TimeOutCount = SDH_TIMEOUT_CNT;
963
964 if (sdh == SDH0)
965 {
966 pSD = &SD0;
967 }
968 else
969 {
970 pSD = &SD1;
971 }
972
973 pSD->i32ErrCode = 0;
974
975 SDH_SDCmdAndRsp2(sdh, 9ul, pSD->RCA, Buffer);
976
977 if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
978 {
979 /* for MMC/eMMC card */
980 if ((Buffer[0] & 0xc0000000) == 0xc0000000)
981 {
982 /* CSD_STRUCTURE [127:126] is 3 */
983 /* CSD version depend on EXT_CSD register in eMMC v4.4 for card size > 2GB */
984 SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul);
985
986 //ptr = (uint8_t *)((uint32_t)_SDH_ucSDHCBuffer );
987 sdh->DMASA = (uint32_t)pSD->dmabuf;;
988 sdh->BLEN = 511ul; /* read 512 bytes for EXT_CSD */
989
990 if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) == Successful)
991 {
992 SDH_SDCommand(sdh, 7ul, 0ul);
993 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
995 {
996 if (--u32TimeOutCount == 0)
997 {
999 break;
1000 }
1001 }
1002
1003 pSD->totalSectorN = (uint32_t)(*(pSD->dmabuf+215))<<24;
1004 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+214))<<16;
1005 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+213))<<8;
1006 pSD->totalSectorN |= (uint32_t)(*(pSD->dmabuf+212));
1007 pSD->diskSize = pSD->totalSectorN / 2ul;
1008 }
1009 }
1010 else
1011 {
1012 /* CSD version v1.0/1.1/1.2 in eMMC v4.4 spec for card size <= 2GB */
1013 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1014 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1015 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1016 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1017
1018 pSD->diskSize = size / 1024ul;
1019 pSD->totalSectorN = size / 512ul;
1020 }
1021 }
1022 else
1023 {
1024 if ((Buffer[0] & 0xc0000000) != 0x0ul)
1025 {
1026 C_Size = ((Buffer[1] & 0x0000003ful) << 16) | ((Buffer[2] & 0xffff0000ul) >> 16);
1027 size = (C_Size+1ul) * 512ul; /* Kbytes */
1028
1029 pSD->diskSize = size;
1030 pSD->totalSectorN = size << 1;
1031 }
1032 else
1033 {
1034 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1035 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1036 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1037 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1038
1039 pSD->diskSize = size / 1024ul;
1040 pSD->totalSectorN = size / 512ul;
1041 }
1042 }
1043 pSD->sectorSize = (int)512;
1044}
1045
1046int32_t SDH_ResetCard(SDH_T *sdh)
1047{
1048 int ret;
1049 uint32_t volatile i;
1050 SDH_INFO_T *pSD;
1051 uint32_t u32TimeOutCount;
1052
1053 sdh->GINTEN = 0ul;
1054 sdh->CTL &= ~SDH_CTL_SDNWR_Msk;
1055 sdh->CTL |= 0x09ul << SDH_CTL_SDNWR_Pos; /* set SDNWR = 9 */
1056 sdh->CTL &= ~SDH_CTL_BLKCNT_Msk;
1057 sdh->CTL |= 0x01ul << SDH_CTL_BLKCNT_Pos; /* set BLKCNT = 1 */
1058 sdh->CTL &= ~SDH_CTL_DBW_Msk; /* SD 1-bit data bus */
1059
1060 if (sdh == SDH0)
1061 {
1062 pSD = &SD0;
1063 }
1064 else
1065 {
1066 pSD = &SD1;
1067 }
1068
1069 pSD->i32ErrCode = 0;
1070
1071 /* set the clock to 300KHz */
1072 SDH_Set_clock(sdh, 300ul);
1073
1074 /* power ON 74 clock */
1075 sdh->CTL |= SDH_CTL_CLK74OEN_Msk;
1076
1077 u32TimeOutCount = SDH_TIMEOUT_CNT;
1079 {
1080 if (--u32TimeOutCount == 0)
1081 {
1083 return SDH_ERR_TIMEOUT;
1084 }
1085 }
1086 ret = SDH_SDCommand(sdh, 0ul, 0ul);
1087 for (i=0x1000ul; i>0ul; i--)
1088 {
1089 }
1090 return ret;
1091}
1092
1104void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
1105{
1106 uint32_t u32TimeOutCount;
1107 volatile int i;
1108 SDH_INFO_T *pSD;
1109
1110 if (sdh == SDH0)
1111 {
1112 pSD = &SD0;
1113 }
1114 else
1115 {
1116 pSD = &SD1;
1117 }
1118
1119 pSD->i32ErrCode = 0;
1120
1122 u32TimeOutCount = SDH_TIMEOUT_CNT;
1124 {
1125 if (--u32TimeOutCount == 0)
1126 {
1128 break;
1129 }
1130 }
1131
1133
1135 u32TimeOutCount = SDH_TIMEOUT_CNT;
1137 {
1138 if (--u32TimeOutCount == 0)
1139 {
1141 break;
1142 }
1143 }
1144
1145 if (sdh == SDH0)
1146 {
1147 NVIC_EnableIRQ(SDH0_IRQn);
1148 memset(&SD0, 0, sizeof(SDH_INFO_T));
1149 SD0.dmabuf = _SDH0_ucSDHCBuffer;
1150 }
1151 else if (sdh == SDH1)
1152 {
1153 NVIC_EnableIRQ(SDH1_IRQn);
1154 memset(&SD1, 0, sizeof(SDH_INFO_T));
1155 SD1.dmabuf = _SDH1_ucSDHCBuffer;
1156 }
1157 else
1158 {
1159 }
1160
1161 sdh->GCTL = SDH_GCTL_SDEN_Msk;
1162
1163 if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
1164 {
1165 sdh->INTEN &= ~SDH_INTEN_CDSRC_Msk;
1166 }
1167 else
1168 {
1169 sdh->INTEN |= SDH_INTEN_CDSRC_Msk;
1170 }
1171
1172 for (i = 0; i < 0x100; i++);
1174
1175 if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
1176 {
1177 /* Use polling mode. */
1178 sdh->INTEN &= ~SDH_INTEN_CDIEN_Msk;
1179 }
1180 else
1181 {
1182 sdh->INTEN |= SDH_INTEN_CDIEN_Msk;
1183 }
1184
1185 sdh->CTL |= SDH_CTL_CTLRST_Msk;
1186 u32TimeOutCount = SDH_TIMEOUT_CNT;
1187 while ((sdh->CTL & SDH_CTL_CTLRST_Msk) == SDH_CTL_CTLRST_Msk)
1188 {
1189 if (--u32TimeOutCount == 0)
1190 {
1192 break;
1193 }
1194 }
1195
1196 if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
1197 {
1198 /* Forcefully reset the SD card state to idle to prevent DAT3 voltage in an unexpected level due to transmission terminated. */
1199 SDH_ResetCard(sdh);
1200 }
1201}
1202
1214uint32_t SDH_Probe(SDH_T *sdh)
1215{
1216 uint32_t val;
1217
1218 sdh->GINTEN = 0ul;
1219 sdh->CTL &= ~SDH_CTL_SDNWR_Msk;
1220 sdh->CTL |= 0x09ul << SDH_CTL_SDNWR_Pos; /* set SDNWR = 9 */
1221 sdh->CTL &= ~SDH_CTL_BLKCNT_Msk;
1222 sdh->CTL |= 0x01ul << SDH_CTL_BLKCNT_Pos; /* set BLKCNT = 1 */
1223 sdh->CTL &= ~SDH_CTL_DBW_Msk; /* SD 1-bit data bus */
1224
1225 if(!(SDH_CardDetection(sdh)))
1226 {
1227 return SDH_NO_SD_CARD;
1228 }
1229
1230 if ((val = SDH_Init(sdh)) != 0ul)
1231 {
1232 return val;
1233 }
1234
1235 /* divider */
1236 if ((SD0.CardType == SDH_TYPE_MMC) || (SD1.CardType == SDH_TYPE_MMC))
1237 {
1238 SDH_Set_clock(sdh, MMC_FREQ);
1239 }
1240 else
1241 {
1242 SDH_Set_clock(sdh, SD_FREQ);
1243 }
1244 SDH_Get_SD_info(sdh);
1245
1246 if ((val = SDH_SelectCardType(sdh)) != 0ul)
1247 {
1248 return val;
1249 }
1250
1251 return 0ul;
1252}
1253
1264int32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1265{
1266 uint32_t volatile bIsSendCmd = FALSE, buf;
1267 uint32_t volatile reg;
1268 uint32_t volatile i, loop, status;
1269 uint32_t blksize = SDH_BLOCK_SIZE;
1270 uint32_t u32TimeOutCount;
1271
1272 SDH_INFO_T *pSD;
1273
1274 if (sdh == SDH0)
1275 {
1276 pSD = &SD0;
1277 }
1278 else
1279 {
1280 pSD = &SD1;
1281 }
1282
1283 pSD->i32ErrCode = 0;
1284
1285 if (u32SecCount == 0ul)
1286 {
1287 return SDH_SELECT_ERROR;
1288 }
1289
1290 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
1291 {
1292 return status;
1293 }
1294
1295 if (SDH_CheckRB(sdh) != Successful)
1296 {
1297 return SDH_ERR_TIMEOUT;
1298 }
1299
1300 sdh->BLEN = blksize - 1ul; /* the actual byte count is equal to (SDBLEN+1) */
1301
1302 if ( (pSD->CardType == SDH_TYPE_SD_HIGH) || (pSD->CardType == SDH_TYPE_EMMC) )
1303 {
1304 sdh->CMDARG = u32StartSec;
1305 }
1306 else
1307 {
1308 sdh->CMDARG = u32StartSec * blksize;
1309 }
1310
1311 sdh->DMASA = (uint32_t)pu8BufAddr;
1312
1313 loop = u32SecCount / 255ul;
1314 for (i=0ul; i<loop; i++)
1315 {
1316 pSD->DataReadyFlag = (uint8_t)FALSE;
1317 reg = sdh->CTL & ~SDH_CTL_CMDCODE_Msk;
1318 reg = reg | 0xff0000ul; /* set BLK_CNT to 255 */
1319 if (bIsSendCmd == FALSE)
1320 {
1321 sdh->CTL = reg|(18ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
1322 bIsSendCmd = TRUE;
1323 }
1324 else
1325 {
1326 sdh->CTL = reg | SDH_CTL_DIEN_Msk;
1327 }
1328
1329 u32TimeOutCount = SDH_TIMEOUT_CNT;
1330 while(!pSD->DataReadyFlag)
1331 {
1332 if (pSD->DataReadyFlag)
1333 {
1334 break;
1335 }
1336 if (pSD->IsCardInsert == FALSE)
1337 {
1338 return SDH_NO_SD_CARD;
1339 }
1340 if (--u32TimeOutCount == 0)
1341 {
1343 break;
1344 }
1345 }
1346
1347 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) != SDH_INTSTS_CRC7_Msk) /* check CRC7 */
1348 {
1349 return SDH_CRC7_ERROR;
1350 }
1351
1352 if ((sdh->INTSTS & SDH_INTSTS_CRC16_Msk) != SDH_INTSTS_CRC16_Msk) /* check CRC16 */
1353 {
1354 return SDH_CRC16_ERROR;
1355 }
1356 }
1357
1358 loop = u32SecCount % 255ul;
1359 if (loop != 0ul)
1360 {
1361 pSD->DataReadyFlag = (uint8_t)FALSE;
1362 reg = sdh->CTL & (~SDH_CTL_CMDCODE_Msk);
1363 reg = reg & (~SDH_CTL_BLKCNT_Msk);
1364 reg |= (loop << 16); /* setup SDCR_BLKCNT */
1365
1366 if (bIsSendCmd == FALSE)
1367 {
1368 sdh->CTL = reg|(18ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
1369 bIsSendCmd = TRUE;
1370 }
1371 else
1372 {
1373 sdh->CTL = reg | SDH_CTL_DIEN_Msk;
1374 }
1375
1376 u32TimeOutCount = SDH_TIMEOUT_CNT;
1377 while(!pSD->DataReadyFlag)
1378 {
1379 if (pSD->IsCardInsert == FALSE)
1380 {
1381 return SDH_NO_SD_CARD;
1382 }
1383 if (--u32TimeOutCount == 0)
1384 {
1386 break;
1387 }
1388 }
1389
1390 if ((sdh->INTSTS & SDH_INTSTS_CRC7_Msk) != SDH_INTSTS_CRC7_Msk) /* check CRC7 */
1391 {
1392 return SDH_CRC7_ERROR;
1393 }
1394
1395 if ((sdh->INTSTS & SDH_INTSTS_CRC16_Msk) != SDH_INTSTS_CRC16_Msk) /* check CRC16 */
1396 {
1397 return SDH_CRC16_ERROR;
1398 }
1399 }
1400
1401 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul)) /* stop command */
1402 {
1403 return SDH_CRC7_ERROR;
1404 }
1405
1406 if (SDH_CheckRB(sdh) != Successful)
1407 {
1408 return SDH_ERR_TIMEOUT;
1409 }
1410
1411 SDH_SDCommand(sdh, 7ul, 0ul);
1412 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
1413 u32TimeOutCount = SDH_TIMEOUT_CNT;
1414 while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
1415 {
1416 if (--u32TimeOutCount == 0)
1417 {
1419 break;
1420 }
1421 }
1422
1423 if (pSD->i32ErrCode != 0)
1424 return Fail;
1425
1426 return Successful;
1427}
1428
1429
1444int32_t SDH_Write(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1445{
1446 uint32_t volatile bIsSendCmd = FALSE;
1447 uint32_t volatile reg;
1448 uint32_t volatile i, loop, status;
1449 uint32_t u32TimeOutCount;
1450
1451 SDH_INFO_T *pSD;
1452
1453 if (sdh == SDH0)
1454 {
1455 pSD = &SD0;
1456 }
1457 else
1458 {
1459 pSD = &SD1;
1460 }
1461
1462 pSD->i32ErrCode = 0;
1463
1464 if (u32SecCount == 0ul)
1465 {
1466 return SDH_SELECT_ERROR;
1467 }
1468
1469 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
1470 {
1471 return status;
1472 }
1473
1474 if (SDH_CheckRB(sdh) != Successful)
1475 {
1476 return SDH_ERR_TIMEOUT;
1477 }
1478
1479 /* According to SD Spec v2.0, the write CMD block size MUST be 512, and the start address MUST be 512*n. */
1480 sdh->BLEN = SDH_BLOCK_SIZE - 1ul;
1481
1482 if ((pSD->CardType == SDH_TYPE_SD_HIGH) || (pSD->CardType == SDH_TYPE_EMMC))
1483 {
1484 sdh->CMDARG = u32StartSec;
1485 }
1486 else
1487 {
1488 sdh->CMDARG = u32StartSec * SDH_BLOCK_SIZE; /* set start address for SD CMD */
1489 }
1490
1491 sdh->DMASA = (uint32_t)pu8BufAddr;
1492 loop = u32SecCount / 255ul; /* the maximum block count is 0xFF=255 for register SDCR[BLK_CNT] */
1493 for (i=0ul; i<loop; i++)
1494 {
1495 pSD->DataReadyFlag = (uint8_t)FALSE;
1496 reg = sdh->CTL & 0xff00c080;
1497 reg = reg | 0xff0000ul; /* set BLK_CNT to 0xFF=255 */
1498 if (!bIsSendCmd)
1499 {
1500 sdh->CTL = reg|(25ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
1501 bIsSendCmd = TRUE;
1502 }
1503 else
1504 {
1505 sdh->CTL = reg | SDH_CTL_DOEN_Msk;
1506 }
1507
1508 u32TimeOutCount = SDH_TIMEOUT_CNT;
1509 while(!pSD->DataReadyFlag)
1510 {
1511 if (pSD->IsCardInsert == FALSE)
1512 {
1513 return SDH_NO_SD_CARD;
1514 }
1515 if (--u32TimeOutCount == 0)
1516 {
1518 break;
1519 }
1520 }
1521
1522 if ((sdh->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0ul)
1523 {
1525 return SDH_CRC_ERROR;
1526 }
1527 }
1528
1529 loop = u32SecCount % 255ul;
1530 if (loop != 0ul)
1531 {
1532 pSD->DataReadyFlag = (uint8_t)FALSE;
1533 reg = (sdh->CTL & 0xff00c080) | (loop << 16);
1534 if (!bIsSendCmd)
1535 {
1536 sdh->CTL = reg|(25ul << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
1537 bIsSendCmd = TRUE;
1538 }
1539 else
1540 {
1541 sdh->CTL = reg | SDH_CTL_DOEN_Msk;
1542 }
1543
1544 u32TimeOutCount = SDH_TIMEOUT_CNT;
1545 while(!pSD->DataReadyFlag)
1546 {
1547 if (pSD->IsCardInsert == FALSE)
1548 {
1549 return SDH_NO_SD_CARD;
1550 }
1551 if (--u32TimeOutCount == 0)
1552 {
1554 break;
1555 }
1556 }
1557
1558 if ((sdh->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0ul)
1559 {
1561 return SDH_CRC_ERROR;
1562 }
1563 }
1565
1566 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul)) /* stop command */
1567 {
1568 return SDH_CRC7_ERROR;
1569 }
1570
1571 if (SDH_CheckRB(sdh) != Successful)
1572 {
1573 return SDH_ERR_TIMEOUT;
1574 }
1575
1576 SDH_SDCommand(sdh, 7ul, 0ul);
1577 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
1578 u32TimeOutCount = SDH_TIMEOUT_CNT;
1579 while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
1580 {
1581 if (--u32TimeOutCount == 0)
1582 {
1584 break;
1585 }
1586 }
1587
1588 if (pSD->i32ErrCode != 0)
1589 return Fail;
1590
1591 return Successful;
1592}
1593 /* end of group SDH_EXPORTED_FUNCTIONS */
1595 /* end of group SDH_Driver */
1597 /* 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:1214
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:1264
#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:1104
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:1444
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