📄 sd_dri.c
字号:
/*!
*@file sd_dri.c
*
*
*
*@version v1.0.0
*@date 2007
*@author jacky291@126.com
*/
#include "sd_dri.h"
#ifndef __SD_CONFIG_H
#include "sd_cfg.h"
#endif
#ifndef __SD_DATA_H
#include "sd_dat.h"
#endif
#ifndef __SD_API_H
#include "sd_api.h"
#endif
#ifndef __SD_CMD_H
#include "sd_cmd.h"
#endif
SD_CARD sd;
/*!
*@brief
* SD_info()
* read the info data from the sd card
*
*@param none
*@retval none
*/
uint32 SD_info(SD_CARD *s)
{
uint8 i, buff[16];
SD_ReadCID(16,buff);
s->MID=buff[0];
s->OID=buff[1]<<8|buff[2];
/**< card name */
for(i=0;i<5;i++){
s->PNM[i]=buff[i+3];
}
s->PRV = buff[9];
/**< serial Num */
for(i=0;i<4;i++){
s->PSN[i]=buff[3+i];
};
/**< read the current VDD */
SD_ReadOCR(4, buff);
/**< read the other informations */
if(SD_ReadCSD(16,buff)!=0){
return 0xFF;
};
return 0;
}
/*!
*@brief
* SD_ActiveInit()
* active the sd card
*
*@param none
*@retval none
*/
uint8 SD_ActiveInit(void)
{
uint8 param[4] = {0,0,0,0},resp,ret;
uint32 i = 0;
do
{ /**< send CMD1 to poll card status */
ret = SD_SendCMD(CMD1, param, R1, &resp);
if (ret==0&&resp==0)return ret;
i++;
}
while (i < SD_IDLE_WAIT_MAX);
if (i >= SD_IDLE_WAIT_MAX) return SD_ERR_TIMEOUT_WAITIDLE;
/**< time out,return error */
return 0;
}
/*!
*@brief
* SD_init()
* read the info data from the sd card
*
*@param none
*@retval none
*/
uint32 SD_init()
{
SD_SPI_Init();
SD_SPI_Clk(SD_INIT_CLK);
SD_powerOff();
SD_powerOn();
SD_SPI_SendByte(0xFF);
SD_SPI_SendByte(0xFF);
SD_SPI_SendByte(0xFF);
SD_SPI_SendByte(0xFF);
if(SD_ResetSD()!=0){ /**< reset the card */
return SD_INIT_FAILED;
};
if(SD_ActiveInit()==WAIT_IDLE_TIMEOUT){
return WAIT_IDLE_TIMEOUT;
};
#if SD_CRC_EN
SD_EnableCRC(1);
#endif
SD_SPI_Clk(SD_MAX_CLK);
SD_SetBlockLen(SD_BLOCKSIZE);
if(SD_info(&sd)!=0){
return 0xFF;
};
return 0;
}
/*!
*@brief
* SD_read()
* read the data from the sd card
* when the addr is block_start addr and the len is READ_BL_LEN it will be the fast!
*@param uint32 addr:start address
*@param uint32 len:the lenth read
*@param uint8 *buff:the receive buff
*@retval return the readed byte length
*/
uint32 SD_read(uint32 addr,uint32 len,uint8 *buff)
{
uint8 readed[READ_BL_LEN];
uint32 i,j,blocks;
uint32 offset_fst=(addr + READ_BL_LEN)%READ_BL_LEN;
uint32 offset_lst=(addr + len)%READ_BL_LEN;
uint32 start_block=addr/READ_BL_LEN;
uint32 end_block=(addr + len -1)/READ_BL_LEN;
blocks =end_block-start_block;
if( blocks==0 ){
SD_ReadSingleBlock(start_block*READ_BL_LEN);
if(SD_ReadBlockData(READ_BL_LEN,readed)==0){ /**< read a sigle sector */
for(i=0;i<len;i++){ /**< copy the data to the buff */
*buff++ = readed[offset_fst + i];
};
}else{
return SD_READ_FAILED;
};
}else{
if(SD_ReadMultipleBlock(start_block*READ_BL_LEN)!=0){ /**< send the read command */
return SD_READ_FAILED;
};
SD_ReadBlockData(READ_BL_LEN,readed);
for(i=offset_fst;i<READ_BL_LEN;i++){ /* copy the data in first sector to the buff */
*buff++ = readed[i];
};
for(i=1;i<blocks;i++){ /* the last block maybe not include all data needed */
if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
for(j=0;j<READ_BL_LEN;j++){ /* copy the data to the buff */
*buff++ = readed[i];
};
};
};
if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
for(i=0;i<offset_lst;i++){ /* copy the data in last sector to the buff */
*buff++ = readed[i];
};
};
SD_StopTransmission();
};
return 0;
}
/*!
*@brief
* SD_write()
* write the data to the sd card
* when the addr is block_start addr and the len is READ_BL_LEN it will be the fast!
*@param uint32 addr:start address
*@param uint32 len:the lenth write
*@param uint8 *buff:the write buff
*@retval return the writed byte length
*/
uint32 SD_write(uint32 addr,uint32 len,uint8 *buff)
{
uint32 i;
uint32 offset_fst=(addr + READ_BL_LEN)%READ_BL_LEN;
uint32 offset_lst=(addr + len)%READ_BL_LEN;
uint32 start_block=addr/READ_BL_LEN;
uint32 end_block=(addr + len -1)/READ_BL_LEN;
uint32 blocks =end_block-start_block;
uint8 readed[READ_BL_LEN];
if( blocks==0 ){
SD_ReadSingleBlock(start_block*READ_BL_LEN);
if(SD_ReadBlockData(READ_BL_LEN,readed)==0){ /* read a sigle sector */
for(i=0;i<len;i++){ /* copy the data to the buff to write */
readed[offset_fst + i]=*buff++;
};
if(SD_WriteSingleBlock(start_block*READ_BL_LEN)==0){ /**< write back the old data and append the new data */
SD_WriteBlockData(0,READ_BL_LEN,readed);
}else{
return SD_WRITE_FAILED;
};
}else{
return SD_READ_FAILED;
};
}else{
if(SD_ReadSingleBlock(start_block*READ_BL_LEN)!=0){ /**< send the read command */
return 255;
};
SD_ReadBlockData(READ_BL_LEN,readed);
for(i=offset_fst;i<READ_BL_LEN;i++){ /**< copy the data in first sector to the buff */
readed[i] =*buff++;
};
if(SD_WriteSingleBlock(start_block*READ_BL_LEN)!=0){
return SD_WRITE_FAILED;
};
SD_WriteBlockData(0,READ_BL_LEN,readed);
for(i=1;i<blocks;i++){ /**< the last block maybe not include all data needed */
if(SD_ReadSingleBlock((start_block + i)*READ_BL_LEN)!=0){
return 255;
};
if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
for(i=0;i<READ_BL_LEN;i++){ /**< copy the data to the buff */
readed[i]=*buff++;
};
};
if(SD_WriteSingleBlock(start_block + i)!=0){ /**< write back */
return SD_WRITE_FAILED;
}else{
SD_WriteBlockData(0,READ_BL_LEN,readed);
};
};
if(SD_ReadSingleBlock(end_block*READ_BL_LEN)!=0) return 255;
if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
for(i=0;i<offset_lst;i++){ /**< copy the data to the buff */
readed[i] = *buff++;
};
};
if(SD_WriteSingleBlock(end_block*READ_BL_LEN)==0){
SD_WriteBlockData(0,READ_BL_LEN,readed);
};
};
return 0;
}
/*!
*@brief
* SD_eraser()
* eraser the data from the sd card
* when the addr is block_start addr and the len is READ_BL_LEN it will be the fast!
*@param uint32 addr:start address
*@param uint32 len:the lenth eraser
*@retval return the erasered byte length
*/
uint32 SD_eraser(uint32 addr,uint32 len)
{
uint32 i;
uint32 offset_fst=(addr + READ_BL_LEN)%READ_BL_LEN;
uint32 offset_lst=(addr + len)%READ_BL_LEN;
uint32 start_sec=addr/READ_BL_LEN;
uint32 end_sec=(addr + len -1)/READ_BL_LEN;
uint32 blocks =end_sec-start_sec;
uint8 readed[READ_BL_LEN];
blocks = end_sec - start_sec;
if( blocks==0 ){
SD_ReadSingleBlock(start_sec*READ_BL_LEN);
if(SD_ReadBlockData(READ_BL_LEN,readed)==0){ /**< read a sigle sector */
for(i=offset_fst;i<offset_fst + len;i++){ /**< copy the data to the buff to write */
readed[i] = 0x00;
};
if(SD_WriteSingleBlock(start_sec*READ_BL_LEN)==0){ /**< write back the old data and append the new data */
SD_WriteBlockData(0,READ_BL_LEN,readed);
}else{
return SD_WRITE_FAILED;
};
}else{
return SD_READ_FAILED;
};
}else{
SD_ReadSingleBlock(start_sec*READ_BL_LEN); /**< send the read command */
SD_ReadBlockData(READ_BL_LEN,readed);
for(i=offset_fst;i<READ_BL_LEN;i++){ /**< copy the data in first sector to the buff */
readed[i] = 0x00;
};
if(SD_WriteSingleBlock(start_sec*READ_BL_LEN)!=0){
return SD_WRITE_FAILED;
}else{
SD_WriteBlockData(0,READ_BL_LEN,readed);
};
if(blocks==1){
SD_EraseStartBlock((start_sec+1)*READ_BL_LEN); /**< Erase */
SD_EraseEndBlock((start_sec+2)*READ_BL_LEN);
SD_EraseSelectedBlock();
}else{
SD_EraseStartBlock((start_sec+1)*READ_BL_LEN); /**< Erase */
SD_EraseEndBlock((end_sec-1)*READ_BL_LEN);
SD_EraseSelectedBlock();
SD_ReadSingleBlock(end_sec*READ_BL_LEN);
SD_ReadBlockData(READ_BL_LEN,readed);
for(i=0;i<offset_lst;i++){ /**< copy the data to the buff */
readed[i] = 0x00;
};
SD_WriteSingleBlock(end_sec*READ_BL_LEN);
SD_WriteBlockData(0,READ_BL_LEN,readed);
SD_StopTransmission();
};
};
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -