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

📄 tidtv_flashmem.c

📁 ti的数字电视芯片 tvp9000的源码
💻 C
字号:
/*******************************************************************************
*	@ModuleName	::	TiDTV_FlashMem.c
*	
*	@Copyright	::	Copyright 2005- Texas Instruments, Inc.
*	
*	@Description::	This file contains all of the methods for
*					writing data to flash memory
*	
*	@History	::
*---------------------------------------
*	08-05-2005	W.Shi	Created
*******************************************************************************/

#include	"ucos_ii.h"

#include	"TiDTV_DataType.h"
#include	"TiDTV_SysCtrl.h"
#include	"TiDTV_FlashMem.h"

// MXIC 29LV320: www.mxic.com.tw
static const USHORT TiDTV_FlashMemBlockSize[] = {
	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,		//  4Kwords block x 8, SA0 -SA7
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,		// 32Kwords block x 8, SA8 -SA15
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,		// 32Kwords block x 8, SA16-SA23
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,		// 32Kwords block x 8, SA24-SA31
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,		// 32Kwords block x 8, SA32-SA39
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,		// 32Kwords block x 8, SA40-SA47
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,		// 32Kwords block x 8, SA48-SA55
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,		// 32Kwords block x 8, SA56-SA63
	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,				// 32Kwords block x 8, SA64-SA70
};

#define	TI_DTV_FLASH_NUM_BLOCK		(sizeof(TiDTV_FlashMemBlockSize) / sizeof(int))

static int TiDTV_FlashToggleErase(void);
static int TiDTV_FlashToggleProgram(void);

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashMemSoftReset
*
*	@Description:: Software reset (Read/Reset)
*
*	@Input		:: none
*
*	@Output		:: none
*
*	@Return		:: none
*******************************************************************************/
void TiDTV_FlashMemSoftReset(void)
{
	*TiDTV_FlashMemBaseAddr = 0x00F0;
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashMemDeviceID
*
*	@Description:: Get the Maker ID and Device ID
*
*	@Input		:: none
*
*	@Output		:: none
*
*	@Return		:: none
*******************************************************************************/
void TiDTV_FlashMemGetDeviceID(USHORT *pMakerID, USHORT *pDeviceID)
{
//	volatile ULONG *pEBI = (volatile ULONG *) 0x10000;	// ebi0 = cs 0
	USHORT MakerID, DeviceID;
	
#if	0
	pEBI[0] = 0x040B0B30;	// pol low  w/16
	pEBI[1] = 0x1F00010B;
	pEBI[2] = 0x0000000C;
	pEBI[3] = 0x010C020A;
	pEBI[4] = 0x0C0B0100;
#endif
	
	TiDTV_FlashMemSoftReset();
	*TiDTV_FlashCmdReg555 = 0xAA;
	*TiDTV_FlashCmdReg2AA = 0x55;
	*TiDTV_FlashCmdReg555 = 0x90;
	
	*pMakerID = *TiDTV_FlashMemReg(0);
	*pDeviceID++ = *TiDTV_FlashMemReg(1);
	*pDeviceID++ = *TiDTV_FlashMemReg(0x0e);
	*pDeviceID = *TiDTV_FlashMemReg(0x0f);
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashMemProgramWord
*
*	@Description:: Program one word (16-bit)
*
*	@Input		::
*		USHORT *pAddr	: pinter to the address for writing
*		USHORT Data		: Data to be written
*
*	@Output		:: none
*
*	@Return		::
*		int	: 0 = OK, -1 = NG
*******************************************************************************/
int TiDTV_FlashMemProgramWord(USHORT *pAddr, USHORT Data)
{
	*TiDTV_FlashCmdReg555 = 0xAA;
	*TiDTV_FlashCmdReg2AA = 0x55;
	*TiDTV_FlashCmdReg555 = 0x20;
	*TiDTV_FlashMemBaseAddr = 0xA0;
	*pAddr = Data;
	
	return TiDTV_FlashToggleProgram();
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashMemProgram
*
*	@Description:: Program Flash Memory
*
*	@Input		::
*		USHORT *pDest	: pointer to the flash address
*		USHORT *pSource	: pointer to the source data
*		int ByteCount	: Number of Bytes to be written
*
*	@Output		:: none
*
*	@Return		::
*		int	: 0 = OK, -1 = NG
*******************************************************************************/
int TiDTV_FlashMemProgram(USHORT *pDest, USHORT *pSource, int ByteCount)
{
	int WordCount = (ByteCount + 1) / 2, RetStatus = TI_DTV_E_OK;
	USHORT *pWorkDest = pDest, *pWorkSource = pSource;
	
	while (WordCount-- > 0 && RetStatus == TI_DTV_E_OK)
		RetStatus = TiDTV_FlashMemProgramWord(pWorkDest++, *pWorkSource++);
	
	// Verification
	if (RetStatus == TI_DTV_E_OK) {
		if (memcmp(pDest, pSource, ByteCount) != 0)
			RetStatus = TI_DTV_E_NG;
	}
	
	return TI_DTV_E_OK;
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashMemEraseChip
*
*	@Description:: To Erase the entire chip
*
*	@Input		:: none
*
*	@Output		:: none
*
*	@Return		::
*		int	: 0 = OK, -1 = NG
*******************************************************************************/
int TiDTV_FlashMemEraseChip(void)
{
	TiDTV_FlashMemSoftReset();		// Software reset (Read/Reset)
	*TiDTV_FlashCmdReg555 = 0xAA;
	*TiDTV_FlashCmdReg2AA = 0x55;
	*TiDTV_FlashCmdReg555 = 0x80;
	*TiDTV_FlashCmdReg555 = 0xAA;
	*TiDTV_FlashCmdReg2AA = 0x55;
	*TiDTV_FlashCmdReg555 = 0x10;
	
	return TiDTV_FlashToggleErase();
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashMemEraseBlock
*
*	@Description:: To Erase one block
*
*	@Input		::
*		USHORT *pBlockAddr	: pointer to the block address
*
*	@Output		:: none
*
*	@Return		::
*		int	: 0 = OK, -1 = NG
*******************************************************************************/
int TiDTV_FlashMemEraseBlock(USHORT *pBlockAddr)
{
    TiDTV_FlashMemSoftReset();		// Software reset (Read/Reset)
	*TiDTV_FlashCmdReg555 = 0xAA;
	*TiDTV_FlashCmdReg2AA = 0x55;
	*TiDTV_FlashCmdReg555 = 0x80;
	*TiDTV_FlashCmdReg555 = 0xAA;
	*TiDTV_FlashCmdReg2AA = 0x55;
	*pBlockAddr = 0x30;
	
	return TiDTV_FlashToggleErase();
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashMemErase
*
*	@Description:: To Erase the necessary Blocks
*
*	@Input		::
*		void *pBaseAddr	: pointer to the Base address to be erased
*		int ByteCount	: Number of bytes to be erased
*
*	@Output		:: none
*
*	@Return		::
*		int	: 0 = OK, -1 = NG
*******************************************************************************/
int TiDTV_FlashMemErase(USHORT *pBaseAddr, int ByteCount)
{
	USHORT *pBlockSize = (USHORT *) &TiDTV_FlashMemBlockSize[0];
	USHORT *pBlockAddr = (USHORT *) TI_DTV_FLASH_BASE_ADDR;
	int i, RetStatus = TI_DTV_E_OK;
	
	for (i = 0; i < TI_DTV_FLASH_NUM_BLOCK - 1; i++) {
		if (pBlockAddr >= pBaseAddr)
			break;
		
		pBlockAddr += *pBlockSize++;
	}
	
	if (i >= TI_DTV_FLASH_NUM_BLOCK - 1)
		RetStatus = TI_DTV_E_NG;
	
	while (ByteCount > 0 && RetStatus == TI_DTV_E_OK) {
		RetStatus = TiDTV_FlashMemEraseBlock(pBlockAddr);
		pBlockAddr += *pBlockSize++;
		ByteCount -= *pBlockSize;
	}
	
	return RetStatus;
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashToggleErase
*
*	@Description:: Toggle the erase operation
*
*	@Input		:: none
*
*	@Output		:: none
*
*	@Return		::
*		int	: 0 = OK, -1 = NG
*******************************************************************************/
static int TiDTV_FlashToggleErase(void)
{
	USHORT PullStatus1, PullStatus2, Toggle;
	int i = 0;	// counter to record how many tries.
	
	while (1) {
		PullStatus1 = *TiDTV_FlashMemBaseAddr;	// get the toggling
		PullStatus2 = *TiDTV_FlashMemBaseAddr;	// get the toggling
		
		Toggle = PullStatus1 ^ PullStatus2;
		
		// check the toggle bit
		if ((Toggle & TI_DTV_FLASH_DQE) == 0) {
			return TI_DTV_E_OK;
		}
		
		if (PullStatus2 & TI_DTV_FLASH_DQ5) {	// check time out
 			PullStatus1 = *TiDTV_FlashMemBaseAddr;	// get the toggling again
			PullStatus2 = *TiDTV_FlashMemBaseAddr;	// get the toggling again
			
			Toggle = PullStatus1 ^ PullStatus2;
			
			// check the toggle bit
			if ((Toggle & TI_DTV_FLASH_DQE) == 0) {
				if (*TiDTV_FlashMemBaseAddr == 0xFFFF)	// double check the earsing
					return TI_DTV_E_OK;
			} else {
				TiDTV_FlashMemSoftReset();	// Software reset (Read/Reset)
				return TI_DTV_E_NG;
        	 }
		}
		
		i++;
	}
}

/*******************************************************************************
*	@RoutineName:: TiDTV_FlashToggleProgram
*
*	@Description:: Toggle the program operation
*
*	@Input		:: none
*
*	@Output		:: none
*
*	@Return		::
*		int	: 0 = OK, -1 = NG
*******************************************************************************/
static int TiDTV_FlashToggleProgram(void)
{
	USHORT PullStatus1, PullStatus2, Toggle;
	int i = 0;	// counter to record how many tries.
	
	while (1) {
		PullStatus1 = *TiDTV_FlashMemBaseAddr;	// get the toggling
		PullStatus2 = *TiDTV_FlashMemBaseAddr;	// get the toggling
		
		Toggle = PullStatus1 ^ PullStatus2;
		
		// check the toggle bit
		if ((Toggle & TI_DTV_FLASH_DQ6) == 0)
			return TI_DTV_E_OK;
		
		if (PullStatus2 & TI_DTV_FLASH_DQ5) {	// check time out
 			PullStatus1 = *TiDTV_FlashMemBaseAddr;	// get the toggling again
			PullStatus2 = *TiDTV_FlashMemBaseAddr;	// get the toggling again
			
			Toggle = PullStatus1 ^ PullStatus2;
			
			// check the toggle bit
			if ((Toggle & TI_DTV_FLASH_DQ6) == 0) {
				return TI_DTV_E_OK;
			} else {
				TiDTV_FlashMemSoftReset();	// Software reset (Read/Reset)
				
				return TI_DTV_E_NG;
			}
		}
		
		if (++i > 0x5000) {		// over the limits but still try
			TiDTV_FlashMemSoftReset();		// Software reset (Read/Reset)
			*TiDTV_FlashMemBaseAddr = 0;
			
			return TI_DTV_E_NG;
		}
	}
}

⌨️ 快捷键说明

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