📄 nf.c
字号:
gl_buffer[byte_6 + 1] = block;
}
}
}
}
temp_address += NF_PAGE_PER_BLOCK;
block++;
}
if (!nf_close_write_session)
{
/* affect to the free physical block a fictive logical block */
/* free physical block => gl_buffer[x] = 0xFF */
temp_address = (Uint32)(free_bloc_pos_odd) << NF_SHIFT_SECTOR_BLOCK;
for (i = 2; i <= 0xFE; i+=4)
{
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_odd(temp_address, 0x05);
byte_5 = Nf_rd_byte_odd(); /* Invalid/Valid block */
byte_6 = Nf_rd_byte_odd(); /* Used/Unused block */
}
while ( ( (byte_6 != 0xFF) && (byte_6 != 0xE8) ) || (byte_5 != 0xFF) );
free_bloc_pos_odd = (temp_address >> NF_SHIFT_SECTOR_BLOCK);
gl_buffer[i] = ((Byte*)&free_bloc_pos_odd)[0] | 0x80;
gl_buffer[i + 1] = ((Byte*)&free_bloc_pos_odd)[1];
}
}
}
if (nf_close_write_session == TRUE) /* if we find two physical blocks with same */
{ /* logical blocks affectation */
/* we have already determine the value of : */
/* - nf_block_to_be_deleted_even : need for nf_close_write_session */
/* - nf_block_to_be_deleted_odd : need for nf_close_write_session */
/* - save_gl_cpt_page_even : need for gl_ptr_mem & gl_cpt_page determination */
/* - save_gl_cpt_page_odd : need for gl_ptr_mem & gl_cpt_page determination */
/* - nf_logical_block : logical block value is need for gl_ptr_mem determination */
/* we need to calculate : */
/* - gl_ptr_mem value */
/* - gl_cpt_page value */
/* - switch even/odd nand flash */
gl_ptr_mem = ( ( ((Uint32)(nf_zone) * 1000) << NF_SHIFT_SECTOR_BLOCK) +
( (Uint32)(nf_logical_block) << NF_SHIFT_SECTOR_BLOCK) +
(((Byte*)&nf_current_physical_sector_addr_even)[3] & 0x3F)) << 1;
gl_cpt_page = 0;
if (bit_double_block_odd == FALSE)
{ /* if we detect only double affectation for even nf */
/* (write session stopped before write on odd nf) */
/* last write was on even nf */
((Byte*)&gl_cpt_page)[0] = save_gl_cpt_page_even;
if (((Byte*)&gl_cpt_page)[0] == 0x08)
{
nf_current_physical_sector_addr_even++;
gl_cpt_page = 0x00;
gl_ptr_mem+=2; /* copy block tail only on nf even */
}
nf_parity_bit = NF_EVEN;
}
else
{
if ( (((Byte*)&nf_current_physical_sector_addr_odd)[3] & 0x3F) ==
(((Byte*)&nf_current_physical_sector_addr_even)[3] & 0x3F))
{
/* if physical address even and old is same -> last write was on odd nf */
nf_current_physical_sector_addr_even++;
gl_ptr_mem++;
((Byte*)&gl_cpt_page)[0] = save_gl_cpt_page_odd;
if (((Byte*)&gl_cpt_page)[0] == 0x08) /* if end of page */
{ /* next write will occur in even nf */
nf_current_physical_sector_addr_odd++;
gl_cpt_page = 0x00;
gl_ptr_mem++;
nf_parity_bit = NF_EVEN;
}
else
{
nf_parity_bit = NF_ODD;
}
}
else
{
/* last write was on even nf */
((Byte*)&gl_cpt_page)[0] = save_gl_cpt_page_even;
nf_current_physical_sector_addr_odd++;
if (((Byte*)&gl_cpt_page)[0] == 0x08)
{
nf_current_physical_sector_addr_even++;
gl_cpt_page = 0x00;
gl_ptr_mem++;
nf_parity_bit = NF_ODD;
}
else
{
nf_parity_bit = NF_EVEN;
}
}
}
nf_calc_logical_block();
if ( (((Byte*)&gl_ptr_mem)[3] & 0x7F) || (gl_cpt_page != 0) )
nf_copy_block_tail(!bit_double_block_odd);
Nf_CS_EVEN();
nf_block_erase((Uint32)(nf_block_to_be_deleted_even) << NF_SHIFT_SECTOR_BLOCK); /* Erase old block */
if (bit_double_block_odd == TRUE)
{
Nf_CS_ODD();
nf_block_erase((Uint32)(nf_block_to_be_deleted_odd) << NF_SHIFT_SECTOR_BLOCK); /* Erase old block */
}
/* reset all variables to restart the scan */
gl_address = (Uint32)(nf_lut_block[nf_zone]) << NF_SHIFT_SECTOR_BLOCK + nf_zone;
}
else
{
/* update LUT */
Nf_CS_EVEN();
Nf_wait_busy_even();
Nf_send_command_even (NF_SEQUENTIAL_DATA_INPUT_CMD);
Nf_send_address_even ( 0x00 ); /* Column address byte 0 */
Nf_send_address_even ( page ); /* Column address byte 1 */
Nf_send_address_even ( ((Byte*)&gl_address)[3] ); /* Row address byte 0 */
Nf_send_address_even ( ((Byte*)&gl_address)[2] ); /* Row address byte 1 */
if (NF_5_CYCLE_ADDRESS_BIT) /* Size of card >= 128Mbytes ? */
Nf_send_address_even ( ((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_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF);
Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF);
Nf_wr_byte_even(0xE8); Nf_wr_byte_even(0xFF); /* Logical block value */
Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); /* ECC area 2 */
Nf_wr_byte_even(0xE8); Nf_wr_byte_even(0xFF); /* Logical block value */
Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); /* ECC area 1 */
gl_address++;
page = 0;
}
Nf_send_command_even(NF_PAGE_PROGRAM_CMD); /* Valid the page programmation */
start += 0x40; /* process next 128 logical block */
end += 0x40;
}
}
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;
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_active_EVEN();
Nf_send_command_even(NF_RESET_CMD);
Nf_active_ODD();
Nf_send_command_odd(NF_RESET_CMD);
#if (NF_CAPACITY_AUTO_DETECT == TRUE) /* Auto Detect the type of nand-flash */
Nf_wait_busy_even();
Nf_send_command_even(NF_READ_ID_CMD);
Nf_send_address_even(0x00);
Nf_rd_byte_even(); /* Maker code */
switch (Nf_rd_byte_even()) /* Device code */
{
/***************************************************************************/
case NF_K9F1G08U0M : /*------- 128 Mbyte -------*/
case NF_K9F1K08Q0M : /*------- 128 Mbyte -------*/
nf_device_type = NF_SIZE_256MB;
nf_zone_max = 1; /* 1 zone : 1024 blocks */
nf_mem_size = (NF_SECTOR_SIZE_256MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
nf_5_cycle_address = 0; /* 4 address cycles */
break;
/***************************************************************************/
case NF_K9K2G08Q0M : /*------- 256 Mbyte -------*/
case NF_K9K2G08U0M : /*------- 256 Mbyte -------*/
nf_device_type = NF_SIZE_512MB;
nf_zone_max = 2; /* 2 zones : 2048 blocks */
nf_mem_size = (NF_SECTOR_SIZE_512MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
nf_5_cycle_address = 1; /* 5 address cycles */
break;
default:
return KO;
}
#else
nf_mem_size = (NF_SECTOR_SIZE + 1) * 4 - 1 - MEM_RESERVED_SIZE;
#endif
nf_reserved_space_start = nf_mem_size + 1;
return OK;
}
/*F**************************************************************************
* NAME: nf_read_open
*----------------------------------------------------------------------------
* PARAMS:
* pos: address of the logic sector to read (size 512 bytes)
*
* return:
* Update memory for reading
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory read update
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit nf_read_open (Uint32 pos)
{
Uint16 physical_block;
if (nf_lut_modified)
{
if (nf_close_write_session)
{
nf_close_write_session = FALSE;
nf_force_write_close();
}
nf_reassign_block();
nf_lut_modified = FALSE;
}
gl_ptr_mem = pos >> 2;
gl_cpt_page = (pos & 0x03) << 9 ;
nf_logical_block = (gl_ptr_mem >> NF_SHIFT_SECTOR_BLOCK) >> 1;
nf_zone = nf_logical_block / 1000; /* Determinate logical zone */
nf_logical_block = nf_logical_block - (1000 * (Uint16)(nf_zone)); /* Logical block value */
/* lut address calculation */
gl_address = ((Uint32)(nf_lut_block[nf_zone]) << NF_SHIFT_SECTOR_BLOCK) +
((Uint32)(nf_lut_index[nf_zone]) << 1) +
(((Byte*)&nf_logical_block)[0] >> 1);
Nf_CS_EVEN();
Nf_wait_busy_even();
Nf_send_command_even (NF_READ_CMD); /* Open the look-up table */
Nf_send_address_even ( nf_logical_block << 2 ); /* Column address Byte 0 */
Nf_send_address_even ( (nf_logical_block >> 6) & 0x07 );/* Column address Byte 1 */
Nf_send_address_even ( ((Byte*)&gl_address)[3] ); /* Row address Byte 0 */
Nf_send_address_even ( ((Byte*)&gl_address)[2] ); /* Row address Byte 1 */
if (NF_5_CYCLE_ADDRESS_BIT) /* Size of nf >= 256Mbytes? */
Nf_send_address_even ( ((Byte*)&gl_address)[1] ); /* Row address Byte 2 */
Nf_send_command_even(NF_READ_CMD2);
nf_busy = TRUE; /* Set busy flag */
nf_write_advanced = FALSE; /* Desactive write optimization */
Nf_wait_busy_even();
((Byte*)&physical_block)[0] = Nf_rd_byte_even() & 0x7F;
((Byte*)&physical_block)[1] = Nf_rd_byte_even();
nf_current_physical_sector_addr_even = ((Uint32)(physical_block) << NF_SHIFT_SECTOR_BLOCK) +
((((Byte*)&gl_ptr_mem)[3] & 0x7F) >> 1) +
((((Byte*)&gl_ptr_mem)[3] & 0x01));
((Byte*)&physical_block)[0] = Nf_rd_byte_even() & 0x7F;
((Byte*)&physical_block)[1] = Nf_rd_byte_even();
nf_current_physical_sector_addr_odd = ((Uint32)(physical_block) << NF_SHIFT_SECTOR_BLOCK) +
((((Byte*)&gl_ptr_mem)[3] & 0x7F) >> 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -