📄 fs_sdmmc_dev.c
字号:
Sdmmc_to_cnt++;
}
//FS_sdmmc_delay(400);
Sdmmc_to_cnt = 0;
#if 0
while (0 == (CMD_RESP_INT & ReadReg32(SDMMC_SD_INT)))
{
// while (SDMMC_CMD_RESP_TX_INT_STAT_YES != (SDMMC_CMD_RESP_TX_INT_STAT_YES & ReadReg32(SDMMC_SD_INT))) {
if (Sdmmc_to_cnt > 0x10000000)
{
//printf("Socle SD/MMC: comamnd%d and response it timeout\n", cmd_abbr);
return -1;
}
Sdmmc_to_cnt++;
}
#endif
WriteReg32(SDMMC_SD_INT, (ReadReg32(SDMMC_SD_INT) & (~SDMMC_CMD_RESP_TX_INT_STAT_YES)));
#else
while (0 == (CMD_RESP_INT & CardIntStatus))
{
if (Sdmmc_to_cnt > 0x1000000)
{
return -1;
}
Sdmmc_to_cnt++;
}
CardIntStatus &= ~CMD_RESP_INT;
#endif
/* Check whether command transfer cause errors */
rdata = ReadReg32(SDMMC_SD_CMDREST);
if (SDMMC_CMD_RESP_TX_STAT_ERR == (rdata & SDMMC_CMD_RESP_TX_STAT_ERR))
{
//goto send_cmd_error;
rdata = ReadReg32(SDMMC_SD_CMDREST);
return rdata;
}
return 0;
}
volatile uint32 SdTansIsrFlag;
void SdTansIsrProc(void)
{
SdTansIsrFlag = 0;
}
/*********************************************************************************************************
*函数描述: 动态设置卡的运行频率
*入口参数: 无
*出口参数: 无
*调用函数: WriteReg32, ReadReg32
*
* History:
* <author> <time> <version> <desc>
* Xiebangwang 2008-03-18 1.0 x
*********************************************************************************************************/
void SdmmcSetFrequency(void)
{
UINT32 freq;
freq = Pll_get_apb_freq();
if (freq <= 40000)
{
MMC_Divider = 0;
SD_Divider = 0;
}
else if (freq < 51000)
{
MMC_Divider = 1;
SD_Divider = 0;
}
else
{
MMC_Divider = 1;
SD_Divider = 1;
}
if ((prevMMC_Divider != MMC_Divider) || (prevSD_Divider != SD_Divider))
{
/* Change clock rate to enter the data transfer mode */
if (MMC_CARD != SdmmcCardType)
{
WriteReg32(SDMMC_SD_CTRL, (ReadReg32(SDMMC_SD_CTRL)&0xF800) | SD_Divider);
}
else
{
WriteReg32(SDMMC_SD_CTRL, (ReadReg32(SDMMC_SD_CTRL)&0xF800) | MMC_Divider);
}
}
prevMMC_Divider = MMC_Divider;
prevSD_Divider = SD_Divider;
}
/*********************************************************************************************************
*函数描述: 获取卡的拔插状态
*入口参数: 无
*出口参数: TRUE--表示卡是插入状态; FALSE--表示卡处于拔出状态
*调用函数:
*
* History:
* <author> <time> <version> <desc>
* Xiebangwang 2008-03-12 1.0 检查当前卡的拔插状态
*********************************************************************************************************/
int SdmmcInsertState(void)
{
uint32 rdata;
uint32 InsertState;
rdata = GPIO_GetPinLevel(SD_DETECT_PIN);
#if (SDCheckInsetLevel == 0)
if (rdata == 1)
#else
if (rdata == 0)
#endif
{
InsertState = FALSE;
}
else
{
InsertState = TRUE;
}
return InsertState;
}
/*********************************************************************************************************
*函数描述: SD卡忙状态检测
*入口参数: 无
*出口参数: 0表示正确,非0表示错误
*调用函数:
*
* History:
* <author> <time> <version> <desc>
* Xiebangwang 2008-03-08 1.0 检测写函数是否完全结束
*********************************************************************************************************/
int SdmmcChkBusy(void)
{
int i, rep;
rep = 0;
do
{
WriteReg32(SDMMC_MMU_CTRL, SDMMC_MMU_DATA_WIDTH_WORD);
WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
SDMMC_DATA_TX_DIR_READ |
SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
SDMMC_DATA_TX_DMA_DIS |
SDMMC_DATA_TX_CYC_MULTIPLE);
Sdmmc_data_transfer_end();
Sdmmc_mmu_swap();
for (i = 128; i != 0; i--)
{
if (0xFFFFFFFF == ReadReg32(SDMMC_MMU_DATA))
{
break;
}
}
if (i != 0)
{
break;
}
rep++;
}
while (rep < 5);
if (rep >= 5)
return 222;
else
return 0;
}
/*********************************************************************************************************
*函数描述: 读SD卡
*入口参数: 块地址,块数,写数据缓冲。
*出口参数: 0表示正确,非0表示错误
*调用函数: WriteReg32, Sdmmc_send_cmd, Sdmmc_data_transfer_end, Sdmmc_mmu_swap, ReadReg32
*
* History:
* <author> <time> <version> <desc>
* LXS,FZF 1.0 采用关中断方法
*
* Xiebangwang 2008-02-16 2.0 取消关中断操作,改变读函数设置时序
* Xiebangwang 2008-02-27 2.1 修改LBA,兼容Ver2.00 or later SD Memory Card
*
*********************************************************************************************************/
int SdmmcReadMSecs(unsigned long LBA, unsigned int count, void *buf)
{
int i;
unsigned int *rbuf;
unsigned int cnt;
int rt = 0; //本函数返回值,0表示正确,非0表示错误
int repeat_times = 0; // 数据传输不成功时,重复读的次数
if (count < 1) //防止非法参数
{
return (-1);
}
/*动态改变卡的运行频率,使卡运行于最佳频率*/
SdmmcSetFrequency();
/* If it is not SDHC,the memory address shoud be in the byte address format */
if (SdmmcCardType != HC_SD_CARD)
{
LBA = LBA << 9; /* convert block number to byte address */
}
Scu_ClockEnable(SDMMC_CLOCK);
for (repeat_times = 0; repeat_times < 20; repeat_times++)
{
rbuf = (unsigned int *)buf;
cnt = count;
rt = 0;
WriteReg32(SDMMC_MMU_CTRL, SDMMC_MMU_DATA_WIDTH_WORD);
if (cnt > 1)
{
WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
SDMMC_DATA_TX_DIR_READ |
SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
SDMMC_DATA_TX_DMA_DIS |
SDMMC_DATA_TX_CYC_MULTIPLE);
}
else
{
WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
SDMMC_DATA_TX_DIR_READ |
SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
SDMMC_DATA_TX_DMA_DIS |
SDMMC_DATA_TX_CYC_SINGLE);
}
/* Send CMD18 to read blocks */
if (Sdmmc_send_cmd(MMC_READ_MULTIPLE_BLOCK, LBA))
{
rt = -2;
}
else
{
while (cnt > 0)
{
/* Wait for the reading transmission to be complete */
if (Sdmmc_data_transfer_end())
{
rt = -3;
break;
}
Sdmmc_mmu_swap();
cnt --;
if (cnt == 0)
{
Sdmmc_delay(200);
/* Send CMD12 to stop the transimission */
if (Sdmmc_send_cmd(MMC_STOP_TRANSMISSION, 0x00000000))
{
rt = -4;
break;
}
}
else if (cnt == 1)
{
WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
SDMMC_DATA_TX_DIR_READ |
SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
SDMMC_DATA_TX_DMA_DIS |
SDMMC_DATA_TX_CYC_SINGLE);
}
else
{
WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
SDMMC_DATA_TX_DIR_READ |
SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
SDMMC_DATA_TX_DMA_DIS |
SDMMC_DATA_TX_CYC_MULTIPLE);
}
for (i = 128; i != 0; i--)
{
*rbuf++ = ReadReg32(SDMMC_MMU_DATA);
}
}
}
if (rt == 0)
{
break;
}
else
{
if (!SdmmcInsertState())
{
Scu_ClockDisable(SDMMC_CLOCK);
return rt; //若是由于,拔卡出现错误,直接退出
}
Sdmmc_delay(200);
/* Send CMD12 to stop the transimission */
Sdmmc_send_cmd(MMC_STOP_TRANSMISSION, 0x00000000);
}
}
#if 0
//下面仅用于设置调试断点
if ((repeat_times == 20) && (rt != 0))
{
int j ;
ReadReg32(SDMMC_SD_CMDREST);
j = 10 ;
cnt++;
}
#endif
Scu_ClockDisable(SDMMC_CLOCK);
return rt;
}
/*********************************************************************************************************
*函数描述: SD卡写函数
*入口参数: 块地址,块数,写数据缓冲。
*出口参数: 0表示正确,非0表示错误
*调用函数: WriteReg32, Sdmmc_send_cmd, Sdmmc_data_transfer_end, Sdmmc_mmu_swap, ReadReg32
*
* History:
* <author> <time> <version> <desc>
* LXS,FZF 1.0 采用关中断方法
*
* Xiebangwang 2008-02-16 2.0 取消关中断操作,改变读函数设置时序
* Xiebangwang 2008-02-27 2.1 修改LBA,兼容Ver2.00 or later SD Memory Card
*
*********************************************************************************************************/
int SdmmcWriteMSecs(unsigned long LBA, unsigned int count, void *buf)
{
unsigned long i;
unsigned long rdata;
unsigned int *rbuf;
unsigned long Sdmmc_to_cnt;
int rt = 0;
int repeat_times;
unsigned int cnt;
char bufIdentify[2];
if (count < 1) //防止非法参数
{
return (1);
}
bufIdentify[0] = *((char*)buf + 510);
bufIdentify[1] = *((char*)buf + 511);
/*动态改变卡的运行频率,使卡运行于最佳频率*/
SdmmcSetFrequency();
/* If it is not SDHC,the memory address should be in the byte address format */
if (SdmmcCardType != HC_SD_CARD)
{
LBA = LBA << 9; /* convert block number to byte address */
}
repeat_times = 0;
Scu_ClockEnable(SDMMC_CLOCK);
while (repeat_times < 20)
{
rbuf = (unsigned int *)buf;
cnt = count;
WriteReg32(SDMMC_MMU_CTRL, SDMMC_MMU_DATA_WIDTH_WORD);
for (i = 128; i != 0; i--)
{
WriteReg32(SDMMC_MMU_DATA, *rbuf++);
}
//Sdmmc_send_cmd(MMC_APP_CMD, SdmmcCardRca); // CMD55(), Make ACMD
//Sdmmc_send_cmd(SD_SET_WR_BLK_ERASE_COUNT,0xff800000|count); // ACMD23 (count) pre erase
/* CMD25 WRITE MULTIPLE BLOCKs */
if (Sdmmc_send_cmd(MMC_WRITE_MULTIPLE_BLOCK, LBA))
{
rt = -1;
goto Repeat_Wrtie_Test;
}
while (cnt > 0)
{
Sdmmc_mmu_swap();
if (cnt == 1)
{
WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
SDMMC_DATA_TX_DIR_WRITE |
SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
SDMMC_DATA_TX_DMA_DIS |
SDMMC_DATA_TX_CYC_SINGLE);
}
else
{
WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
SDMMC_DATA_TX_DIR_WRITE |
SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
SDMMC_DATA_TX_DMA_DIS |
SDMMC_DATA_TX_CYC_MULTIPLE);
for (i = 128; i != 0; i--)
{
WriteReg32(SDMMC_MMU_DATA, *rbuf++);
}
}
/* Wait for the writing transmission to be complete */
if (Sdmmc_data_transfer_end())
{
rt = -3;
break;
}
cnt--;
}
/* Send CMD12 to stop the transimission */
if (Sdmmc_send_cmd(MMC_STOP_TRANSMISSION, 0x00000000))
{
rt = -4;
}
/* Wait for the card to depart from the busy state */
Sdmmc_to_cnt = 0;
do
{
if (Sdmmc_to_cnt > 0x1000000)
{
rt = -5;
break;
}
rdata = ReadReg32(SDMMC_SD_CARDA);
Sdmmc_to_cnt++;
}
while (SDMMC_CARD_BUSY_SIGNAL_HIGH != (rdata & SDMMC_CARD_BUSY_SIGNAL_HIGH));
Repeat_Wrtie_Test:
if (rt == 0)
{
break;
}
if (!SdmmcInsertState())
{
Scu_ClockDisable(SDMMC_CLOCK);
return rt; //若是由于,拔卡出现错误,直接退出
}
repeat_times ++;
}
if ((count >= 0x20) && (count <= 0x26) && (0x55 == bufIdentify[0]) && (0x0AA == bufIdentify[1]))
{
SdmmcChkBusy();
}
Scu_ClockDisable(SDMMC_CLOCK);
return(rt);
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -