25#define SDH_BLOCK_SIZE 512ul
34static uint32_t _SDH0_ReferenceClock, _SDH1_ReferenceClock;
37#pragma data_alignment = 4
38static uint8_t _SDH0_ucSDHCBuffer[512];
39static uint8_t _SDH1_ucSDHCBuffer[512];
41static uint8_t _SDH0_ucSDHCBuffer[512]
__attribute__((aligned(4)));
42static uint8_t _SDH1_ucSDHCBuffer[512]
__attribute__((aligned(4)));
47static int32_t SDH_CheckRB(
SDH_T *sdh)
49 uint32_t u32TimeOutCount1, u32TimeOutCount2;
69 if (--u32TimeOutCount1 == 0)
79 if (--u32TimeOutCount2 == 0)
93uint32_t SDH_SDCommand(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
95 volatile uint32_t buf, val = 0ul;
120 if (--u32TimeOutCount == 0)
134uint32_t SDH_SDCmdAndRsp(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t ntickCount)
136 volatile uint32_t buf;
151 for (i = 0; i < 0x100; i++);
157 if (ntickCount > 0ul)
161 if(ntickCount-- == 0ul)
180 if (--u32TimeOutCount == 0)
193 uint32_t tmp0 = 0ul, tmp1= 0ul;
194 tmp1 = sdh->
RESP1 & 0xfful;
195 tmp0 = sdh->
RESP0 & 0xful;
196 if ((tmp1 != 0x55ul) && (tmp0 != 0x01ul))
224uint32_t SDH_Swap32(uint32_t val)
230 val |= (buf<<8) & 0xff0000ul;
231 val |= (buf>>8) & 0xff00ul;
232 val |= (buf>>24)& 0xfful;
237uint32_t SDH_SDCmdAndRsp2(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t puR2ptr[])
265 if (--u32TimeOutCount == 0)
274 for (i=0ul; i<5ul; i++)
276 tmpBuf[i] = SDH_Swap32(sdh->
FB[i]);
278 for (i=0ul; i<4ul; i++)
280 puR2ptr[i] = ((tmpBuf[i] & 0x00fffffful)<<8) | ((tmpBuf[i+1ul] & 0xff000000ul)>>24);
295uint32_t SDH_SDCmdAndRspDataIn(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
297 volatile uint32_t buf;
299 uint32_t u32TimeOutCount;
313 buf = (sdh->
CTL & (~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8ul)|
325 if (--u32TimeOutCount == 0)
339 if (--u32TimeOutCount == 0)
361#define SDH_CLK_DIV0_MAX 256ul
363void SDH_Set_clock(
SDH_T *sdh, uint32_t sd_clock_khz)
366 static uint32_t u32SD_ClkSrc = 0ul, u32SD_PwrCtl = 0ul;
375 if (sd_clock_khz <= 400ul)
377 u32SD_PwrCtl =
CLK->PWRCTL;
387 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
393 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
399 CLK->PWRCTL = u32SD_PwrCtl;
402 CLK->CLKSEL0 = (
CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | u32SD_ClkSrc;
409 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
422 CLK->CLKSEL0 = (
CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | u32SD_ClkSrc;
429 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
441 if(sd_clock_khz >= 50000ul)
443 sd_clock_khz = 50000ul;
448 rate = _SDH0_ReferenceClock / sd_clock_khz;
451 if ((_SDH0_ReferenceClock % sd_clock_khz) != 0ul)
458 rate = _SDH1_ReferenceClock / sd_clock_khz;
461 if ((_SDH1_ReferenceClock % sd_clock_khz) != 0ul)
467 if(rate >= SDH_CLK_DIV0_MAX)
469 rate = SDH_CLK_DIV0_MAX;
473 div1 = (rate - 1ul) & 0xFFul;
478 CLK->CLKDIV0 &= ~CLK_CLKDIV0_SDH0DIV_Msk;
483 CLK->CLKDIV3 &= ~CLK_CLKDIV3_SDH1DIV_Msk;
513 sdh->
CTL &= ~SDH_CTL_CLKKEEP_Msk;
529 for (i = 0ul; i < 5000ul; i++)
544 sdh->
CTL &= ~SDH_CTL_CLKKEEP_Msk;
550uint32_t SDH_Init(
SDH_T *sdh)
552 uint32_t
volatile i, status;
554 uint32_t CIDBuffer[4];
555 uint32_t
volatile u32CmdTimeOut;
557 uint32_t u32TimeOutCount;
571 SDH_Set_clock(sdh, 300ul);
583 if (--u32TimeOutCount == 0)
590 SDH_SDCommand(sdh, 0ul, 0ul);
591 for (i=0x1000ul; i>0ul; i--)
597 u32CmdTimeOut = 0xFFFFFul;
599 i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
603 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
605 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut);
609 while ((resp & 0x00800000ul) != 0x00800000ul)
611 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
613 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut);
615 if (--u32TimeOutCount == 0)
621 if ((resp & 0x00400000ul) == 0x00400000ul)
633 SDH_SDCommand(sdh, 0ul, 0ul);
634 for (i=0x100ul; i>0ul; i--)
638 i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
642 SDH_SDCommand(sdh, 0ul, 0ul);
643 for (i=0x100ul; i>0ul; i--)
649 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul)
653 while ((resp & 0x00800000ul) != 0x00800000ul)
658 SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut);
661 if (--u32TimeOutCount == 0)
668 if ((resp & 0x00400000ul) == 0x00400000ul)
686 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut);
689 while ((resp & 0x00800000ul) != 0x00800000ul)
691 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
693 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut);
695 if (--u32TimeOutCount == 0)
712 SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
715 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) !=
Successful)
719 pSD->
RCA = 0x10000ul;
723 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) !=
Successful)
729 pSD->
RCA = (sdh->
RESP0 << 8) & 0xffff0000;
743 uint32_t
volatile status=0ul;
744 uint16_t current_comsumption, busy_status0;
752 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) !=
Successful)
757 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
758 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
759 if (!current_comsumption)
764 busy_status0 = (uint16_t)(*(pSD->
dmabuf + 28)) << 8;
765 busy_status0 |= (uint16_t)(*(pSD->
dmabuf + 29));
772 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) !=
Successful)
781 if (--u32TimeOutCount == 0)
791 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
792 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
793 if (!current_comsumption)
807int32_t SDH_SelectCardType(
SDH_T *sdh)
809 uint32_t
volatile status=0ul;
812 uint32_t u32TimeOutCount;
825 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
844 if (--u32TimeOutCount == 0)
851 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
855 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
860 if ((*pSD->
dmabuf & 0xful) == 0x2ul)
862 status = SDH_SwitchToHighSpeed(sdh, pSD);
870 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
874 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
886 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
890 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
896 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
901 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
913 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
918 param = (3ul << 24) | (183ul << 16) | (1ul << 8);
919 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) !=
Successful)
938 SDH_SDCommand(sdh, 7ul, 0ul);
943 if (--u32TimeOutCount == 0)
958void SDH_Get_SD_info(
SDH_T *sdh)
960 unsigned int R_LEN, C_Size, MULT, size;
977 SDH_SDCmdAndRsp2(sdh, 9ul, pSD->
RCA, Buffer);
982 if ((Buffer[0] & 0xc0000000) == 0xc0000000)
986 SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul);
992 if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) ==
Successful)
994 SDH_SDCommand(sdh, 7ul, 0ul);
998 if (--u32TimeOutCount == 0)
1015 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1016 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1017 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1018 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1026 if ((Buffer[0] & 0xc0000000) != 0x0ul)
1028 C_Size = ((Buffer[1] & 0x0000003ful) << 16) | ((Buffer[2] & 0xffff0000ul) >> 16);
1029 size = (C_Size+1ul) * 512ul;
1036 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1037 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1038 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1039 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1048int32_t SDH_ResetCard(
SDH_T *sdh)
1051 uint32_t
volatile i;
1053 uint32_t u32TimeOutCount;
1056 sdh->
CTL &= ~SDH_CTL_SDNWR_Msk;
1058 sdh->
CTL &= ~SDH_CTL_BLKCNT_Msk;
1060 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
1074 SDH_Set_clock(sdh, 300ul);
1082 if (--u32TimeOutCount == 0)
1088 ret = SDH_SDCommand(sdh, 0ul, 0ul);
1089 for (i=0x1000ul; i>0ul; i--)
1108 uint32_t u32TimeOutCount;
1127 if (--u32TimeOutCount == 0)
1140 if (--u32TimeOutCount == 0)
1151 SD0.
dmabuf = _SDH0_ucSDHCBuffer;
1153 else if (sdh ==
SDH1)
1157 SD1.
dmabuf = _SDH1_ucSDHCBuffer;
1167 sdh->
INTEN &= ~SDH_INTEN_CDSRC_Msk;
1174 for (i = 0; i < 0x100; i++);
1180 sdh->
INTEN &= ~SDH_INTEN_CDIEN_Msk;
1191 if (--u32TimeOutCount == 0)
1221 sdh->
CTL &= ~SDH_CTL_SDNWR_Msk;
1223 sdh->
CTL &= ~SDH_CTL_BLKCNT_Msk;
1225 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
1232 if ((val = SDH_Init(sdh)) != 0ul)
1246 SDH_Get_SD_info(sdh);
1248 if ((val = SDH_SelectCardType(sdh)) != 0ul)
1266int32_t
SDH_Read(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1268 uint32_t
volatile bIsSendCmd =
FALSE, buf;
1269 uint32_t
volatile reg;
1270 uint32_t
volatile i, loop, status;
1272 uint32_t u32TimeOutCount;
1287 if (u32SecCount == 0ul)
1292 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1302 sdh->
BLEN = blksize - 1ul;
1306 sdh->
CMDARG = u32StartSec;
1310 sdh->
CMDARG = u32StartSec * blksize;
1313 sdh->
DMASA = (uint32_t)pu8BufAddr;
1315 loop = u32SecCount / 255ul;
1316 for (i=0ul; i<loop; i++)
1319 reg = sdh->
CTL & ~SDH_CTL_CMDCODE_Msk;
1320 reg = reg | 0xff0000ul;
1321 if (bIsSendCmd ==
FALSE)
1342 if (--u32TimeOutCount == 0)
1360 loop = u32SecCount % 255ul;
1364 reg = sdh->
CTL & (~SDH_CTL_CMDCODE_Msk);
1365 reg = reg & (~SDH_CTL_BLKCNT_Msk);
1366 reg |= (loop << 16);
1368 if (bIsSendCmd ==
FALSE)
1385 if (--u32TimeOutCount == 0)
1403 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1413 SDH_SDCommand(sdh, 7ul, 0ul);
1418 if (--u32TimeOutCount == 0)
1446int32_t
SDH_Write(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1448 uint32_t
volatile bIsSendCmd =
FALSE;
1449 uint32_t
volatile reg;
1450 uint32_t
volatile i, loop, status;
1451 uint32_t u32TimeOutCount;
1466 if (u32SecCount == 0ul)
1471 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1486 sdh->
CMDARG = u32StartSec;
1493 sdh->
DMASA = (uint32_t)pu8BufAddr;
1494 loop = u32SecCount / 255ul;
1495 for (i=0ul; i<loop; i++)
1498 reg = sdh->
CTL & 0xff00c080;
1499 reg = reg | 0xff0000ul;
1517 if (--u32TimeOutCount == 0)
1531 loop = u32SecCount % 255ul;
1535 reg = (sdh->
CTL & 0xff00c080) | (loop << 16);
1553 if (--u32TimeOutCount == 0)
1568 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1578 SDH_SDCommand(sdh, 7ul, 0ul);
1583 if (--u32TimeOutCount == 0)
void *__dso_handle __attribute__((weak))
NuMicro peripheral access layer header file.
#define CLK_CLKSEL0_SDH0SEL_HCLK
#define CLK_CLKSEL0_SDH1SEL_PLL
#define CLK_CLKSEL0_SDH0SEL_HXT
#define CLK_CLKSEL0_SDH0SEL_HIRC
#define CLK_CLKSEL0_SDH0SEL_PLL
#define CLK_CLKSEL0_SDH1SEL_HXT
#define CLK_CLKSEL0_SDH1SEL_HIRC
#define CLK_CLKSEL0_SDH1SEL_HCLK
uint32_t CLK_GetHCLKFreq(void)
Get HCLK frequency.
uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
uint32_t CLK_GetHXTFreq(void)
Get external high speed crystal clock frequency.
#define TRUE
Boolean true, define to use in API parameters or return value.
#define FALSE
Boolean false, define to use in API parameters or return value.
#define SDH_DMACTL_DMAEN_Msk
#define SDH_CTL_SDNWR_Pos
#define SDH_CTL_CLK8OEN_Msk
#define SDH_GCTL_GCTLRST_Msk
#define CLK_CLKSEL0_SDH1SEL_Msk
#define SDH_INTSTS_CDSTS_Msk
#define SDH_INTSTS_DAT0STS_Msk
#define CLK_PWRCTL_HIRCEN_Msk
#define CLK_CLKSEL0_SDH0SEL_Msk
#define SDH_INTEN_CDSRC_Msk
#define SDH_CTL_CLK74OEN_Msk
#define SDH_DMACTL_DMARST_Msk
#define SDH_CTL_BLKCNT_Pos
#define SDH_GCTL_SDEN_Msk
#define SDH_INTSTS_CDIF_Msk
#define CLK_CLKDIV0_SDH0DIV_Pos
#define SDH_INTSTS_CRC7_Msk
#define SDH_INTEN_CDIEN_Msk
#define SDH_INTSTS_CRC16_Msk
#define SDH_INTEN_BLKDIEN_Msk
#define SDH_INTSTS_CRCIF_Msk
#define SDH_CTL_CLKKEEP_Msk
#define CLK_CLKDIV3_SDH1DIV_Pos
#define SDH_CTL_CTLRST_Msk
#define CardDetect_From_DAT3
int32_t SDH_CardDetection(SDH_T *sdh)
uint32_t SDH_Probe(SDH_T *sdh)
This function use to initial SD card.
unsigned char volatile DataReadyFlag
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.
unsigned char IsCardInsert
unsigned int totalSectorN
void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
This function use to reset SD function and select card detection source and pin.
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.
__STATIC_INLINE void SYS_LockReg(void)
Enable register write-protection function.
uint32_t SYS_IsRegLocked(void)
Check if register is locked nor not.
__STATIC_INLINE void SYS_UnlockReg(void)
Disable register write-protection function.