📄 sd_dat.c
字号:
/*!
*@file sd_dat.h
* the data transe functions here
*
*
*@version v1.0.0
*@date 2007
*@author jacky291@126.com
*/
#include "sd_dat.h"
#ifndef __SD_CONFIG_H
#include "sd_cfg.h"
#endif
#ifndef __SD_SPI_H
#include "sd_spi.h"
#endif
#if SD_CRC_EN
#include "sd_crc.h"
#endif
/*!
*@brief
* SD_ReadRegister()
* read sd register after the commands
*
*@param len:data length
*@param *recbuf the data buffer addr.
*@retval 0: right >0: error code
*/
uint8 SD_ReadRegister(uint32 len, uint8 *recbuf)
{
uint32 i = 0;
/**< wait for the response */
if(SD_SPI_WaitForLow(200)==SPI_TIMEOUT){
return 1;
};
/**< receive the response */
for(i=0;i<len;i++){
recbuf[i]=SD_SPI_RecByte();
};
i = SD_SPI_RecByte();
i = (i << 8) + SD_SPI_RecByte(); /* get 16-bit CRC */
#if SD_CRC_EN
if (i != SD_GetCRC16(recbuf, len))
{ /* CRC check is error */
SD_SPI_SendByte(0xFF);
return SD_ERR_DATA_CRC16; /* return error of CRC16 */
}
#endif
SD_SPI_SendByte(0xFF); /* clock out 8 clk before return */
return SD_NO_ERR;
}
/*!
*@brief
* void SD_WaitBusy()
* poll SD Card wheather it is busy
*@param uint32 timeout:the time wait
*@retval 0: not time out > 0: error code
*/
uint8 SD_WaitBusy(uint32 timeout)
{
uint32 i = 0;
uint8 tmp;
do
{ /* wait for being busy end */
tmp = SD_SPI_RecByte();
i++;
}while ((tmp != 0xFF) && (i < timeout)); /* always receive 0xFF when card is busy */
if(i < timeout)
return 0; /* return 0 indicate that operation is not time out */
else
return SD_TIMEOUT_WAIT; /* return error code indicate that operation is time out */
}
/*!
*@brief
* SD_ReadBlockData()
* read block data from sd card
*
*@param len : length
*@param *recbuf : the buffer of receive
*@retval 0: right >0: error code
*/
uint8 SD_ReadBlockData(uint32 len, uint8 *recbuf)
{
uint8 tmp;
uint32 i = 0;
do
{ /* wait for receiving data start token 0xFE */
tmp = SD_SPI_RecByte();
i++;
}while((tmp == 0xFF) && (i < SD_READREG_TIMEOUT));
if (i >= SD_READREG_TIMEOUT)
{
return SD_ERR_TIMEOUT_READ; /* return error timeout error code of reading */
}
if (tmp != SD_TOK_READ_STARTBLOCK) /* read start block token is error */
{
SD_SPI_SendByte(0xFF);
return SD_ERR_DATA_START_TOK;
}
for (i = 0; i <len; i++)
recbuf[i] = SD_SPI_RecByte(); /* receive data */
i = SD_SPI_RecByte();
i = (i << 8) + SD_SPI_RecByte(); /* get 16-bit CRC */
#if SD_CRC_EN
if (i != SD_GetCRC16(recbuf, len))
{ /* CRC check is error */
SD_SPI_SendByte(0xFF);
return SD_ERR_DATA_CRC16; /* return error of CRC16 */
}
#endif
SD_SPI_SendByte(0xFF);
return 0; /* return function perform sucessfully */
}
/*!
*@brief
* SD_WriteBlockData()
* write block data to sd card
*
*@param bmulti : multi blocks operate 1:Y 0:N
*@param len : length
*@param *sendbuf : the buffer of send
*@retval 0: right >0: error code
*/
uint8 SD_WriteBlockData(uint8 bmulti, uint32 len, uint8 *sendbuf)
{
uint16 i;
uint8 tmp;
SD_SPI_SendByte(0xFF); /* clock out 8 clk before start */
if (bmulti == 1)
SD_SPI_SendByte(SD_TOK_WRITE_STARTBLOCK_M); /* start token of write multi blocks */
else
SD_SPI_SendByte(SD_TOK_WRITE_STARTBLOCK); /* start token of write single block */
for (i = 0; i <len; i++)
{
SD_SPI_SendByte(sendbuf[i]); /* send data */
};
#if SD_CRC_EN
i = SD_GetCRC16(sendbuf,len); /* calculate CRC16 */
#endif
SD_SPI_SendByte((i >> 8) & 0xFF);
SD_SPI_SendByte(i & 0xFF); /* send CRC16 check code */
tmp = SD_SPI_RecByte();
if ((tmp & SD_RESP_DATA_MSK) != SD_RESP_DATA_ACCETPTED)
{
SD_SPI_SendByte(0xFF); /* clock out 8 clk before return */
return SD_ERR_DATA_RESP; /* data response error */
}
SD_WaitBusy(SD_WAIT_WRITE_TIME);
return 0; /* write right */
}
/*!
*@brief
* SD_StopMultiToken(void)
* send the token that stop multiple block write
*
*@param none
*@retval none
*/
void SD_StopMultiToken(void)
{
SD_SPI_SendByte(0xFF); /* send 8 clock first */
SD_SPI_SendByte(SD_TOK_STOP_MULTI); /* send stop transmission token */
SD_SPI_RecByte();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -