📄 sdk7a404_strataflash.c
字号:
*
* Processing:
* See function.
*
* Parameters: None
*
* Outputs: None
*
* Returns: The total number of available bytes for all devices in FLASH
*
* Notes: None
*
**********************************************************************/
UNS_32 cfi_getdevsize(void)
{
return cfi_dg.devsize;
}
/***********************************************************************
*
* Function: cfi_clear_block_lock
*
* Purpose: Clear a block lock
*
* Processing:
* See function.
*
* Parameters:
* block: Block to unlock
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void cfi_clear_block_lock(UNS_32 block)
{
UNS_32 *addr = (UNS_32 *) cfi_get_block_address(block);
UNS_32 tmp;
/* Clear block lock */
flash_write(addr, CFI32_SET_BLOCK_COMMAND);
flash_write(addr, CFI32_CONFIRM_CLEAR_BLOCK_COMMAND);
/* Wait until operation is complete */
tmp=cfi_wait_read(addr);
cfi_clear_status(addr);
}
/***********************************************************************
*
* Function: cfi_set_block_lock
*
* Purpose: Set a block lock
*
* Processing:
* See function.
*
* Parameters:
* block: Block to lock
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void cfi_set_block_lock(UNS_32 block)
{
UNS_32 *addr = (UNS_32 *) cfi_get_block_address(block);
int ret;
/* Set block lock */
flash_write(addr, CFI32_SET_BLOCK_COMMAND);
flash_write(addr, CFI32_CONFIRM_SET_BLOCK_COMMAND);
/* Wait until operation is complete */
ret=cfi_read_status(addr);
// if (ret=)
cfi_wait_read(addr);
cfi_clear_status(addr);
}
/***********************************************************************
*
* Function: cfi_get_block_count
*
* Purpose: Returns the total number of blocks in FLASH
*
* Processing:
* See function.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Returns the total number of blocks in FLASH
*
* Notes: None
*
**********************************************************************/
UNS_32 cfi_get_block_count(void)
{
return cfi_dg.blocks;
}
/***********************************************************************
*
* Function: cfi_get_block_address
*
* Purpose: Returns the starting address of the block
*
* Processing:
* See function.
*
* Parameters:
* block: Block to return starting address to
*
* Outputs: None
*
* Returns: Returns the starting address of the block
*
* Notes: None
*
**********************************************************************/
UNS_32 cfi_get_block_address(UNS_32 block)
{
return cfi_dg.blk_addr[block];
}
/***********************************************************************
*
* Function: cfi_get_block_size
*
* Purpose: Returns the size of the block
*
* Processing:
* See function.
*
* Parameters:
* block: Block to return size of
*
* Outputs: None
*
* Returns: Returns the size of the block
*
* Notes: None
*
**********************************************************************/
UNS_32 cfi_get_block_size(UNS_32 block)
{
return cfi_dg.blk_size[block];
}
/***********************************************************************
*
* Function: cfi_get_wb_size
*
* Purpose: Returns the size of the write buffer
*
* Processing:
* See function.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Returns the size of the write buffer (in 32-bit words)
*
* Notes: None
*
**********************************************************************/
UNS_32 cfi_get_wb_size(void)
{
return cfi_dg.wb_size;
}
/***********************************************************************
*
* Function: cfi_get_block_from_address
*
* Purpose: Returns the block number for the passed address
*
* Processing:
* See function.
*
* Parameters:
* addr: Address to return block number for
*
* Outputs: None
*
* Returns:
* Returns the block number for the passed address, or 0xFFFFFFFF
* if the block was not found for the address
*
* Notes: None
*
**********************************************************************/
UNS_32 cfi_get_block_from_address(UNS_32 *addr)
{
UNS_32 found_block = 0xFFFFFFFF, block, saddr;
/* Search all block address ranges until found */
block = 0;
saddr = (UNS_32) addr;
while ((block < cfi_dg.blocks) && (found_block == 0xFFFFFFFF))
{
if ((saddr >= cfi_dg.blk_addr[block]) &&
(saddr < (cfi_dg.blk_addr[block]) + cfi_dg.blk_size[block]))
{
/* Block found */
found_block = block;
}
block++;
}
return found_block;
}
/***********************************************************************
*
* Function: cfi_erase_block
*
* Purpose: Erases a block of FLASH
*
* Processing:
* See function.
*
* Parameters:
* block: Block to erase
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void cfi_erase_block(UNS_32 block)
{
volatile UNS_32 *addr = (UNS_32 *) cfi_get_block_address(block);
/* Erase lock */
flash_write(addr, CFI32_BLOCKERASE_COMMAND);
flash_write(addr, CFI32_CONFIRM_CLEAR_BLOCK_COMMAND);
/* Wait until operation is complete */
cfi_wait_read(addr);
cfi_clear_status(addr);
}
/***********************************************************************
*
* Function: cfi_erase_device
*
* Purpose: Erases the entire FLASH device
*
* Processing:
* See function.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void cfi_erase_device(void)
{
UNS_32 block;
/* Erase all blocks */
for (block = 0; block <= cfi_dg.blocks; block++)
{
cfi_clear_block_lock(block);
cfi_erase_block(block);
cfi_set_block_lock(block);
}
}
/***********************************************************************
*
* Function: cfi_write
*
* Purpose: Write a single value (32-bits) to the FLASH devices
*
* Processing:
* See function.
*
* Parameters:
* addr: Address to program
* val: 32-bit value to program at address
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: The FLASH block must have been previously unlocked
*
**********************************************************************/
void cfi_writeword(volatile UNS_32 *addr,
UNS_32 val)
{
UNS_32 tmp;
flash_write(addr, CFI32_BYTEWRITE_COMMAND);
flash_write(addr, val);
/* Wait until device is read */
tmp=cfi_wait_read(addr);
cfi_clear_status(addr);
}
/***********************************************************************
*
* Function: cfi_exitprog_mode
*
* Purpose: Return FLASH devices to normal mode
*
* Processing:
* See function.
*
* Parameters:
* addr: Any address of StrataFlash device
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void cfi_exitprog_mode(volatile UNS_32 *addr)
{
/* Exit programming mode */
flash_write(addr, CFI32_WRITE_EXIT_COMMAND);
}
/***********************************************************************
*
* Function: cfi_write_to_buffer
*
* Purpose: Write data to FLASH (using buffer)
*
* Processing:
* See function.
*
* Parameters:
* src: Address of source data
* dest: Address of FLASH to write data to
* words: Number of 32-bit words to write
*
* Outputs: None
*
* Returns: The number of actual 32-bit words written
*
* Notes: None
*
**********************************************************************/
INT_32 cfi_write_to_buffer(UNS_32 *src,
volatile UNS_32 *dest,
INT_32 words)
{
UNS_32 count, *bsave;
/* Get block number from this address */
count = cfi_get_block_from_address((UNS_32 *) dest);
/* Get starting block address of this block */
bsave = (UNS_32 *) cfi_get_block_address(count);
if (words > 0)
{
/* Block write command */
flash_write(bsave, CFI32_BLOCK_WRITE_COMMAND);
/* Wait until device is ready */
cfi_wait_read(bsave);
/* Write count (in bytes) limited to buffer size */
if (words > cfi_dg.wb_size)
{
words = cfi_dg.wb_size;
}
/* Since the write buffer size is expected in bytes and we
store the value in 32-bit words, convert the write count to
a byte size first */
flash_write(bsave, (words | (words << 16)));
/* Write all data or until the write buffer is full,
whichever comes first */
count = 0;
while ((words > 0) && (count < cfi_dg.wb_size))
{
/* Start programming */
flash_write(dest, src[count]);
dest++;
count++;
words--;
}
/* Confirm buffer write */
flash_write(bsave, CFI32_CONFIRM_BUFWRITE_COMMAND);
/* Wait until device is ready */
cfi_wait_read(bsave);
}
return count;
}
/// creator add
#define flash_base_addr 0x0000000
#define data_start_addr 0xc0000000
#define data_size 0x00020000 // 128k
#define MAIN_BLOCK_SIZE_32 0x00040000 //256KB total, 128KB for each memory
#define MAIN_BLOCK_NUM_32 128
#define MAIN_BLOCK_SIZE MAIN_BLOCK_SIZE_32
#define BLOB_FLASH_LEN 0x20000
#define BLOCK_SIZE 0x40000 ///256k for each erase block
int v_start( void )
{
UNS_32 ret, data_write;
unsigned char *d;
int i,j;
unsigned long * src_addr;
UNS_32 *tmp_addr ; ///should be 0x00000000
unsigned long block_size;
src_addr = data_start_addr; ///should be 0xc0000000
d=0x71000000; ///写cpld上的flash Register
*d=(*d|0xff);
//ret=cfi_detect(0x0);
//cfi_erase_device();
//while(1);
tmp_addr = 0x0;
block_size = 0x20000;
/*for blob*/
{
flash_write(tmp_addr, CFI32_SET_BLOCK_COMMAND);
flash_write(tmp_addr, CFI32_CONFIRM_CLEAR_BLOCK_COMMAND);
cfi_wait_read(tmp_addr);
cfi_clear_status(tmp_addr);
flash_write(tmp_addr, CFI32_BLOCKERASE_COMMAND);
flash_write(tmp_addr, CFI32_CONFIRM_CLEAR_BLOCK_COMMAND);
cfi_wait_read(tmp_addr);
cfi_clear_status(tmp_addr);
for( j=0; j<block_size; j+=4 )
{
data_write = *src_addr++ ;
cfi_writeword((volatile UNS_32 *)tmp_addr, data_write);
tmp_addr = tmp_addr + 1;
}
flash_write(tmp_addr-block_size, CFI32_SET_BLOCK_COMMAND);
flash_write(tmp_addr-block_size, CFI32_CONFIRM_SET_BLOCK_COMMAND);
flash_write(tmp_addr-block_size, CFI32_CLEAR_STATUS_COMMAND);
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -