?? sddriver.c
字號:
/*******************************************************************************************************
** Descriptions: sd 卡驅動軟件包: SD卡物理層 用戶API函數
********************************************************************************************************/
#include "define.h"
/* SD卡信息結構體變量 the information structure variable of SD Card */
sd_struct sds;
/* 超時時間單位表(單位:0.000000001ns) timeout unit table */
const uint32 time_unit[8] = {1000000000,100000000,10000000,
1000000,100000,10000,1000,100};
/* 超時時間表 timeout value table */
const uint8 time_value[16] = { 0,10,12,13,15,20,25,30,
35,40,45,50,55,60,70,80};
/* 超時時間因數表 timeout factor table */
const uint8 r2w_fator[6] = {1,2,4,8,16,32};
/********************************************************************************************
用戶API函數: 初始化,讀,寫,擦 SD卡 User API Function: Initialize,read,write,erase SD Card
********************************************************************************************/
/*******************************************************************************************************************
** 函數名稱: INT8U SD_Initialize() Name: INT8U SD_Initialize()
** 功能描述: 初始化SD卡 Function: initialize sd card
** 輸 入: 無 Input: NULL
** 輸 出: 0: 正確 >0: 錯誤碼 Output: 0: right >0: error code
********************************************************************************************************************/
uint8 SD_Initialize(void)
{
uint8 recbuf[4],ret;
SD_HardWareInit(); /* 初始化讀寫SD卡的硬件條件 Initialize the hardware that access SD Card */
SPI_CS_Assert(); /* 1. 置CS為低 assert CS */
SD_SPIDelay(30); /* 2. 至少延時 74 clock delay more than 74 clock */
SPI_CS_Deassert(); /* 3. 置CS為高 dessert CS */
SD_SPIDelay(3); /* 4. 延時2(8 clock) delay 2(8 clock) */
ret = SD_ResetSD(); /* 5. 發出CMDO命令復位SD卡 send CMD0 command to reset sd card */
if (ret != SD_NO_ERR)
return ret;
ret = SD_ActiveInit(); /* 6. 激活卡進入初始化過程. active card initialize process */
if (ret != SD_NO_ERR)
return ret;
ret = SD_ReadOCR(4, recbuf); /* 7. 讀OCR寄存器,查詢卡支持的電壓值 read OCR register,get the supported voltage */
if (ret != SD_NO_ERR)
return ret;
if ((recbuf[1] & MSK_OCR_33) != MSK_OCR_33)
return SD_ERR_VOL_NOTSUSP; /* 不支持3.3V,返回錯誤碼 not support 3.3V,return error code */
SPI_ClkToMax(); /* 8. 設置SPI時鐘到最大值 set SPI clock to maximum */
#if SD_CRC_EN
ret = SD_EnableCRC(1); /* 使能CRC校驗 enable CRC check */
if (ret != SD_NO_ERR)
return ret;
#endif
ret = SD_SetBlockLen(SD_BLOCKSIZE); /* 9. 設置塊的長度: 512Bytes Set the block length: 512Bytes */
if (ret != SD_NO_ERR)
return ret;
return (SD_GetCardInfo()); /* 10. 讀CSD寄存器,獲取SD卡信息 read CSD register, get the information of SD card */
}
/*******************************************************************************************************************
** 函數名稱: INT8U SD_GetCardInfo() Name: INT8U SD_GetCardInfo()
** 功能描述: 獲得SD卡的信息 Function: get the information of SD card
** 輸 入: INT8U cardtype: 卡類型 Input: INT8U cardtype: card type
** 輸 出: 0: 正確 >0: 錯誤碼 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); /* 計算超時時間值 calculate timeout value */
/* 計算塊的最大長度 */ /* calculate the size of a sector */
sds.block_len = 1 << (csdbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK); /* (2 ^ READ_BL_LEN) */
/* 計算卡中塊的個數 */ /* 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) */
/* 獲得卡中塊的數量 */ /* get the block numbers in card */
sds.block_num = sds.block_num * (1 << tmp); /* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
/* 計算扇區大小 */ /*calculate the size of sector */
sds.erase_unit = ((csdbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) +
((csdbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1; /* SD (SECTOR_SIZE + 1) */
return SD_NO_ERR; /* 返回執行成功 return perform sucessfully */
}
/*******************************************************************************************************************
** 函數名稱: INT8U SD_CalTimeout() Name: INT8U SD_CalTimeout()
** 功能描述: 計算讀/寫/擦超時時間 Function: get the information of SD card
** 輸 入: INT8U cardtype: 卡類型 Input: INT8U cardtype: card type
INT8U *csdbuf : CSD寄存器內容 INT8U *csdbuf : CSD register content
** 輸 出: 0: 正確 >0: 錯誤碼 Output: 0: right >0: error code
*******************************************************************************************************************/
void SD_CalTimeout(uint8 *csdbuf)
{
uint32 tmp;
uint8 time_u,time_v,fator;
sds.timeout_read = READ_TIMEOUT_100MS; /* 默認讀超時為100ms */
sds.timeout_write = WRITE_TIMEOUT_250MS; /* 默認寫超時為250ms */
sds.timeout_erase = WRITE_TIMEOUT_250MS;
time_u = (csdbuf[TAAC_POS] & TAAC_MSK); /* 讀超時時間單位 read timeout unit */
time_v = (csdbuf[TAAC_POS] & NSAC_MSK) >> 3; /* 讀超時時間值 read timeout value */
fator = (csdbuf[R2WFACTOR_POS] & R2WFACTOR_MSK) >> 2; /* 寫超時時間因數 write timeout factor */
if(time_v == 0) return;
if(fator >= 6) return;
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) */
/* 計算得到的超時值 the timeout value of being calculated */
sds.timeout_read = tmp;
sds.timeout_write = tmp * r2w_fator[fator]; /* (TACC * f + NSAC * 100) * R2WFACTOR (單位 unit:clock)*/
sds.timeout_read = sds.timeout_read * 100 / 8; /* 實際值為計算值的100倍 */
sds.timeout_write = sds.timeout_write * 100 / 8;
if (sds.timeout_read > READ_TIMEOUT_100MS) /* 取計算值與默認值中的最小值 */
sds.timeout_read = READ_TIMEOUT_100MS;
if (sds.timeout_write > WRITE_TIMEOUT_250MS)
sds.timeout_write = WRITE_TIMEOUT_250MS;
sds.timeout_erase = sds.timeout_write;
}
/*******************************************************************************************************************
** 函數名稱: INT8U SD_CalTimeout() Name: INT8U SD_CalTimeout()
** 功能描述: 計算讀/寫/擦超時時間 Function: get the information of SD card
** 輸 入: INT8U *cardtype: 卡類型接收緩沖 Input: INT8U *cardtype: card type receive buff
** 輸 出: 0: 正確 >0: 錯誤碼 Output: 0: right >0: error code
** 函數說明: 該命令不斷重復發送到SD卡,直到響應R1的Bit0(Idle)位為0,表示SD卡內部初始化處理完成。
當響應的Idle位為0時,SD卡就完全進入SPI模式了。當然重復發送命令CMD1是有次數限制的,
最大次數為宏定義SD_IDLE_WAIT_MAX.
*******************************************************************************************************************/
uint8 SD_ActiveInit(void)
{
uint8 param[4] = {0,0,0,0},resp[5],ret;
uint32 i = 0;
do
{ /* 發出CMD1, 查詢卡的狀態, 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));
/* 如果響應R1的最低位Idle位為1,則繼續循環 */
if (i >= SD_IDLE_WAIT_MAX)
return SD_ERR_TIMEOUT_WAITIDLE; /* 超時,返回錯誤 time out,return error */
return SD_NO_ERR;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -