📄 flash_nvram56xx.c
字号:
{
switch(B_FlashChipID)
{
case SST25VF010_ID:
#if(DISABLE_SST == 0)
_fmemcpy(&DecompBuf[0],&RamResidentCode_SST[0],sizeof(RamResidentCode_SST));
msgx("SST",0);
break;
#else
msg("Error - SST is disabled !",0);
return;
#endif
case PM25LV010_ID:
#if(DISABLE_PMC == 0)
_fmemcpy(&DecompBuf[0],&RamResidentCode_PMC[0],sizeof(RamResidentCode_PMC));
msgx("PMC",0);
break;
#else
msg("Error - PMC is disabled !",0);
return;
#endif
case WB25X00_ID:
#if(DISABLE_WB == 0)
_fmemcpy(&DecompBuf[0],&RamResidentCode_WB[0],sizeof(RamResidentCode_WB));
msgx("WB",0);
break;
#else
msg("Error - WB is disabled !",0);
return;
#endif
case STM25PExx_ID:
#if(DISABLE_ST_PE == 0)
_fmemcpy(&DecompBuf[0],&RamResidentCode_ST_PE[0],sizeof(RamResidentCode_ST_PE));
msgx("ST_PE",0);
break;
#else
msg("Error - ST_PE is disabled !",0);
return;
#endif
default:
msg("Error - B_FlashChipID is wrong !",B_FlashChipID);
return; // added
};
}
#endif //NVRAM_USE_FLASH
// Put WrAddr into format that ram routine wants: unified 20-bit address
DW_WrAddr = HUGE(WrAddr);
msg("RAM resident START",0);
gm_DisableInterrupts();
//Toggle gpio is only for testing purpose
//gm_SetRegBitsByte(GPIO_DIRCTRL1, 0x7f);
//gm_SetRegBitsByte(BYPASS, 0x24);
//to toggle gpio for testing
//gm_SetRegBitsByte(GPOUTPUT1, GPIO6_IO);
B_CacheCtrl = gm_ReadRegByte(SPI_CACHE_CTRL);
// gm_ClearRegBitsByte(SPI_CACHE_CTRL, SPI_CACHE_EN); //Disable Cache
gm_ClearRegBitsByte(SPI_CONTROL, FLASH_CHIP_SEL);
RamEntry(cmd,(BYTE far *)DW_WrAddr,length,buff);
//gm_ClearRegBitsByte(GPOUTPUT1, GPIO6_IO);
msg("RAM resident END: length = %d", length);
for(W_DummyCount = 0; W_DummyCount < 256; W_DummyCount++)
{
*(pW_Cache) = 0;
pW_Cache++;
}
gm_WriteRegByte(SPI_CACHE_CTRL,B_CacheCtrl); // re-enable cache
ENABLE_INT();
//Resume vblank ISR for adc calibration
StartADCCalibrationISR();
}
#else
#error Parallel device not supported in 56xx
#endif
#endif
#if NVRAM_USE_FLASH
// Added function to clear blocks of a same type more efficiently (especially for page-write type of flash like PMC).
//***************************************************************
// FUNCTION : pp_ClearNVRAMBlockWithSameType
// DESCRIPTION : Clear all nvram block with the same blockType, mainly for ModeDependent Entries.
// INPUT : B_BlockType (block id),
// B_StartIndex (block index),
// B_MaxEntry (counted from startIndex)
// buffer (allocated first for all entries, size = (Length+headerSize)*B_MaxEntry, buff has to be initialized
// Length (entry length)
//
// OUTPUT : gmt_RET_STAT
// USED_REGS : None
//
//Note: there could be another way to implement this function by using less buffer with size=length+hearder size,
// but call executeRamResidentCmd for B_MaxIndex times.
//
//***************************************************************
gmt_RET_STAT pp_ClearNVRAMBlockWithSameType(BYTE B_BlockType, BYTE B_StartIndex, BYTE B_MaxEntry, BYTE *Bp_Buffer, WORD W_Length)
{
BYTE far *pbAddr;
BYTE version = 0x00;
WORD room, i, j;
block_hdr_type hdr;
//to format buffer for all entries
for (j = 0; j < B_MaxEntry; j++)
{
hdr.Type = B_BlockType;
hdr.Index = j + B_StartIndex;
hdr.Size = W_Length + sizeof(block_hdr_type);
hdr.Checksum = 0;
for (i = 0; i < W_Length; i++)
{
hdr.Checksum += Bp_Buffer[j * hdr.Size + BLOCK_DATA_OFFSET + i];
}
//only update header
_fmemcpy(&Bp_Buffer[j*hdr.Size], &hdr, BLOCK_DATA_OFFSET);
}
// find an empty block
pbAddr = findBlockType(0xff, 0xff, &version);
msgx("B_BlockType %x",(WORD)B_BlockType);
msgx("pbAddr seg %x",(WORD)((DWORD)pbAddr >> 16));
msgx("pbAddr off %x",(WORD)pbAddr);
// see if there's enough room in this FLASH sector for our new block.
room = (WORD)(HUGE((DWORD)workingSector + FLASHUserPrefSectorSize) - HUGE(pbAddr));
msgx("room %d",(WORD)room);
msgx("size for an entry %d",(WORD)hdr.Size);
msgx("Total size %d",(WORD)hdr.Size * B_MaxEntry);
if( (room < (hdr.Size * B_MaxEntry)) || (pbAddr == NULL_PTR)) // not enough room. Time to prune the sector.
{
msgx("..prune1..",0);
msgx("room %d",(WORD)room);
msgx("size for an entry %d",(WORD)hdr.Size);
msgx("Total size %d",(WORD)hdr.Size * B_MaxEntry);
prune();
// find an empty block
pbAddr = findBlockType(0xff, 0xff, &version);
if (pbAddr == NULL_PTR)
return gmd_FAIL; // if after prune, still no room, nothing else we can do.
}
// write data in buffer for all entries to nvram
executeRamResidentCmd(FLASH_NV_WRITE, pbAddr, hdr.Size * B_MaxEntry, Bp_Buffer);
msgx("pp_ClearNVRAMBlockWithSameType",0);
return gmd_OK;
}
//***************************************************************
// FUNCTION : gm_InitNVRAM
// DESCRIPTION : Initialize internal ROM NVRAM routines.
// INPUT : None
// OUTPUT : gmt_RET_STAT
// USED_REGS : None
//***************************************************************
gmt_RET_STAT pp_InitNVRAM(void)
{
#if FLASH_TYPE == SPI_FLASH
BYTE B_FlashChipSize = 0;
#if(DISABLE_AUTODETECT == 0)
BYTE far *Bp_Buff = &B_FlashChipID;
msg("Begin AUTODETECT",0);
executeRamResidentCmd(FLASH_NV_AUTODETECT, NULL_PTR, 0, Bp_Buff);
msg("End AUTODETECT",0);
B_FlashChipSize = ( B_FlashChipID & 0xF0 );
B_FlashChipID = ( B_FlashChipID & 0x0F );
msg("B_FlashChipID = %x",B_FlashChipID);
msg("B_FlashChipSize = %x",B_FlashChipSize);
//set optimal clock based on flash type
// SetOptimalSPIClock();
#else
B_FlashChipID = FLASH_CHIP_TYPE;
B_FlashChipSize = FLASH_CHIP_SIZE;
msg("DISABLE AUTODETECT B_FlashChipID = %x ",B_FlashChipID);
msg("DISABLE AUTODETECT B_FlashChipSize = %x ",B_FlashChipSize);
#endif // #if(DISABLE_AUTODETECT == 0)
// if(ST0000000_ID == B_FlashChipID)
// {
// FLASHUserPrefSectorStart = FLASHUserPrefSectorStartST;
// FLASHUserPrefSectorSize = FLASHUserPrefSectorSizeST;
// }
// else
// {
switch(B_FlashChipSize)
{
case SIZE_128K: FLASHUserPrefSectorStart = FLASHUserPrefSectorStartS128;
break;
case SIZE_256K: FLASHUserPrefSectorStart = FLASHUserPrefSectorStartS256;
break;
case SIZE_512K: FLASHUserPrefSectorStart = FLASHUserPrefSectorStartS512;
break;
default:
msg("Wrong B_FlashChipSize = %x ",B_FlashChipSize);
FLASHUserPrefSectorStart = FLASHUserPrefSectorStartS128;
};
FLASHUserPrefSectorSize = FLASHUserPrefSectorSizeS4;
// }
#else
FLASHUserPrefSectorStart = FLASHUserPrefSectorStartD; // For parallel flash
FLASHUserPrefSectorSize = FLASHUserPrefSectorSizeD;
#endif // #if FLASH_TYPE == SPI_FLASH
#if USE_1K_SECTOR
//To protect flash
if(B_FlashChipID==PM25LV010_ID)
{
msg("Begin PROTECT",0);
executeRamResidentCmd(FLASH_NV_PROTECT, NULL_PTR, 0, Bp_Buff);
msg("End PROTECT",0);
FLASHUserPrefSectorStart = FLASHUserPrefSectorStartS1;
FLASHUserPrefSectorSize = FLASHUserPrefSectorSizeS1;
}
#endif
findWorkingSector();
#if FAST_FLASH_PAGE_UPDATE
MakeCountTable();
#endif
return gmd_OK;
}
//***************************************************************
// FUNCTION : pp_GetNVRAMBlockInfo
// DESCRIPTION : Returns gmt_BLOCKINFO on B_BlockType. gmt_BLOCKIFO
// contains information like absolute address of block
// and the size of the block
// INPUT : B_BlockType (block id) and the B_BlockIndex
// OUTPUT : gmt_RET_STAT
// USED_REGS : None
//***************************************************************
gmt_BLOCKINFO pp_GetNVRAMBlockInfo(BYTE B_BlockType, BYTE B_BlockIndex)
{
BYTE far *pbAddr;
BYTE version = 0x00;
block_info.address = 0x00;
block_info.length = 0x00;
pbAddr = findBlockType(B_BlockType, B_BlockIndex, &version);
if(pbAddr != NULL_PTR)
{
block_info.address = (WORD)(HUGE(pbAddr) - HUGE(workingSector) + BLOCK_DATA_OFFSET);
block_info.length = getLength(pbAddr) - BLOCK_DATA_OFFSET;
}
return block_info;
}
//***************************************************************
// FUNCTION : pp_ReadNVRAMBlock
// DESCRIPTION : Read a data block into buffer.
// INPUT : B_BlockType (block id), B_index (block index), buffer, offset, length
// OUTPUT : gmt_RET_STAT
// USED_REGS : None
//***************************************************************
gmt_RET_STAT pp_ReadNVRAMBlock(BYTE B_BlockType, BYTE B_Index, BYTE * Bp_Buffer, WORD W_Offset, WORD W_Length )
{
BYTE far *pbAddr;
BYTE version = 0x00;
// if findBockType returns NULL_PTR (0x00), and the version number
// returned is non-zero, then it did find a valid block, but the most
// recent is corrupt, so search again but with a version number one
// less then the one returned.
do
{
if((pbAddr = findBlockType(B_BlockType,B_Index,&version)) != NULL_PTR)
{
if(!checkChecksum(pbAddr))
{
pbAddr = NULL_PTR;
msg("version bad: %d",(WORD)version);
}
}
}while(((DWORD)pbAddr == NULL_PTR) && (version-- > 0x01));
if((DWORD)pbAddr == NULL_PTR)
{
msg("entry not found",0);
return gmd_FAIL; // couldn't find block
}
if(W_Length == 0x00)
W_Length = getLength(pbAddr); // if no length supplied, use full length.
_fmemcpy(Bp_Buffer, &pbAddr[BLOCK_DATA_OFFSET + W_Offset], W_Length);
return gmd_OK;
}
//***************************************************************
// FUNCTION : pp_WriteNVRAMBlock
// DESCRIPTION : Write data block
// INPUT : B_BlockType (block id), B_index (block index), buffer, offset, length
// OUTPUT : gmt_RET_STAT
// USED_REGS : None
//***************************************************************
gmt_RET_STAT pp_WriteNVRAMBlock(BYTE B_BlockType, BYTE B_Index, BYTE *Bp_Buffer, WORD W_Offset, WORD W_Length)
{
BYTE far *pbAddr;
BYTE version = 0x00, createHeader = gmd_TRUE;
WORD room, i;
block_hdr_type hdr;
hdr.Type = B_BlockType;
hdr.Index = B_Index;
hdr.Size = W_Length + W_Offset + sizeof(block_hdr_type);
hdr.Checksum = 0;
for(i=0;i < W_Length;i++)
{
hdr.Checksum += Bp_Buffer[i];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -