📄 ms_drv.c
字号:
}
/*-----------------------------------*/
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 + -