26 #define SDH_BLOCK_SIZE 512ul 35 static uint32_t _SDH0_ReferenceClock, _SDH1_ReferenceClock;
38 #pragma data_alignment = 4 39 static uint8_t _SDH0_ucSDHCBuffer[512];
40 static uint8_t _SDH1_ucSDHCBuffer[512];
42 static uint8_t _SDH0_ucSDHCBuffer[512]
__attribute__((aligned(4)));
43 static uint8_t _SDH1_ucSDHCBuffer[512]
__attribute__((aligned(4)));
48 void SDH_CheckRB(
SDH_T *sdh)
64 uint32_t SDH_SDCommand(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
66 volatile uint32_t buf, val = 0ul;
93 uint32_t SDH_SDCmdAndRsp(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t ntickCount)
95 volatile uint32_t buf;
111 if (ntickCount > 0ul)
115 if(ntickCount-- == 0ul)
139 uint32_t tmp0 = 0ul, tmp1= 0ul;
140 tmp1 = sdh->
RESP1 & 0xfful;
141 tmp0 = sdh->
RESP0 & 0xful;
142 if ((tmp1 != 0x55ul) && (tmp0 != 0x01ul))
170 uint32_t SDH_Swap32(uint32_t val)
176 val |= (buf<<8) & 0xff0000ul;
177 val |= (buf>>8) & 0xff00ul;
178 val |= (buf>>24)& 0xfful;
183 uint32_t SDH_SDCmdAndRsp2(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t puR2ptr[])
212 for (i=0ul; i<5ul; i++)
214 tmpBuf[i] = SDH_Swap32(sdh->
FB[i]);
216 for (i=0ul; i<4ul; i++)
218 puR2ptr[i] = ((tmpBuf[i] & 0x00fffffful)<<8) | ((tmpBuf[i+1ul] & 0xff000000ul)>>24);
229 uint32_t SDH_SDCmdAndRspDataIn(
SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
231 volatile uint32_t buf;
280 #define SDH_CLK_DIV0_MAX 256ul 282 void SDH_Set_clock(
SDH_T *sdh, uint32_t sd_clock_khz)
285 static uint32_t u32SD_ClkSrc = 0ul, u32SD_PwrCtl = 0ul;
290 if (sd_clock_khz <= 400ul)
292 u32SD_PwrCtl =
CLK->PWRCTL;
302 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
308 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
314 CLK->PWRCTL = u32SD_PwrCtl;
324 _SDH0_ReferenceClock = (
__HIRC / 1000ul);
344 _SDH1_ReferenceClock = (
__HIRC / 1000ul);
356 if(sd_clock_khz >= 50000ul)
358 sd_clock_khz = 50000ul;
363 rate = _SDH0_ReferenceClock / sd_clock_khz;
366 if ((_SDH0_ReferenceClock % sd_clock_khz) != 0ul)
373 rate = _SDH1_ReferenceClock / sd_clock_khz;
376 if ((_SDH1_ReferenceClock % sd_clock_khz) != 0ul)
382 if(rate >= SDH_CLK_DIV0_MAX)
384 rate = SDH_CLK_DIV0_MAX;
388 div1 = (rate - 1ul) & 0xFFul;
406 uint32_t i, val =
TRUE;
434 for(i= 0ul; i < 5000ul; i++)
454 uint32_t SDH_Init(
SDH_T *sdh)
456 uint32_t
volatile i, status;
458 uint32_t CIDBuffer[4];
459 uint32_t
volatile u32CmdTimeOut;
472 SDH_Set_clock(sdh, 300ul);
485 SDH_SDCommand(sdh, 0ul, 0ul);
486 for (i=0x1000ul; i>0ul; i--)
492 u32CmdTimeOut = 0xFFFFFul;
494 i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
498 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
500 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut);
503 while ((resp & 0x00800000ul) != 0x00800000ul)
505 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
507 SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut);
510 if ((resp & 0x00400000ul) == 0x00400000ul)
522 SDH_SDCommand(sdh, 0ul, 0ul);
523 for (i=0x100ul; i>0ul; i--)
527 i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
531 SDH_SDCommand(sdh, 0ul, 0ul);
532 for (i=0x100ul; i>0ul; i--)
538 if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul)
541 while ((resp & 0x00800000ul) != 0x00800000ul)
546 SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut);
550 if ((resp & 0x00400000ul) == 0x00400000ul)
568 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut);
570 while ((resp & 0x00800000ul) != 0x00800000ul)
572 SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
574 SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut);
588 SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
591 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) !=
Successful)
595 pSD->
RCA = 0x10000ul;
599 if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) !=
Successful)
605 pSD->
RCA = (sdh->
RESP0 << 8) & 0xffff0000;
615 uint32_t
volatile status=0ul;
616 uint16_t current_comsumption, busy_status0;
621 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) !=
Successful)
626 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
627 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
628 if (!current_comsumption)
633 busy_status0 = (uint16_t)(*(pSD->
dmabuf + 28)) << 8;
634 busy_status0 |= (uint16_t)(*(pSD->
dmabuf + 29));
641 if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) !=
Successful)
652 current_comsumption = (uint16_t)(*pSD->
dmabuf) << 8;
653 current_comsumption |= (uint16_t)(*(pSD->
dmabuf + 1));
654 if (!current_comsumption)
668 uint32_t SDH_SelectCardType(
SDH_T *sdh)
670 uint32_t
volatile status=0ul;
683 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
698 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
702 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
707 if ((*pSD->
dmabuf & 0xful) == 0x2ul)
709 status = SDH_SwitchToHighSpeed(sdh, pSD);
717 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
721 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
733 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
737 if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) !=
Successful)
743 if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->
RCA, 0ul)) !=
Successful)
748 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) !=
Successful)
765 param = (3ul << 24) | (183ul << 16) | (1ul << 8);
766 if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) !=
Successful)
782 SDH_SDCommand(sdh, 7ul, 0ul);
793 void SDH_Get_SD_info(
SDH_T *sdh)
795 unsigned int R_LEN, C_Size, MULT, size;
809 SDH_SDCmdAndRsp2(sdh, 9ul, pSD->
RCA, Buffer);
814 if ((Buffer[0] & 0xc0000000) == 0xc0000000)
818 SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul);
824 if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) ==
Successful)
826 SDH_SDCommand(sdh, 7ul, 0ul);
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);
853 if ((Buffer[0] & 0xc0000000) != 0x0ul)
855 C_Size = ((Buffer[1] & 0x0000003ful) << 16) | ((Buffer[2] & 0xffff0000ul) >> 16);
856 size = (C_Size+1ul) * 512ul;
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);
904 SD0.
dmabuf = _SDH0_ucSDHCBuffer;
906 else if (sdh ==
SDH1)
910 SD1.
dmabuf = _SDH1_ucSDHCBuffer;
961 if ((val = SDH_Init(sdh)) != 0ul)
975 SDH_Get_SD_info(sdh);
977 if ((val = SDH_SelectCardType(sdh)) != 0ul)
995 uint32_t
SDH_Read(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
997 uint32_t
volatile bIsSendCmd =
FALSE, buf;
998 uint32_t
volatile reg;
999 uint32_t
volatile i, loop, status;
1012 if (u32SecCount == 0ul)
1017 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1023 sdh->
BLEN = blksize - 1ul;
1027 sdh->
CMDARG = u32StartSec;
1031 sdh->
CMDARG = u32StartSec * blksize;
1034 sdh->
DMASA = (uint32_t)pu8BufAddr;
1036 loop = u32SecCount / 255ul;
1037 for (i=0ul; i<loop; i++)
1041 reg = reg | 0xff0000ul;
1042 if (bIsSendCmd ==
FALSE)
1075 loop = u32SecCount % 255ul;
1081 reg |= (loop << 16);
1083 if (bIsSendCmd ==
FALSE)
1112 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1118 SDH_SDCommand(sdh, 7ul, 0ul);
1142 uint32_t
SDH_Write(
SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
1144 uint32_t
volatile bIsSendCmd =
FALSE;
1145 uint32_t
volatile reg;
1146 uint32_t
volatile i, loop, status;
1159 if (u32SecCount == 0ul)
1164 if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->
RCA, 0ul)) !=
Successful)
1176 sdh->
CMDARG = u32StartSec;
1183 sdh->
DMASA = (uint32_t)pu8BufAddr;
1184 loop = u32SecCount / 255ul;
1185 for (i=0ul; i<loop; i++)
1188 reg = sdh->
CTL & 0xff00c080;
1189 reg = reg | 0xff0000ul;
1215 loop = u32SecCount % 255ul;
1219 reg = (sdh->
CTL & 0xff00c080) | (loop << 16);
1246 if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))
1252 SDH_SDCommand(sdh, 7ul, 0ul);
#define CLK_CLKSEL0_SDH1SEL_Msk
unsigned char volatile DataReadyFlag
#define CLK_CLKDIV3_SDH1DIV_Msk
#define SDH_DMACTL_DMARST_Msk
#define CLK_CLKSEL0_SDH0SEL_HCLK
unsigned int totalSectorN
#define CLK_CLKSEL0_SDH0SEL_Msk
#define SDH_CTL_CTLRST_Msk
#define SDH_GCTL_SDEN_Msk
#define SDH_CTL_CLK74OEN_Msk
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.
#define CLK_CLKSEL0_SDH0SEL_HIRC
#define SDH_INTEN_CDIEN_Msk
#define SDH_GCTL_GCTLRST_Msk
#define SDH_INTSTS_CRC7_Msk
#define TRUE
Boolean true, define to use in API parameters or return value.
#define SDH_DMACTL_DMAEN_Msk
NuMicro peripheral access layer header file.
#define CLK_CLKSEL0_SDH1SEL_HXT
void *__dso_handle __attribute__((weak))
#define FALSE
Boolean false, define to use in API parameters or return value.
#define CardDetect_From_DAT3
#define SDH_CTL_CMDCODE_Msk
#define SDH_INTSTS_CDSTS_Msk
#define CLK_CLKSEL0_SDH1SEL_PLL
#define SDH_CTL_BLKCNT_Pos
uint32_t SDH_Probe(SDH_T *sdh)
This function use to initial SD card.
#define SDH_INTEN_CDSRC_Msk
#define CLK_PWRCTL_HIRCEN_Msk
#define CLK_CLKSEL0_SDH0SEL_HXT
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
#define SDH_CTL_CLKKEEP_Msk
#define CLK_CLKSEL0_SDH0SEL_PLL
uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
#define CLK_CLKDIV0_SDH0DIV_Msk
#define CLK_CLKSEL0_SDH1SEL_HIRC
#define CLK_CLKDIV3_SDH1DIV_Pos
#define SDH_INTSTS_DAT0STS_Msk
__STATIC_INLINE void SYS_UnlockReg(void)
Disable register write-protection function.
#define SDH_CTL_SDNWR_Msk
#define CLK_CLKDIV0_SDH0DIV_Pos
#define SDH_INTEN_BLKDIEN_Msk
uint32_t CLK_GetHCLKFreq(void)
Get HCLK frequency.
#define SDH_INTSTS_CRC16_Msk
void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
This function use to reset SD function and select card detection source and pin.
#define CLK_CLKSEL0_SDH1SEL_HCLK
#define SDH_CTL_SDNWR_Pos
#define SDH_INTSTS_CRCIF_Msk
uint32_t SDH_CardDetection(SDH_T *sdh)
#define SDH_CTL_BLKCNT_Msk
#define SDH_CTL_CLK8OEN_Msk
uint32_t CLK_GetHXTFreq(void)
Get external high speed crystal clock frequency.