?? nf.c
字號:
if ((byte_6 == 0xE8) && ((gl_address & 0x1F) == 0))
{
lut_index[i]--;
gl_address = gl_address - NB_PAGE_BY_LUT;
}
else
{
lut_index[i]-=2;
gl_address = gl_address - (NB_PAGE_BY_LUT << 1);
}
Nf_read_open_C_area_even(gl_address, 0x00);
if (Nf_rd_byte_even() != 0xFF) /* LUT have been modified */
{
nf_block_erase(gl_address);
lut_is_present[i] = FALSE;
lut_index[i] = 0;
Nf_wait_busy_even();
}
}
}
/*****************************************************************/
/* Find free physical block for LUT for each zone */
/*****************************************************************/
for (i = 0; i < NF_ZONE_MAX_CPT; i++)
{
if (lut_is_present[i] == FALSE)
{
block = last_physical_used_block_even[i];
start = (Uint16)(i); /* starting value for each zone */
j = 0; /* reset turn around counter */
if (block == start) /* starting block for scan */
{
block = start + ((NF_ZONE_MAX_CPT << 10) - NF_ZONE_MAX_CPT);
}
block_valid = FALSE; /* init flag block valid */
do
{
gl_address = (Uint32)(block) << 5;
Nf_read_open_C_area_even(gl_address, 0x05);
byte_5 = Nf_rd_byte_even();
byte_6 = Nf_rd_byte_even();
if ( (byte_5 == 0xFF) && (byte_6 == 0xFF) ) /* not assigned and valid block */
{
block_valid = TRUE; /* find a correct block */
}
else /* else decrease block number */
{
if (block == start)
{
block = start + ((NF_ZONE_MAX_CPT << 10) - NF_ZONE_MAX_CPT);
}
else
{
block-=NF_ZONE_MAX_CPT;
}
}
j++;
}
while (( !block_valid ) && (j < 1024));
if (j == 1024)
return KO;
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*/
/* ********************************************************/
for (nf_zone = 0; nf_zone < NF_ZONE_MAX_CPT; nf_zone++) /* for each zone */
{
if (lut_is_present[nf_zone] == FALSE)
{
start = 0x00;
end = 0x40; /* 256 bytes for gl_buffer <-> 64 blocks */
free_bloc_pos_even = (Uint16)(last_physical_used_block_even[nf_zone]);
free_bloc_pos_odd = (Uint16)(last_physical_used_block_odd[nf_zone]);
gl_address = (Uint32)(lut_block[nf_zone]) << 5;
lut_part = 0;
do
{
Nf_CS_EVEN(); /* even Part */
nf_init_buffer(); /* reinitialize the buffer */
temp_address = (Uint32)(nf_zone) << 5; /* at the beginning */
block = (Uint16)(nf_zone);
Nf_wait_busy_even();
for (j = NF_BLOCK_PER_ZONE; j != 0 ; j--) /* for each block */
{
Nf_read_open_C_area_even(temp_address, 0x05);
if (Nf_rd_byte_even() == 0xFF) /* If not a bad block */
{
block2.b[0] = Nf_rd_byte_even(); /* Read logical block address */
block2.b[1] = Nf_rd_byte_even();
if ( (block2.b[0] & 0xF8) == 0x10)
{
block2.w = (block2.w & 0x0FFF) >> 1;
if ( (block2.w < end) && (block2.w >= start))
{
gl_buffer[(Byte)(4 * block2.b[1])] = block >> 8; /* Save logical block value */
gl_buffer[(Byte)(4 * block2.b[1] + 1)] = block & 0xFF; /* in the buffer */
}
}
}
temp_address += (NF_ZONE_MAX_CPT << 5);
block+=NF_ZONE_MAX_CPT;
}
/* affect to the free physical block a fictive logical block */
/* free physical block => gl_buffer[x] = 0xFF */
temp_address = (Uint32)(free_bloc_pos_even) << 5;
for (j = 0; j <= 0xFC; j += 4)
{
if (gl_buffer[j] == 0xFF)
{
do /* Search free physical block */
{
temp_address += (NF_ZONE_MAX_CPT << 5);
if (temp_address >= ((Uint32)(NF_ZONE_MAX_CPT) << 15) )
temp_address = (Uint32)(nf_zone) << 5;
Nf_read_open_C_area_even(temp_address, 0x05);
byte_5 = Nf_rd_byte_even(); /* Invalid/Valid block */
byte_6 = Nf_rd_byte_even(); /* Used/Unused block */
}
while ( ( (byte_6 != 0xFF) && (byte_6 != 0xE8) ) || (byte_5 != 0xFF) );
free_bloc_pos_even = temp_address >> 5;
gl_buffer[j] = (free_bloc_pos_even >> 8) | 0x80;
gl_buffer[j + 1] = free_bloc_pos_even;
}
}
Nf_CS_ODD(); /* Odd Part */
temp_address = (Uint32)(nf_zone) << 5; /* We start at the beginning */
block = (Uint16)(nf_zone);
Nf_wait_busy_odd();
for (j = NF_BLOCK_PER_ZONE; j != 0 ; j--) /* for each block */
{
Nf_read_open_C_area_odd(temp_address, 0x05);
if (Nf_rd_byte_odd() == 0xFF) /* If not a bad block */
{
block2.b[0] = Nf_rd_byte_odd(); /* Read logical block address */
block2.b[1] = Nf_rd_byte_odd();
if ( (block2.b[0] & 0xF8) == 0x10)
{
block2.w = (block2.w & 0x0FFF) >> 1;
if ( (block2.w < end) && (block2.w >= start))
{ /* Save logical block value in the buffer */
gl_buffer[(Byte)(4 * block2.b[1] + 2)] = block >> 8;
gl_buffer[(Byte)(4 * block2.b[1] + 1 + 2)] = block;
}
}
}
temp_address += (NF_ZONE_MAX_CPT << 5);
block+= NF_ZONE_MAX_CPT;
}
/* affect to the free physical block a fictive logical block */
/* free physical block => gl_buffer[x] = 0xFF */
temp_address = (Uint32)(free_bloc_pos_odd) << 5;
for (j = 2; j <= 0xFE; j+=4)
{
if (gl_buffer[j] == 0xFF)
{
do /* Search free physical block */
{
temp_address += (NF_ZONE_MAX_CPT << 5);
if (temp_address >= ((Uint32)(NF_ZONE_MAX_CPT) << 15) )
temp_address = (Uint32)(nf_zone) << 15;
Nf_read_open_C_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 >> 5;
gl_buffer[j] = (free_bloc_pos_odd >> 8) | 0x80;
gl_buffer[j + 1] = free_bloc_pos_odd;
}
}
Nf_CS_EVEN();
Nf_wait_busy_even();
if (lut_part == 0)
{
Nf_write_open_A_area_even(gl_address, 0x00); /* First part of LUT */
nf_download_buffer();
}
else
{
Nf_write_open_B_area_even(gl_address, 0x00);
nf_download_buffer();
/* 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 */
/* Increase the address of the conversion table */
gl_address++;
}
lut_part = ~lut_part;
Nf_send_command_even(NF_PAGE_PROGRAM_CMD);
start += 0x40; /* process next 64 logical block */
end += 0x40;
nf_init_buffer(); /* reinitialize the global buffer */
}
while (start < NF_BLOCK_PER_ZONE);
}
}
Nf_wait_busy_even();
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)
{
Byte manufacturer;
P2 = NF_IDLE_STATE_ADD;
Nf_CS_EVEN();
Nf_wait_busy_even();
Nf_send_command_even(NF_RESET_CMD);
Nf_CS_ODD();
Nf_wait_busy_odd();
Nf_send_command_odd(NF_RESET_CMD);
Nf_wait_busy_odd();
#if (NF_CAPACITY_AUTO_DETECT == TRUE)
Nf_send_command_even(NF_READ_ID_CMD);
Nf_send_address_even(0x00);
manufacturer = Nf_rd_byte_even();
nf_copy_back = FALSE;
switch (Nf_rd_byte_even())
{
/******************************************************************************/
case 0x73 : /*--------- 2 * 16 Mbyte ---------*/
nf_device_type = NF_SIZE_32MB;
nf_zone_max = 1; /* 1 zone / slot : 1024 blocks */
nf_mem_size = NF_SECTOR_SIZE_32MB - MEM_RESERVED_SIZE;
nf_4_cycle_address = 0; /* 3 address cycles */
break;
/******************************************************************************/
case 0x75 : /*--------- 2 * 32 Mbyte ---------*/
nf_device_type = NF_SIZE_64MB;
nf_zone_max = 2; /* 2 zones / slot : 2048 blocks */
nf_mem_size = NF_SECTOR_SIZE_64MB - MEM_RESERVED_SIZE;
nf_4_cycle_address = 0; /* 3 address cycles */
if (manufacturer == M_SAMSUNG)
{
nf_copy_back = TRUE;
}
break;
/******************************************************************************/
case 0x76 : /*--------- 2 * 64 Mbyte --------*/
nf_device_type = NF_SIZE_128MB;
nf_zone_max = 4; /* 4 zones / slot : 4096 blocks */
nf_mem_size = NF_SECTOR_SIZE_128MB - MEM_RESERVED_SIZE;
nf_4_cycle_address = 1; /* 4 address cycles */
if (manufacturer == M_SAMSUNG)
{
nf_copy_back = TRUE;
}
break;
/******************************************************************************/
case 0x79 : /*-------- 2 * 128 Mbyte --------*/
nf_device_type = NF_SIZE_256MB;
nf_zone_max = 8; /* 8 zones / slot : 8192 blocks */
nf_mem_size = NF_SECTOR_SIZE_256MB - MEM_RESERVED_SIZE;
nf_4_cycle_address = 1; /* 4 address cycles */
if (manufacturer == M_SAMSUNG)
{
nf_copy_back = TRUE;
}
break;
/******************************************************************************/
default: /* Nand Flash not recognise or */
return KO; /* bad response */
/******************************************************************************/
}
#else
nf_mem_size = NF_DISK_SIZE - MEM_RESERVED_SIZE;
#endif
nf_reserved_space_start = nf_mem_size + 1;
return OK;
}
/*F**************************************************************************
* NAME: nf_read_open
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -