📄 fdi_mpll.c
字号:
HARDWARE_INITIALIZE;
/* Relocated functions based on configuration */
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
|| (ENABLE_PR != FDI_NONE))
src_ptr = (BYTE_PTR) LowLvlReadStat;
size = (WORD) ((DWORD) LowLvlEnd - (DWORD) LowLvlReadStat);
MemoryMove(dst_ptr, src_ptr, size);
PtrLowLvlReadStat = (LLREADSTAT_FUNCPTR) (address);
#if (BLOCK_LOCK_SUPPORT == TRUE)
PtrLowLvlLock = (LLLOCK_FUNCPTR) (address +
((DWORD) LowLvlLock - (DWORD) LowLvlReadStat));
#endif /* BLOCK_LOCK_SUPPORT */
#if (ENABLE_PR != FDI_NONE)
PtrLowLvlProtectReg = (LLPR_FUNCPTR) (address +
((DWORD) LowLvlProtectReg - (DWORD) LowLvlReadStat));
#endif /* ENABLE_PR */
#elif (BLOCK_LOCK_SUPPORT == TRUE)
PtrLowLvlLock = (LLLOCK_FUNCPTR) LowLvlLock;
#endif /* OPTIONAL_FEATURES */
return HW_ERR_NONE;
}
#else /* RELOCATE_CODE != TRUE */
/*#############################################################################
### FlashDevInit (Non-Relocate Version)
###
### DESCRIPTION:
### Initializes the pointers used by the flash device functions. Though
### the flash device functions do not check, this function must be
### called before any of the flash device functions can be called.
###
### PARAMETERS:
### IN: address (DWORD) - The physical address to where the low-level
### functions will be relocated. For debugging purposes, it is
### ignored.
### OUT:
###
### RETURNS:
### HW_ERR_NONE.
###
*/
HW_ERROR FlashDevInit()
{
HARDWARE_INITIALIZE;
/* Assign based on configuration */
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
|| (ENABLE_PR != FDI_NONE))
PtrLowLvlReadStat = (LLREADSTAT_FUNCPTR) LowLvlReadStat;
#endif /* (BLOCK_LOCK_SUPPORT && ENABLE_NONFDI_BLOCKLOCKING) || ENABLE_PR */
#if (BLOCK_LOCK_SUPPORT == TRUE)
PtrLowLvlLock = (LLLOCK_FUNCPTR) LowLvlLock;
#endif /* BLOCK_LOCK_SUPPORT */
#if (ENABLE_PR != FDI_NONE)
PtrLowLvlProtectReg = (LLPR_FUNCPTR) LowLvlProtectReg;
#endif /* ENABLE_PR */
return HW_ERR_NONE;
}
#endif /* DEBUG_LOWLVL */
/*#############################################################################
### FlashDevCompatCheck
###
### DESCRIPTION:
### Verifies compatibility with flash support by the user application.
### If the function determines that the component is incompatible, it
### returns an error.
###
### PARAMETERS:
### IN: address (DWORD) - The absolute address of the window in flash
### to scan.
### OUT:
###
### RETURNS:
### If the flash type is supported, the function returns HW_ERR_NONE. If
### the flash type is not supported or if there was an error clearing
### the status register, the function returns HW_ERR_COMPAT.
###
*/
HW_ERROR FlashDevCompatCheck(DWORD address, DWORD size)
{
volatile FLASH_DATA_PTR flash_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
FLASH_DATA status_reg;
HW_ERROR compat;
/* look for the first value that is not FLASH_STATUS_READY */
for (*flash_ptr = FLASH_COMMAND_READ; (DWORD) flash_ptr < (address + size);
flash_ptr++)
{
if (*flash_ptr != FLASH_STATUS_READY)
{
break;
}
}
/* if at or past end of window, no compatibility issue */
if ((DWORD) flash_ptr >= (address + size))
{
compat = HW_ERR_NONE;
}
/* otherwise, clear status register and check value */
else
{
*flash_ptr = FLASH_COMMAND_CLEAR;
*flash_ptr = FLASH_COMMAND_STATUS;
status_reg = *flash_ptr;
*flash_ptr = FLASH_COMMAND_READ;
if (status_reg == FLASH_STATUS_READY)
{
compat = HW_ERR_NONE;
}
else
{
compat = HW_ERR_COMPAT;
}
}
return compat;
}
/*#############################################################################
### FlashDevWrite
###
### DESCRIPTION:
### This function writes 'size' bytes of data from a specified buffer to
### the destination addresss within the device(s). The Background Manager,
### Reclaim Task, and Code Manager determine the relative address by
### using the FDI mapping structures. This function translates the
### relative address into a physical system addres and verifies the
### address range. After aligning the source and destination buffers,
### the function takes the flash write semaphore and calls the low-level
### function LowLvlWrite() via its function pointer. Upon completion
### of the write, the function releases the flash write semaphore and
### returns the appropriate value.
###
### PARAMETERS:
### IN: buffer_ptr (BYTE_PTR) - A pointer to the start address of the
### data to be written.
### address (DWORD) - The destination address within the flash
### device(s).
### size (DWORD) - The amount of data, in bytes, to write.
###
### RETURNS:
### If any portion of the data being written 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 writing
### the data to flash, HW_ERR_WRITE is returned. Finally, if all the
### parameters are within the appropriate ranges and the data was
### written successfully, the function returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevWrite(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
BYTE_PTR dst_byte_ptr, src_byte_ptr;
FLASH_DATA_PTR dst_data_ptr;
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 */
mDEBUG_PLR_SIMULATION(size);
/* address validation */
address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(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(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;
}
/* 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 */
mDEBUG_PLR_SIMULATION(0);
/* address validation */
address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(address, 0);
flash_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
#if (DIRECT_ACCESS_VOLUME == TRUE)
/* take flash erase mutex */
SEM_MTX_WAIT(SEM_FlashErase);
#endif /* DIRECT_ACCESS_VOLUME */
/* 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;
mDEBUG_RESET_ERASE();
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -