⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_read_write.c

📁 SD卡功能模块 音远文件例如MIDI mp3的读写存储
💻 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 + -