📄 flash.c
字号:
}
} while(j < FLASH_LOG_MAX_SIZE); // while log records exist
return; // exit
}
//==========================================================================================
// Function: RunStateMachine()
//
// Description: Runs the state machine in a dedicated manner until it achieves an idle
// state.
//
// Revision History:
//==========================================================================================
void RunStateMachine(i16 Target, u32 Address, u16 Data, i16 Operation)
{
DownLoadActive = 5; // allow the lights to work
if(FlashLEDMask == 0) // if the led's are not already on
{
FlashLEDMask = LED_START; // initialize them
}
EnableFlashWriteAccess(); // allow access to the flash
FlashLoadAddress[Target] = Address; // assign address to write data to
FlashBuffer[Target][0] = Data; // get data to copy
FlashSize[Target] = Operation; // indicate operation needed
do
{
FlashStateMachine(); // clock the state machine
} while(CurrentState != SM_Idle || FlashLEDMask != 0); // until it is completely idle
return; // operation complete, exit
}
//==========================================================================================
// Function: SM_Idle()
//
// Description: The idle state for the flash state machine.
//
// Checks in rotation each flash target to see if there are any flash
// commands which need to be executed and if so executes them by setting
// the appropriate state.
//
// Commands are recognized by a non-zero count in the FlashSize global
// variable. If the value is positive then there is data in the FlashBuffer
// variable to write to flash. If the value is -1 then the flash needs to
// be erased. If the value is less than -1 then a sector needs to be
// ersed.
//
// When no commands are pending and no error exists, this routine is
// responsible for setting the StateMachineStatus to FLASH_STATUS_COMPLETE.
//
// Revision History:
//==========================================================================================
void *SM_Idle(void)
{
i16 i;
for(i = 0; i < FLASH_TARGET_COUNT; i++) // loop through all targets at least once
{
CurrentTarget++; // bump pointer to next target
if(CurrentTarget >= FLASH_TARGET_COUNT) // if we have overflowed the number of targets
{
CurrentTarget = 0; // reset the counter
}
if(FlashSize[CurrentTarget] != 0) // if this target is active
{
TargetStatus[CurrentTarget] = 1; // indicate the target is active
if(FlashSize[CurrentTarget] > 0) // if writing to flash
{
StateData.Address = GetBaseAddress(CurrentTarget); // get pointer to appropriate image
StateData.Address += FlashLoadAddress[CurrentTarget]; // get base address of line to write to
StateData.Address += FlashSize[CurrentTarget] - 1; // update address to write to, we write from end of buffer forward
FlashSize[CurrentTarget]--; // update the pointer
StateData.Data = FlashBuffer[CurrentTarget][FlashSize[CurrentTarget]]; // get next (from end) word to write
return WriteFlashData;
}
else // if erasing flash or sectors
{
if(FlashSize[CurrentTarget] == -1) // if erasing all of flash
{
StateData.Data = 0xFFFFu; // indicate expected data after erase
StateData.Address = GetBaseAddress(CurrentTarget); // get pointer to appropriate image
return EraseFlash; // switch to erasing flash state
}
else // if erasing a sector
{
StateData.Address = GetBaseAddress(CurrentTarget); // get pointer to appropriate image
StateData.Address += FlashLoadAddress[CurrentTarget]; // indicate sector to erase
StateData.Data = 0xFFFFu; // indicate expected data after erase
return EraseSector; // switch to erasing sector state
}
}
}
else // if nothing to write
{
if(WriteTag[CurrentTarget] != 0) // check to see if a tag needs writing
{
StateData.Address = GetBaseAddress(CurrentTarget); // assign image tag address
switch(CurrentTarget)
{
case FLASH_TARGET_PROG: // if working with DSP code
StateData.Address += FLASH_IMAGE_PROG_TAG_OFFSET; // add in offset
break;
}
StateData.Data = FLASH_IMAGE_LOAD; // assign tag value
WriteTag[CurrentTarget] = 0; // clear the write tag flag
return WriteFlashData;
}
}
TargetStatus[CurrentTarget] = 0; // if we made it here, this target is no longer active
}
if(StateMachineStatus < FLASH_STATUS_TIMEOUT) // if no errors occurred
{
StateMachineStatus = FLASH_STATUS_COMPLETE; // set status to complete
UpdateStatus(CurrentTarget); // update appropriate status
DisableFlashWriteAccess(); // disallow flash access since all work is done
}
if(DownLoadActive == 0) // if not in an active download
{
FlashLEDMask = 0; // make sure the LEDs are off
}
else // if in an active download
{
DownLoadActive--; // decrement the flag
}
return SM_Idle; // stay in idle state
}
//==========================================================================================
// Function: FlashStateMachine()
//
// Description: The flash state machine handler function.
//
// Holds the current state in the CurrentState variable. Each time a
// state is executed, that state returns the next state to execute which
// could be itself or another state depending upon what its inputs are.
//
// This routine is called repeatedly from the main loop thus the state
// machine is always active but may simply be idle.
//
// Revision History:
//==========================================================================================
void FlashStateMachine(void)
{
Set_XF(XF_FLASH_SM);
if(DownLoadActive != 0 && FlashLEDMask == 0) // if supposed to be showing status
{
FlashLEDMask = LED_START; // turn on the lights
Dir = 0; // set the direction to start
}
if(FlashLEDMask != 0 && uFlashShow > LED_UPDATE_RATE) // if need to update light status
{
uFlashShow = 0; // reset the counter
if(DisplayMode != 0) // if in erasure mode
{
if((FlashLEDMask & 0xFF) == 0 || (FlashLEDMask & 0xFF) > 0x80) // if an invalid display code found
{
FlashLEDMask = 1; // reinitialize the display mask
Dir = 1; // reinitialize the direction
}
if((FlashLEDMask & 0xFF) == 1 && Dir == 0) // if at limit and direction needs to change
{
Dir = 1; // change direction
}
if((FlashLEDMask & 0xFF) == 0x80 && Dir != 0) // if at limit and direction needs to change
{
Dir = 0; // change direction
}
if(Dir == 0) // if going in right to left direction
{
FlashLEDMask >>= 1; // move light one bit right
}
else
{ // if going in left to right direction
FlashLEDMask <<= 1; // move light one bit left
}
}
else // if in erasing mode
{
if((FlashLEDMask & 0x81) == 0x81 && (FlashLEDMask & 0xFF) != 0xFF) // if an invalid display code found
{
FlashLEDMask = 0xFF; // reinitialize the display mask
}
if((FlashLEDMask & 1) != 1) // if filling from the left
{
FlashLEDMask |= 0x100; // add it fill bit
}
FlashLEDMask >>= 1; // shift the lights left
}
AssignLEDs(FlashLEDMask); // force output
}
CurrentState = ((void * (*)(void)) CurrentState)(); // execute the current state
Clear_XF(XF_FLASH_SM);
return;
}
//==========================================================================================
// Function: Xlate()
//
// Description: Translates data to match pin labels on the flash part since they
// are swapped on the board with respect to the DSP pin labels.
//
// This is necessary when writing commands to the flash but not data.
//
// Revision History:
//==========================================================================================
u16 Xlate(u16 Data)
{
u16 ReturnValue;
i16 Index;
u16 temp;
ReturnValue = 0; // initialize return value
for(Index = 0; Index < 16; Index++) // loop through all data bits
{
temp = (Data >> Index) & 1; // get current bit we are working on
temp <<= TranslationMap[Index]; // move the bit to translated position
ReturnValue |= temp; // add in the bit
}
return ReturnValue; // return translated value
}
//==========================================================================================
// Function: UnXlate()
//
// Description: Un-Translates flash data to match pin labels on the DSP since the data
// pins are swapped on the board with respect to the DSP pin labels.
//
// This is necessary when reading command status from the flash but not
// for data.
//
// Revision History:
//==========================================================================================
u16 UnXlate(u16 Data)
{
u16 ReturnValue;
i16 Index;
u16 temp;
ReturnValue = 0; // initialize return value
for(Index = 0; Index < 16; Index++) // loop through all data bits
{
temp = Data >> TranslationMap[Index]; // shift the data appropriately
temp &= 1; // get current bit we are working on
ReturnValue |= temp << Index; // add in the bit
}
return ReturnValue; // return translated value
}
//==========================================================================================
// Function: CommandPolling()
//
// Description: Polls the flash to see if the most recently issued write 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 the data being written is the last line of a file, denoted by
// WriteTag of the current target being 1, moves to the SetTag state of
// state machine to update image tags as necessary.
//
// Refer to the flash specification sheet for polling algorithm.
//
// Revision History:
//==========================================================================================
void* CommandPolling(void)
{
u16 Status;
DisplayMode = 0; // indicate we are writing flash
Status = ReadFlash(StateData.Address); // read flash status
// if translated bit 7 matches what was written
if((Status & Xlate(0x0080u)) == (StateData.Data & Xlate(0x0080u)))
{
if(ReadFlash(StateData.Address) != StateData.Data) // if verification fails
{
StateMachineStatus = FLASH_STATUS_VERIFY_FAIL; // set error
UpdateStatus(CurrentTarget); // update appropriate status
FlashSize[CurrentTarget] = 0; // clear out the status
return SM_Idle; // return to idle loop
}
if(FlashSize[CurrentTarget] > 0) // if still writes left to do
{
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
}
if((Status & Xlate(0x0020u)) == 0) // if write command not finished
{
return CommandPolling; // stay in command polling state
}
Status = ReadFlash(StateData.Address); // read flash status
// if translated bit 7 matches what was written
if((Status & Xlate(0x0080u)) == (StateData.Data & Xlate(0x0080u)))
{
if(ReadFlash(StateData.Address) != StateData.Data) // if verification fails
{
StateMachineStatus = FLASH_STATUS_VERIFY_FAIL; // set error
UpdateStatus(CurrentTarget); // update appropriate status
FlashSize[CurrentTarget] = 0; // clear out the status
return SM_Idle; // return to idle loop
}
if(FlashSize[CurrentTarget] > 0) // if still writes left to do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -