📄 tidtv_flashmem.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 + -