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

📄 ms_drv.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 2 页
字号:
}

/*-----------------------------------*/
static int  ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer)
{
	MS_STATUS status;
	kal_uint8 PagesPerBlk,page,readpage,len,*ptr;
	kal_uint32 lba,pba;
	kal_uint8 retry = 0;
	
	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;
	}
	PagesPerBlk = gMS.PagesPerBlk;
	lba = Sector/PagesPerBlk;
	page = Sector%PagesPerBlk;
	ptr = (kal_uint8*) Buffer;
	MSDC_PDNControl(KAL_FALSE);
	while(1)
	{
		if(PagesPerBlk - page < Sectors)
			len = PagesPerBlk - page;
		else
			len = Sectors;			
		ASSERT(len >= 1 && len <= 32);
		status = MS_API_LogToPhy(gMS.pLPTbl,lba,&pba);
		if(status != MS_NOERROR)
			goto ERR_EXIT;//return FS_MSDC_READ_SECTOR_ERROR;
		if(len == 1)
			status = MS_API_ReadSinglePage(pba,page,(kal_uint32*)ptr,NULL);
		else
			status = MS_API_ReadBlock(pba, (kal_uint32*)ptr, NULL, page, len, &readpage);	
		if(status != MS_NOERROR)
			goto ERR_EXIT;//return FS_MSDC_READ_SECTOR_ERROR;
		Sectors -= len;
		if(Sectors == 0) break;
		page = 0;
		ptr += 	MS_PAGE_SIZE*len;
		lba++;	
	}
	MSDC_PDNControl(KAL_TRUE);
   return FS_NO_ERROR;
   
ERR_EXIT:		
	if(retry++ <= MAX_TRY && kal_query_systemInit()== KAL_FALSE)
	{		
		if(status == MS_ERR_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(MS_Initialize() != NO_ERROR)
				return FS_MSDC_READ_SECTOR_ERROR;
		}
		
		//dbg_print("R: fail retry:%d adrs:%d sectors: %d \r\n",retry,Sector, Sectors);
		goto START;
	}
	MSDC_PDNControl(KAL_TRUE);
	return FS_MSDC_READ_SECTOR_ERROR;
}

/*-----------------------------------*/
/*
only allow two case:
case 1: Sectors == 1
case 2: Sectors == gMS.PagesPerBlk

*/
static int  WriteSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer)
{	
	MS_STATUS status;
	kal_uint8 PagesPerBlk,page,pages,extra[4],owflag,len;
	kal_uint32 lba,pba,i,spareblk;
	kal_uint8 *p = NULL,*ptr;
	kal_uint16 *LPTable,*FreeTable;
	kal_uint8 retry = 0;
	
	gMSDC_Handle.timeout_count = 0;
START:	
	if(!gMSDC_Handle.mIsInitialized)
	{
		//dbg_print("Write but not Initialized \r\n");
		MSDC_PDNControl(KAL_TRUE);
		return FS_MSDC_WRITE_SECTOR_ERROR;
	}
	LPTable = gMS.pLPTbl;
	FreeTable = gMS.pFreeTbl;
	PagesPerBlk = gMS.PagesPerBlk;
	ptr = (kal_uint8*)Buffer;
	p = (kal_uint8 * )MS_buffer;

	// get physical block address from sector	
	lba = Sector/PagesPerBlk;
	len = page = Sector%PagesPerBlk;
	MSDC_PDNControl(KAL_FALSE);
	while(1)
	{
		if(PagesPerBlk - page < Sectors)
			len = PagesPerBlk - page;
		else
			len = Sectors;			
		ASSERT(len >= 1 && len <= 32);
		status = MS_API_LogToPhy(LPTable,lba,&pba);
		if(status != MS_NOERROR)
			goto ERR_EXIT;
		// read the entire block
		status = MS_API_ReadBlock(pba,(kal_uint32*)p, (kal_uint32 *)extra, 0, PagesPerBlk, &pages);
		if(status != MS_NOERROR)
			goto ERR_EXIT;
		// set update status to 0
		owflag = extra[0];
		extra[0] &= ~MS_OVFLG_UDST;
		status = MS_API_WriteExtraData(pba, 0, (kal_uint32 *)extra);
		if(status != MS_NOERROR)
			goto ERR_EXIT;
		// update the page in the memory
		kal_mem_cpy((kal_uint8*)(p+page*MS_PAGE_SIZE), (kal_uint8*)ptr, MS_PAGE_SIZE*len);
		// find a unused block from FreeTable, erase it and write updated info into it
		i = 0;
		while((FreeTable[i++] == 0xFFFF) && (i < MS_FREETABLE_SIZE));
		spareblk = FreeTable[i-1];
		status = MS_API_EraseBlock(spareblk);
		if(status != MS_NOERROR)
			goto ERR_EXIT;
		extra[0] = owflag;
		status = MS_API_WriteBlock(spareblk, (kal_uint32*)p, (kal_uint32*)extra, 0, PagesPerBlk, &pages);
		if(status != MS_NOERROR)
			goto ERR_EXIT;
		// update the LPTable and FreeTable
		LPTable[MS_GetLPIndex(lba)] = spareblk;
		FreeTable[i-1] = pba;
		// erase original block
		status = MS_API_EraseBlock(pba);
		if(status != MS_NOERROR)
			goto ERR_EXIT;
		Sectors -= len;
		if(Sectors == 0) break;
		ptr += 	MS_PAGE_SIZE*len;		
		page = 0;
		lba++;			
	} // end of while
	MSDC_PDNControl(KAL_TRUE);
   return FS_NO_ERROR;
   
ERR_EXIT:
	//dbg_print("W: fail %d\r\n",retry);
	if(retry++ <= MAX_TRY && kal_query_systemInit()== KAL_FALSE)
	{
		if(status == MS_ERR_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(write fail)");
			gMSDC_Handle.mIsInitialized = KAL_FALSE;
			retry = 0;
			if(MS_Initialize() != NO_ERROR)
				return FS_MSDC_READ_SECTOR_ERROR;
		}		
		//dbg_print("W: fail retry:%d adrs:%d sectors: %d \r\n",retry,Sector, Sectors);
		goto START;
	}
	MSDC_PDNControl(KAL_TRUE);
	return FS_MSDC_WRITE_SECTOR_ERROR;
	
}

/*-----------------------------------*/
static int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, DWORD Flags)
{
	kal_uint8 retry = 0;

	//dbg_print("MountDevice_MS \r\n");
	
	if(gMSDC_Handle.mIsInitialized)
		return SECTOR_SIZE;		
	
START:	
	if(!gMSDC_Handle.mIsPresent)
	{
		//dbg_print("not present \r\n");
		MSDC_PDNControl(KAL_TRUE);
		return FS_MSDC_MOUNT_ERROR;
	}		
	MSDC_PDNControl(KAL_FALSE);
   if(MS_Initialize() != NO_ERROR)
   {   	
   	goto ERR_EXIT;
   }	
   #if defined(MS_FORMAT)
   if(MS_MountDevice(DeviceType) != FS_NO_ERROR)
   	goto ERR_EXIT;
	#endif
   // get total sector number
   {
	   int i = 0;
	  	FS_PartitionRecord *ptr;
	   kal_uint8 c = gMS.Capacity;
   		   
	   while((c >>= 1) != 2)
	   	i++;	   
		ptr = (FS_PartitionRecord*)MS_MBR[i];
		gMS.TotalSectors = ptr->Sectors;
   }
	   	
   MSDC_PDNControl(KAL_TRUE);
   return SECTOR_SIZE;
   
ERR_EXIT:	
	
	if(retry++ < MAX_TRY)
	{
		//dbg_print("Mount MS failed! retry: %d \r\n",retry);
		goto START;
	}
	MSDC_PDNControl(KAL_TRUE);
	return FS_MSDC_MOUNT_ERROR;
   
}

/*-----------------------------------*/
static int  MediaChanged(void * DriveData)
{
   //dbg_print("MediaChanged\n\r");
	if(gMSDC_Handle.mIsPresent)
	{
		if(gMSDC_Handle.mIsInitialized)
		{
		   //dbg_print("Ready\n\r");
   		return FS_NO_ERROR;
		}
		else
		{
		   //dbg_print("Not Init\n\r");
			return FS_MSDC_PRESNET_NOT_READY;
		}
	}

   //dbg_print("No card\n\r");
	return FS_MSDC_NOT_PRESENT;
}

/*-----------------------------------*/
static int  GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
{
   int i = 0;
   kal_uint8 c = gMS.Capacity;
   	
   // get index for MS_MBR
   while((c >>= 1) != 2)
   	i++;	   
   kal_mem_cpy((void*)DiskGeometry,(void*)MS_MBR[i],MS_MBR_SIZE);
	*MediaDescriptor = MSDC_MEDIA_DESCRIPTOR;
	if(gMS.is_wp)
		return FS_WRITE_PROTECTION;	
   return FS_NO_ERROR;
}

/*-----------------------------------*/
static int  ShutDown(void * DriveData)
{
   return FS_NO_ERROR;
}

FS_Driver FS_MsDrv = {
   MountDevice,
   ShutDown,
   ReadSectors,
   WriteSectors,
   MediaChanged,
   DiscardSectors,
   GetDiskGeometry,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   MSDC_GetCardStatus   
};

#endif // (__MSDC_MS__)


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -