📄 flash.c
字号:
/*
for( CurrenBlockNumber = 0; CurrenBlockNumber < NUM_BLOCKS-1; CurrenBlockNumber++ ) { //total 131: CurBlock = 0~130
if ((flash_offset>=BlockOffset[CurrenBlockNumber]) && (flash_offset<BlockOffset[CurrenBlockNumber+1]) ) {
ret_val = BlockOffset[CurrenBlockNumber];
break;
}
}
*/
// ret_val = flash_offset & FLASH_BLOCK_SIZE;
return ret_val;
}
unsigned int flash_block_unlock(unsigned int flash_offset,unsigned int lock_block)//flash_block_address
{
unsigned int flash_block_address;
unsigned int lock_status;
if (lock_block != Correct_block)
{
lock_block = flash_find_block_address(flash_offset,lock_block);
flash_block_address = BlockOffset[lock_block];
}
else if (lock_block == Correct_block)
{
flash_block_address = flash_offset;
}
// flash_block_address <<= 1;
// flash_block_address += FLASH_BASE;
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_CONFIGURATION;
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_UNLOCK;
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ_ELECTRONIC_SIGNATURE;
lock_status = *( (unsigned short *)(flash_block_address) + 0x02 ); //flash_offset<-->flash_block_address
if(lock_status != FLASH_BLOCK_PROTECTION_UNLOCKED)
{
//printf("%x unlock error!\n",flash_offset);
//while(1);
}
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ;
return lock_block;
}
unsigned int flash_block_lock(unsigned int flash_offset,unsigned int lock_block)
{
unsigned int flash_block_address;
unsigned int lock_status;
if (lock_block != Correct_block)
{
lock_block = flash_find_block_address(flash_offset,lock_block);
flash_block_address = BlockOffset[lock_block];
}
else if (lock_block == Correct_block)
{
flash_block_address = flash_offset;
}
// flash_block_address <<= 1;
// flash_block_address += FLASH_BASE;
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_CONFIGURATION;
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_LOCK;
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ_ELECTRONIC_SIGNATURE;
lock_status = *( (unsigned short *)(flash_block_address) + 0x02 ); //flash_offset<-->flash_block_address
if(lock_status != FLASH_BLOCK_PROTECTION_LOCKED)
{
//printf("%x lock error!\n",flash_offset);
//while(1);
}
*( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ;
return lock_block;
}
void ghdi_flash_block_erase(UINT32 CurrenBlockOffset)
{
// UINT32 CurrenBlockOffset=BlockOffset[BlockNumber]; //erase addr = CurrenBlockOffset;
unsigned short flash_status_reg;
unsigned int lock_block;
lock_block = 0x20000000;
/* Validate paratmers */
if( ( CurrenBlockOffset == NULL ) ) /* Add flash parameter checking later */
{
while(1);
}
lock_block = flash_block_unlock(CurrenBlockOffset,lock_block);
*( (unsigned short *)CurrenBlockOffset) = (unsigned short)FLASH_CMD_BLOCK_ERASE;
*( (unsigned short *)CurrenBlockOffset) = (unsigned short)FLASH_CMD_UNLOCK;
do
{
flash_status_reg = *( (unsigned short *)(CurrenBlockOffset));
}
while( (flash_status_reg & SR7) == 0);
if( ( (flash_status_reg & SR3) == SR3 ) ||
( ( (flash_status_reg & SR4) == SR4 ) && ( (flash_status_reg & SR5) == SR5 ) ) ||
( (flash_status_reg & SR5) == SR5 ) ||
( (flash_status_reg & SR1) == SR1 ) )
{
//printf("Erase error! block: %x\n",CurrenBlockOffset);
//while(1);
}
lock_block = flash_block_lock(CurrenBlockOffset,lock_block);
}
/* API added by WBH, 20071106 */
unsigned int flash_get_block_addr_base(unsigned int sys_addr_within_block)
{
unsigned int ret_val;
unsigned int flash_block_addr_mask;
ASSERT( sys_addr_within_block >= FLASH_BASE );
ASSERT( sys_addr_within_block < (FLASH_BASE + FLASH_SIZE) );
/* Within parameter blocks range */
if( ( sys_addr_within_block >= FLASH_BASE + FLASH_NORMAL_BLOCK_SIZE *FLASH_NORMAL_BLOCK_NUM ) &&
( sys_addr_within_block < FLASH_BASE + (FLASH_NORMAL_BLOCK_SIZE *FLASH_NORMAL_BLOCK_NUM) + (FLASH_PARAMETER_BLOCK_SIZE *FLASH_PARAMETER_BLOCK_NUM) )
)
{
flash_block_addr_mask = (FLASH_PARAMETER_BLOCK_SIZE - 1);
}
/* Within normal blocks range */
else
{
flash_block_addr_mask = (FLASH_NORMAL_BLOCK_SIZE - 1);
}
ret_val = sys_addr_within_block & ~flash_block_addr_mask;
return ret_val;
}
unsigned int flash_get_block_addr_base_from_id(unsigned int block_id)
{
unsigned int ret_val;
ASSERT( block_id <= FLASH_TOTAL_BLOCK_NUM );
/* Within parameter blocks range */
if( ( block_id >= FLASH_NORMAL_BLOCK_NUM ) &&
( block_id < FLASH_NORMAL_BLOCK_NUM + FLASH_PARAMETER_BLOCK_NUM )
)
{
ret_val = FLASH_BASE +
(FLASH_NORMAL_BLOCK_SIZE * FLASH_NORMAL_BLOCK_NUM ) +
(FLASH_PARAMETER_BLOCK_SIZE * (block_id - FLASH_NORMAL_BLOCK_NUM ) ) ;
}
/* Within normal blocks range */
else
{
ret_val = FLASH_BASE +
(FLASH_NORMAL_BLOCK_SIZE * block_id);
}
return ret_val;
}
unsigned int flash_get_block_size_from_id(unsigned int block_id)
{
unsigned int ret_val;
ASSERT( block_id <= FLASH_TOTAL_BLOCK_NUM );
/* Within parameter blocks range */
if( ( block_id >= FLASH_NORMAL_BLOCK_NUM ) &&
( block_id < FLASH_NORMAL_BLOCK_NUM + FLASH_PARAMETER_BLOCK_NUM )
)
{
ret_val = FLASH_PARAMETER_BLOCK_SIZE;
}
/* Within normal blocks range */
else
{
ret_val = FLASH_NORMAL_BLOCK_SIZE;
}
return ret_val;
}
/* Block lock/unlock/lock-down function */
unsigned int flash_block_cntl(unsigned int sys_addr_within_block, unsigned int operation)
{
unsigned int block_base_address;
unsigned int lock_status;
unsigned int ret_val = 1;
static const unsigned short flash_op_cmd_set[2] = {FLASH_CMD_LOCK,
FLASH_CMD_UNLOCK};
static const unsigned short flash_op_expected_state_set[2] = {FLASH_BLOCK_PROTECTION_LOCKED,
FLASH_BLOCK_PROTECTION_UNLOCKED};
unsigned int flash_op_cmd, flash_op_expexted_state;
/* Validate parameters */
ASSERT(sys_addr_within_block >= FLASH_BASE );
ASSERT(sys_addr_within_block < (FLASH_BASE + FLASH_SIZE) );
ASSERT(operation < FLASH_OPERATION_MAX);
flash_op_cmd = flash_op_cmd_set[operation];
flash_op_expexted_state = flash_op_expected_state_set[operation];
/* Get block base address with respect to the system memory space */
block_base_address = flash_get_block_addr_base(sys_addr_within_block);
*( (unsigned short *)(block_base_address) ) = (unsigned short)FLASH_CMD_CONFIGURATION;
*( (unsigned short *)(block_base_address) ) = (unsigned short)flash_op_cmd;
*( (unsigned short *)(block_base_address) ) = (unsigned short)FLASH_CMD_READ_ELECTRONIC_SIGNATURE;
lock_status = *( (unsigned short *)(block_base_address) + 0x02 ); //flash_offset<-->flash_block_address
ASSERT(lock_status == flash_op_expexted_state);
*( (unsigned short *)(block_base_address) ) = (unsigned short)FLASH_CMD_READ;
return ret_val;
}
/*******************************************************************************
*
* Function name: nor_flash_write
* --------------
* Description: Write word data to flash
* ------------
* Parameters: addr: the location of flash where the data will be written to.
* ----------- length: how long the data is. The lenght unit is 16 bits.
* *data: The pointer to the written data.
*
* Returns: None
* --------
*
******************************************************************************/
void nor_flash_write (unsigned int addr, unsigned short *data, unsigned int length)
{
int i, fail_count, max_fail_count;
unsigned int flash_write_starting_address;
unsigned short flash_status_reg;
ASSERT( addr >= FLASH_BASE );
ASSERT( (addr + ( length << 1 ) ) < (FLASH_BASE + FLASH_SIZE) );
fail_count = 0;
max_fail_count = 10000000; /* Just a large number for waiting */ flash_write_starting_address = addr;
for(i=0; i<length; i++)
{
flash_block_cntl((flash_write_starting_address) + (i << 1) , FLASH_OPERATION_UNLOCK);
*( (unsigned short *)(flash_write_starting_address) + i) = (unsigned short)FLASH_CMD_WRITE;
*( (unsigned short *)(flash_write_starting_address) + i) = *(data+i);
do
{
flash_status_reg = *( (unsigned short *)(flash_write_starting_address) + i);
if(fail_count > max_fail_count)
{
/* erase failed */
ASSERT(FALSE);
}
else
{
fail_count++;
}
}
while( (flash_status_reg & SR7) == 0);
ASSERT( (flash_status_reg & SR3) != SR3 ); /* Vpp invalid, abort */
ASSERT( (flash_status_reg & SR4) != SR4 ); /* Program error */
ASSERT( (flash_status_reg & SR1) != SR1 ); /* Program/erase on protected block, abort */
flash_block_cntl((flash_write_starting_address) + (i << 1) , FLASH_OPERATION_LOCK);
}
}
/*******************************************************************************
*
* Function name: nor_flash_sector_erase
* --------------
* Description: Erase the whole content of a sector.
* ------------
* Parameters: addr: the address within this sector.
* -----------
* Returns: Status (1: success, -1: fail)
* --------
*
******************************************************************************/
int nor_flash_sector_erase (unsigned int addr)
{
int status = 1; //Assume ok by default
UINT32 fail_count, max_fail_count;
unsigned short flash_status_reg;
unsigned int block_base_address;
/* Validate paratmers */
ASSERT( addr >= FLASH_BASE );
fail_count = 0;
max_fail_count = 300;
block_base_address = flash_get_block_addr_base(addr); flash_block_cntl(block_base_address, FLASH_OPERATION_UNLOCK);
*( (unsigned short *)block_base_address) = (unsigned short)FLASH_CMD_BLOCK_ERASE;
*( (unsigned short *)block_base_address) = (unsigned short)FLASH_CMD_UNLOCK;
do
{
flash_status_reg = *( (unsigned short *)(block_base_address));
if(fail_count > max_fail_count)
{
status = -1; /* erase failed */
break;
}
else
{
//NU_Sleep(10);//10 ticks = 10 * 10ms = 0.1 sec
gpt_sleep_us(10*1000);
fail_count++;
}
}
while( (flash_status_reg & SR7) == 0);
ASSERT( (flash_status_reg & SR3) != SR3 );
ASSERT( ( (flash_status_reg & SR4) != SR4 ) || ( (flash_status_reg & SR5) != SR5 ) );
ASSERT( (flash_status_reg & SR5) != SR5 );
ASSERT( (flash_status_reg & SR1) != SR1 );
flash_block_cntl(addr, FLASH_OPERATION_LOCK);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -