📄 nf.c
字号:
{
block_valid = TRUE; /* find a correct block */
}
else /* else decrease block number */
{
if (block == start)
{
block = start + 1023;
}
else
{
block--;
}
}
j++;
}
while ( (!block_valid) && (j < 1024) );
if (j == 1024)
{
return KO;
}
nf_lut_block[i] = block; /* Update look up table address */
}
}
/**********************************************************/
/* Create the look-up table */
/* Process is done zone per zone and by step of 256 blocks*/
/* block2 : logical block value */
/* block : physical block value */
/* byte_6 : logical block index in the buffer */
/* ********************************************************/
for (nf_zone = 0; nf_zone < NF_ZONE_MAX_CPT; nf_zone++) /* for each zone */
{
if ( !(lut_is_present & (0x01 << nf_zone))) /* If not LUT */
{
start = 0x00;
end = 0x80;
free_bloc_pos = (Uint16)(last_physical_used_block[nf_zone]);
gl_address = (Uint32)(nf_lut_block[nf_zone]) << NF_SHIFT_SECTOR_BLOCK;
page = 0;
do
{
nf_init_buffer();
temp_address = (Uint32)(nf_zone) << NF_SHIFT_SECTOR_ZONE;
block = (Uint16)(nf_zone) << NF_SHIFT_BLOCK_ZONE;
Nf_wait_busy();
for (j = NF_BLOCK_PER_ZONE; j != 0 ; j--) /* for each block */
{
Nf_read_open_spare_area(temp_address, 0x05);
if (Nf_rd_byte() == 0xFF) /* if not a bad block */
{
block2.b[0] = Nf_rd_byte(); /* read logical block address */
block2.b[1] = Nf_rd_byte();
byte_6 = block2.b[1] & 0xFE; /* block index in the buffer */
if ( (block2.b[0] & 0xF8) == 0x10) /* if this block is assigned */
{
block2.w = (block2.w & 0x0FFF) >> 1;
if ( (block2.w < end) && (block2.w >= start))
{
if (gl_buffer[byte_6] != 0xFF) /* check if the logical block */
{ /*was affected */
/* this physical block is already affected */
/* we have to find wich block have to be deleted */
i = block; /* save physical block value */
/* Byte addr 11 -> = 0x00 if the block have to be deleted */
Nf_read_open_spare_area(temp_address, 0x11);
if (Nf_rd_byte() == 0x00)
{
nf_block_to_be_deleted = block; /* this is the block to be deleted */
block = ((Uint16)(gl_buffer[byte_6]) << 8) + gl_buffer[byte_6 + 1];
}
else
{ /* the block to be deleted is the block stored in the buffer */
nf_block_to_be_deleted = (Uint16)(gl_buffer[byte_6] << 8) + gl_buffer[byte_6 + 1];
/* update now the buffer with the good block value */
gl_buffer[byte_6] = ((Byte*)&block)[0];
gl_buffer[byte_6 + 1] = ((Byte*)&block)[1];
}
/* for the last block, find the last sector used */
temp_address = (Uint32)(block) << NF_SHIFT_SECTOR_BLOCK;
do
{
Nf_read_open_spare_area(temp_address, 0x06);
(((Byte*)&temp_address)[3])++;
byte_6 = Nf_rd_byte();
}
while ( (byte_6 != 0xFF) && ( (((Byte*)&temp_address)[3] & 0x3F) != 0));
if (byte_6 == 0xFF)
{
(((Byte*)&temp_address)[3])-=2;
}
else
{
(((Byte*)&temp_address)[3])--;
}
Nf_read_open_spare_area(temp_address, 0x10); /* Byte addr 10 -> internal counter page */
/* we prepare now the copy block tail data */
/* first: we restore the logical sector value */
/* note : there is 1000 logicals blocks per zone */
/* block2 : logical block */
gl_ptr_mem = ((Uint32)(block2.w) << NF_SHIFT_SECTOR_BLOCK) /* logical block value */
+ (((Byte*)&temp_address)[3] & 0x3F) /* add sector address in the logical block */
+ (((Uint32)(nf_zone) * 1000) << NF_SHIFT_SECTOR_BLOCK); /* add 1000 logical blocks per zone */
/* second : we restore the physical sector address */
/* block : physical block */
nf_current_physical_sector_addr = ((Uint32)(block) << NF_SHIFT_SECTOR_BLOCK)
+ (((Byte*)&temp_address)[3] & 0x3F);
gl_cpt_page = 0;
byte_5 = ~(Nf_rd_byte());
while (byte_5 != 0)
{
((Byte*)&gl_cpt_page)[0] += 2;
byte_5 = byte_5 >> 1;
}
if (gl_cpt_page)
((Byte*)&gl_cpt_page)[0] -= 2;
if (((Byte*)&gl_cpt_page)[0] == 0x08)
{
gl_ptr_mem++;
nf_current_physical_sector_addr++;
gl_cpt_page = 0;
}
/* set nf_block_used to true to force the copy tail */
nf_block_used = TRUE;
/* complete the last copy tail */
nf_force_write_close();
/* restore value for temp_address and gl_address : */
/* gl_address have been modified by nf_copy_block_tail */
/* temp_address contain the value of gl_ptr_mem */
/* block value was saved in the variable i */
/* a block was deleted so wait nf being ready */
Nf_wait_busy();
nf_close_write_session = TRUE;
}
else
{ /* new affected physical block */
gl_buffer[byte_6] = ((Byte*)&block)[0];
gl_buffer[byte_6 + 1] = ((Byte*)&block)[1];
}
}
}
}
if (nf_close_write_session == TRUE)
{
temp_address = (Uint32)(nf_zone) << NF_SHIFT_SECTOR_ZONE;
block = (Uint16)(nf_zone) << NF_SHIFT_BLOCK_ZONE;
gl_address = (Uint32)(nf_lut_block[nf_zone]) << NF_SHIFT_SECTOR_BLOCK;
j = NF_BLOCK_PER_ZONE + 1;
nf_init_buffer();
nf_close_write_session = FALSE;
}
else
{
temp_address += NF_PAGE_PER_BLOCK;
block++;
}
}
/* affect to the free physical block a fictive logical block */
/* and complete free spare physical blocks */
/* free physical block => gl_buffer[x] = 0xFF */
temp_address = (Uint32)(free_bloc_pos) << NF_SHIFT_SECTOR_BLOCK;
for (i = 0; i <= 0xFE; i+=2)
{
if (gl_buffer[i] == 0xFF)
{
do /* search free physical block */
{
temp_address += NF_PAGE_PER_BLOCK;
if (temp_address >= ((Uint32)(nf_zone + 1) << NF_SHIFT_SECTOR_ZONE) )
temp_address = (Uint32)(nf_zone) << NF_SHIFT_SECTOR_ZONE;
Nf_read_open_spare_area(temp_address, 0x05);
byte_5 = Nf_rd_byte(); /* Invalid/Valid block */
byte_6 = Nf_rd_byte(); /* Used/Unused block */
}
while ( ( (byte_6 != 0xFF) && (byte_6 != 0xE8) ) || (byte_5 != 0xFF) );
free_bloc_pos = (temp_address >> NF_SHIFT_SECTOR_BLOCK);
gl_buffer[i] = ((Byte*)&free_bloc_pos)[0] | 0x80;
gl_buffer[i + 1] = ((Byte*)&free_bloc_pos)[1];
}
}
/* Update LUT */
Nf_send_command (NF_SEQUENTIAL_DATA_INPUT_CMD);
Nf_send_address ( 0x00 ); /* Column address byte 0 */
Nf_send_address ( page ); /* Column address byte 1 */
Nf_send_address ( ((Byte*)&gl_address)[3] ); /* Row address byte 0 */
Nf_send_address ( ((Byte*)&gl_address)[2] ); /* Row address byte 1 */
if (NF_5_CYCLE_ADDRESS_BIT) /* Size of card >= 128Mbytes ? */
Nf_send_address ( ((Byte*)&gl_address)[1] ); /* Row address Byte 2 */
nf_download_buffer(); /* Write 256 bytes from the buffer */
page++;
if (page == 0x08)
{
/* Write redundant 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(0xE8); Nf_wr_byte(0xFF); /* Logical block value */
Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); /* ECC area 2 */
Nf_wr_byte(0xE8); Nf_wr_byte(0xFF); /* Logical block value */
Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); /* ECC area 1 */
}
Nf_send_command(NF_PAGE_PROGRAM_CMD); /* Valid the page programmation */
start += 0x80; /* process next 128 logical block */
end += 0x80;
}
while (start < NF_BLOCK_PER_ZONE);
}
}
/* Global initialization */
nf_block_min = 0xFFFF; /* Starting buffer value */
nf_gl_buf_idx_max = 0; /* Max index in the buffer */
nf_lut_modified = FALSE; /* Buffer change flag */
nf_gl_buf_idx = 0; /* Main buffer index */
gl_buf_free_idx = 0; /* Free physical buffer idx */
nf_old_zone = 0xFF; /* Previous zone number */
nf_close_write_session = FALSE;
nf_write_advanced = FALSE;
#undef temp_address
return OK;
}
/*F**************************************************************************
* NAME: nf_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* OK : init complete
* KO : - NF not supported or not recognise
*----------------------------------------------------------------------------
* PURPOSE:
* NF initialisation
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit nf_init (void)
{
P2 = NF_IDLE_STATE_ADD;
Nf_CS_ON();
Nf_send_command(NF_RESET_CMD);
Nf_wait_busy();
#if (NF_CAPACITY_AUTO_DETECT == TRUE) /* Auto Detect the type of nand-flash */
Nf_send_command(NF_READ_ID_CMD);
Nf_send_address(0x00);
Nf_rd_byte(); /* Maker code */
switch (Nf_rd_byte()) /* Device code */
{
/***************************************************************************/
case NF_128_1_8V : /*------- 128 Mbyte -------*/
case NF_128_3V : /*------- 128 Mbyte -------*/
nf_device_type = NF_SIZE_128MB;
nf_zone_max = 1; /* 1 zone : 1024 blocks */
nf_mem_size = (NF_SECTOR_SIZE_128MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
nf_5_cycle_address = 0; /* 4 address cycles */
break;
/***************************************************************************/
case NF_256_1_8V : /*------- 256 Mbyte -------*/
case NF_256_3V : /*------- 256 Mbyte -------*/
nf_device_type = NF_SIZE_256MB;
nf_zone_max = 2; /* 2 zones : 2048 blocks */
nf_mem_size = (NF_SECTOR_SIZE_256MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
nf_5_cycle_address = 1; /* 5 address cycles */
break;
/***************************************************************************/
case NF_512_1_8V : /*------- 512 Mbyte -------*/
case NF_512_3V : /*------- 512 Mbyte -------*/
nf_device_type = NF_SIZE_512MB;
nf_zone_max = 4; /* 4 zones : 4096 blocks */
nf_mem_size = (NF_SECTOR_SIZE_512MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
nf_5_cycle_address = 1; /* 5 address cycles */
break;
/***************************************************************************/
case NF_1024_1_8V : /*------- 1024 Mbyte -------*/
case NF_1024_3V : /*------- 1024 Mbyte -------*/
nf_device_type = NF_SIZE_1024MB;
nf_zone_max = 8; /* 8 zones : 8192 blocks */
nf_mem_size = (NF_SECTOR_SIZE_1024MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
nf_5_cycle_address = 1; /* 5 address cycles */
break;
/***************************************************************************/
case NF_2048_1_8V : /*------- 2048 Mbyte -------*/
case NF_2048_3V : /*------- 2048 Mbyte -------*/
nf_device_type = NF_SIZE_2048MB;
nf_zone_max = 16; /* 16 zones : 16384 blocks */
nf_mem_size = (NF_SECTOR_SIZE_2048MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
nf_5_cycle_address = 1; /* 5 address cycles */
break;
default:
return KO;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -