?? sd_cmd.c
字號:
/*--------------File Info-------------------------------------------------------
** 文 件 名: SD_Cmd.c
** 最后修改日期: 2008.3.28
** 版 本: V1.0
** 描 述: sd 卡驅動軟件包: SD卡物理層
**------------------------------------------------------------------------------
** Created by:
** Created date:
*******************************************************************************/
#include "SYS_Config.h"
#include "SD_Config.h"
#include "SD_Hal.h"
#include "SD_CRC.h"
#include "SD_Cmd.h"
#include "SD_Drive.h"
/*******************************************************************************
** 函數名稱: INT8U SD_SendCmd()
** 功能描述: 向卡發送命令,并取得響應
** 輸 入: INT8U cmd : 命令字
INT8U *param : 命令參數,長度為4字節
INT8U resptype : 響應類型
INT8U *resp : 響應,長度為1-5字節
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_SendCmd(INT8U cmd,INT8U *param,INT8U resptype,INT8U *resp)
{
INT32S i,rlen ;
INT8U tmp ;
SPI_CS_Assert();
SPI_SendByte((cmd&0x3F)|0x40);
/* 發送命令頭和命令字 send command header and word */
for(i=3;i>=0;i--)
SPI_SendByte(param[i]);
/* 發送參數 send parameters */
#if SD_CRC_EN
tmp=SD_GetCmdByte6((cmd&0x3F)|0x40,param);
SPI_SendByte(tmp);
#else
SPI_SendByte(0x95);
/* CRC校驗碼,只用于第1個命令 CRC,only used for the first command */
#endif
rlen=0 ;
/* 根據不同的命令,得到不同的響應長度 */
switch(resptype)
{
case R1 :
case R1B:rlen=1 ;break ;
case R2 :rlen=2 ;break ;
case R3 :rlen=5 ;break ;
default :
SPI_SendByte(0xFF);
SPI_CS_Deassert();
return SD_ERR_CMD_RESPTYPE ; // 返回命令響應類型錯誤
break ;
}
i=0 ;
/* 等待響應,響應的開始位為0 */
do
{
/* Wait for a response,a response is a start bit(zero) */
tmp=SPI_RecByte();
i++;
}
while(((tmp&0x80)!=0)&&(i<SD_CMD_TIMEOUT));
if(i>=SD_CMD_TIMEOUT)
{
SPI_CS_Deassert();
return SD_ERR_CMD_TIMEOUT ;
/* 返回命令超時 return response timeout of command */
}
for(i=rlen-1;i>=0;i--)
{
resp[i]=tmp ;
tmp=SPI_RecByte();
/* 循環的最后發送8clock at the last recycle,clock out 8 clock */
}
SPI_CS_Deassert();
return SD_NO_ERR ;
/* 返回執行成功 return perform sucessfully */
}
/*******************************************************************************
** 函數名稱: void SD_PackParam()
** 功能描述: 將32位的參數轉為字節形式
** 輸 入: INT8U *parameter: 字節參數緩沖區
INT32U value : 32位參數
** 輸 出: 無
*******************************************************************************/
void SD_PackParam(INT8U *parameter,INT32U value)
{
parameter[3]=(INT8U)(value>>24);
parameter[2]=(INT8U)(value>>16);
parameter[1]=(INT8U)(value>>8);
parameter[0]=(INT8U)(value);
}
/*******************************************************************************
** 函數名稱: INT8U SD_BlockCommand()
** 功能描述: 塊命令
** 輸 入: INT8U cmd : 命令字
INT8U resptype : 響應類型
INT32U parameter: 塊操作參數
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_BlockCommand(INT8U cmd,INT8U resptype,INT32U parameter)
{
INT8U param[4],resp,ret ;
parameter<<=SD_BLOCKSIZE_NBITS ;
/* 調整地址:左移9位 adjust address: move 9 bits left */
SD_PackParam(param,parameter);
/* 將參數轉化為字節形式 change the parameter to bytes form */
ret=SD_SendCmd(cmd,param,resptype,&resp);
if(ret!=SD_NO_ERR)
return ret ;
/* 結束數據傳輸失敗 stop transmission operation fail */
if(resp!=0)
return SD_ERR_CMD_RESP ;
/* 響應錯誤 response is error */
return SD_NO_ERR ;
}
/*************************************************
下面為SD卡SPI命令
/*******************************************************************************
** 函數名稱: INT8U SD_ResetSD()
** 功能描述: 復位SD卡
** 輸 入: 無
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_ResetSD(void)
{
INT8U param[4]={0,0,0,0},resp ;
return(SD_SendCmd(CMD0,param,CMD0_R,&resp));
/* 復位命令 command that reset sd card */
}
/*******************************************************************************
** 函數名稱: INT8U SD_ReadCSD()
** 功能描述: 讀SD卡的CSD寄存器
** 輸 入: INT8U csdlen : 寄存器長度(固定為16)
INT8U *recbuf : 接收緩沖區
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_ReadCSD(INT8U csdlen,INT8U *recbuf)
{
INT8U param[4]={0,0,0,0},resp,ret ;
ret=SD_SendCmd(CMD9,param,CMD9_R,&resp);
/* 讀CSD寄存器命令 command that read CSD register */
if(ret!=SD_NO_ERR)
return ret ;
if(resp!=0)
return SD_ERR_CMD_RESP ;/* 響應錯誤 response is error */
return(SD_ReadRegister(csdlen,recbuf));
}
/*******************************************************************************
** 函數名稱: INT8U SD_ReadCID()
** 功能描述: 讀SD卡的CID寄存器
** 輸 入: INT8U cidlen : 寄存器長度(固定為16)
INT8U *recbuf : 接收緩沖區
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
#if SD_ReadCID_EN
INT8U SD_ReadCID(INT8U cidlen,INT8U *recbuf)
{
INT8U param[4]={0,0,0,0},resp,ret ;
ret=SD_SendCmd(CMD10,param,CMD10_R,&resp);
/* 讀CID寄存器命令 command that read CID register */
if(ret!=SD_NO_ERR)
return ret ;
if(resp!=0)
return SD_ERR_CMD_RESP ;
/* 響應錯誤 response is error */
return(SD_ReadRegister(cidlen,recbuf));
}
#endif
/*******************************************************************************
** 函數名稱: INT8U SD_StopTransmission()
** 功能描述: 停止數據傳輸
** 輸 入: 無
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_StopTransmission(void)
{
INT8U param[4]={0,0,0,0},resp ;
return(SD_SendCmd(CMD12,param,CMD12_R,&resp));
/* 結束數據傳輸命令失敗 stop transmission command fail */
}
/*******************************************************************************
** 函數名稱: INT8U SD_ReadCard_Status()
** 功能描述: 讀SD卡的 Card Status 寄存器
** 輸 入: INT8U len: 寄存器長度(固定為2)
INT8U *recbuf : 接收緩沖區
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_ReadCard_Status(INT8U len,INT8U *buffer)
{
INT8U param[4]={0,0,0,0};
len=len;
return(SD_SendCmd(CMD13,param,CMD13_R,buffer));
/* 讀 Card Status 寄存器 */
}
/*******************************************************************************
** 函數名稱: INT8U Sd_SetBlockLen()
** 功能描述: 設置一個塊的長度
** 輸 入: INT32U length : 塊的長度值
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_SetBlockLen(INT32U length)
{
INT8U param[4],resp,ret ;
SD_PackParam(param,length);
/* 將參數轉化為字節形式 change the parameter to bytes form */
ret=SD_SendCmd(CMD16,param,CMD16_R,&resp);
if(ret!=SD_NO_ERR)
return ret ;
/* 設置塊的長度為length失敗 set the length of block to length fail */
if(resp!=0)
return SD_ERR_CMD_RESP ;
/* 響應錯誤 response is error */
return SD_NO_ERR ; /* 返回執行成功 return perform sucessfully */
}
/*******************************************************************************
** 函數名稱: INT8U SD_ReadSingleBlock()
** 功能描述: 讀單塊命令
** 輸 入: INT32U blockaddr: 塊地址
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_ReadSingleBlock(INT32U blockaddr)
{
return(SD_BlockCommand(CMD17,CMD17_R,blockaddr));
/* 讀單塊命令 command that read single block */
}
/*******************************************************************************
** 函數名稱: INT8U SD_ReadMultipleBlock()
** 功能描述: 讀多塊命令
** 輸 入: INT32U blockaddr: 塊地址
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_ReadMultipleBlock(INT32U blockaddr)
{
return(SD_BlockCommand(CMD18,CMD18_R,blockaddr));
/* 讀多塊命令 command that read multiple block */
}
/*******************************************************************************
** 函數名稱: INT8U SD_WriteSingleBlock()
** 功能描述: 寫單塊命令
** 輸 入: INT32U blockaddr: block address Input:
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_WriteSingleBlock(INT32U blockaddr)
{
return(SD_BlockCommand(CMD24,CMD24_R,blockaddr));
/* 寫單塊命令 command that write single block */
}
/*******************************************************************************
** 函數名稱: INT8U SD_WriteMultipleBlock()
** 功能描述: 寫多塊命令
** 輸 入: INT32U blockaddr: 塊地址
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_WriteMultipleBlock(INT32U blockaddr)
{
return(SD_BlockCommand(CMD25,CMD25_R,blockaddr));
/* 寫多塊命令 command that write multiple block */
}
/*******************************************************************************
** 函數名稱: INT8U SD_ProgramCSD()
** 功能描述: 寫CSD寄存器
** 輸 入: INT8U *buff : CSD寄存器內容
INT8U len : CSD寄存器長度
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
#if SD_ProgramCSD_EN
INT8U SD_ProgramCSD(INT8U len,INT8U*buff)
{
INT8U param[4]={0,0,0,0},resp,ret ;
if(len!=16)
return SD_ERR_USER_PARAM ;
ret=SD_SendCmd(CMD27,param,CMD27_R,&resp);
/* 發送寫CSD寄存器命令 send command that write CSD */
if(ret!=SD_NO_ERR)
return ret ;
if(resp!=0)
return SD_ERR_CMD_RESP ;
buff[15]=(SD_GetCRC7(buff,15)<<1)+0x01 ;
/* 計算CSD中的crc 位域 calculate crc field in CSD */
return(SD_WriteBlockData(0,16,buff));
}
#endif
#if SD_EraseBlock_EN
/*******************************************************************************
** 函數名稱: INT8U SD_EraseStartBlock()
** 功能描述: 設置塊擦除起始地址
** 輸 入: INT32U startblock: 塊地址
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_EraseStartBlock(INT32U startblock)
{
return(SD_BlockCommand(CMD32,CMD32_R,startblock));
/* 發送擦除起始塊地址 send the start block address of erasing operation */
}
/*******************************************************************************
** 函數名稱: INT8U SD_EraseEndBlock()
** 功能描述: 設置塊擦除終止地址
** 輸 入: INT32U endblock: 塊地址
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_EraseEndBlock(INT32U endblock)
{
return(SD_BlockCommand(CMD33,CMD33_R,endblock));
/* 發送擦除終止塊地址 send the end block address of erasing operation */
}
/*******************************************************************************
** 函數名稱: INT8U SD_EraseSelectedBlock()
** 功能描述: 擦除已選中的塊
** 輸 入: 無
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_EraseSelectedBlock(void)
{
INT8U param[4],resp,tmp ;
SD_PackParam(param,0);
tmp=SD_SendCmd(CMD38,param,CMD38_R,&resp);
/* 擦除所選擇的塊 erase blocks selected */
if(tmp!=SD_NO_ERR)
return tmp ;
/* 等待擦除完成 wait for finishing erasing */
if(SD_WaitBusy(SD_WAIT_ERASE)!=SD_NO_ERR)
return SD_ERR_TIMEOUT_ERASE ;
else
return SD_NO_ERR ;
}
#endif
/******************************************************************************
** 函數名稱: INT8U SD_ReadOCR()
** 功能描述: 讀操作條件寄存器OCR
** 輸 入: INT8U ocrlen : 寄存器長度(固定為4)
INT8U *recbuf : 接收緩沖區
** 輸 出: 0: 正確 >0: 錯誤碼
*******************************************************************************/
INT8U SD_ReadOCR(INT8U ocrlen,INT8U *recbuf)
{
INT8U param[4]={0,0,0,0},resp[5],tmp ;
ocrlen=ocrlen;
tmp=SD_SendCmd(CMD58,param,CMD58_R,resp);
/* 讀 OCR 寄存器命令 */
/* read OCR register command */
if(tmp!=SD_NO_ERR)
return tmp ;
if(resp[0]!=0)
return SD_ERR_CMD_RESP ;
/* 響應錯誤 response is error */
for(tmp=0;tmp<4;tmp++)
recbuf[tmp]=resp[tmp+1];/* 復制OCR寄存器內容到接收緩沖區 */
return SD_NO_ERR ;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -