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;
375 if (sd_clock_khz <= 400ul)
386 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
392 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
400 CLK->CLKSEL0 = (
CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH0SEL_Msk) | u32SD_ClkSrc;
407 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
420 CLK->CLKSEL0 = (
CLK->CLKSEL0 & ~CLK_CLKSEL0_SDH1SEL_Msk) | u32SD_ClkSrc;
427 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
439 if(sd_clock_khz >= 50000ul)
441 sd_clock_khz = 50000ul;
446 rate = _SDH0_ReferenceClock / sd_clock_khz;
449 if ((_SDH0_ReferenceClock % sd_clock_khz) != 0ul)
456 rate = _SDH1_ReferenceClock / sd_clock_khz;
459 if ((_SDH1_ReferenceClock % sd_clock_khz) != 0ul)
465 if(rate >= SDH_CLK_DIV0_MAX)
467 rate = SDH_CLK_DIV0_MAX;
471 div1 = (rate - 1ul) & 0xFFul;
476 CLK->CLKDIV0 &= ~CLK_CLKDIV0_SDH0DIV_Msk;
481 CLK->CLKDIV3 &= ~CLK_CLKDIV3_SDH1DIV_Msk;
511 sdh->
CTL &= ~SDH_CTL_CLKKEEP_Msk;
527 for (i = 0ul; i < 5000ul; i++)
542 sdh->
CTL &= ~SDH_CTL_CLKKEEP_Msk;
548uint32_t SDH_Init(
SDH_T *sdh)
550 uint32_t
volatile i, status;
552 uint32_t CIDBuffer[4];
553 uint32_t
volatile u32CmdTimeOut;
555 uint32_t u32TimeOutCount;
569 SDH_Set_clock(sdh, 300ul);
581 if (--u32TimeOutCount == 0)
588 SDH_SDCommand(sdh, 0ul, 0ul);
589 for (i=0x1000ul; i>0ul; i--)
595 u32CmdTimeOut = 0xFFFFFul;
597 i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
601 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
603 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut);
607 while ((resp & 0x00800000ul) != 0x00800000ul)
609 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
611 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut);
613 if (--u32TimeOutCount == 0)
619 if ((resp & 0x00400000ul) == 0x00400000ul)
631 SDH_SDCommand(sdh, 0ul, 0ul);
632 for (i=0x100ul; i>0ul; i--)
636 i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
640 SDH_SDCommand(sdh, 0ul, 0ul);
641 for (i=0x100ul; i>0ul; i--)
647 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul)
651 while ((resp & 0x00800000ul) != 0x00800000ul)
656 SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut);
659 if (--u32TimeOutCount == 0)
666 if ((resp & 0x00400000ul) == 0x00400000ul)
684 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut);
687 while ((resp & 0x00800000ul) != 0x00800000ul)
689 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
691 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut);
693 if (--u32TimeOutCount == 0)
710 SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
713 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) !=
Successful)
717 pSD->
RCA = 0x10000ul;
721 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) !=
Successful)
727 pSD->
RCA = (sdh->
RESP0 << 8) & 0xffff0000;
741 uint32_t
volatile status=0ul;
742 uint16_t current_comsumption, busy_status0;
750 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) !=
Successful)
755 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
756 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
757 if (!current_comsumption)
762 busy_status0 = (uint16_t)(*(pSD->
dmabuf + 28)) << 8;
763 busy_status0 |= (uint16_t)(*(pSD->
dmabuf + 29));
770 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) !=
Successful)
779 if (--u32TimeOutCount == 0)
789 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
790 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
791 if (!current_comsumption)
805int32_t SDH_SelectCardType(
SDH_T *sdh)
807 uint32_t
volatile status=0ul;
810 uint32_t u32TimeOutCount;
823 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
842 if (--u32TimeOutCount == 0)
849 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
853 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
858 if ((*pSD->
dmabuf & 0xful) == 0x2ul)
860 status = SDH_SwitchToHighSpeed(sdh, pSD);
868 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
872 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
884 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
888 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
894 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
899 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
911 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
916 param = (3ul << 24) | (183ul << 16) | (1ul << 8);
917 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) !=
Successful)
936 SDH_SDCommand(sdh, 7ul, 0ul);
941 if (--u32TimeOutCount == 0)
956void SDH_Get_SD_info(
SDH_T *sdh)
958 unsigned int R_LEN, C_Size, MULT, size;
975 SDH_SDCmdAndRsp2(sdh, 9ul, pSD->
RCA, Buffer);
980 if ((Buffer[0] & 0xc0000000) == 0xc0000000)
984 SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul);
990 if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) ==
Successful)
992 SDH_SDCommand(sdh, 7ul, 0ul);
996 if (--u32TimeOutCount == 0)
1013 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1014 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1015 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1016 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1024 if ((Buffer[0] & 0xc0000000) != 0x0ul)
1026 C_Size = ((Buffer[1] & 0x0000003ful) << 16) | ((Buffer[2] & 0xffff0000ul) >> 16);
1027 size = (C_Size+1ul) * 512ul;
1034 R_LEN = (Buffer[1] & 0x000f0000ul) >> 16;
1035 C_Size = ((Buffer[1] & 0x000003fful) << 2) | ((Buffer[2] & 0xc0000000ul) >> 30);
1036 MULT = (Buffer[2] & 0x00038000ul) >> 15;
1037 size = (C_Size+1ul) * (1ul<<(MULT+2ul)) * (1ul<<R_LEN);
1046int32_t SDH_ResetCard(
SDH_T *sdh)
1049 uint32_t
volatile i;
1051 uint32_t u32TimeOutCount;
1054 sdh->
CTL &= ~SDH_CTL_SDNWR_Msk;
1056 sdh->
CTL &= ~SDH_CTL_BLKCNT_Msk;
1058 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
1072 SDH_Set_clock(sdh, 300ul);
1080 if (--u32TimeOutCount == 0)
1086 ret = SDH_SDCommand(sdh, 0ul, 0ul);
1087 for (i=0x1000ul; i>0ul; i--)
1106 uint32_t u32TimeOutCount;
1125 if (--u32TimeOutCount == 0)
1138 if (--u32TimeOutCount == 0)
1149 SD0.
dmabuf = _SDH0_ucSDHCBuffer;
1151 else if (sdh ==
SDH1)
1155 SD1.
dmabuf = _SDH1_ucSDHCBuffer;
1165 sdh->
INTEN &= ~SDH_INTEN_CDSRC_Msk;
1172 for (i = 0; i < 0x100; i++);
1178 sdh->
INTEN &= ~SDH_INTEN_CDIEN_Msk;
1189 if (--u32TimeOutCount == 0)
1219 sdh->
CTL &= ~SDH_CTL_SDNWR_Msk;
1221 sdh->
CTL &= ~SDH_CTL_BLKCNT_Msk;
1223 sdh->
CTL &= ~SDH_CTL_DBW_Msk;
1230 if ((val = SDH_Init(sdh)) != 0ul)
1244 SDH_Get_SD_info(sdh);
1246 if ((val = SDH_SelectCardType(sdh)) != 0ul)
1264int32_t
SDH_Read(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1266 uint32_t
volatile bIsSendCmd =
FALSE, buf;
1267 uint32_t
volatile reg;
1268 uint32_t
volatile i, loop, status;
1270 uint32_t u32TimeOutCount;
1285 if (u32SecCount == 0ul)
1290 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1300 sdh->
BLEN = blksize - 1ul;
1304 sdh->
CMDARG = u32StartSec;
1308 sdh->
CMDARG = u32StartSec * blksize;
1311 sdh->
DMASA = (uint32_t)pu8BufAddr;
1313 loop = u32SecCount / 255ul;
1314 for (i=0ul; i<loop; i++)
1317 reg = sdh->
CTL & ~SDH_CTL_CMDCODE_Msk;
1318 reg = reg | 0xff0000ul;
1319 if (bIsSendCmd ==
FALSE)
1340 if (--u32TimeOutCount == 0)
1358 loop = u32SecCount % 255ul;
1362 reg = sdh->
CTL & (~SDH_CTL_CMDCODE_Msk);
1363 reg = reg & (~SDH_CTL_BLKCNT_Msk);
1364 reg |= (loop << 16);
1366 if (bIsSendCmd ==
FALSE)
1383 if (--u32TimeOutCount == 0)
1401 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1411 SDH_SDCommand(sdh, 7ul, 0ul);
1416 if (--u32TimeOutCount == 0)
1444int32_t
SDH_Write(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1446 uint32_t
volatile bIsSendCmd =
FALSE;
1447 uint32_t
volatile reg;
1448 uint32_t
volatile i, loop, status;
1449 uint32_t u32TimeOutCount;
1464 if (u32SecCount == 0ul)
1469 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1484 sdh->
CMDARG = u32StartSec;
1491 sdh->
DMASA = (uint32_t)pu8BufAddr;
1492 loop = u32SecCount / 255ul;
1493 for (i=0ul; i<loop; i++)
1496 reg = sdh->
CTL & 0xff00c080;
1497 reg = reg | 0xff0000ul;
1515 if (--u32TimeOutCount == 0)
1529 loop = u32SecCount % 255ul;
1533 reg = (sdh->
CTL & 0xff00c080) | (loop << 16);
1551 if (--u32TimeOutCount == 0)
1566 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1576 SDH_SDCommand(sdh, 7ul, 0ul);
1581 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.