📄 fdi_mpll.c
字号:
/* align addresses & determine buffer offset */
dst_data_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
dst_offset = UNALIGNED_BYTES(address);
dst_byte_ptr = (BYTE_PTR) temp_buffer + dst_offset;
data_size = COPY_BUFFER_SIZE - dst_offset;
src_byte_ptr = buffer_ptr;
/* take flash write mutex and perform hardware precondition */
SEM_MTX_WAIT(SEM_FlashWrite);
HARDWARE_PRECONDITION;
/* save current flash state */
preempted_state = CurrentFlashState;
/* suspend if flash is busy erasing */
CurrentFlashState = SET_PARTITION_STATE(address, HW_STATE_STATUS);
*dst_data_ptr = FLASH_COMMAND_STATUS;
if ((*dst_data_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
*dst_data_ptr = FLASH_COMMAND_SUSPEND;
*dst_data_ptr = FLASH_COMMAND_STATUS;
while ((*dst_data_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
if (*dst_data_ptr & FLASH_STATUS_ERASE_SUSPENDED)
{
suspended = (BYTE) TRUE;
}
}
while ((size > 0) && (status == HW_ERR_NONE))
{
/* */
byte_size = GET_MIN(data_size, size);
/* calculate the number of FLASH_DATA to write */
data_size = (byte_size + dst_offset + sizeof(FLASH_DATA) - 1) /
sizeof(FLASH_DATA);
/*
* fill the temp buffer with F's if the amount of data is
* not the size of the hardware buffer
*/
if (byte_size != COPY_BUFFER_SIZE)
{
/* temp_buffer[0] = ALL_F;*/
/*temp_buffer[data_size] = ALL_F;*/
MemorySet((BYTE_PTR) temp_buffer, 0xff, COPY_BUFFER_SIZE);
}
MemoryMove(dst_byte_ptr, src_byte_ptr, (WORD) byte_size);
/* write buffer */
status = WriteToFlash(dst_data_ptr, temp_buffer, data_size);
/* update pointers/variables */
dst_data_ptr += data_size;
dst_byte_ptr = (BYTE_PTR) temp_buffer;
src_byte_ptr += byte_size;
size -= byte_size;
data_size = COPY_BUFFER_SIZE;
dst_offset = 0;
}
/* place the partition back into read array mode */
dst_data_ptr--;
CurrentFlashState = SET_PARTITION_STATE((DWORD)dst_data_ptr, HW_STATE_READ);
*dst_data_ptr = FLASH_COMMAND_READ;
/* resume if flash was suspended */
if (suspended)
{
*dst_data_ptr = FLASH_COMMAND_RESUME;
}
/* restore flash state */
CurrentFlashState = preempted_state;
dst_data_ptr = (FLASH_DATA_PTR) GET_PARTITION_ADDRESS(CurrentFlashState);
switch (GET_PARTITION_STATE(CurrentFlashState))
{
case HW_STATE_READ:
*dst_data_ptr = FLASH_COMMAND_READ;
break;
case HW_STATE_STATUS:
*dst_data_ptr = FLASH_COMMAND_STATUS;
break;
default:
break;
}
mDEBUG_PLR_SIMULATION_MLC_STATUS();
/* perform hardware postcondition, post flash write mutex, and return */
HARDWARE_POSTCONDITION;
SEM_MTX_POST(SEM_FlashWrite);
return status;
}
/*#############################################################################
### FlashDevEraseBlock
###
### DESCRIPTION:
### This function erases a single flash erase-block beginning at the
### address specified. The Reclaim Task and Code Manager determine the
### relative address by using the FDI mapping structures. This function
### performs several actions before calling LowLvlEraseBlock() to perform
### the actual erase. First, the function translates the relative address
### into a physical system address and verifies the address range. After
### taking the flash erase semaphore, it calls the low-level function
### LowLvlEraseBlock() via its function pointer. Upon completion of the
### erase, the function releases the flash erase semaphore and returns
### the appropriate value.
###
### PARAMETERS:
### IN: address (DWORD) - The starting address of the block within
### flash to be erased.
### OUT:
###
### RETURNS:
### If the address being specified does not fall within the data managed
### area (or the code managed area if DAV is enabled), the function
### returns HW_ERR_PARAM. If an error occurred while erasing the block,
### the function returns HW_ERR_ERASE. Finally, if all parameters are
### within the appropriate ranges and the block was successfully erased,
### the function returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevEraseBlock(DWORD address)
{
volatile FLASH_DATA_PTR flash_ptr;
DWORD preempted_state;
DWORD key0, key1;
HW_ERROR status;
/* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
mDEBUG_PLR_SIMULATION(0);
#endif
/* address validation */
address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(address, 0);
flash_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
/* E5.3.875 START */
/*#if (DIRECT_ACCESS_VOLUME == TRUE)*/
/* take flash erase mutex */
SEM_MTX_WAIT(SEM_FlashErase);
/*#endif /DIRECT_ACCESS_VOLUME */
/* E5.3.875 END */
/* set current flash state */
preempted_state = CurrentFlashState;
CurrentFlashState = SET_PARTITION_STATE(address, HW_STATE_STATUS);
/* perform erase */
DISABLE_INTERRUPTS(key0, key1);
UNLOCK_BLOCK(flash_ptr);
*flash_ptr = FLASH_COMMAND_ERASE;
*flash_ptr = FLASH_COMMAND_CONFIRM;
/*E.5.4.940 START*/
/*mDEBUG_RESET_ERASE();*/
/*E.5.4.940 END*/
ENABLE_INTERRUPTS(key0, key1);
/* wait until flash is done */
while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
/* lock the block if enabled */
DISABLE_INTERRUPTS(key0, key1);
LOCK_BLOCK(flash_ptr);
ENABLE_INTERRUPTS(key0, key1);
#endif
/* check for errors */
if (*flash_ptr & FLASH_STATUS_ERROR)
{
*flash_ptr = FLASH_COMMAND_CLEAR;
status = HW_ERR_ERASE;
}
else
{
status = HW_ERR_NONE;
}
/* E5.3.875 START */
/*#if (DIRECT_ACCESS_VOLUME == TRUE)*/
/* post flash erase mutex */
SEM_MTX_POST(SEM_FlashErase);
/*#endif /DIRECT_ACCESS_VOLUME */
/* E5.3.875 END */
/*
* place the current partition into read array mode, and restore
* the preempted operation's state
*/
CurrentFlashState = SET_PARTITION_STATE(address, HW_STATE_READ);
*flash_ptr = FLASH_COMMAND_READ;
CurrentFlashState = preempted_state;
flash_ptr = (FLASH_DATA_PTR) GET_PARTITION_ADDRESS(CurrentFlashState);
switch (GET_PARTITION_STATE(CurrentFlashState))
{
case HW_STATE_READ:
*flash_ptr = FLASH_COMMAND_READ;
break;
case HW_STATE_STATUS:
*flash_ptr = FLASH_COMMAND_STATUS;
break;
default:
break;
}
return status;
}
/*#############################################################################
### FlashDevCopy
###
### DESCRIPTION:
### This function is used to copy valid data during reclaim and during
### updates to copy data that is not changing. The Background Manager,
### Reclaim Task, and Code Manager determine the relative address by
### using the FDI mapping structures. This function reads and writes
### data by calling FlashDevRead() and FlashDevWrite().
###
### PARAMETERS:
### IN: dst_address (DWORD) - The starting address within flash to copy
### data to.
### src_address (DWORD) - The starting address within flash to read
### the data from.
### size (DWORD) - The amount of data, in bytes, to copy.
###
### RETURNS:
### If the source and destination buffers do not lie entirely within the
### data managed area (or code managed area if DAV is enabled), the
### function returns HW_ERR_PARAM. If an error occurred while writing
### to the flash hardware, the function returns HW_ERR_WRITE. Finally,
### if all parameters are within the appropriate ranges and the buffer
### was successfully copied, the funciton returns HW_ERR_NONE.
###
*/
/* E5.0.480 START */
HW_ERROR FlashDevCopy(DWORD dst_address, DWORD src_address, DWORD size)
{
BYTE_PTR dst_byte_ptr, src_byte_ptr;
/* E5.1.769 START */
volatile FLASH_DATA_PTR dst_data_ptr;
volatile FLASH_DATA_PTR src_data_ptr;
/* E5.1.769 END */
FLASH_DATA temp_buffer[COPY_BUFFER_SIZE / sizeof(FLASH_DATA)];
DWORD dst_offset;
DWORD byte_size, data_size;
HW_ERROR status = HW_ERR_NONE;
DWORD preempted_state;
BYTE suspended = (BYTE) FALSE;
/* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
mDEBUG_PLR_SIMULATION(size);
#endif
/* address validation */
dst_address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(dst_address, size);
src_address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(src_address, size);
/* if size is 0, return */
if (size == 0)
{
return HW_ERR_NONE;
}
/* align addresses & determine buffer offset */
dst_data_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(dst_address);
dst_offset = UNALIGNED_BYTES(dst_address);
dst_byte_ptr = (BYTE_PTR) temp_buffer + dst_offset;
data_size = COPY_BUFFER_SIZE - dst_offset;
src_byte_ptr = (BYTE_PTR) src_address;
/* take flash write mutex and perform hardware precondition */
SEM_MTX_WAIT(SEM_FlashWrite);
HARDWARE_PRECONDITION;
/* save current flash state */
preempted_state = CurrentFlashState;
/* suspend if flash is busy erasing */
CurrentFlashState = SET_PARTITION_STATE(dst_address, HW_STATE_STATUS);
*dst_data_ptr = FLASH_COMMAND_STATUS;
if ((*dst_data_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
*dst_data_ptr = FLASH_COMMAND_SUSPEND;
*dst_data_ptr = FLASH_COMMAND_STATUS;
while ((*dst_data_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
if (*dst_data_ptr & FLASH_STATUS_ERASE_SUSPENDED)
{
suspended = (BYTE) TRUE;
}
}
while ((size > 0) && (status == HW_ERR_NONE))
{
/* */
byte_size = GET_MIN(data_size, size);
/* calculate the number of FLASH_DATA to write */
data_size = (byte_size + dst_offset + sizeof(FLASH_DATA) - 1) /
sizeof(FLASH_DATA);
/*
* fill the temp buffer with F's if the amount of data is
* not the size of the hardware buffer
*/
if (byte_size != COPY_BUFFER_SIZE)
{
/*temp_buffer[0] = ALL_F;*/
/*temp_buffer[data_size] = ALL_F;*/
MemorySet((BYTE_PTR) temp_buffer, 0xff, COPY_BUFFER_SIZE);
}
src_data_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS((DWORD) src_byte_ptr);
CurrentFlashState =
SET_PARTITION_STATE((DWORD) src_data_ptr, HW_STATE_READ);
*src_data_ptr = FLASH_COMMAND_READ;
MemoryMove(dst_byte_ptr, src_byte_ptr, (WORD) byte_size);
/* write buffer */
CurrentFlashState =
SET_PARTITION_STATE((DWORD) dst_data_ptr, HW_STATE_STATUS);
status = WriteToFlash(dst_data_ptr, temp_buffer, data_size);
/* update pointers/variables */
dst_data_ptr += data_size;
dst_byte_ptr = (BYTE_PTR) temp_buffer;
src_byte_ptr += byte_size;
size -= byte_size;
data_size = COPY_BUFFER_SIZE;
dst_offset = 0;
}
/* place the partition back into read array mode */
dst_data_ptr--;
CurrentFlashState = SET_PARTITION_STATE((DWORD)dst_data_ptr, HW_STATE_READ);
*dst_data_ptr = FLASH_COMMAND_READ;
/* resume if flash was suspended */
if (suspended)
{
*dst_data_ptr = FLASH_COMMAND_RESUME;
}
/* restore flash state */
CurrentFlashState = preempted_state;
dst_data_ptr = (FLASH_DATA_PTR) GET_PARTITION_ADDRESS(CurrentFlashState);
switch (GET_PARTITION_STATE(CurrentFlashState))
{
case HW_STATE_READ:
*dst_data_ptr = FLASH_COMMAND_READ;
break;
case HW_STATE_STATUS:
*dst_data_ptr = FLASH_COMMAND_STATUS;
break;
default:
break;
}
/* perform hardware postcondition, post flash write mutex, and return */
HARDWARE_POSTCONDITION;
SEM_MTX_POST(SEM_FlashWrite);
return status;
}
/* E5.0.480 END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -