Exemplo n.º 1
0
Arquivo: FAT.C Projeto: nvero/fmhobby
//FAT初始化,不含SD的初始化,用之前应先调用sd的初始化
//返回值:0,初始化成功
//    其他,初始化失败   
unsigned char FAT_Init(void)//Initialize of FAT  need initialize SD first
{  		   
	bootsector710 *bs  = 0;
	bpb710        *bpb = 0;			  
	partrecord    *pr  = 0;

	DWORD hidsec=0;
	u32 Capacity;	 
	Capacity = SD_GetCapacity();				   
	if(Capacity<0xff)return 1;	    
	if(SD_ReadSingleBlock(0,fat_buffer))return 2;
	bs = (bootsector710 *)fat_buffer;	
	pr = (partrecord *)((partsector *)fat_buffer)->psPart;//first partition
	hidsec = pr->prStartLBA;//the hidden sectors
	if(hidsec >= Capacity/512)hidsec = 0;	 
	else 
	{
		if(SD_ReadSingleBlock(pr->prStartLBA,fat_buffer))return 3;//read the bpb sector
		bs = (bootsector710 *)fat_buffer;
		if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)
		{
			hidsec = 0;
			if(SD_ReadSingleBlock(0,fat_buffer))return 4;//read the bpb sector
			bs = (bootsector710 *)fat_buffer;	
		}
	}	  
	if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)return 5;//对付没有bootsect的sd卡	//dead with the card which has no bootsect
	bpb = (bpb710 *)bs->bsBPB;
	if(bpb->bpbFATsecs)//detemine thd FAT type  //do not support FAT12
	{
		FAT32_Enable=0;	//FAT16
		FATsectors	  = bpb->bpbFATsecs;//FAT表占用的扇区数 
		FirstDirClust = 2;
	}
	else
	{
		FAT32_Enable=1;	//FAT32
		FATsectors	  = bpb->bpbBigFATsecs;//FAT占用的扇区数 
		FirstDirClust = bpb->bpbRootClust;
	}

	BytesPerSector	= bpb->bpbBytesPerSec;      //每扇区字节数
	SectorsPerClust	= (BYTE)bpb->bpbSecPerClust;//每簇扇区数
	FirstFATSector	= bpb->bpbResSectors+hidsec;//第一个FAT表扇区
	RootDirCount	= bpb->bpbRootDirEnts;		//根目录项数
	RootDirSectors	= (RootDirCount*32)>>9;		//根目录占用的扇区数
	FirstDirSector	= FirstFATSector+bpb->bpbFATs*FATsectors;//第一个目录扇区
	FirstDataSector	= FirstDirSector+RootDirSectors;//第一个数据扇区
	return 0; 
}  
Exemplo n.º 2
0
int main(void)
{
    uint32_t i;
    DelayInit();
    GPIO_QuickInit(HW_GPIOE, 6, kGPIO_Mode_OPP);
    UART_QuickInit(UART0_RX_PD06_TX_PD07, 115200);
    printf("SD test\r\n");
    printf("please insert SD card...\r\n");
    //SD卡模块快速初始化,设置速度为20000000
    SD_QuickInit(20000000);
    //获取SD卡的容量
    printf("SD size:%dMB\r\n", SD_GetSizeInMB());
    /* 读取0扇区数据,每一个扇区512字节 */
    SD_ReadSingleBlock(0, sd_buffer);
    /* 打印0扇区数据 */
    printf("sectoer 0 data:\r\n");
    for(i = 0; i < 512; i++)
    {
        printf("0x%02X ", sd_buffer[i]);
    }
    while(1)
    {
        //小灯闪烁
        GPIO_ToggleBit(HW_GPIOE, 6);
        DelayMs(500);
    }
}
Exemplo n.º 3
0
Arquivo: FAT.C Projeto: nvero/fmhobby
//读取512个字节
//FileInfo:要读取的文件
//buf     :数据缓存区
//返回值  :0,操作失败,1,操作成功
unsigned char F_Read(FileInfoStruct *FileInfo,u8 *buf)
{	
	DWORD sector;			   		  
	sector=fatClustToSect(FileInfo->F_CurClust);//得到当前簇号对应的扇区号	   	 		    
	if(SD_ReadSingleBlock(sector+FileInfo->F_Offset,buf))return 0;//读数错误   
	FileInfo->F_Offset++;
	if(FileInfo->F_Offset==SectorsPerClust)	//簇的尽头,换簇
	{
		FileInfo->F_Offset=0;		    
		FileInfo->F_CurClust=FAT_NextCluster(FileInfo->F_CurClust);//读取下一个簇号
		if((FAT32_Enable==0&&FileInfo->F_CurClust==0xffff) \
		||FileInfo->F_CurClust==0x0ffffff8||FileInfo->F_CurClust == 0x0fffffff)return 0;//error	    
	} 
	return 1;//读取成功
} 
Exemplo n.º 4
0
DRESULT disk_read (
	BYTE drv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	BYTE count		/* Number of sectors to read (1..255) */
)
{
	u8 res=0;
    if (drv || !count)
    {    
        return RES_PARERR;  //仅支持单磁盘操作,count不能等于0,否则返回参数错误
    }
    if(!SD_DET())
    {
        return RES_NOTRDY;  //没有检测到SD卡,报NOT READY错误
    }

    
	
    if(count==1)            //1个sector的读操作      
    {                                                
        res = SD_ReadSingleBlock(sector, buff);      
    }                                                
    else                    //多个sector的读操作     
    {                                                
        res = SD_ReadMultiBlock(sector, buff, count);
    }                                                
	/*
    do                           
    {                                          
        if(SD_ReadSingleBlock(sector, buff)!=0)
        {                                      
            res = 1;                           
            break;                             
        }                                      
        buff+=512;                             
    }while(--count);                                         
    */
    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res == 0x00)
    {
        return RES_OK;
    }
    else
    {
        return RES_ERROR;
    }
}
Exemplo n.º 5
0
DRESULT disk_read (
	BYTE drv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	BYTE count		/* Number of sectors to read (1..255) */
)
{
	u8 res=0;
    if (drv || !count)
    {    
        return RES_PARERR;  // only supports single disk operation, count is not equal to 0, otherwise parameter error
    }
   // if(!SD_DET())
   // {
   //     return RES_NOTRDY;  // does not detect SD card, NOT READY error reported
   // }

    
	
    if(count==1) // sector reads 1
    {                                                
        res = SD_ReadSingleBlock(sector, buff);      
    }                                                
    else // multiple sector read operations
    {                                                
        res = SD_ReadMultiBlock(sector, buff, count);
    }                                                
	/*
    do                           
    {                                          
        if(SD_ReadSingleBlock(sector, buff)!=0)
        {                                      
            res = 1;                           
            break;                             
        }                                      
        buff+=512;                             
    }while(--count);                                         
    */
    // Process the return value, the return value of the SPI_SD_driver.c the return value turned into ff.c
    if(res == 0x00)
    {
        return RES_OK;
    }
    else
    {
        return RES_ERROR;
    }
}
Exemplo n.º 6
0
/*****************************SD卡读取********************************/
void Sd_D(void)
{
	uint8_t i;
	while(SD_ReadSingleBlock(SD_D,Send_Data) != ESDHC_OK);
	for(i=0;i<=127;i++)
	{
		Sent_Data->Pixels[i] = Send_Data[i];
	}
	Sent_Data->Lcr[0].Left = Send_Data[197];
	Sent_Data->Lcr[0].Right = Send_Data[198];
	Sent_Data->Lcr[0].Center = Send_Data[199];
	
	Sent_Data->Lcr[1].Left = Send_Data[197];
	Sent_Data->Lcr[1].Right = Send_Data[198];
	Sent_Data->Lcr[1].Center = Send_Data[199];
	
	SD_D++;
}
Exemplo n.º 7
0
DRESULT disk_read (BYTE drv,BYTE* buff,DWORD sector,BYTE count)//哪个卡(一般为0),读出的数据存储的地方,块地址,块个数
{
	u8 res=0;
    if (drv || !count)
    {    
        return RES_PARERR;  //仅支持单磁盘操作,count不能等于0,否则返回参数错误
    }
    if(SD_Insert_Status())
    {
        return RES_NOTRDY;  //没有检测到SD卡,报NOT READY错误
    }

    
	
    if(count==1)            //1个sector的读操作      
    {                                                
        res = SD_ReadSingleBlock(sector, buff);      
    }                                                
    else                    //多个sector的读操作     
    {                                                
        res = SD_ReadMultiBlock(sector, buff, count);
    }                                                
	/*
    do                           
    {                                          
        if(SD_ReadSingleBlock(sector, buff)!=0)
        {                                      
            res = 1;                           
            break;                             
        }                                      
        buff+=512;                             
    }while(--count);                                         
    */
    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res == 0x00)
    {
        return RES_OK;
    }
    else
    {
        return RES_ERROR;
    }
}
Exemplo n.º 8
0
Arquivo: FAT.C Projeto: nvero/fmhobby
//在SD卡上的FAT表中查找下一簇号
//cluster:当前簇号
//返回值:0x0ffffff8,表示没有后续簇了
//	   		 其他值,下一簇号				   		    
unsigned long FAT_NextCluster(unsigned long cluster)
{
	DWORD sector;
	DWORD offset;  

	if(FAT32_Enable)offset = cluster/128;//FAT32的FAT表中,用四个字节表示一个簇地址.512/4=128
	else offset = cluster/256;			 //FAT16的FAT表中,用两个字节表示一个簇地址.512/2=256
	if(cluster<2)return 0x0ffffff8;		 //簇0,1不能用于存放
	sector=FirstFATSector+offset;//计算该簇实际所在扇区

	if(SD_ReadSingleBlock(sector,fat_buffer))return 0x0ffffff8;//读取FAT表,发生错误是返回0x0ffffff8
	if(FAT32_Enable)
	{
		offset=cluster%128;//计算在扇区内的偏移
		sector=((unsigned long *)fat_buffer)[offset];//u32	
	}
	else
	{
		offset=cluster%256;//计算在扇区内的偏移
		sector=((unsigned short *)fat_buffer)[offset];//u16
	}			   
	return (unsigned long)sector;//return the cluste number
}	  
Exemplo n.º 9
0
Arquivo: FAT.C Projeto: nvero/fmhobby
//查找系统文件
//在指定目录下,找寻一个指定类型的指定名字的文件
//cluster:文件夹的簇号!!!
//Name   :文件的名字
//type   :文件类型
//返回值 :该文件的详细信息/如果 FileInfo.F_StartCluster=0 则说明此次寻找失败
FileInfoStruct F_Search(u32 cluster,unsigned char *Name,u32 type)
{
	DWORD sector;			 
	DWORD tempclust;
	unsigned char cnt;
	unsigned int offset; 	    
	direntry *item = 0;	  
	FileInfoStruct FileInfo;    			    
	if(cluster==0 && FAT32_Enable==0)//FAT16根目录读取
	{			 
		for(cnt=0;cnt<RootDirSectors;cnt++)
		{
			if(SD_ReadSingleBlock(FirstDirSector+cnt,fat_buffer))
			{
				FileInfo.F_StartCluster=0;//读数错误 
				return FileInfo;   
			}
			for(offset=0;offset<512;offset+=32)
			{
				item=(direntry *)(&fat_buffer[offset]);//指针转换
				//找到一个可用的文件
				if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))//找到一个合法文件
				{		   
					if(item->deAttributes != AM_LFN)//忽略长文件名	 
					{  	 				 
						CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息	   
						if(FileInfo.F_Type&type)//找到一个合适的类型了
						{
						   // //printf("File Name:%s\n",FileInfo.F_Name);
	
							//找到了文件,返回这个文件的首簇
							if(mystrcmp(Name,FileInfo.F_Name))
							{						    
								return FileInfo; 
							}
						} 	  
						LongNameFlag=0;//清空长文件名
					}
				}
			}
		}  				 
	}else//其他文件夹/FAT32系统
	{
		tempclust=cluster;
		while(1)
		{
			sector=fatClustToSect(tempclust);
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(SD_ReadSingleBlock(sector+cnt,fat_buffer))
				{
					FileInfo.F_StartCluster=0;//读数错误 
					return FileInfo;   
				}
				for(offset=0;offset<512;offset+=32)
				{
					item=(direntry *)(&fat_buffer[offset]);
					if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))
					{				
						if(item->deAttributes != AM_LFN) //忽略长文件名		    
						{  	 				 
							CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息	  

							if(FileInfo.F_Type&type)//找到一个合适的类型了
							{	/*										   
								//printf("F_Info->F_Name:%s\n",FileInfo.F_Name);
								//printf("F_Info->F_Type:%d\n",FileInfo.F_Type);
								//printf("F_Info->F_Size:%d\n",FileInfo.F_Size);
								//printf("F_Info->F_StartClusterH:%x\n",FileInfo.F_StartCluster>>8); 	
								//printf("F_Info->F_StartClusterL:%x\n\n",FileInfo.F_StartCluster&0xff); */
								//找到了文件,返回这个文件的首簇
								if(mystrcmp(Name,FileInfo.F_Name))
								{						 
									return FileInfo; 
								}
							} 	  
							LongNameFlag=0;//清空长文件名
						}
					}
				}
			}						  
			tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
			if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
		}  
	}		   
	FileInfo.F_StartCluster=0;//读数错误 
	return FileInfo;   					    
}	 	 	 						  
Exemplo n.º 10
0
Arquivo: FAT.C Projeto: nvero/fmhobby
//浏览目标文件夹下面的一个文件类
//dir_clust:当前目录所在簇号
//FileInfo :目标文件的实体对象(FileInfoStruct体)
//type     :要查找的文件类型:1<<0,mp1;1<<1,mp2;1<<2,mp3;1<<3,mp4;1<<4,m4a;1<<5,3gp;
//                           1<<6,3g2;1<<7,ogg;1<<8,acc;1<<9,wma;1<<10,wav;1<<11,mid;
//							 1<<12,flac;1<<13,lrc;1<<14,txt;1<<15,c;1<<16,h;1<<17,file;
//                           1<<18,fon;1<<19,sys;1<<20,bmp;1<<21,jpg;1<<22,jpeg; 
//count    :0,返回当前目录下,该类型文件的个数;不为零时,返回第count个文件的详细信息
//返回值   :1,操作成功.0,操作失败
u8 Get_File_Info(u32 dir_clust,FileInfoStruct *FileInfo,u32 type,u16 *count)
{ 			  	   
	DWORD sector;
	DWORD cluster=dir_clust;
	DWORD tempclust;
	unsigned char cnt;
	unsigned int offset;		 
	unsigned short cont=0;//文件索引标志 <65536
	unsigned char j; //long name fat_buffer offset;
	unsigned char *p;//long name fat_buffer pointer
	direntry *item = 0;
	winentry *we =0;	  
	cont=0;
	LongNameFlag = 0;//清空长文件名标志

	//SD_Init();//初始化SD卡,在意外拔出之后可以正常使用
	//goto SD;
	if(cluster==0 && FAT32_Enable==0)//FAT16根目录读取
	{			 
		for(cnt=0;cnt<RootDirSectors;cnt++)
		{
			if(SD_ReadSingleBlock(FirstDirSector+cnt,fat_buffer))return 0;//读数错误    	   
			for(offset=0;offset<512;offset+=32)
			{
				item=(direntry *)(&fat_buffer[offset]);//指针转换
				//找到一个可用的文件
				if((item->deName[0]!=0x2E)&&(item->deName[0]!=0x00)&&(item->deName[0]!=0xe5)
				||((item->deName[0]==0x2E)&&(item->deName[1]==0x2E)))//找到一个合法文件.忽略".",使用".."
				{		   
					if(item->deAttributes == 0x0f)//找到一个长文件名
					{
						we = (winentry *)(&fat_buffer[offset]);
						j = 26 *( (we->weCnt-1) & WIN_CNT);//长文件名的长度
                        if(j<MAX_LONG_NAME_SIZE-25)
						{
							p = &LongNameBuffer[j];//偏移到目标地址
							for (j=0;j<10;j++)	*p++ = we->wePart1[j];			
							for (j=0;j<12;j++)	*p++ = we->wePart2[j];
							for (j=0;j<4;j++)	*p++ = we->wePart3[j];	
							if (we->weCnt & 0x40) (*(unsigned int *)p) = 0;  				
							if ((we->weCnt & WIN_CNT) == 1) LongNameFlag = 1;//最后一个长文件项找到了	
						}	    
					}else 
					{  	 										 									 
						if(type&FileType_Tell(item->deExtension))//找到一个目标文件
						{
							cont++;//文件索引增加
						 }
						 //查找该目录下,type类型的文件个数
						if(*count&&cont==*count)
						{
							////printf("\ncount:%d",*count);
							CopyDirentruyItem(FileInfo,item);//复制目录项,提取详细信息 
							return 1;//找到目标文件成功	 
						}
						LongNameFlag=0;//清空长文件名
					}
				}
			}
		}  				 
	}
	else//其他文件夹/FAT32系统
	{
		tempclust=cluster;
		while(1)
		{
			sector=fatClustToSect(tempclust);
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(SD_ReadSingleBlock(sector+cnt,fat_buffer))return 0;
				for(offset=0;offset<512;offset+=32)
				{
					item=(direntry *)(&fat_buffer[offset]);
					if((item->deName[0]!=0x2E)&&(item->deName[0]!=0x00)&&(item->deName[0]!=0xe5)
					||((item->deName[0]==0x2E)&&(item->deName[1]==0x2E)))//找到一个合法文件.忽略".",使用".."
					{				
						if(item->deAttributes == 0x0f) //得到一个长文件名
						{
							we = (winentry *)(&fat_buffer[offset]);
							j = 26 *( (we->weCnt-1) & WIN_CNT);
							if(j<MAX_LONG_NAME_SIZE-25)
							{
								p = &LongNameBuffer[j];//p指向长文件名的存放地址
								for (j=0;j<10;j++)	*p++ = we->wePart1[j];			
								for (j=0;j<12;j++)	*p++ = we->wePart2[j];
								for (j=0;j<4;j++)	*p++ = we->wePart3[j];	
								if (we->weCnt & 0x40) (*(unsigned int *)p) = 0;				
								if ((we->weCnt & WIN_CNT) == 1) LongNameFlag = 1;	
							}										    			 
						}	  
						else 
						{
							if(type&FileType_Tell(item->deExtension))//找到一个目标文件
							{
								cont++;//文件索引增加
							 }
							 //查找该目录下,type类型的文件个数
							if(*count&&cont==*count)
							{
								CopyDirentruyItem(FileInfo,item);//复制目录项,提取详细信息  
								return 1;//找到目标文件成功	 
							}
							LongNameFlag=0;//清空长文件名
						}
					}
				}
			}						  
			tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
			if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
		}  
	}
	if(*count==0)
	{
		*count=cont;//得到总共文件数目
		return 1;   //操作成功,找到cont个符合条件的文件了
	}else return 0; //操作失败,没找到文件,或者出错
}
Exemplo n.º 11
0
void SDCardReadWriteTextTask(void* parameters)
{
	uint8_t outbuf[512];
	uint8_t inbuf[512];
	int i;

	//LED_LowLevel_Init();
	//UART_LowLevel_Init();
	SD_LowLevel_Init();   //Initialize PINS, vector table and SDIO interface
	//UART_SendLine("Ready...Steady\n");

	printf("SSD\n\r");
	LEDOn(LED2);

	//Initialize the SD
	SD_Init();  //After return from this function sd is in transfer mode.
	//UART_SendLine("GO\n");

	printf("SDI\n\r");
	LEDOff(LED2);

	//Write a single block to the SD
	for (i=0;i<512;i++) {
		outbuf[i]='a';
	}

	//Single Block Test
	SD_WriteSingleBlock(outbuf, 3000);
	SD_ReadSingleBlock(inbuf, 3000);
	//UART_SendLine("First Block\n");
	//UART_Send(inbuf,512);
	printf("\n\r%s", "First Block");
	printf("\n\r%i,%i,%i,%i", (int)inbuf[0], (int)inbuf[1], (int)inbuf[2], (int)inbuf[3]);

	SD_WriteSingleBlock(outbuf, 3001);
	SD_ReadSingleBlock(inbuf, 3001);
	//UART_SendLine("Second Block\n");
	//UART_Send(inbuf,512);
	printf("\n\r%s", "Second Block");
	printf("\n\r%i,%i,%i,%i", (int)inbuf[0], (int)inbuf[1], (int)inbuf[2], (int)inbuf[3]);

	//Multiple block
	SD_StartMultipleBlockWrite(1000);
	SD_WriteData(outbuf,500);
	SD_WriteData(outbuf+50,50);
	SD_WriteData(outbuf,500);
	SD_StopMultipleBlockWrite();


	SD_ReadSingleBlock(inbuf, 1000);
	//UART_SendLine("Mult. Block 1\n");
	//UART_Send(inbuf,512);
	printf("\n\r%s", "Mult. Block 1");
	printf("\n\r%i,%i,%i,%i", (int)inbuf[0], (int)inbuf[1], (int)inbuf[2], (int)inbuf[3]);
	SD_WaitTransmissionEnd();
	SD_ReadSingleBlock(inbuf, 1001);
	//UART_SendLine("Mult. Block 2\n");
	//UART_Send(inbuf,512);
	printf("\n\r%s", "Mult. Block 2");
	printf("\n\r%i,%i,%i,%i", (int)inbuf[0], (int)inbuf[1], (int)inbuf[2], (int)inbuf[3]);

//	LEDOn(LED6);

	portTickType lastExecutionTime = xTaskGetTickCount();
	for (;;)
	{
		DelayUntilTime( &lastExecutionTime, SDCardReadWriteTextTaskT);

	}
}
Exemplo n.º 12
0
/*-----------------------------------*/
static int  ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer)
{

    SDC_CMD_STATUS status;
    kal_uint8 retry = 0;
    kal_uint32 adrs;

#if defined(__SIM_PLUS__)
    sd_select_enum sel;

    if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
        sel = SD_EXT;
    else
        sel = SD_SIM;
    MSDC_Switch_Card(sel);
#endif

#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
    if(gSD->flags & SD_FLAG_HCS_SUPPORT)
        adrs = Sector;
    else
#endif
        adrs = Sector * SECTOR_SIZE;
    gMSDC_Handle->timeout_count = 0;
start:
    if(!gMSDC_Handle->mIsInitialized)
    {
        //dbg_print("Read but not Initialized \r\n");
        MSDC_PDNControl(KAL_TRUE);
        return FS_MSDC_READ_SECTOR_ERROR;
    }
    retry ++;
    MSDC_PDNControl(KAL_FALSE);
#ifndef LSD_SINGLE_READ
    if(Sectors > 1)
        status = SD_ReadMultiBlock((kal_uint32)adrs,(kal_uint32*)Buffer,(kal_uint32)Sectors);
    else
        status = SD_ReadSingleBlock((kal_uint32)adrs,(kal_uint32*)Buffer);
#else
    while(Sectors) {
        status = SD_ReadSingleBlock((kal_uint32)adrs,(kal_uint32*)Buffer);

        if(status != NO_ERROR )
            break;
        (kal_uint8 *)Buffer += SECTOR_SIZE;
        Sector ++;
#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
        if(gSD->flags & SD_FLAG_HCS_SUPPORT)
            adrs = Sector;
        else
#endif
            adrs = Sector * SECTOR_SIZE;

        Sectors--;
    }
#endif
    if(status != NO_ERROR )
    {
        sd_r++;
        if(kal_query_systemInit()== KAL_TRUE)
        {
            MSDC_PDNControl(KAL_TRUE);
            return FS_MSDC_READ_SECTOR_ERROR;
        }
        //dbg_print("read retry:%d,status:%d,total %d\r\n",retry,status,sd_r);
        if(status == ERR_CMD_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR)
            gMSDC_Handle->timeout_count++;
        if(gMSDC_Handle->timeout_count++ == 3 && gMSDC_Handle->mIsPresent == KAL_TRUE)
        {
            kal_print("[MSDC]:re-mount(read fail)");
            gMSDC_Handle->mIsInitialized = KAL_FALSE;
            retry = 0;
            if(SD_Initialize() != NO_ERROR)
            {
                MSDC_PDNControl(KAL_TRUE);
                return FS_MSDC_READ_SECTOR_ERROR;
            }
        }
        if(retry >= SD_MAX_RETRY)
        {
            MSDC_PDNControl(KAL_TRUE);
            return FS_MSDC_READ_SECTOR_ERROR;
        }
        else
        {
            // kal_prompt_trace(MOD_AUD,"CRC etry:%d,status:%d",retry,status);
            goto start;
        }
    }
    MSDC_PDNControl(KAL_TRUE);
    return FS_NO_ERROR;
}