📄 fdi_spll.c
字号:
### limit expired or if an error occurred during programming, the function
### returns HW_ERR_WRITE. Finally, if the command was successfully issued,
### the function returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevProtectReg(FLASH_DATA_PTR factory_reg_ptr,
FLASH_DATA_PTR user_reg_ptr,
FLASH_DATA_PTR lock_reg_ptr,
HW_CMD command,
BYTE register_num,
BYTE lock_flag)
{
FLASH_DATA pr_lock_vals[] =
{
FLASH_PR_LOCK0_VALUE, FLASH_PR_LOCK1_VALUE, FLASH_PR_LOCK2_VALUE,
FLASH_PR_LOCK3_VALUE, FLASH_PR_LOCK4_VALUE, FLASH_PR_LOCK5_VALUE,
FLASH_PR_LOCK6_VALUE, FLASH_PR_LOCK7_VALUE, FLASH_PR_LOCK8_VALUE,
FLASH_PR_LOCK9_VALUE, FLASH_PR_LOCK10_VALUE, FLASH_PR_LOCK11_VALUE,
FLASH_PR_LOCK12_VALUE, FLASH_PR_LOCK13_VALUE, FLASH_PR_LOCK14_VALUE,
FLASH_PR_LOCK15_VALUE, FLASH_PR_LOCK16_VALUE
};
volatile FLASH_DATA_PTR flash_ptr =
(FLASH_DATA_PTR) PARAMETER_PARTITION_START_ADDRESS;
FLASH_DATA data;
HW_ERROR retval = HW_ERR_NONE;
DWORD key0, key1;
DWORD data_amt, i;
DISABLE_INTERRUPTS(key0, key1);
data = PtrLowLvlReadStat(flash_ptr);
ENABLE_INTERRUPTS(key0, key1);
/* check to see if flash is suspended */
/* Begin E.5.1.867 */
if ((data &
(FLASH_STATUS_WRITE_SUSPENDED | FLASH_STATUS_ERASE_SUSPENDED)) &&
((command == HW_CMD_WRITE_PR) || (command == HW_CMD_WRITE_PR_LOCK)))
{
retval = HW_ERR_SUSPEND;
}
/* End E.5.1.867 */
/* check to see if flash is ready for protection register operation */
else if ((data & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
retval = HW_ERR_NOTRDY;
}
/* OK to perform operation */
else
{
/* set pointer to appropriate lock register */
flash_ptr += GET_PR_LOCK_REG(register_num);
switch (command)
{
case HW_CMD_WRITE_PR:
/*
* need to set flash pointer to appropriate block and the
* appropriate size for the protection register bank
*/
flash_ptr++;
if (!register_num)
{
flash_ptr += FLASH_PR_64BIT_SIZE;
data_amt = FLASH_PR_64BIT_SIZE;
}
else
{
flash_ptr += (FLASH_PR_128BIT_SIZE * (register_num - 1));
data_amt = FLASH_PR_128BIT_SIZE;
}
/* write data to protection register */
for (i = 0; i < data_amt; i++, flash_ptr++)
{
HARDWARE_PRECONDITION;
DISABLE_INTERRUPTS(key0, key1);
retval = PtrLowLvlProtectReg(flash_ptr, user_reg_ptr + i,
command);
ENABLE_INTERRUPTS(key0, key1);
HARDWARE_POSTCONDITION;
if (retval != HW_ERR_NONE)
{
break;
}
}
if ((lock_flag) && (retval == HW_ERR_NONE))
{
flash_ptr = (FLASH_DATA_PTR) PARAMETER_PARTITION_START_ADDRESS;
flash_ptr += GET_PR_LOCK_REG(register_num);
data = pr_lock_vals[register_num];
HARDWARE_PRECONDITION;
DISABLE_INTERRUPTS(key0, key1);
retval = PtrLowLvlProtectReg(flash_ptr, &data,
HW_CMD_WRITE_PR_LOCK);
ENABLE_INTERRUPTS(key0, key1);
HARDWARE_POSTCONDITION;
}
break;
case HW_CMD_READ_PR:
flash_ptr++;
/*
* if protection register bank #0 is specified, read both
* user and factory values
*/
if (!register_num)
{
data_amt = FLASH_PR_64BIT_SIZE;
for (i = 0; i < data_amt; i++, flash_ptr++)
{
DISABLE_INTERRUPTS(key0, key1);
retval = PtrLowLvlProtectReg(flash_ptr, factory_reg_ptr + i,
command);
retval =
PtrLowLvlProtectReg((flash_ptr +FLASH_PR_64BIT_SIZE),
user_reg_ptr + i, command);
ENABLE_INTERRUPTS(key0, key1);
}
}
/* otherwise, all data goes into the user registers */
else
{
flash_ptr += (FLASH_PR_128BIT_SIZE * (register_num - 1));
data_amt = FLASH_PR_128BIT_SIZE;
for (i = 0; i < data_amt; i++, flash_ptr++)
{
DISABLE_INTERRUPTS(key0, key1);
retval = PtrLowLvlProtectReg(flash_ptr, user_reg_ptr + i,
command);
ENABLE_INTERRUPTS(key0, key1);
}
}
break;
case HW_CMD_WRITE_PR_LOCK:
data = pr_lock_vals[register_num];
HARDWARE_PRECONDITION;
DISABLE_INTERRUPTS(key0, key1);
retval = PtrLowLvlProtectReg(flash_ptr, &data, command);
ENABLE_INTERRUPTS(key0, key1);
HARDWARE_POSTCONDITION;
break;
case HW_CMD_READ_PR_LOCK:
DISABLE_INTERRUPTS(key0, key1);
retval = PtrLowLvlProtectReg(flash_ptr, &data, command);
ENABLE_INTERRUPTS(key0, key1);
*lock_reg_ptr = data;
break;
default:
retval = HW_ERR_PARAM;
}
}
return retval;
}
#endif /* ENABLE_PR */
#if (PACKET_DATA == TRUE)
#if (BUFFER_SIZE > 0)
/*#############################################################################
### FlashDevWritePacket
###
### DESCRIPTION:
### Allows the Data Manager to write packets to flash. Unlike
### FlashDevWrite(), this function will not align the data if the data
### is not aligned. However, it will check to see if the addresses are
### aligned if PARAM_CHECK (found in FDI_Type.h) is set to TRUE.
###
### PARAMETERS:
### IN: buffer_ptr (BYTE_PTR) - Source buffer of the data to be written.
### address (DWORD) - Flash data fragment start address for the
### write.
### size (DWORD) - Size of the buffer to be written, in bytes.
### OUT:
###
### RETURNS:
### If PARAM_CHECK is set to TRUE and the addresses are not aligned,
### the function returns HW_ERR_PARAM. If an error occurred when writing
### any data, the function returns HW_ERR_WRITE. Otherwise, the function
### returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevWritePacket(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
FLASH_DATA_PTR dst_data_ptr, src_data_ptr;
DWORD key0, key1;
DWORD data_size;
HW_ERROR status = HW_ERR_NONE;
/* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
mDEBUG_PLR_SIMULATION(size);
#endif /* TEST_PLR == BKGD_MLC or DAV_MLC */
/**/
CHECK_ALIGNMENT((DWORD) buffer_ptr);
CHECK_ALIGNMENT(address);
CHECK_ALIGNMENT(size);
dst_data_ptr = (FLASH_DATA_PTR) address;
src_data_ptr = (FLASH_DATA_PTR) buffer_ptr;
size /= sizeof(FLASH_DATA);
HARDWARE_PRECONDITION;
/*
* to get the best performance out of flash, all buffered writes
* should occur on buffer boundaries. Write the initial data that is
* not buffer aligned so that all subsequent writes are on buffer
* boundaries.
*/
while ((size > 0) && (status == HW_ERR_NONE))
{
/**/
data_size = GET_MIN(size, BUFFER_SIZE / sizeof(FLASH_DATA));
/* write buffer */
do
{
#if (TIME_MONITOR_ENABLED == TRUE)
TIME_MONITOR(key0, key1);
#else
DISABLE_INTERRUPTS(key0, key1);
#endif
status = PtrLowLvlWrite(dst_data_ptr, src_data_ptr, data_size);
ENABLE_INTERRUPTS(key0, key1);
} while ((status == HW_ERR_SUSPEND) || (status == HW_ERR_ABORT));
/* update pointers/variables */
dst_data_ptr += data_size;
src_data_ptr += data_size;
size -= data_size;
}
HARDWARE_POSTCONDITION;
return status;
}
#else /* BUFFER_SIZE == 0 */
/*#############################################################################
### FlashDevWritePacket
###
### DESCRIPTION:
### Allows the Data Manager to write packets to flash. Unlike
### FlashDevWrite(), this function will not align the data if the data
### is not aligned. However, it will check to see if the addresses are
### aligned if PARAM_CHECK (found in FDI_Type.h) is set to TRUE.
###
### PARAMETERS:
### IN: buffer_ptr (BYTE_PTR) - Source buffer of the data to be written.
### address (DWORD) - Flash data fragment start address for the
### write.
### size (DWORD) - Size of the buffer to be written, in bytes.
### OUT:
###
### RETURNS:
### If PARAM_CHECK is set to TRUE and the addresses are not aligned,
### the function returns HW_ERR_PARAM. If an error occurred when writing
### any data, the function returns HW_ERR_WRITE. Otherwise, the function
### returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevWritePacket(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
DWORD dst_data_addr, src_data_addr;
DWORD key0, key1;
DWORD data_size;
HW_ERROR status = HW_ERR_NONE;
/* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
mDEBUG_PLR_SIMULATION(size);
#endif /* TEST_PLR == BKGD_MLC or DAV_MLC */
/**/
CHECK_ALIGNMENT((DWORD) buffer_ptr);
CHECK_ALIGNMENT(address);
CHECK_ALIGNMENT(size);
dst_data_addr = (DWORD) address;
src_data_addr = (DWORD) buffer_ptr;
data_size = size / sizeof(FLASH_DATA);
HARDWARE_PRECONDITION;
/*
* with non-buffered components, data only needs to be written on
* aligned addresses.
*/
do
{
#if (TIME_MONITOR_ENABLED == TRUE)
TIME_MONITOR(key0, key1);
#else
DISABLE_INTERRUPTS(key0, key1);
#endif
status = PtrLowLvlWritePacket(&dst_data_addr, &src_data_addr,
&data_size);
ENABLE_INTERRUPTS(key0, key1);
} while (status == HW_ERR_SUSPEND);
HARDWARE_POSTCONDITION;
return status;
}
#endif /* BUFFER_SIZE */
#endif /* PACKET_DATA */
/*#############################################################################
### FlashDevFindInstance
###
### DESCRIPTION:
### Scans all unit headers in block designated by address, look for
### the first empty unit header or the instance to be located.
###
### PARAMETERS:
### IN:
### identifier - unique identifier of data
### table_number - number of the sequence table being searched
### this_instance - sequence table instance number for this block
### type - parameter or data stream identification
### attribute - attribute type to search for
### command - FIND_INSTANCE or FIND_LAST_HEADER
### block - sequence table block number
### hdr_status - header status value to look for
### OUT:
### block_addr_ptr - first address of this block
### header_offset_ptr - byte offset to the unit header
### unit_offset_ptr - byte offset to the data unit or fragment unit
###
### GLOBALS:
###
### FORMAT:
### HW_ERROR FlashFindDevInstance(DWORD_PTR, DWORD_PTR, DWORD_PTR,IDTYPE,
### WORD, WORD, WORD, WORD, BYTE, BYTE, BYTE)
###
### RETURNS:
### HW_ERR_SYSTEM This instance no find
### HW_ERR_NONE function execution is successful
###
*/
HW_ERROR
FlashDevFindInstance(DWORD_PTR blk_addr_ptr,
DWORD_PTR header_offset_ptr,
DWORD_PTR unit_offset_ptr,
IDTYPE identifier,
WORD table_number,
WORD this_instance,
WORD block,
WORD hdr_status,
BYTE type,
BYTE attribute,
BYTE command)
{
UNIT_HEADER header;
UNIT_HDR_PTR pHdr;
DWORD address;
WORD physical_block;
SEM_MTX_WAIT(SEM_BlockTable);
physical_block = FDI_LogicalBlockTable[block].physical_block_number;
SEM_MTX_POST(SEM_BlockTable);
*blk_addr_ptr = BLOCK_ADDRESS(physical_block);
*unit_offset_ptr = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -