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  }
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;
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 
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)|
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 
266  {
267  /* check CRC7 */
268  return SDH_CRC7_ERROR;
269  }
270 
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 */
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 
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 {
890  {
891  }
892 
894 
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  {
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  {
1241  return SDH_CRC_ERROR;
1242  }
1243  }
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 
#define CLK_CLKSEL0_SDH1SEL_Msk
Definition: clk_reg.h:2523
#define SDH_TYPE_EMMC
Definition: sdh.h:47
#define CLK
Definition: M480.h:368
unsigned int CardType
Definition: sdh.h:81
#define SDH_CTL_RIEN_Msk
Definition: sdh_reg.h:841
unsigned char volatile DataReadyFlag
Definition: sdh.h:80
__IO uint32_t DMACTL
Definition: sdh_reg.h:758
__I uint32_t RESP0
Definition: sdh_reg.h:779
#define CLK_CLKDIV3_SDH1DIV_Msk
Definition: clk_reg.h:2658
#define SDH_TYPE_SD_HIGH
Definition: sdh.h:44
#define SDH_DMACTL_DMARST_Msk
Definition: sdh_reg.h:796
#define CLK_CLKSEL0_SDH0SEL_HCLK
Definition: clk.h:81
unsigned int totalSectorN
Definition: sdh.h:83
#define CLK_CLKSEL0_SDH0SEL_Msk
Definition: clk_reg.h:2520
#define SDH_CTL_CTLRST_Msk
Definition: sdh_reg.h:865
#define SDH_GCTL_SDEN_Msk
Definition: sdh_reg.h:829
__IO uint32_t FB[32]
Definition: sdh_reg.h:754
#define SDH_CTL_CLK74OEN_Msk
Definition: sdh_reg.h:853
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
#define CLK_CLKSEL0_SDH0SEL_HIRC
Definition: clk.h:80
#define SDH_TYPE_UNKNOWN
Definition: sdh.h:43
#define SDH_INTEN_CDIEN_Msk
Definition: sdh_reg.h:886
#define SDH_GCTL_GCTLRST_Msk
Definition: sdh_reg.h:826
#define SDH_INTSTS_CRC7_Msk
Definition: sdh_reg.h:907
#define TRUE
Boolean true, define to use in API parameters or return value.
Definition: M480.h:607
__IO uint32_t CTL
Definition: sdh_reg.h:775
#define SDH_DMACTL_DMAEN_Msk
Definition: sdh_reg.h:793
NuMicro peripheral access layer header file.
#define SDH1
Definition: M480.h:393
unsigned char * dmabuf
Definition: sdh.h:86
#define CLK_CLKSEL0_SDH1SEL_HXT
Definition: clk.h:83
void *__dso_handle __attribute__((weak))
Definition: _syscalls.c:35
#define FALSE
Boolean false, define to use in API parameters or return value.
Definition: M480.h:608
#define CardDetect_From_DAT3
Definition: sdh.h:68
#define SDH_CTL_CMDCODE_Msk
Definition: sdh_reg.h:862
#define SDH_CRC_ERROR
Definition: sdh.h:58
#define SDH_INTSTS_CDSTS_Msk
Definition: sdh_reg.h:928
#define CLK_CLKSEL0_SDH1SEL_PLL
Definition: clk.h:84
#define Fail
Definition: sdh.h:40
#define SDH_CTL_BLKCNT_Pos
Definition: sdh_reg.h:870
uint32_t SDH_Probe(SDH_T *sdh)
This function use to initial SD card.
Definition: sdh.c:945
#define SDH_CTL_R2EN_Msk
Definition: sdh_reg.h:850
#define SDH_INTEN_CDSRC_Msk
Definition: sdh_reg.h:898
#define CLK_PWRCTL_HIRCEN_Msk
Definition: clk_reg.h:2283
#define SD_FREQ
Definition: sdh.h:62
unsigned int RCA
Definition: sdh.h:82
#define SDHC_FREQ
Definition: sdh.h:63
#define CLK_CLKSEL0_SDH0SEL_HXT
Definition: clk.h:78
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
__IO uint32_t INTEN
Definition: sdh_reg.h:777
unsigned char IsCardInsert
Definition: sdh.h:77
#define SDH_CMD8_ERROR
Definition: sdh.h:59
Definition: sdh.h:75
#define SDH_CTL_CLKKEEP_Msk
Definition: sdh_reg.h:859
__IO uint32_t INTSTS
Definition: sdh_reg.h:778
#define CLK_CLKSEL0_SDH0SEL_PLL
Definition: clk.h:79
uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
Definition: clk.c:1188
#define CLK_CLKDIV0_SDH0DIV_Msk
Definition: clk_reg.h:2631
#define SDH_BLOCK_SIZE
Definition: sdh.c:26
unsigned int diskSize
Definition: sdh.h:84
int sectorSize
Definition: sdh.h:85
#define MMC_FREQ
Definition: sdh.h:61
#define SDH_CTL_COEN_Msk
Definition: sdh_reg.h:838
__IO uint32_t BLEN
Definition: sdh_reg.h:781
#define CLK_CLKSEL0_SDH1SEL_HIRC
Definition: clk.h:85
Definition: sdh_reg.h:26
#define SDH_INIT_ERROR
Definition: sdh.h:55
#define CLK_CLKDIV3_SDH1DIV_Pos
Definition: clk_reg.h:2657
#define SDH_CTL_DBW_Msk
Definition: sdh_reg.h:868
#define SDH_INTSTS_DAT0STS_Msk
Definition: sdh_reg.h:916
#define SDH_CRC16_ERROR
Definition: sdh.h:57
#define SDH_TYPE_SD_LOW
Definition: sdh.h:45
#define Successful
Definition: sdh.h:39
__STATIC_INLINE void SYS_UnlockReg(void)
Disable register write-protection function.
Definition: sys.h:1586
#define SDH_CTL_SDNWR_Msk
Definition: sdh_reg.h:874
#define SDH_SELECT_ERROR
Definition: sdh.h:53
__IO uint32_t GINTEN
Definition: sdh_reg.h:770
#define CLK_CLKDIV0_SDH0DIV_Pos
Definition: clk_reg.h:2630
#define SDH_INTEN_BLKDIEN_Msk
Definition: sdh_reg.h:880
#define SDH_ERR_DEVICE
Definition: sdh.h:51
__IO uint32_t GCTL
Definition: sdh_reg.h:769
unsigned char R3Flag
Definition: sdh.h:78
#define __HIRC
Definition: system_M480.h:36
uint32_t CLK_GetHCLKFreq(void)
Get HCLK frequency.
Definition: clk.c:244
#define SDH_INTSTS_CRC16_Msk
Definition: sdh_reg.h:910
__I uint32_t RESP1
Definition: sdh_reg.h:780
__IO uint32_t DMASA
Definition: sdh_reg.h:762
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
#define SDH0
Definition: M480.h:392
#define CLK_CLKSEL0_SDH1SEL_HCLK
Definition: clk.h:86
#define SDH_CTL_SDNWR_Pos
Definition: sdh_reg.h:873
#define SDH_TYPE_MMC
Definition: sdh.h:46
unsigned char R7Flag
Definition: sdh.h:79
#define SDH_INTSTS_CRCIF_Msk
Definition: sdh_reg.h:904
#define SDH_NO_SD_CARD
Definition: sdh.h:50
uint32_t SDH_CardDetection(SDH_T *sdh)
#define SDH_CTL_BLKCNT_Msk
Definition: sdh_reg.h:871
#define SDH_CTL_CLK8OEN_Msk
Definition: sdh_reg.h:856
#define SDH_CRC7_ERROR
Definition: sdh.h:56
#define SDH_CTL_DIEN_Msk
Definition: sdh_reg.h:844
#define SDH_CTL_DOEN_Msk
Definition: sdh_reg.h:847
__IO uint32_t CMDARG
Definition: sdh_reg.h:776
uint32_t CLK_GetHXTFreq(void)
Get external high speed crystal clock frequency.
Definition: clk.c:120