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

📄 ms.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 4 页
字号:
* 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 + -