📄 flash.c
字号:
{
StateData.Address--; // move to next address to write
FlashSize[CurrentTarget]--; // update the pointer
StateData.Data = FlashBuffer[CurrentTarget][FlashSize[CurrentTarget]]; // get next word
return WriteFlashData; // write this word
}
return SM_Idle; // go to idle state, will update flash status for us
}
WriteFlash(StateData.Address, Xlate(0x00F0)); // write reset command
StateMachineStatus = FLASH_STATUS_WRITE_FAIL; // indicate failed status
UpdateStatus(CurrentTarget); // update appropriate status
return SM_Idle; // exit
}
//==========================================================================================
// Function: EraseCommandPolling()
//
// Description: Polls the flash to see if the most recently issued erase command is
// complete.
//
// Returns next state in the state machine which could be itself if the
// command is not complete. Also checks for errors and sets
// StateMachineStatus appropriately.
//
// If a complete flash erase was issued, the returned state is
// WriteBootCode which rewrites the boot code into the reset vectors of
// flash for proper loading of the correct image.
//
// Refer to the flash specification sheet for polling algorithm.
//
// Revision History:
//==========================================================================================
void* EraseCommandPolling(void)
{
u16 Status;
DisplayMode = 1; // indicate we are erasing flash
Status = ReadFlash(StateData.Address); // read flash status
// if translated bit 7 matches what was written
if((Status & Xlate(0x0080u)) == (StateData.Data & Xlate(0x0080u)))
{
FlashSize[CurrentTarget] = 0; // clear our command status
return SM_Idle; // have the idle state update our status
}
if((Status & Xlate(0x0020u)) == 0) // if erase command not completed
{
return EraseCommandPolling; // stay in this state
}
Status = ReadFlash(StateData.Address); // read flash status
// if translated bit 7 matches what was written
if((Status & Xlate(0x0080u)) == (StateData.Data & Xlate(0x0080u)))
{
FlashSize[CurrentTarget] = 0; // clear our command status
return SM_Idle; // have the idle state update our status
}
WriteFlash(StateData.Address, Xlate(0x00F0)); // write reset command
StateMachineStatus = FLASH_STATUS_ERASE_FAIL; // update status
UpdateStatus(CurrentTarget); // update appropriate status
return SM_Idle; // let idle state update our status
}
//==========================================================================================
// Function: EraseFlash()
//
// Description: Issues an erase flash command to the flash and sets the next state
// to EraseCommandPolling to monitor the progress.
//
// Revision History:
//==========================================================================================
void* EraseFlash(void)
{
// begin chip erase procedure
WriteFlash(0x8555ul, Xlate(0x00AAu)); // write first unlock command
WriteFlash(0x82AAul, Xlate(0x0055u)); // write second unlock command
WriteFlash(0x8555ul, Xlate(0x0080u)); // write setup command
WriteFlash(0x8555ul, Xlate(0x00AAu)); // write third unlock command
WriteFlash(0x82AAul, Xlate(0x0055u)); // write fourth unlock command
WriteFlash(0x8555ul, Xlate(0x0010u)); // write chip erase command
return EraseCommandPolling; // move to erase command polling state
}
//==========================================================================================
// Function: EraseSector()
//
// Description: Issues an erase sector command to the flash and sets the next state
// to EraseCommandPolling to monitor the progress.
//
// Revision History:
//==========================================================================================
void* EraseSector(void)
{
// begin sector erase procedure
WriteFlash(0x8555ul, Xlate(0x00AAu)); // write first unlock command
WriteFlash(0x82AAul, Xlate(0x0055u)); // write second unlock command
WriteFlash(0x8555ul, Xlate(0x0080u)); // write setup command
WriteFlash(0x8555ul, Xlate(0x00AAu)); // write third unlock command
WriteFlash(0x82AAul, Xlate(0x0055u)); // write fourth unlock command
WriteFlash(StateData.Address, Xlate(0x0030u)); // write sector erase command
return EraseCommandPolling; // move to erase command polling state
}
//==========================================================================================
// Function: GetBaseAddress()
//
// Description: returns the base address of the appropriate code image or the beginning
// of flash if not working on a code type of target
//
// Revision History:
//==========================================================================================
u32 GetBaseAddress(i16 Target)
{
u32 rtn;
switch(Target) // select target
{
case FLASH_TARGET_PROG: // if working with DSP code
rtn = FLASH_IMAGE_PROG; // return pointer to DSP image
break;
case FLASH_TARGET_LOG: // if working with log data
rtn = FLASH_LOG_BASE_ADDRESS; // return pointer tolog space
break;
case FLASH_TARGET_BOOT: // if working with the boot code
rtn = FLASH_IMAGE_BOOT; // return pointer to boot space
break;
case FLASH_TARGET_COPY: // if working on flash copy
rtn = FLASH_IMAGE_ACTIVE; // return pointer to copy space
break;
}
return rtn; // give'm what they wanted
}
//==========================================================================================
// Function: WriteFlashData()
//
// Description: Issues a single write command to the flash. The data to be written and
// the address to write it at is located in the StateData global structure.
//
// Before the write command is issued, the flash is validated to make sure
// the data pattern can actually be written since bits can only be cleared
// during a flash write.
//
// Revision History:
//==========================================================================================
void* WriteFlashData(void)
{
// if pattern cannot be written to flash
if((ReadFlash(StateData.Address) & StateData.Data) != StateData.Data)
{
StateMachineStatus = FLASH_STATUS_NOT_ERASED; // indicate data pattern invalid
UpdateStatus(CurrentTarget); // update appropriate status
return SM_Idle;
}
WriteFlash(0x8555ul, Xlate(0x00AAu)); // write first unlock command
WriteFlash(0x82AAul, Xlate(0x0055u)); // write second unlock command
WriteFlash(0x8555ul, Xlate(0x00A0u)); // write program word command
WriteFlash(StateData.Address, StateData.Data); // write the word
return CommandPolling; // move to command polling state
}
//==========================================================================================
// Function: ValidateFlashModification()
//
// Description: validates the EnableFlashWrites global variable has been written with
// the appropriate authorization code to allow flash writes to succeed.
//
// Revision History:
//==========================================================================================
i16 ValidateFlashModification(void)
{
if(EnableFlashWrites != 0x27B3) // if somebody did not enable the flash
{
StateMachineStatus = FLASH_STATUS_NO_MODIFY;
UpdateStatus(CurrentTarget); // update appropriate target status
return StateMachineStatus; // indicate the error
}
return 0; // return status OK
}
//==========================================================================================
// Function: EnableFlashWriteAccess()
//
// Description: Writes the authorization code to EnableFlashWrites global variable
// allowing flash write to succeed.
//
// Revision History:
//==========================================================================================
void EnableFlashWriteAccess(void)
{
EnableFlashWrites = 0x27B3;
return;
}
//==========================================================================================
// Function: DisableFlashWriteAccess()
//
// Description: Clears the EnableFlashWrites global variable so flash writes will
// not succeed.
//
// Revision History:
//==========================================================================================
void DisableFlashWriteAccess(void)
{
EnableFlashWrites = 0;
return;
}
//==========================================================================================
// Function: ValidateFlashComponent()
//
// Description: Checks to see the flash is a recognizable part which guarantees these
// routines will work with it properly.
//
// Revision History:
//==========================================================================================
i16 ValidateFlashComponent(void)
{
u16 ManufacturerID;
u16 DeviceID;
EnableFlashWriteAccess(); // enable access to the flash
WriteFlash(0x8100ul, Xlate(0x00F0)); // write reset command
WriteFlash(0x8555ul, Xlate(0x00AAu)); // write first unlock command
WriteFlash(0x82AAul, Xlate(0x0055u)); // write second unlock command
WriteFlash(0x8555ul, Xlate(0x0090u)); // write autoselect command
ManufacturerID = UnXlate(ReadFlash(0x8100)); // read who made it
DeviceID = UnXlate(ReadFlash(0x8101)); // read what it is
WriteFlash(0x8100, Xlate(0x00F0)); // write reset command
DisableFlashWriteAccess(); // disable access to the flash
if((ManufacturerID & 0xFF) != 0x01) // if an invalid manufacturing ID
{
return FLASH_STATUS_MANUFACTURER; // return failed status
}
else // if an AMD flash
{
if(DeviceID != 0x22BA) // if incorrect part number for AMD flash
{
return FLASH_STATUS_PART_NO; // return failed status
}
}
return 0; // return good status
}
//==========================================================================================
// Function: WriteFlash()
//
// Description: Writes Data to Address in flash.
// The write is accomplished by setting up a single DMA transfer.
// The DMA can access flash memory space independent of how the memory
// spaces are defined by the OVLY and MP/MC bits thus eliminating the need
// to manage swapping RAM in and out.
//
// Revision History:
//==========================================================================================
void WriteFlash(u32 Address, u16 Data)
{
if(ValidateFlashModification() != 0) // if access not allowed
{
return;
}
FarWrite(Address, Data);
return;
}
//==========================================================================================
// Function: ReadFlash()
//
// Description: Reads from flash at Address.
// The read is accomplished by setting up a single DMA transfer.
// The DMA can access flash memory space independent of how the memory
// spaces are defined by the OVLY and MP/MC bits thus eliminating the need
// to manage swapping RAM in and out.
//
// Revision History:
//==========================================================================================
u16 ReadFlash(u32 Address)
{
return FarRead(Address);
}
//==========================================================================================
// Function: GetBufferCharacter()
//
// Description: Reads a nibble from the input buffer at the nibble offset specified
// by Position and returns it
//
// Revision History:
//==========================================================================================
i16 GetBufferCharacter(i16 Position)
{
u16 Character = uUartDataArray[Position >> 2]; // get word position in buffer
i16 Shift = (3 - (Position & 0x03)) * 4; // calculate shift distance
return (Character >> Shift) & 0xFu; // return value of this nibble
}
//==========================================================================================
// Function: FlashErase()
//
// Description: Called to initiate an erasure of some part of the flash.
//
// If the target is a code image, the code sector image is erased.
// If the target is in user space, only the sector containing
// the address specified in FlashLoadAddress of the target is erased.
//
// Revision History:
//==========================================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -