?? nf_drv2.c
字號:
* PURPOSE: This function reassign the block value in LUT (copy of LUT)
*
*
*****************************************************************************
* NOTE:
*
*
*****************************************************************************/
void nf_reassign_block(void)
{
data Uint16 start;
data Uint32 address2; /* LUT Source address */
data Uint16 logical_block_value; /* logical block value to be reassigned */
Byte pdata *ptr = &gl_buffer[0]; /* gl_buffer pointer */
Byte data n_zone; /* zone counter */
Byte data dummy;
Byte data i, j;
j = 0;
/* Target address */
address = (Uint32)(look_up_table_block) << 5;
/* Source address */
address2 = address_look_up_table;
for (n_zone = 0; n_zone < NF_ZONE_MAX; n_zone++)
{
start = 0;
do
{
Nf_wait_busy();
/* Open look-up table in read mode */
Nf_send_command(NF_READ_A_AREA_CMD); /* First half array */
Nf_send_address( 0x00);
Nf_send_address ( ((Byte*)&address2)[3] ); /* 2nd address cycle */
Nf_send_address ( ((Byte*)&address2)[2] ); /* 3rd address cycle */
if (nf_device_type >= 64) /* Size of card >= 64Mbytes ?*/
Nf_send_address ( ((Byte*)&address2)[1] );/* 4th address cycle */
Nf_wait_busy();
nf_upload_buffer();
/* Reassign logical block */
for (i=0; i < index_reassign; i++)
{
if (reassign_block[i].zone == n_zone)
{
logical_block_value = reassign_block[i].logical_block;
if ( ( logical_block_value < (start + 128)) && (logical_block_value >= start) )
{
ptr = (2 * (logical_block_value & 0x7F));
(*ptr++) = reassign_block[i].physical_block >> 8;
(*ptr) = reassign_block[i].physical_block;
}
}
}
Nf_send_command(NF_READ_A_AREA_CMD); /* First half array */
Nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD);
Nf_send_address(0x00);
Nf_send_address ( ((Byte*)&address)[3] ); /* 2nd address cycle */
Nf_send_address ( ((Byte*)&address)[2] ); /* 3rd address cycle */
if (nf_64) /* Size of card >= 64Mbytes ?*/
Nf_send_address ( ((Byte*)&address)[1] ); /* 4th address cycle */
/* Write 256 bytes from the buffer */
nf_download_buffer();
/* Valid the page programmation */
Nf_send_command(NF_PAGE_PROGRAM_CMD);
start += 128;
/* Wait for R/B signal */
Nf_wait_busy();
/* Open look-up table in read mode */
Nf_send_command(NF_READ_B_AREA_CMD); /* Second half array */
Nf_send_address(0x00);
Nf_send_address ( ((Byte*)&address2)[3] ); /* 2nd address cycle */
Nf_send_address ( ((Byte*)&address2)[2] ); /* 3rd address cycle */
if (nf_64) /* Size of card >= 64Mbytes ?*/
Nf_send_address ( ((Byte*)&address2)[1] );/* 4th address cycle */
Nf_wait_busy();
nf_upload_buffer();
/* Reassign logical block */
for (i = 0; i < index_reassign; i++)
{
if (reassign_block[i].zone == n_zone)
{
logical_block_value = reassign_block[i].logical_block;
if ( ( logical_block_value < (start + 128)) && (logical_block_value >= start) )
{
ptr = (2 * (logical_block_value & 0x7F));
(*ptr++) = reassign_block[i].physical_block >> 8;
(*ptr) = reassign_block[i].physical_block;
}
if (start >= 896)
{
while ( (j < index_block_erased) && (block_to_be_erased[j] < ((Uint16)(n_zone + 1) << 10)))
{
dummy = 192 + index_block_used[j];
gl_buffer[dummy++] = block_to_be_erased[j] >> 8;
gl_buffer[dummy] = block_to_be_erased[j];
j++;
}
}
}
}
nf_send_w_cmd(MODE_CMDB,0);
/* Write 256 bytes from the buffer */
nf_download_buffer();
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xE8);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xE8);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
/* Valid the page programmation */
Nf_send_command(NF_PAGE_PROGRAM_CMD);
start += 128;
address2++;
address++;
}
while (start < 1024);
}
/* Update address of look up table */
Nf_wait_busy();
Nf_send_command (NF_READ_A_AREA_CMD);
Nf_send_command (NF_BLOCK_ERASE_CMD); /* Auto Block Erase Setup */
Nf_send_address ( ((Byte*)&address_look_up_table)[3] ); /* 2nd address cycle*/
Nf_send_address ( ((Byte*)&address_look_up_table)[2] ); /* 3rd address cycle*/
if (nf_64) /* Size of card >= 64Mbytes ?*/
Nf_send_address ( ((Byte*)&address_look_up_table)[1] ); /* 4th address cycle*/
Nf_send_command(NF_BLOCK_ERASE_CONFIRM_CMD); /* Erase command */
address_look_up_table = (Uint32)(look_up_table_block) << 5;
Nf_wait_busy();
}
/*F**************************************************************************
* NAME: nf_mark_bad_block
*----------------------------------------------------------------------------
* PARAMS:
*
*
* RETURN:
*
*
*----------------------------------------------------------------------------
* PURPOSE: Write 0x00 on block status byte (Byte 5 of spare data)
*
*
*****************************************************************************
* NOTE: This function use the global variable Uint32 address
*****************************************************************************/
void nf_mark_bad_block(void)
{
Nf_wait_busy();
Nf_send_command (NF_READ_C_AREA_CMD);
Nf_send_command (NF_SEQUENTIAL_DATA_INPUT_CMD);
Nf_send_address (0x00);
Nf_send_address ( ((Byte*)&address)[3] ); /* 2nd address cycle */
Nf_send_address ( ((Byte*)&address)[2] ); /* 3rd address cycle */
if (nf_64) /* Size of card >= 64Mbytes ?*/
Nf_send_address ( ((Byte*)&address)[1] ); /* 4th address cycle */
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0x00);
Nf_wr_byte(0x00);
Nf_wr_byte(0x00);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
/* Send program command */
Nf_send_command (NF_PAGE_PROGRAM_CMD);
}
/*F**************************************************************************
* NAME: nf_block_erase
*----------------------------------------------------------------------------
* PARAMS:
*
*
* RETURN: OK : erase done
* KO : erase not done
*
*----------------------------------------------------------------------------
* PURPOSE: Erase a block on Nand Flash Media
************************************************************************/
extern bdata bit Nf_WP;
extern xdata Byte mode_state;
bit nf_block_erase (Uint32 pos)
{
if((mode_state == MODE_DOWNLOAD) && (!Nf_WP))
{
return KO;
}
Nf_wait_busy();
Nf_send_command (NF_READ_A_AREA_CMD);
Nf_send_command (NF_BLOCK_ERASE_CMD); /* Auto Block Erase Setup */
Nf_send_address ( ((Byte*)&pos)[3] ); /* 2nd address cycle */
Nf_send_address ( ((Byte*)&pos)[2] ); /* 3rd address cycle */
if (nf_64) /* Size of card >= 64Mbytes ? */
Nf_send_address ( ((Byte*)&pos)[1] ); /* 4th address cycle */
Nf_send_command(NF_BLOCK_ERASE_CONFIRM_CMD);/* Erase command */
return OK;
}
/*F**************************************************************************
* NAME: nf_erase_all_block
*----------------------------------------------------------------------------
* PARAMS:
*
*
* RETURN:
*
*----------------------------------------------------------------------------
* PURPOSE: This function erase all blocks on a NF card and write CIS
* information
*
*
*************************************************************************/
bit nf_erase_all_block(void)
{
Byte pdata *ptr = &gl_buffer[0];
bit bad_block_detect;
Uint16 i;
Byte temp;
Nf_CS_ON();
// Erase all block
for (address = 0; address<(Uint32)(nf_zone_max) * 1024 * 32; address+=32)
{
if((address>=(Uint32)(1024-12)*32)&&(address<(Uint32)1024*32)
||((address>=(Uint32)(2048-13)*32)&&(address<(Uint32)2048*32)))
{
nf_mark_bad_block();
continue;
}
// Read block status byte
Nf_wait_busy();
if (1)
{
nf_block_erase(address);
if ( nf_check_status() == KO)
{ // Failure on erase operation
nf_mark_bad_block();
}
else
{ // Fill redundant area with 0x00
Nf_wait_busy();
Nf_send_command(NF_READ_C_AREA_CMD);
Nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD);
Nf_send_address(0x00);
Nf_send_address ( ((Byte*)&address)[3] ); // 2nd address cycle
Nf_send_address ( ((Byte*)&address)[2] ); // 3rd address cycle
if (nf_64) // Size of card >= 64Mbytes ?
Nf_send_address ( ((Byte*)&address)[1] ); // 4th address cycle
for (temp = 16; temp != 0; temp--)Nf_wr_byte(0x00);
// Valid the page programmation
Nf_send_command(NF_PAGE_PROGRAM_CMD);
if ( nf_check_status() == KO)
{ // Failure on program operation
nf_mark_bad_block();
}
// Read 16 bytes
Nf_wait_busy();
Nf_send_command(NF_READ_C_AREA_CMD);
Nf_send_address(0x00);
Nf_send_address( ((Byte*)&address)[3] ); // 2nd address cycle
Nf_send_address( ((Byte*)&address)[2] ); // 3rd address cycle
if (nf_64) // Size of card >= 64Mbytes ?
Nf_send_address( ((Byte*)&address)[1] ); // 4th address cycle
Nf_wait_busy();
bad_block_detect = FALSE;
for (temp = 16; temp != 0; temp--)
{
if (Nf_rd_byte() != 0x00) bad_block_detect = TRUE;
}
if (bad_block_detect)
{
nf_mark_bad_block();
}
else
{// Finally, erase the block
nf_block_erase(address);
if ( nf_check_status() == KO)
{ // Failure on erase operation
nf_mark_bad_block();
}
}
}
}
}
address=STORE_BEGIN_PAGE;
nf_mark_bad_block();
// Reconstruct the CIS
// Open in write mode at the address 0x00
Nf_wait_busy();
Nf_send_command(NF_READ_A_AREA_CMD);
Nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD);
Nf_send_address(0x00);
Nf_send_address(0x00);
Nf_send_address(0x00);
if (nf_64)
Nf_send_address(0x00);
// Save CIS table in gl_buffer
for (i = 0; i < 0x70; i++)
{
(*ptr++) = nf_cis_table[i];
}
for (i = 0; i < 0x90; i++)
{
(*ptr++) = 0;
}
// write buffer 2 times
nf_download_buffer();
nf_download_buffer();
// Write spare data
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0x00);
Nf_wr_byte(0x00);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0x00);
Nf_wr_byte(0x00);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
Nf_wr_byte(0xFF);
// Valid the page programmation
Nf_send_command(NF_PAGE_PROGRAM_CMD);
read_spare_byte();
Nf_CS_OFF();
return OK;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -