?? sddriver.c
字號(hào):
if (ret == SD_NO_ERR)
sendbuf = sendbuf + SD_BLOCKSIZE;
else
{ /* 寫(xiě)失敗 write fail */
SD_StopTransmission(); /* 停止數(shù)據(jù)傳輸 stop data transmission */
SD_WaitBusy(SD_WAIT_WRITE); /* 等待 waiting */
SD_EndSD();
return ret;
}
}
SD_StopMultiToken(); /* 發(fā)送數(shù)據(jù)停止令牌 send data stop token */
ret = SD_WaitBusy(SD_WAIT_WRITE); /* 等待寫(xiě)入的完成 wait for finishing writing */
if (ret != SD_NO_ERR)
{
SD_EndSD();
return SD_ERR_TIMEOUT_WRITE;
}
if (sds.card_type == CARDTYPE_SD)
{
ret = SD_GetNumWRBlcoks(&i); /* 讀正確寫(xiě)入的塊數(shù) read the blocks that be written correctly */
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret;
}
if(i != blocknum)
ret = SD_ERR_WRITE_BLKNUMS; /* 正確寫(xiě)入塊數(shù)錯(cuò)誤 the blocks that be written correctly is error */
}
else
{
ret = SD_ReadCard_Status(2, tmp);
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret; /* 讀寄存器失敗 read register fail */
}
if((tmp[0] != 0) || (tmp[1] != 0))
ret = SD_ERR_WRITE_BLK; /* 響應(yīng)指示寫(xiě)失敗 response indicate write fail */
}
SD_EndSD();
return ret; /* 返回寫(xiě)入成功 return write sucessfully */
}
#endif
/*********************************************************************************************************************
** 函數(shù)名稱(chēng): uint8 SD_EraseBlock() Name: uint8 SD_EraseBlock()
** 功能描述: 擦除SD/MMC卡中的塊 Function: Erase the block of SD/MMC card
** 輸 入: uint32 startaddr: 起始地址 Input: uint32 startaddr: start address
uint32 endaddr : 終止地址 uint32 endaddr : end address
** 輸 出: 0: 成功 >0: 錯(cuò)誤碼 Output: 0: right >0: error code
** 注 意: startaddr 和 blocknum 建議為 sds.erase_unit 的整數(shù)倍, 因?yàn)橛械目ㄖ荒芤?sds.erase_unit 為單位進(jìn)行擦除
*********************************************************************************************************************/
#if SD_EraseBlock_EN
uint8 SD_EraseBlock(uint32 startaddr, uint32 blocknum)
{
uint32 tmp;
uint8 ret;
SD_StartSD(); /* 向OS申請(qǐng)?jiān)L問(wèn)卡信號(hào)量 request semaphore acessed SD/MMC to OS */
if (SD_ChkCard() != 1)
{
SD_EndSD();
return SD_ERR_NO_CARD; /* 卡沒(méi)完全插入卡中 card is not inserted entirely */
}
if ((startaddr + blocknum) > sds.block_num)
{
SD_EndSD();
return SD_ERR_OVER_CARDRANGE; /* 操作超出卡容量范圍 operate over the card range */
}
if (SD_ChkCardWP() == 1)
{
SD_EndSD();
return SD_ERR_WRITE_PROTECT; /* 卡有寫(xiě)保護(hù) */
}
tmp = blocknum - sds.erase_unit;
while(tmp >= 0) /* 每次擦除扇區(qū) once erase is sector size */
{
ret = SD_EraseStartBlock(startaddr); /* 選擇起始?jí)K地址 select start address */
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret;
}
ret = SD_EraseEndBlock(startaddr + sds.erase_unit - 1); /* 選擇終止塊地址 select end address */
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret;
}
ret = SD_EraseSelectedBlock(); /* 擦除所選的塊 erase blocks selected */
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret;
}
startaddr += sds.erase_unit; /* 起始地址遞增 */
blocknum -= sds.erase_unit;
tmp = blocknum - sds.erase_unit;
};
if (blocknum > 0) /* 擦除不夠once_erase塊 */
{ /* erase blocks that numbers is not enough once_erase */
ret = SD_EraseStartBlock(startaddr);
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret;
}
ret = SD_EraseEndBlock(startaddr + blocknum - 1);
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret;
}
ret = SD_EraseSelectedBlock();
if (ret != SD_NO_ERR)
{
SD_EndSD();
return ret;
}
}
SD_EndSD();
return SD_NO_ERR; /* 返回擦除成功 return erase sucessfully */
}
#endif
/*****************************************************************
下面為子程序
*****************************************************************/
/*******************************************************************************************************************
** 函數(shù)名稱(chēng): uint8 SD_GetCardInfo() Name: uint8 SD_GetCardInfo()
** 功能描述: 獲得SD/MMC卡的信息 Function: get the information of SD/MMC card
** 輸 入: uint8 cardtype: 卡類(lèi)型 Input: uint8 cardtype: card type
** 輸 出: 0: 成功 >0: 錯(cuò)誤碼 Output: 0: right >0: error code
*******************************************************************************************************************/
uint8 SD_GetCardInfo()
{
uint32 tmp;
uint8 csdbuf[16],ret;
ret = SD_ReadCSD(16, csdbuf); /* 讀CSD寄存器 read CSD register */
if (ret != SD_NO_ERR)
return ret;
SD_CalTimeout(csdbuf); /* 計(jì)算超時(shí)時(shí)間值 calculate timeout value */
/* 計(jì)算塊的最大長(zhǎng)度 */ /* calculate the size of a sector */
sds.block_len = 1 << (csdbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK); /* (2 ^ READ_BL_LEN) */
/* 計(jì)算卡中塊的個(gè)數(shù) */ /* calculate the sector numbers of the SD Card */
sds.block_num = ((csdbuf[C_SIZE_POS1] & C_SIZE_MSK1) << 10) +
(csdbuf[C_SIZE_POS2] << 2) +
((csdbuf[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1; /* (C_SIZE + 1)*/
tmp = ((csdbuf[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) +
((csdbuf[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2; /* (C_SIZE_MULT + 2) */
/* 獲得卡中塊的數(shù)量 */ /* get the block numbers in card */
sds.block_num = sds.block_num * (1 << tmp); /* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
/* 計(jì)算擦除的單位(單位: 塊) */
if (sds.card_type == CARDTYPE_MMC)
{
tmp = ((csdbuf[ERASE_GRP_SIZE_POS] & ERASE_GRP_SIZE_MSK) >> 2) + 1; /* (ERASE_GRP_SIZE + 1) */
/* (ERASE_GRP_SIZE + 1) * (ERASE_GRP_MULTI + 1) */
tmp *= ((csdbuf[ERASE_GRP_MULTI_POS1] & ERASE_GRP_MULTI_MSK1) << 3) +
((csdbuf[ERASE_GRP_MULTI_POS2] & ERASE_GRP_MULTI_MSK2) >> 5) + 1;
}
else /*calculate the size of sector */
tmp = ((csdbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) +
((csdbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1; /* SD: SECTOR_SIZE */
sds.erase_unit = tmp; /* 擦除單位(塊) */
return SD_NO_ERR; /* 返回執(zhí)行成功 return perform sucessfully */
}
/*******************************************************************************************************************
** 函數(shù)名稱(chēng): uint8 SD_CalTimeout() Name: uint8 SD_CalTimeout()
** 功能描述: 計(jì)算讀/寫(xiě)/擦超時(shí)時(shí)間 Function: calculate timeout of reading,writing,erasing
** 輸 入: uint8 *csdbuf : CSD寄存器內(nèi)容 Input: uint8 *csdbuf : CSD register content
** 輸 出: 0: 成功 >0: 錯(cuò)誤碼 Output: 0: right >0: error code
*******************************************************************************************************************/
uint8 SD_CalTimeout(uint8 *csdbuf)
{
uint32 tmp;
uint8 time_u,time_v,fator;
sds.timeout_read = READ_TIMEOUT_100MS; /* 默認(rèn)讀超時(shí)為100ms */
sds.timeout_write = WRITE_TIMEOUT_250MS; /* 默認(rèn)寫(xiě)超時(shí)為250ms */
sds.timeout_erase = WRITE_TIMEOUT_250MS;
time_u = (csdbuf[TAAC_POS] & TAAC_MSK); /* 讀超時(shí)時(shí)間單位 read timeout unit */
time_v = (csdbuf[TAAC_POS] & NSAC_MSK) >> 3; /* 讀超時(shí)時(shí)間值 read timeout value */
fator = (csdbuf[R2WFACTOR_POS] & R2WFACTOR_MSK) >> 2; /* 讀超時(shí)時(shí)間因數(shù) read timeout factor */
if(time_v == 0) return SD_ERR_CARD_PARAM; /* 卡參數(shù)有錯(cuò)誤 card parameter is error */
tmp = SPI_CLOCK * time_value[time_v] / 10 / time_unit[time_u]; /* TACC * f (單位 unit: clock) */
tmp = tmp + csdbuf[NSAC_POS] * 100; /* TACC * f + NSAC * 100 (單位 unit: clock) */
/* 計(jì)算得到的超時(shí)值 the timeout value of being calculated */
sds.timeout_read = tmp;
sds.timeout_write = tmp * r2w_fator[fator]; /* (TACC * f + NSAC * 100) * R2WFACTOR (單位 unit:clock)*/
if (sds.card_type == CARDTYPE_SD)
{
sds.timeout_read = sds.timeout_read * 100 / 8; /* 實(shí)際值為計(jì)算值的100倍 */
sds.timeout_write = sds.timeout_write * 100 / 8;
if (sds.timeout_read > READ_TIMEOUT_100MS) /* 取計(jì)算值與默認(rèn)值中的最小值 */
sds.timeout_read = READ_TIMEOUT_100MS;
if (sds.timeout_write > WRITE_TIMEOUT_250MS)
sds.timeout_write = WRITE_TIMEOUT_250MS;
}
else
{
sds.timeout_read = sds.timeout_read * 10 / 8; /* 實(shí)際值為計(jì)算值的10倍 */
sds.timeout_write = sds.timeout_write * 10 / 8;
}
sds.timeout_erase = sds.timeout_write;
#if SD_UCOSII_EN
sds.timeout_read = (sds.timeout_read << 3) * OS_TICKS_PER_SEC / SPI_CLOCK;
sds.timeout_write =(sds.timeout_write << 3) * OS_TICKS_PER_SEC / SPI_CLOCK;
sds.timeout_erase = sds.timeout_write; /* (單位 unit: os tick) */
#endif
return SD_NO_ERR;
}
/*******************************************************************************************************************
** 函數(shù)名稱(chēng): uint8 SD_ActiveInit() Name: uint8 SD_ActiveInit()
** 功能描述: 激活卡,并獲得卡型 Function: active card, and get the card type
** 輸 入: 無(wú) Input: NULL
** 輸 出: 0: 成功 >0: 錯(cuò)誤碼 Output: 0: right >0: error code
** 函數(shù)說(shuō)明: 該命令不斷重復(fù)發(fā)送到SD卡,直到響應(yīng)R1的Bit0(Idle)位為0,表示SD卡內(nèi)部初始化處理完成。
當(dāng)響應(yīng)的Idle位為0時(shí),SD卡就完全進(jìn)入SPI模式了。當(dāng)然重復(fù)發(fā)送命令CMD1是有次數(shù)限制的,
最大次數(shù)為宏定義SD_IDLE_WAIT_MAX.
*******************************************************************************************************************/
uint8 SD_ActiveInit(void)
{
uint8 param[4] = {0,0,0,0},resp[5],ret;
uint32 i = 0;
do
{ /* 發(fā)出CMD1, 查詢(xún)卡的狀態(tài), send CMD1 to poll card status */
ret = SD_SendCmd(CMD1, param, CMD1_R, resp);
if (ret != SD_NO_ERR)
return ret;
i ++;
}while (((resp[0] & MSK_IDLE) == MSK_IDLE) && (i <= SD_IDLE_WAIT_MAX));
/* 如果響應(yīng)R1的最低位Idle位為1,則繼續(xù)循環(huán) */
/* if response R1 Idle bit is 1,continue recycle */
if (i >= SD_IDLE_WAIT_MAX)
return SD_ERR_TIMEOUT_WAITIDLE; /* 超時(shí),返回錯(cuò)誤 time out,return error */
ret = SD_SendCmd(CMD55, param, CMD55_R, resp);
if (ret != SD_NO_ERR)
return ret;
ret = SD_SendCmd(ACMD41, param, ACMD41_R, resp); /* 激活內(nèi)部初始化命令 active card to initialize process internal */
if (ret != SD_NO_ERR)
return SD_ERR_UNKNOWN_CARD;
if ((resp[0] & 0xFE) == 0)
sds.card_type = CARDTYPE_SD; /* 是SD卡 the card is SD card */
else
sds.card_type = CARDTYPE_MMC; /* 是MMC卡 the card is MMC card */
return SD_NO_ERR;
}
/*******************************************************************************************************************
** 函數(shù)名稱(chēng): void SD_StartSD() Name: uint8 SD_StartSD()
** 功能描述: 向操作系統(tǒng)申請(qǐng)?jiān)L問(wèn)SD卡的權(quán)限 Function: request the right of operating sd to OS
** 輸 入: 無(wú) Input: NULL
** 返 回: 無(wú) return: NULL
********************************************************************************************************************/
void SD_StartSD(void)
{
#if SD_UCOSII_EN
uint8 ret;
OSSemPend(pSemSD, 0, &ret); /* 等待訪問(wèn)卡信號(hào)量可用 wait for semaphore that accessed Card */
#endif
}
/*******************************************************************************************************************
** 函數(shù)名稱(chēng): void SD_EndSD() Name: uint8 SD_EndSD()
** 功能描述: 訪問(wèn)SD卡的權(quán)限歸還操作系統(tǒng) Function: return the right of operating sd to OS
** 輸 入: 無(wú) Input: NULL
** 返 回: 無(wú) return: NULL
********************************************************************************************************************/
void SD_EndSD(void)
{
#if SD_UCOSII_EN
OSSemPost(pSemSD); /* 將訪問(wèn)卡信號(hào)量還給操作系統(tǒng) return the semaphore accessing Card to OS */
#endif
}
/*******************************************************************************************************************
** 函數(shù)名稱(chēng): INT16U SD_GetZLGSDVer() Name: INT16U SD_GetZLGSDVer()
** 功能描述: 得到ZLG/SD的版本號(hào) Function: get the version of ZLG/SD
** 輸 入: 無(wú) Input: NULL
** 輸 出: 版本號(hào) Output: Version
** 版本記錄:
V1.0 支持訪問(wèn)SD 卡,只能在前后臺(tái)系統(tǒng)運(yùn)行
V2.0 支持訪問(wèn)SD和MMC卡,可運(yùn)行于前后系統(tǒng)或UCOS-II
*******************************************************************************************************************/
uint16 SD_GetZLGSDVer(void)
{
return 0x0200; /* 版本號(hào)為 2.00 */
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -