📄 ms.c
字号:
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_ClrBuffer()
{
MS_STATUS status;
kal_uint8 intreg;
if((status = MS_TPC_SetCmd(CMD_CLEAR_BUF,&intreg))!=MS_NOERROR)
return status;
if(!(intreg & INT_CED))
return MS_ERRORS;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_Stop
*
* DESCRIPTION
* To send a reset comand to Flash Memory chip
*
* PARAMETERS
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_Stop()
{
MS_STATUS status;
kal_uint8 intreg;
if((status = MS_TPC_SetCmd(CMD_FLASH_STOP,&intreg))!=MS_NOERROR)
return status;
if(!(intreg & INT_CED))
return MS_ERRORS;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_AnalysisBB
*
* DESCRIPTION
* Analysis boot block and store the corresponding information in the global variable.
*
* PARAMETERS
* bootblk: buffer contains first page of the bootblock.
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
* gMS
*
* NOTE
* the entries of the boot block is coded in big endien
* the offset of corresponding is defined in the spec. of MS
*************************************************************************/
void MS_AnalysisBB(kal_uint32* bootblk)
{
kal_uint8 *ptr,tmp[4];
ptr = (kal_uint8*)bootblk;
// get number of disable blocks
MSDC_InvertN(tmp,(ptr+MS_BB_HEADER_SIZE+4),4);
gMS.DisBlk = *(kal_uint32*)tmp/2;
// get block size
MSDC_InvertN(tmp,(ptr+MS_BB_HEADER_SIZE+MS_BB_SYSTEM+2),2);
gMS.BlockSize = *(kal_uint16*)tmp * 1024;
// get number of block
MSDC_InvertN(tmp,(ptr+MS_BB_HEADER_SIZE+MS_BB_SYSTEM+4),2);
gMS.NumBlock = *(kal_uint16*)tmp;
MSDC_InvertN(tmp,(ptr+MS_BB_HEADER_SIZE+MS_BB_SYSTEM+32),2);
gMS.Capacity = *(kal_uint16*)tmp;
gMS.PagesPerBlk = gMS.BlockSize/MS_PAGE_SIZE;
}
/*************************************************************************
* FUNCTION
* MS_API_ReadBootBlk
*
* DESCRIPTION
* 1. find the boot block(BB) and save it in gMS.BootBlock_no.
* 2. Get gMS.DisBlk, gMS.BlockSize, gMS.NumBlock, gMS.InfoBlk form BB
*
* PARAMETERS
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
* gMS
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_ReadBootBlk(void)
{
MS_STATUS status;
kal_uint32 i,extra;
kal_uint8 *ptr;
kal_uint8 rxbuffer[MS_PAGE_SIZE];
ptr = (kal_uint8 *)&extra;
// check first 12 blocks to find the boot block
for(i = 0; i < 12; i++)
{
if((status = MS_API_ReadExtraData(i,0,&extra))!=MS_NOERROR)
return status;
//check block status and system bit of Management flag
if((*ptr & MS_OVFLG_BKST) && !(*(ptr+1) & MS_MANAFLG_SYS))
{ // it is the boot block
// read the page 0 from the boot block
if((status = MS_API_ReadSinglePage(i,0,(kal_uint32*)rxbuffer,&extra))!=MS_NOERROR)
return status;
// check the block ID
if((*(kal_uint8*)rxbuffer == 0x00) && (*((kal_uint8*)rxbuffer+1) == 0x01) )
{
kal_uint8 tmp[2];
gMS.BootBlock_no = i;
MS_AnalysisBB((kal_uint32*)rxbuffer);
// get phy block number of information block(page 1)
if((status = MS_API_ReadSinglePage(i,1,(kal_uint32*)rxbuffer,&extra))!=MS_NOERROR)
return status;
MSDC_InvertN(tmp,rxbuffer,2);
gMS.InfoBlk = *(kal_uint16*)tmp;
return MS_NOERROR;
}
else
return MS_ERRORS;
}
}
return MS_ERRORS;
}
/*************************************************************************
* FUNCTION
* MS_API_GenLPTable
*
* DESCRIPTION
* 1. Generate a physical to logical translation table for a segment
* 2. Generate a free block table for a segment
* 3. After successful generation, save segment number.
*
* PARAMETERS
* lptbl: a buffer used for storing generated L->P table.
* ftbl: a buffer used for storing free block address.
* seg: segmentation number
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
* gLPtable
* gMS.Seg
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_GenLPTable(kal_uint16 *lptbl,kal_uint16 *ftbl,kal_uint8 seg)
{
int pblk, minpblk;
kal_uint8 extra[4],extra2[4];
kal_uint16 *fptr,ladrs,lindex;
MS_STATUS status;
if( seg > (gMS.NumBlock/512 - 1))
return MS_ERRORS;
kal_mem_set(ftbl, 0xff, MS_FREETABLE_SIZE * sizeof(kal_uint16));
kal_mem_set(lptbl,0xff, MS_LPTABLE_SIZE * sizeof(kal_uint16));
minpblk = seg * 512;
// contruct the table of physicat -> logical table
for(pblk = minpblk, fptr = ftbl; pblk < minpblk + 512; pblk++)
{
status = MS_API_ReadExtraData(pblk,0,(kal_uint32*)extra);
if(status)
continue;
// The last segment and translation block ?
if((seg == (gMS.NumBlock/512 -1)) && !(extra[1]&MS_MANAFLG_PLTB))
{
continue;
// assume logical address should be 0xFFFF
//status = MS_API_EraseBlock(pblk);
//if(status)
//return MS_ERRORS;
}
// block status = 0 or page statu != 11
if(!(extra[0] & MS_OVFLG_BKST)
|| !((extra[0] & MS_OVFLG_PGST) == MS_OVFLG_PGST))
continue;
// system bit of management flag 0: boot blocks
if(!(extra[1] & MS_MANAFLG_SYS))
continue;
// skip information block
if(pblk == gMS.InfoBlk)
continue;
// store logical address
MSDC_InvertN((kal_uint8*)&ladrs,&extra[2],2);
if(seg ==0)
lindex = ladrs;
else
lindex = ladrs-seg*496+2;
if(ladrs == 0xffff)
{
status = MS_API_EraseBlock(pblk);
if(status)
return MS_ERRORS;
*fptr++ = pblk;
continue;
}
if(lptbl[lindex] == 0xffff)
{
lptbl[lindex] = pblk;
continue;
}
// more than one pblk have the same logical address
MS_API_ReadExtraData(lptbl[lindex], 0, (kal_uint32*)extra2);
if((extra[0]&MS_OVFLG_UDST) == (extra2[0]&MS_OVFLG_UDST))
{ // with the same update status
MS_API_EraseBlock(lptbl[lindex]);
*fptr++ = lptbl[lindex];
continue;
}
// different update status
if(!(extra[0]&MS_OVFLG_UDST))
{
MS_API_EraseBlock(lptbl[lindex]);
*fptr = lptbl[lindex];
lptbl[lindex] = pblk;
continue;
}
MS_API_EraseBlock(pblk);
*fptr = pblk;
}
gMS.Seg = seg;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_LogToPhy
*
* DESCRIPTION
* Get physical address through logical address
*
* PARAMETERS
* lptbl: logical to physical translation table
* ladrs: logical address
* padrs: physical address
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
* gMS.pLPTbl
* gMS.pFreeTbl
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_LogToPhy(kal_uint16* lptbl, kal_uint32 ladrs, kal_uint32* padrs)
{
kal_uint8 seg;
kal_uint16 min;
seg = (ladrs < 494)?0:((ladrs-494)/496 + 1);
min = (seg == 0)?0:(seg*496-2);
// check if ladrs is inside the segment of the lptbl
// reference the lptbl to get the physical address
if(seg != gMS.Seg)
MS_API_GenLPTable(gMS.pLPTbl,gMS.pFreeTbl,seg);
*padrs = *(lptbl+ladrs-min);
return MS_NOERROR;
}
// Find discontiunous logical address and fix it.
#define ERRS 16
MS_STATUS MS_API_CheckLogicalAdrsValid(void)
{
MS_STATUS status;
int seg,i,count;
kal_uint16 *LPTable, *FreeTable, err[ERRS],maxladrs;
kal_uint8 extra[4],check;
LPTable = gMS.pLPTbl;
FreeTable = gMS.pFreeTbl;
kal_mem_set(err,0xFF,ERRS*sizeof(kal_uint16));
check = 0;
for(seg = 0; seg < gMS.NumBlock/BLOCKS_PER_SEGMENT;seg++)
{
status = MS_API_GenLPTable(LPTable, FreeTable, seg);
if(status)
return MS_ERR_LPTABLE;
if(seg == 0)
maxladrs = 494;
else
maxladrs = 496;
count = 0;
for(i = 0; i < maxladrs; i++)
if(LPTable[i] == 0xFFFF)
err[count++] = i; // record incontinuous logical address
if(count > 14) // seg 0 has only 14 free blocks
return MS_ERR_LPTABLE; //please us reassign logical number
// use free blocks to fix the discontinuous logical address
for(i=0;i<count;i++,check++)
{
status = MS_API_EraseBlock(FreeTable[i]);
if(status)
return MS_ERR_LPTABLE;
extra[2] = HIBYTE(err[i]);
extra[3] = LOBYTE(err[i]);
status = MS_API_WriteExtraData(FreeTable[i], 0, (kal_uint32*)extra);
if(status)
return MS_ERR_LPTABLE;
}
}
return (check)?MS_ERR_LPTABLE:MS_NOERROR;
}
#endif // defined(__MSDC_MS__)
// the following code is for msdc testing
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#ifdef MASS
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif //FPGA_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -