📄 nf.c
字号:
* NAME: nf_invert_block
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* invert a used physical block with a spare free block
* set block_used to TRUE or FALSE
* update the current physical sector address
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void nf_invert_block(void)
{
if ( !(nf_buf[nf_gl_buf_idx].w & 0x8000))
{
if ((nf_buf_free[gl_buf_free_idx] & 0x7FFF) == nf_lut_block[nf_zone])
{
gl_buf_free_idx++;
if (gl_buf_free_idx > nf_spare_block)
{
gl_buf_free_idx = 0;
}
}
/* invert the block and assign the next block to be deleted */
nf_block_to_be_deleted = nf_buf[nf_gl_buf_idx].w;
nf_buf[nf_gl_buf_idx].w = nf_buf_free[gl_buf_free_idx] & 0x7FFF;
nf_buf_free[gl_buf_free_idx] = nf_block_to_be_deleted | 0x8000;
nf_block_used = TRUE; /* block have to be deleted */
gl_buf_free_idx++;
if (gl_buf_free_idx > nf_spare_block ) /* increase the spare buffer index */
{
gl_buf_free_idx = 0;
}
}
else
{
nf_block_used = FALSE;
nf_buf[nf_gl_buf_idx].w &= 0x7FFF;
}
/* update the max index buffer */
if (nf_gl_buf_idx > nf_gl_buf_idx_max)
nf_gl_buf_idx_max = nf_gl_buf_idx;
/* Update the current physical sector address */
nf_current_physical_sector_addr = ((Uint32)(nf_buf[nf_gl_buf_idx].w) << NF_SHIFT_SECTOR_BLOCK);
}
/*F**************************************************************************
* NAME: nf_write_open
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
* PARAMS:
* pos: address of the the next write data
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory write update
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit nf_write_open (Uint32 pos)
{
Byte i;
bit change_zone = FALSE;
if (nf_write_advanced) /* Previous operation was a write mass storage session */
{
nf_write_advanced = FALSE; /* nf_write_advanced will be set only if there is a mass storage session */
if (pos == save_gl_ptr_mem) /* if this sector is the previous "next sector" */
{
nf_current_physical_sector_addr = save_physical_sector; /* Update sector information */
gl_ptr_mem = pos >> 2;
gl_cpt_page = (pos & 0x03) << 9;
nf_busy = FALSE; /* clear busy flag */
nf_wr_open = TRUE; /* set write open flag to send write open cmd */
return OK;
}
}
Nf_CS_ON();
if (nf_close_write_session)
{
nf_close_write_session = FALSE;
nf_force_write_close();
}
gl_ptr_mem = pos >> 2;
gl_cpt_page = (pos & 0x03) << 9;
/* Determine the logical block value and logical zone value */
nf_logical_block = (gl_ptr_mem >> NF_SHIFT_SECTOR_BLOCK);
nf_zone = 0;
while (nf_logical_block > 999)
{
nf_logical_block -= 1000;
nf_zone++;
}
if (nf_zone != nf_old_zone)
{
change_zone = TRUE;
if (nf_lut_modified)
{ /* save old lut */
i = nf_old_zone;
nf_old_zone = nf_zone;
nf_zone = i;
nf_reassign_block();
nf_lut_modified = FALSE;
nf_zone = nf_old_zone;
}
else
{ /* update old zone value */
nf_old_zone = nf_zone;
}
nf_block_min = 0xFFFF;
gl_buf_free_idx = 0;
}
nf_calc_logical_block();
if ( (nf_logical_block >= nf_block_min) && (nf_logical_block < (nf_block_min + NF_BUFFER_SIZE)))
{ /* we don't have to update the buffer */
nf_gl_buf_idx = nf_logical_block - nf_block_min;
}
else
{ /* we have to update the buffer */
nf_look_up_table_block = nf_lut_block[nf_zone]; /* get lut block address */
if (nf_lut_modified) /* if lut have been modified */
{
nf_reassign_block(); /* update lut */
}
gl_address = ((Uint32)(nf_look_up_table_block)<<NF_SHIFT_SECTOR_BLOCK)
+ nf_lut_index[nf_zone]; /* calculate the address for LUT access */
nf_spare_block = nf_spare_block_number[nf_zone]; /* initialize the number of spare block */
nf_block_min = nf_logical_block; /* starting block value */
nf_block_max = ((nf_logical_block + NF_BUFFER_SIZE) > 999) ? (1000 - nf_logical_block) : NF_BUFFER_SIZE;
Nf_wait_busy();
Nf_send_command (NF_READ_CMD); /* Open the look-up table */
Nf_send_address (nf_logical_block << 1); /* Column address Byte 0 */
Nf_send_address (nf_logical_block >> 7); /* 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_send_command (NF_READ_CMD2);
Nf_wait_busy();
for (i = 0; i < nf_block_max ; i++)
{
nf_buf[i].b[0] = Nf_rd_byte(); /* read lut */
nf_buf[i].b[1] = Nf_rd_byte();
}
if (change_zone) /* if it is a new zone, then */
{ /* reload the spare buffer */
Nf_send_command(NF_RANDOM_READ_CMD_C1); /* read LUT at column address */
Nf_send_address(0xD0); /* 2000 -> 07D0 */
Nf_send_address(0x07);
Nf_send_command(NF_RANDOM_READ_CMD_C2);
Nf_wait_busy();
for (i = 0; i <= nf_spare_block; i++)
{
nf_buf_free[i] = (Uint16)(Nf_rd_byte()<<8);
nf_buf_free[i] += Nf_rd_byte();
}
}
nf_gl_buf_idx = 0; /* initialize index for main buffer */
nf_gl_buf_idx_max = 0; /* initialize the max index for the buffer */
}
/* if block is already assigned, then invert with a spare block */
nf_invert_block();
if ( nf_block_used ) /* block already used? */
{
nf_copy_block_head(); /* then copy the first part of block */
}
else
{
nf_init_spare(); /* else init spare data for new logical block */
}
gl_address = ((Uint32)(nf_look_up_table_block)<<NF_SHIFT_SECTOR_BLOCK)
+ (Uint32)(nf_lut_index[nf_zone]);
Nf_wait_busy();
Nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD); /* write lut as modified */
Nf_send_address(0x00); /* column address byte 0 */
Nf_send_address(0x08); /* 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 nf > 128Mbytes ? */
Nf_send_address ( ((Byte*)&gl_address)[1] ); /* row address Byte 2 */
Nf_wr_byte(0x00); /* reset first byte */
Nf_send_command(NF_PAGE_PROGRAM_CMD); /* send program command to the device */
nf_busy = FALSE; /* clear flag busy */
nf_lut_modified = TRUE; /* set lut flag modified */
nf_wr_open = TRUE; /* set this flag to send write command */
Nf_CS_OFF();
return OK;
}
/*F**************************************************************************
* NAME: nf_write_close
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory write close: release NF
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit nf_write_close (void)
{
Nf_CS_ON();
if ( (gl_cpt_page & 0x1FF) != 0) /* uncomplete write sector (for nf_write_byte only) */
{
for ( ; ((gl_cpt_page & 0x1FF) != 0); gl_cpt_page++)
Nf_wr_byte(0x00);
Nf_send_command(NF_RANDOM_DATA_INPUT_CMD);/* open at the beginning of spare data */
Nf_send_address(0x00);
Nf_send_address(0x08);
nf_update_spare_data();
Nf_send_command(NF_PAGE_PROGRAM_CMD); /* send program command */
if ( ((Byte*)&gl_cpt_page)[0] == 0x08) /* if end of page (2Kb) */
{
gl_cpt_page = 0; /* reset global byte counter */
gl_ptr_mem++; /* increase global mem pointer */
nf_current_physical_sector_addr++; /* increase physical sector address */
}
}
else
{
if (gl_cpt_page != 0) /* a 512b page have been written */
{
Nf_send_command (NF_RANDOM_DATA_INPUT_CMD);
Nf_send_address ( 0x00 );
Nf_send_address ( 0x08 );
nf_update_spare_data();
Nf_send_command (NF_PAGE_PROGRAM_CMD);
}
/* if gl_cpt_page = 0, that means that spare data are already update */
}
nf_close_write_session = TRUE; /* At next read open : finish write session (block tail copy) */
save_gl_ptr_mem = (gl_ptr_mem << 2) + (gl_cpt_page >> 9);
save_physical_sector = nf_current_physical_sector_addr;
// nf_close_write_session = FALSE;
// nf_force_write_close();
if (nf_block_used) /* If block was previously affected and have to be deleted */
{ /* then mark it for recovery case */
gl_address = ((Uint32)(nf_block_to_be_deleted) << NF_SHIFT_SECTOR_BLOCK);
Nf_wait_busy();
Nf_send_command (NF_SEQUENTIAL_DATA_INPUT_CMD);
Nf_send_address ( 0x11 );
Nf_send_address ( NF_SPARE_PAGE );
Nf_send_address ( ((Byte*)&gl_address)[3] );
Nf_send_address ( ((Byte*)&gl_address)[2] );
if (NF_5_CYCLE_ADDRESS_BIT) /* Size of card >= 128Mbytes ? */
Nf_send_address ( ((Byte*)&gl_address)[1] ); /* Row address Byte 2 */
Nf_wr_byte(0x00);
Nf_send_command (NF_PAGE_PROGRAM_CMD);
}
Nf_CS_OFF();
return OK;
}
/*F**************************************************************************
* NAME: nf_write_byte
*----------------------------------------------------------------------------
* PARAMS:
* b: data to write
*
* RETURN:
* write status: OK: write done
* KO: write not done
*
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory write function
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -