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