📄 sd_read_write.c
字号:
#ifndef SD_READ_WRITE_C
#define SD_READ_WRITE_C
/**************************************START OF THE FILE****************************************************************/
/************************************************************************************/
/* */
/* Copyright (C) 2004 Medeli Electric Industry Co., LTD. */
/* */
/* System Name : IC-1000 */
/* File Name : sd_init.c */
/* Revision : 1.00 */
/* Date : 2006/4/6 */
/* Initial version */
/* Joe's work */
/************************************************************************************/
typedef struct
{
UWORD src_addr;
UWORD dst_addr;
UWORD length;
UBYTE resp;
}SD_TEST_READ;
SD_TEST_READ sd_test_read;
/*******************************Constants************************************/
/**************************Variable Declaration******************************/
/********************************Locoal**************************************/
/*******************************External*************************************/
/**************************Function Declaration******************************/
/********************************Locoal**************************************/
/*******************************External*************************************/
/***************************Start of program*********************************/
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
void sd_read_single_block(UWORD dsc_addr,UWORD length)
{
// sio_block_read_start(0,dsc_addr,length);
sio_dma_read(0,dsc_addr,length);
while(!sio_vars.data_finish)
{/* 等待数据发送、接收时运行外部程序 */
sd_exprc.normal[sd_exprc.cur_prc++]();
if(sd_exprc.cur_prc>=SD_EXPRC_NUM)
{
sd_exprc.cur_prc=0;
}
}
sio_return_single_mode_rising();
return;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
void sd_write_single_block(UWORD src_addr,UWORD length)
{
// sio_block_write_start(0,src_addr,length);
sio_dma_write(0,src_addr,length);
while(!sio_vars.data_finish)
{/* 等待数据发送、接收时运行外部程序 */
sd_exprc.normal[sd_exprc.cur_prc++]();
if(sd_exprc.cur_prc>=SD_EXPRC_NUM)
{
sd_exprc.cur_prc=0;
}
}
sio_return_single_mode_rising();
return;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_check_datablock_head(void)
{
UWORD i=0;
UBYTE temp,ret=SD_ERROR;
do
{/* 等待接收数据开始令牌0xfe wait for receiving data start token 0xfe */
temp=sd_get_byte();
i++;
}while((temp==0xff)&&(i<sd_vars.timeout_read));
if((i<sd_vars.timeout_read)||(temp!=SD_TOK_READ_STARTBLOCK))
{
ret=SD_OK;
}
else
{
sd_send_byte(0xff);
}
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_check_data_crc(UBYTE* data_pt,UWORD length)
{
UBYTE ret=SD_ERROR;
#if SD_CRC_ENABLED
sd_vars.data_crc=sd_get_byte();
sd_vars.data_crc<<=8;
sd_vars.data_crc+=sd_get_byte();
if(sd_get_crc16(data_pt,length)==sd_vars.data_crc)
{
ret=SD_OK;
}
#else
sd_get_byte();
sd_get_byte();
ret=SD_OK;
#endif
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_read_block_data(UWORD src_addr,UWORD dst_addr)
{
UBYTE ret=SD_ERROR;
if(sd_check_datablock_head()==SD_OK)
{
sd_read_single_block(dst_addr,SD_BLOCK_LENGTH);
#if SD_CRC_ENABLED
return sd_check_data_crc((UBYTE *)dst_addr,SD_BLOCK_LENGTH);
#else
sd_get_byte();
ret=SD_OK;
#endif
}
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_stop_transmission(void)
{
UBYTE ret;
sd_delay(1);
sd_write_com_para(0,0,0,0);
if(sd_send_cmd(CMD12,sd_vars.com_para,0,sd_vars.resp)==SD_OK)
{
if(!sd_vars.resp[0])
{
ret=SD_OK;
}
else
{
ret=SD_ERROR;
}
}
else
{
ret=SD_ERROR;
}
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_read_blocks(UWORD src_addr,UWORD dst_addr,UWORD length)
{
UBYTE ret=SD_OK;
UWORD read_times=(length+SD_BLOCK_LENGTH-1)/SD_BLOCK_LENGTH;
rPDATC&=~(1<<15);/* 245 cs assert */
SD_CS_ASSERT;
sd_delay(4);
sd_pack_com_para(sd_vars.com_para,src_addr);
sd_vars.short_timer=0;
if(((ret=sd_send_cmd(CMD18,sd_vars.com_para,0,sd_vars.resp)) == SD_OK)&&(!sd_vars.resp[0]))
{
for(;(read_times)&&(ret==SD_OK); read_times--,dst_addr+=SD_BLOCK_LENGTH,src_addr+=SD_BLOCK_LENGTH)
{
ret=sd_read_block_data(src_addr,dst_addr);
// SD_CS_DEASSERT;
//
// sd_exprc.using_sio();
//
// SD_CS_ASSERT;
}
}
if(ret==SD_OK)
{
ret=sd_stop_transmission();
}
else
{
sd_test_read.src_addr=src_addr;
sd_test_read.dst_addr=dst_addr;
sd_test_read.length=length;
sd_test_read.resp=sd_vars.resp[0];
}
SD_CS_DEASSERT;
rPDATC|=(1<<15);/* 245 cs deassert */
sd_exprc.using_sio();
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_wait_busy(UBYTE wait_type)
{
UBYTE ret=SD_ERROR;
UWORD wait_cycle= (wait_type==SD_WAIT_WRITE)? sd_vars.timeout_write:sd_vars.timeout_erase;
for(;wait_cycle;wait_cycle--)
{
if(sd_get_byte()==0xff)
{
ret=SD_OK;
break;
}
if(!(wait_cycle%100))
{/* 100个字节的等待后执行一次外部程序 */
sd_exprc.normal[sd_exprc.cur_prc++]();
if(sd_exprc.cur_prc>=SD_EXPRC_NUM)
{
sd_exprc.cur_prc=0;
}
}
}
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_write_block_data(UWORD src_addr)
{
UBYTE resp,ret=SD_ERROR;
UHWORD crc_16=0;
sd_delay(1);
sd_send_byte(SD_TOK_WRITE_STARTBLOCK_M);
sd_write_single_block(src_addr,SD_BLOCK_LENGTH);
#if SD_CRC_ENABLED
crc_16=sd_get_crc16((UBYTE *)src_addr,SD_BLOCK_LENGTH);
#endif
sd_send_byte((crc_16>>8)&0xff);
sd_send_byte(crc_16&0xff);
resp=sd_get_byte();
if((resp&SD_RESP_DATA_MSK)==SD_RESP_DATA_ACCETPTED)
{
if(sd_wait_busy(SD_WAIT_WRITE)==SD_OK)
{
ret=SD_OK;
}
}
else
{/* 返回之前发送8个clock clock out 8 clk before return */
sd_send_byte(0xff);
}
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_check_written_block_num(UWORD written_num)
{
UBYTE buf[4],ret=SD_ERROR;
UWORD sd_write_num;
sd_write_com_para(0,0,0,0);
if((sd_send_cmd(CMD55,sd_vars.com_para,0,sd_vars.resp)==SD_OK)&&(!sd_vars.resp[0]))
{/* 后续命令为一个应用命令 */
if((sd_send_cmd(ACMD22,sd_vars.com_para,1,sd_vars.resp)==SD_OK)&&(!sd_vars.resp[0]))
{/* 读取正确写入的块数命令 */
if(sd_check_datablock_head()==SD_OK)
{/* 块数量以数据块读取的格式传送 */
buf[0]=sd_get_byte();
buf[1]=sd_get_byte();
buf[2]=sd_get_byte();
buf[3]=sd_get_byte();
if(sd_check_data_crc((UBYTE *)buf,4)==SD_OK)
{
sd_write_num=(buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3];
if(sd_write_num==written_num)
{
ret=SD_OK;
}
sd_delay(1);
}
}
}
}
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
void sd_stop_multi_write(void)
{
sd_delay(1);
sd_send_byte(SD_TOK_STOP_MULTI);
sd_delay(1);
return;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
UBYTE sd_write_blocks(UWORD src_addr,UWORD dst_addr,UWORD length)
{
UBYTE ret=SD_ERROR;
UWORD i,write_times=(length+SD_BLOCK_LENGTH-1)/SD_BLOCK_LENGTH;
for(i=write_times;i;i--)
{
if(sd_write_block_data(src_addr)==SD_OK)
{
src_addr+=SD_BLOCK_LENGTH;
}
else
{
sd_stop_transmission();
sd_wait_busy(SD_WAIT_WRITE);
return ret;
}
}
sd_stop_multi_write();
/* 发送数据停止令牌 send data stop token */
if((sd_wait_busy(SD_WAIT_WRITE)==SD_OK)&&(sd_check_written_block_num(write_times)==SD_OK))
{
ret=SD_OK;
}
return ret;
}
/****************************************************************************/
/* initial sd card interface */
/* Function : init_sd */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
void sd_exprc_nope(void)
{
return;
}
/****************************************END OF THE FILE****************************************************************/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -