26#define SDH_BLOCK_SIZE 512ul
35static uint32_t _SDH0_ReferenceClock, _SDH1_ReferenceClock;
38#pragma data_alignment = 4
39static uint8_t _SDH0_ucSDHCBuffer[512];
40static uint8_t _SDH1_ucSDHCBuffer[512];
42static uint8_t _SDH0_ucSDHCBuffer[512]
__attribute__((aligned(4)));
43static uint8_t _SDH1_ucSDHCBuffer[512]
__attribute__((aligned(4)));
48uint32_t SDH_CheckRB(
SDH_T *sdh)
79uint32_t SDH_SDCommand(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
81 volatile uint32_t buf, val = 0ul;
108uint32_t SDH_SDCmdAndRsp(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t ntickCount)
110 volatile uint32_t buf;
126 if (ntickCount > 0ul)
130 if(ntickCount-- == 0ul)
162 uint32_t tmp0 = 0ul, tmp1= 0ul;
163 tmp1 = sdh->
RESP1 & 0xfful;
164 tmp0 = sdh->
RESP0 & 0xful;
165 if ((tmp1 != 0x55ul) && (tmp0 != 0x01ul))
193uint32_t SDH_Swap32(uint32_t val)
199 val |= (buf<<8) & 0xff0000ul;
200 val |= (buf>>8) & 0xff00ul;
201 val |= (buf>>24)& 0xfful;
206uint32_t SDH_SDCmdAndRsp2(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t puR2ptr[])
239 for (i=0ul; i<5ul; i++)
241 tmpBuf[i] = SDH_Swap32(sdh->
FB[i]);
243 for (i=0ul; i<4ul; i++)
245 puR2ptr[i] = ((tmpBuf[i] & 0x00fffffful)<<8) | ((tmpBuf[i+1ul] & 0xff000000ul)>>24);
256uint32_t SDH_SDCmdAndRspDataIn(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
258 volatile uint32_t buf;
271 buf = (sdh->
CTL & (~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8ul)|
315#define SDH_CLK_DIV0_MAX 256ul
317void SDH_Set_clock(
SDH_T *sdh, uint32_t sd_clock_khz)
320 static uint32_t u32SD_ClkSrc = 0ul, u32SD_PwrCtl = 0ul;
325 if (sd_clock_khz <= 400ul)
327 u32SD_PwrCtl =
CLK->PWRCTL;
337 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
343 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
349 CLK->PWRCTL = u32SD_PwrCtl;
352 CLK->CLKSEL0 = (
CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | u32SD_ClkSrc;
359 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
372 CLK->CLKSEL0 = (
CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | u32SD_ClkSrc;
379 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
391 if(sd_clock_khz >= 50000ul)
393 sd_clock_khz = 50000ul;
398 rate = _SDH0_ReferenceClock / sd_clock_khz;
401 if ((_SDH0_ReferenceClock % sd_clock_khz) != 0ul)
408 rate = _SDH1_ReferenceClock / sd_clock_khz;
411 if ((_SDH1_ReferenceClock % sd_clock_khz) != 0ul)
417 if(rate >= SDH_CLK_DIV0_MAX)
419 rate = SDH_CLK_DIV0_MAX;
423 div1 = (rate - 1ul) & 0xFFul;
428 CLK->CLKDIV0 &= ~CLK_CLKDIV0_SDH0DIV_Msk;
433 CLK->CLKDIV3 &= ~CLK_CLKDIV3_SDH1DIV_Msk;
441 uint32_t i, val =
TRUE;
469 for(i= 0ul; i < 5000ul; i++)
483 sdh->
CTL &= ~SDH_CTL_CLKKEEP_Msk;
489uint32_t SDH_Init(
SDH_T *sdh)
491 uint32_t
volatile i, status;
493 uint32_t CIDBuffer[4];
494 uint32_t
volatile u32CmdTimeOut;
507 SDH_Set_clock(sdh, 300ul);
520 SDH_SDCommand(sdh, 0ul, 0ul);
521 for (i=0x1000ul; i>0ul; i--)
527 u32CmdTimeOut = 0xFFFFFul;
529 i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
533 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
535 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut);
538 while ((resp & 0x00800000ul) != 0x00800000ul)
540 if (SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut) ==
SDH_NO_SD_CARD)
543 if (SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut) ==
SDH_NO_SD_CARD)
547 if ((resp & 0x00400000ul) == 0x00400000ul)
559 SDH_SDCommand(sdh, 0ul, 0ul);
560 for (i=0x100ul; i>0ul; i--)
564 i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
568 SDH_SDCommand(sdh, 0ul, 0ul);
569 for (i=0x100ul; i>0ul; i--)
575 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul)
578 while ((resp & 0x00800000ul) != 0x00800000ul)
583 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) ==
SDH_NO_SD_CARD)
588 if ((resp & 0x00400000ul) == 0x00400000ul)
606 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut);
608 while ((resp & 0x00800000ul) != 0x00800000ul)
610 if (SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut) ==
SDH_NO_SD_CARD)
613 if (SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut) ==
SDH_NO_SD_CARD)
628 SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
631 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) !=
Successful)
635 pSD->
RCA = 0x10000ul;
639 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) !=
Successful)
645 pSD->
RCA = (sdh->
RESP0 << 8) & 0xffff0000;
655 uint32_t
volatile status=0ul;
656 uint16_t current_comsumption, busy_status0;
661 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) !=
Successful)
666 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
667 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
668 if (!current_comsumption)
673 busy_status0 = (uint16_t)(*(pSD->
dmabuf + 28)) << 8;
674 busy_status0 |= (uint16_t)(*(pSD->
dmabuf + 29));
681 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) !=
Successful)
696 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
697 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
698 if (!current_comsumption)
712uint32_t SDH_SelectCardType(
SDH_T *sdh)
714 uint32_t
volatile status=0ul;
727 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
732 if ((status = SDH_CheckRB(sdh)) !=
Successful)
745 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
749 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
754 if ((*pSD->
dmabuf & 0xful) == 0x2ul)
756 status = SDH_SwitchToHighSpeed(sdh, pSD);
764 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
768 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
780 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
784 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
790 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
795 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
807 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
812 param = (3ul << 24) | (183ul << 16) | (1ul << 8);
813 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) !=
Successful)
817 if ((status = SDH_CheckRB(sdh)) !=
Successful)
832 SDH_SDCommand(sdh, 7ul, 0ul);
847int32_t SDH_Get_SD_info(
SDH_T *sdh)
849 unsigned int R_LEN, C_Size, MULT, size;
863 SDH_SDCmdAndRsp2(sdh, 9ul, pSD->
RCA, Buffer);
868 if ((Buffer[0] & 0xc0000000) == 0xc0000000)
872 SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul);
878 if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) ==
Successful)
880 SDH_SDCommand(sdh, 7ul, 0ul);
900 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
901 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
902 MULT = (Buffer[2] & 0x00038000ul) >> 15;
903 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
911 if ((Buffer[0] & 0xc0000000) != 0x0ul)
913 C_Size = ((Buffer[1] & 0x0000003ful) << 16) | ((Buffer[2] & 0xffff0000ul) >> 16);
914 size = (C_Size+1ul) * 512ul;
921 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
922 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
923 MULT = (Buffer[2] & 0x00038000ul) >> 15;
924 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
963 SD0.
dmabuf = _SDH0_ucSDHCBuffer;
965 else if (sdh ==
SDH1)
969 SD1.
dmabuf = _SDH1_ucSDHCBuffer;
979 sdh->
INTEN &= ~SDH_INTEN_CDSRC_Msk;
1013 sdh->
CTL &= ~SDH_CTL_SDNWR_Msk;
1015 sdh->
CTL &= ~SDH_CTL_BLKCNT_Msk;
1017 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
1024 if ((val = SDH_Init(sdh)) != 0ul)
1038 if (SDH_Get_SD_info(sdh) != 0)
1041 if ((val = SDH_SelectCardType(sdh)) != 0ul)
1059uint32_t
SDH_Read(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1061 uint32_t
volatile bIsSendCmd =
FALSE, buf;
1062 uint32_t
volatile reg;
1063 uint32_t
volatile i, loop, status;
1076 if (u32SecCount == 0ul)
1081 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1085 if ((status = SDH_CheckRB(sdh)) !=
Successful)
1090 sdh->
BLEN = blksize - 1ul;
1094 sdh->
CMDARG = u32StartSec;
1098 sdh->
CMDARG = u32StartSec * blksize;
1101 sdh->
DMASA = (uint32_t)pu8BufAddr;
1103 loop = u32SecCount / 255ul;
1104 for (i=0ul; i<loop; i++)
1107 reg = sdh->
CTL & ~SDH_CTL_CMDCODE_Msk;
1108 reg = reg | 0xff0000ul;
1109 if (bIsSendCmd ==
FALSE)
1138 loop = u32SecCount % 255ul;
1142 reg = sdh->
CTL & (~SDH_CTL_CMDCODE_Msk);
1143 reg = reg & (~SDH_CTL_BLKCNT_Msk);
1144 reg |= (loop << 16);
1146 if (bIsSendCmd ==
FALSE)
1175 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1179 if ((status = SDH_CheckRB(sdh)) !=
Successful)
1184 SDH_SDCommand(sdh, 7ul, 0ul);
1212uint32_t
SDH_Write(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1214 uint32_t
volatile bIsSendCmd =
FALSE;
1215 uint32_t
volatile reg;
1216 uint32_t
volatile i, loop, status;
1229 if (u32SecCount == 0ul)
1234 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1239 if ((status = SDH_CheckRB(sdh)) !=
Successful)
1249 sdh->
CMDARG = u32StartSec;
1256 sdh->
DMASA = (uint32_t)pu8BufAddr;
1257 loop = u32SecCount / 255ul;
1258 for (i=0ul; i<loop; i++)
1261 reg = sdh->
CTL & 0xff00c080;
1262 reg = reg | 0xff0000ul;
1288 loop = u32SecCount % 255ul;
1292 reg = (sdh->
CTL & 0xff00c080) | (loop << 16);
1319 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1323 if ((status = SDH_CheckRB(sdh)) !=
Successful)
1328 SDH_SDCommand(sdh, 7ul, 0ul);
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 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
uint32_t SDH_Probe(SDH_T *sdh)
This function use to initial SD card.
unsigned char volatile DataReadyFlag
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.
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.
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.
uint32_t SDH_CardDetection(SDH_T *sdh)
__STATIC_INLINE void SYS_UnlockReg(void)
Disable register write-protection function.