nf_mngt.h File Reference

#include "config.h"
#include "conf_nf.h"
#include "nf.h"
#include "modules/control_access/ctrl_status.h"
#include "nf_drv.h"

Include dependency graph for nf_mngt.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Cache_lut
struct  Cache_fbb

Defines

#define NF_BLK_RCV_NO_RECOVERY   0xA5
#define NF_BLK_RCV_PENDING_RECOVERY   0x5A
#define NF_LOW_N_FREE_THRESHOLD   5
#define NF_PAGE_BUFFER_SIZE   2048
#define NF_FULL_PAGE_BUFFER_SIZE   ( (NF_PAGE_BUFFER_SIZE) + (NF_PAGE_BUFFER_SIZE)/32 )
#define NF_SHIFT_SUBLUT_PHYS   ( (G_SHIFT_PAGE_BYTE)-1 )
#define NF_SUBLUT_SIZE   ( 1L<<(NF_SHIFT_SUBLUT_PHYS) )
#define NF_N_MAX_BLOCKS   (8*1024)
#define N_SUBLUT   (NF_N_DEVICES*NF_N_MAX_BLOCKS/(512/2))
#define S_SHIFT_SECTOR_BYTE   s_shift_sector_byte
#define S_SHIFT_LOG_PAGE_SECTOR   s_shift_log_page_sector
#define S_SHIFT_LOG_BLOCK_SECTOR   s_shift_log_block_sector
#define S_MNGT_DEV   ((NF_N_DEVICES)-1)
#define Nf_check_fbb(x)   nf_check_fbb(x)
#define Nf_check_lut()   nf_check_lut()
#define CACHE_LUT_SIZE   (NF_CACHE_LUT_LOG_SZ*NF_N_DEVICES)
#define CACHE_FBB_SIZE   (NF_CACHE_FBB_LOG_SZ*NF_N_DEVICES)

Enumerations

enum  Nf_sense { NF_READ = 0, NF_WRITE }

Functions

static void nf_check_fbb (Bool b_ecc_err)
static void nf_check_lut (void)
Ctrl_status nf_test_unit_ready (void)
 Initializes the NF driver on the first USB Test Unit Ready.
Ctrl_status nf_read_capacity (U32 *)
 Returns the address of the last valid logical sector.
Bool nf_wr_protect (void)
Bool nf_removal (void)
Ctrl_status nf_10 (U32 addr, U16 nb_sector, Nf_sense)
Ctrl_status nf_dfc_read_resume (void)
Ctrl_status nf_dfc_write_resume (void)
Ctrl_status nf_dfc_read_stop (U16 remaining_sectors)
Ctrl_status nf_dfc_write_stop (U16 remaining_sectors)
 This function must be called when a write10 operation (from USB) is finished Last page written is programmed and environment is saved.
void nf_dfc_read_standby (U16)
void nf_dfc_read_restart (void)
U32 nf_get_sectors_number (void)
 Returns a pointer on the internal buffer address.
U8nf_get_buffer_addr (void)
void nf_init (void)
 Initializes the nand flash memory driver.
Status_bool nf_verify (void)
 Ensure that the memory is in a good state before starting to use it.
Status_bool nf_verify_resume (void)
 Ensure that the memory is in a good state before starting to use it.
void nf_cleanup_memory (void)
 Cleanup the memory by erasing all the management blocks.
void nf_upload (U8 _MEM_TYPE_SLOW_ *, U8)
 Upload packets of 16 bytes from the NAND Flash to RAM.
void nf_download (U8 _MEM_TYPE_SLOW_ *, U8)
 Download packets of 16 bytes from RAM to the NAND Flash.
U32 nf_block_2_page (U16 block_addr)
void nf_ecc_mngt (void)
void nf_sync (void)
void nf_copy (U32 copy_dst)
 Copy a NF page to a new one.
Status_bool nf_write_lut (U8 pos, U8 i_sub_lut, U16 sub_lut_log_sz)
 Writes a LUT in memory from a buffer.
Status_bool nf_write_fbb (void)
 Writes the Free-blocks block into the Nand Flash.
void nf_cache_fbb_refill (void)
 Reload the FBB cache memory, starting from 0.
void nf_swap (U8 dev_id, U8 u8_ofst_lut, U8 u8_ofst_fbb)
 Swap 2 blocks from the LUT and the FBB.
void nf_cache_fbb_flush (Bool)
 Flushes the FBB cache into a new FBB entry.
void nf_recovery (U16 block_1, U16 block_2)
void nf_copy_tail (void)
Ctrl_status nf_read_10 (U32 log_sector, U16 n_sectors)
 This function initializes the Nand Flash for a read operation.
Ctrl_status nf_write_10 (U32 log_sector, U16 n_sectors)
 This function initializes the Nand Flash for a write operation.
Ctrl_status nf_ram_2_nf (U32 addr, U8 *ram)
 This fonction initialise the memory for a write operation from ram buffer.
Ctrl_status nf_nf_2_ram (U32 addr, U8 *ram)
 This fonction read 1 sector from NF to ram buffer.

Variables

_MEM_TYPE_SLOW_ U16 _debug


Detailed Description

This file is the header file for the high level management of the nand flash memory devices.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file nf_mngt.h.


Define Documentation

#define NF_BLK_RCV_NO_RECOVERY   0xA5

Definition at line 58 of file nf_mngt.h.

#define NF_BLK_RCV_PENDING_RECOVERY   0x5A

Definition at line 59 of file nf_mngt.h.

#define NF_LOW_N_FREE_THRESHOLD   5

Definition at line 61 of file nf_mngt.h.

Referenced by nf_rebuild().

#define NF_PAGE_BUFFER_SIZE   2048

Definition at line 74 of file nf_mngt.h.

Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_rebuild(), and nf_write_lut().

#define NF_FULL_PAGE_BUFFER_SIZE   ( (NF_PAGE_BUFFER_SIZE) + (NF_PAGE_BUFFER_SIZE)/32 )

Definition at line 79 of file nf_mngt.h.

Referenced by nf_cache_fbb_flush(), and nf_init_buffer().

#define NF_SHIFT_SUBLUT_PHYS   ( (G_SHIFT_PAGE_BYTE)-1 )

Definition at line 80 of file nf_mngt.h.

Referenced by nf_cache_lut_flush(), nf_cache_lut_refill(), and nf_rebuild().

#define NF_SUBLUT_SIZE   ( 1L<<(NF_SHIFT_SUBLUT_PHYS) )

Definition at line 81 of file nf_mngt.h.

Referenced by nf_cache_lut_flush(), nf_rebuild(), and nf_scan().

#define NF_N_MAX_BLOCKS   (8*1024)

Definition at line 85 of file nf_mngt.h.

#define N_SUBLUT   (NF_N_DEVICES*NF_N_MAX_BLOCKS/(512/2))

Definition at line 86 of file nf_mngt.h.

Referenced by nf_rebuild().

#define S_SHIFT_SECTOR_BYTE   s_shift_sector_byte

Definition at line 101 of file nf_mngt.h.

Referenced by nf_get_sectors_number(), nf_init(), nf_nf_2_ram(), nf_ram_2_nf(), nf_translate(), and nf_write_10().

#define S_SHIFT_LOG_PAGE_SECTOR   s_shift_log_page_sector

Definition at line 102 of file nf_mngt.h.

Referenced by nf_open_write(), and nf_translate().

#define S_SHIFT_LOG_BLOCK_SECTOR   s_shift_log_block_sector

Definition at line 103 of file nf_mngt.h.

Referenced by nf_copy_tail(), nf_ram_2_nf(), nf_rebuild(), nf_translate(), and nf_write_10().

#define S_MNGT_DEV   ((NF_N_DEVICES)-1)

Definition at line 112 of file nf_mngt.h.

Referenced by nf_cache_fbb_flush(), nf_cache_fbb_refill(), nf_cache_lut_flush(), nf_cache_lut_refill(), nf_check_fbb(), nf_check_lut(), nf_open_write(), nf_rebuild(), nf_scan(), nf_write_fbb(), and nf_write_lut().

#define Nf_check_fbb (  )     nf_check_fbb(x)

Definition at line 118 of file nf_mngt.h.

Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_dfc_write_stop(), nf_translate(), and nf_verify_resume().

 
#define Nf_check_lut (  )     nf_check_lut()

Definition at line 119 of file nf_mngt.h.

Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_dfc_write_stop(), nf_translate(), and nf_verify_resume().

#define CACHE_LUT_SIZE   (NF_CACHE_LUT_LOG_SZ*NF_N_DEVICES)

Definition at line 134 of file nf_mngt.h.

Referenced by nf_cache_lut_flush(), nf_cache_lut_refill(), and nf_swap().

#define CACHE_FBB_SIZE   (NF_CACHE_FBB_LOG_SZ*NF_N_DEVICES)

Definition at line 147 of file nf_mngt.h.

Referenced by nf_cache_fbb_flush(), nf_cache_fbb_refill(), and nf_swap().


Enumeration Type Documentation

enum Nf_sense

Enumerator:
NF_READ 
NF_WRITE 

Definition at line 151 of file nf_mngt.h.

00152 {
00153    NF_READ=0
00154 ,  NF_WRITE
00155 } Nf_sense;


Function Documentation

static void nf_check_fbb ( Bool  b_ecc_err  )  [static]

static void nf_check_lut ( void   )  [static]

Ctrl_status nf_test_unit_ready ( void   ) 

Initializes the NF driver on the first USB Test Unit Ready.

Parameters:
none 
Returns:
CTRL_GOOD if ok, CTRL_NO_PRESENT in case of problems.

Definition at line 215 of file nf_mngt.c.

References CTRL_FAIL, CTRL_GOOD, nf_verify(), nf_XMCR_disable(), nf_XMCR_enable(), and PASS.

00216 {
00217   Status_bool tmp_bool;
00218 
00219 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00220    nf_XMCR_enable();
00221 #endif
00222 
00223    tmp_bool = nf_verify();
00224 
00225 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00226    nf_XMCR_disable();
00227 #endif
00228 
00229    return ( tmp_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL;
00230 }

Here is the call graph for this function:

Ctrl_status nf_read_capacity ( U32 u32_nb_sector  ) 

Returns the address of the last valid logical sector.

Parameters:
none 
Returns:
CTRL_GOOD if ok, CTRL_NO_PRESENT in case of problems.

Definition at line 240 of file nf_mngt.c.

References CTRL_FAIL, CTRL_GOOD, nf_get_sectors_number(), nf_verify(), nf_XMCR_disable(), nf_XMCR_enable(), and PASS.

00241 {
00242   Status_bool status_bool;
00243 
00244 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00245    nf_XMCR_enable();
00246 #endif
00247 
00248    status_bool = nf_verify();
00249 
00250 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00251    nf_XMCR_disable();
00252 #endif
00253 
00254    *u32_nb_sector = nf_get_sectors_number()-1;
00255    return ( status_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL;
00256 }

Here is the call graph for this function:

Bool nf_wr_protect ( void   ) 

Definition at line 259 of file nf_mngt.c.

References FALSE.

00260 {
00261     return FALSE;
00262 }

Bool nf_removal ( void   ) 

Definition at line 264 of file nf_mngt.c.

References TRUE.

00265 {
00266     return TRUE;
00267 }

Ctrl_status nf_10 ( U32  addr,
U16  nb_sector,
Nf_sense   
)

Ctrl_status nf_dfc_read_resume ( void   ) 

Ctrl_status nf_dfc_write_resume ( void   ) 

Ctrl_status nf_dfc_read_stop ( U16  remaining_sectors  ) 

Ctrl_status nf_dfc_write_stop ( U16  u16_nb_sector_remaining  ) 

This function must be called when a write10 operation (from USB) is finished Last page written is programmed and environment is saved.

Parameters:
log_sector Logical sector address to start read
nb_sector Number of sectors to transfer
Returns:
CTRL_GOOD if ok, CTRL_FAIL if read outside memory

Definition at line 767 of file nf_mngt.c.

References CTRL_GOOD, FALSE, LSB0, Nf_check_fbb, Nf_check_lut, nf_erase_old_blocks(), NF_N_DEVICES, NF_PAGE_PROGRAM_CMD, NF_TRANS_NORMAL, nf_translate(), nfc_reset_nands(), Nfc_set_cmd, SIZE_BLOCK_PAGE, trace(), trace_hex32(), and trace_nl().

00768 {
00769    Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page
00770    // Note that if the page is not completely filled in yet but still programmed, the next copy tail will allow partial page program
00771 
00772    // retreive exact logical/physical position (in case that transfer
00773    // did not perform the exact number of sectors)
00774    s_curr_log_sector = s_save_log_addr - u16_nb_sector_remaining;
00775    if( 0!=u16_nb_sector_remaining )
00776    {
00777       nf_translate( NF_TRANS_NORMAL );
00778    }
00779    g_last_log_sector  = s_curr_log_sector; // Memorize next logical sector to be managed
00780 
00781    // Test if transfer stop at end of logical blocks.
00782    if( s_n_sectors==0 )
00783    {
00784       if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1))  // new block
00785       && (g_curr_dev_id==0                                  )) // on device 0.
00786      {
00787          // Delete old blocks
00788          //
00789          nf_erase_old_blocks();
00790       }
00791    }
00792    trace("nf_dfc_write_stop;"); trace_hex32(g_last_log_sector); trace_nl();
00793 
00794    // Ensure that all internal programming are complete, since we are
00795    // using cache programming (WP may be asserted for icons or fonts
00796    // loading). Moreover, on some NFs (ST, Samsung)
00797    // it is necessary to reset the devices after copy-back commands
00798    // If not, strange behaviour may happen: no busy when opening
00799    // a page for reading...
00800    nfc_reset_nands( NF_N_DEVICES ); // Reset all the NF devices
00801 
00802    Nf_check_fbb( FALSE );
00803    Nf_check_lut();
00804 
00805    return CTRL_GOOD;
00806 } // end of nf_dfc_write_stop

Here is the call graph for this function:

void nf_dfc_read_standby ( U16   ) 

void nf_dfc_read_restart ( void   ) 

U32 nf_get_sectors_number ( void   ) 

Returns a pointer on the internal buffer address.

This function is used for test only.

Parameters:
none 
Returns:
pointer on an internal buffer of 2112 bytes. Returns the total number of sectors that can be used on the memory.
This number is computed during the power on, after a scan of the memory.

Parameters:
none 
Returns:
Number of sectors.

Definition at line 293 of file nf_mngt.c.

References G_SHIFT_BLOCK_PAGE, G_SHIFT_PAGE_BYTE, and S_SHIFT_SECTOR_BYTE.

00294 {
00295    return
00296       (U32)g_n_export_blocks
00297    << (G_SHIFT_BLOCK_PAGE +G_SHIFT_PAGE_BYTE -S_SHIFT_SECTOR_BYTE)
00298    ;
00299 }

U8* nf_get_buffer_addr ( void   ) 

void nf_init ( void   ) 

Initializes the nand flash memory driver.

The device identification is performed to initialize the driver accordingly

Parameters:
none 
Returns:
none

Definition at line 148 of file nf_unusual.c.

Referenced by main().

00149 {
00150    g_nf_init=FALSE;
00151 //   s_pending_write=FALSE;
00152 
00153 #if (NF_GENERIC_DRIVER==TRUE)
00154 #error Check this init...
00155    g_n_zones             = NF_N_ZONES;
00156    g_n_blocks            = NF_N_BLOCKS;
00157    g_shift_block_page    = NF_SHIFT_BLOCK_PAGE;
00158    g_shift_page_byte     = NF_SHIFT_PAGE_BYTE;
00159    s_shift_sector_byte   = NF_SHIFT_SECTOR_BYTE;
00160    g_n_row_cycles        = NF_N_ROW_CYCLES;
00161 
00162    if ( Is_nf_2k() ) // 2KB pages
00163    {
00164       g_ofst_blk_status     = 0;
00165    }
00166    if ( Is_nf_512() ) // 512B pages
00167    {
00168       g_ofst_blk_status     = 5;
00169    }
00170 
00171    s_shift_log_page_sector  = G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE + NF_SHIFT_N_DEVICES;
00172    s_shift_log_block_sector = s_shift_log_page_sector + G_SHIFT_BLOCK_PAGE;
00173 #endif
00174 
00175    g_cache_lut.ctrl.valid = FALSE; g_cache_lut.ctrl.dirty = FALSE;
00176    g_cache_fbb.ctrl.valid = FALSE; g_cache_fbb.ctrl.dirty = FALSE;
00177    g_last_log_sector= 0xFFFFFFFF;
00178 }

Here is the caller graph for this function:

Status_bool nf_verify ( void   ) 

Ensure that the memory is in a good state before starting to use it.

Parameters:
none 
Returns:
a status: PASS if the command has been succesfully executed; FAIL else

Definition at line 199 of file nf_mngt.c.

References nf_verify_resume(), and PASS.

00200 {
00201    if ( g_nf_init ) return PASS;
00202 
00203    return nf_verify_resume();
00204 }

Here is the call graph for this function:

Status_bool nf_verify_resume ( void   ) 

Ensure that the memory is in a good state before starting to use it.

The function will scan the memory, test if the memory is valid, clean it if it has to and rebuild all the management blocks. This function shall be called prior to any use of the memory after a power-up.

Parameters:
none 
Returns:
a status: PASS if the command has been succesfully executed; FAIL else

Definition at line 193 of file nf_unusual.c.

Referenced by nf_verify().

00194 {
00195    U8 u8_nb_loop;
00196    Bool status_bool;
00197 
00198 
00199 #if (ERASING_ALL==ENABLE)
00200    ut_nfc_erase_all();
00201 #endif
00202    
00203    status_bool = nf_scan();
00204 
00205    if(( PASS!=status_bool )
00206    || ( is_nf_invalid()   )  // The NF is not cleanly built
00207    ) {
00208       // The NF seems not cleanly built, or not built at all.
00209       //
00210       u8_nb_loop = 0;
00211       while( 1 )
00212       {
00213          u8_nb_loop++;
00214          if( u8_nb_loop > 2 )
00215          {
00216             status_bool=FAIL;
00217             break;  // Error NF access or control
00218          }
00219          nf_cleanup_memory();
00220          if( PASS != nf_scan() )
00221             continue;
00222          if( PASS != nf_rebuild() )
00223             continue;
00224          status_bool = PASS;
00225          break;
00226       }
00227    }
00228    if (status_bool==PASS)
00229    {
00230       g_nf_init = TRUE;
00231       Nf_check_lut();
00232       Nf_check_fbb( FALSE );
00233    }
00234 
00235    return status_bool;
00236 }

Here is the caller graph for this function:

void nf_cleanup_memory ( void   ) 

Cleanup the memory by erasing all the management blocks.

The sub-LUT blocks, the recovery block and the free-blocks block will be erased on any devices.

Parameters:
none 

Definition at line 247 of file nf_unusual.c.

Referenced by nf_verify_resume().

00248 {
00249    U8   i_dev  =0;
00250    U16  i_block=0;
00251    U8   block_valid;
00252    U8   block_id;
00253 
00254    // Scan all the devices and looks for:
00255    // - the sub-LUT
00256    // - the recovery block
00257    // - the free-blocks block
00258    //
00259    for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00260    {
00261       // Select the devices
00262       //
00263       Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00264 
00265       for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00266       {
00267 
00268          nfc_open_page_read( nf_block_2_page(i_block), NF_SPARE_POS);
00269          block_valid = Nfc_rd_data_fetch_next();
00270          block_id    = Nfc_rd_data()           ;
00271 
00272          if ( block_valid!=0xFF )
00273          {
00274             continue; // The block is bad
00275          }
00276 
00277          if(( NFC_BLK_ID_SUBLUT==block_id )
00278          || ( NFC_BLK_ID_FBB   ==block_id ))
00279          {
00280             nfc_erase_block( nf_block_2_page(i_block), TRUE ) ;
00281             if ( FAIL==nfc_check_status() )
00282             {
00283                nfc_mark_bad_block( nf_block_2_page(i_block) );
00284             }
00285          }
00286       } // for( i_block...
00287    } // for( i_dev...
00288 } // nf_cleanup_memory

Here is the caller graph for this function:

void nf_upload ( U8 _MEM_TYPE_SLOW_ *  datbuf,
U8  loop 
)

Upload packets of 16 bytes from the NAND Flash to RAM.

Parameters:
U8 * datbuf pointer to RAM U8 loop number of 16 bytes packets
Returns:
none

Definition at line 1696 of file nf_mngt.c.

References _MEM_TYPE_SLOW_, and Nf_rd_byte.

01697 {
01698   U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf;
01699   U8 i = loop;
01700 
01701   while (i != 0)
01702   {
01703      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01704      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01705      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01706      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01707      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01708      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01709      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01710      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01711      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01712      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01713      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01714      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01715      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01716      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01717      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01718      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01719      i--;
01720   }
01721 }

void nf_download ( U8 _MEM_TYPE_SLOW_ *  datbuf,
U8  loop 
)

Download packets of 16 bytes from RAM to the NAND Flash.

Parameters:
U8 * datbuf pointer to RAM U8 loop number of 16 bytes packets
<global parameters>="">

Returns:
none

Definition at line 1660 of file nf_mngt.c.

References _MEM_TYPE_SLOW_, and Nf_wr_byte.

01661 {
01662   U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf;
01663   U8 i = loop;
01664 
01665   while (i != 0)
01666   {
01667      Nf_wr_byte(*(tempbuf)); tempbuf++;
01668      Nf_wr_byte(*(tempbuf)); tempbuf++;
01669      Nf_wr_byte(*(tempbuf)); tempbuf++;
01670      Nf_wr_byte(*(tempbuf)); tempbuf++;
01671      Nf_wr_byte(*(tempbuf)); tempbuf++;
01672      Nf_wr_byte(*(tempbuf)); tempbuf++;
01673      Nf_wr_byte(*(tempbuf)); tempbuf++;
01674      Nf_wr_byte(*(tempbuf)); tempbuf++;
01675      Nf_wr_byte(*(tempbuf)); tempbuf++;
01676      Nf_wr_byte(*(tempbuf)); tempbuf++;
01677      Nf_wr_byte(*(tempbuf)); tempbuf++;
01678      Nf_wr_byte(*(tempbuf)); tempbuf++;
01679      Nf_wr_byte(*(tempbuf)); tempbuf++;
01680      Nf_wr_byte(*(tempbuf)); tempbuf++;
01681      Nf_wr_byte(*(tempbuf)); tempbuf++;
01682      Nf_wr_byte(*(tempbuf)); tempbuf++;
01683      i--;
01684   }
01685 }

U32 nf_block_2_page ( U16  block_addr  ) 

Definition at line 303 of file nf_mngt.c.

References G_SHIFT_BLOCK_PAGE.

00304 {
00305    return (U32)block_addr<<G_SHIFT_BLOCK_PAGE;
00306 }

void nf_ecc_mngt ( void   ) 

void nf_sync ( void   ) 

void nf_copy ( U32  copy_dst  ) 

Copy a NF page to a new one.

This function copies a NF page into a new page. It uses the copy-back command if it is possible.

Parameters:
g_copy_src (global) Source page address
copy_dst Recipient page address

Definition at line 1856 of file nf_mngt.c.

References G_COPY_BACK_CONT, G_COPY_BACK_DISCONT, G_N_ROW_CYCLES, G_N_ZONES, G_SHIFT_BLOCK_PAGE, G_SHIFT_PAGE_BYTE, Is_nf_2k, LSB, LSB0, LSB1, MSB, MSB1, nf_download(), NF_PAGE_PROGRAM_CMD, NF_RANDOM_DATA_INPUT_CMD, NF_SPARE_POS, nf_upload(), nfc_copy_back_init(), NFC_OFST_3_DATA_DST, nfc_open_page_read(), nfc_open_page_write(), Nfc_set_adc, Nfc_set_adr, Nfc_set_cmd, NFC_SPARE_OFST_3_BYTE_3, NFC_SPARE_OFST_6_LBA, Nfc_unprotect_all_flash, and Nfc_wr_data.

01857 {
01858    Bool b_copy_fast;
01859    U8   zone_A, zone_B;
01860 
01861    // Compute the possibility of fast copy
01862    if( 0 == G_COPY_BACK_CONT )
01863    {
01864       b_copy_fast = 0;     // never possible
01865    }
01866    else
01867    {
01868       if( (1 == G_COPY_BACK_CONT) && (1==G_COPY_BACK_DISCONT) )
01869       {
01870          b_copy_fast = 1;  // always possible
01871       }
01872       else
01873       {
01874          // Check block address
01875          b_copy_fast = 1;  // by default possible
01876          if( 1 != G_COPY_BACK_CONT )
01877          {
01878 /*
01879             zone_A = (g_copy_src>>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT);
01880             zone_B = (copy_dst  >>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT);
01881 */
01882             // block_zone = page add / number of page / 1024
01883             if( Is_nf_2k() )
01884             {
01885                // block_zone = (page add >> (G_SHIFT_BLOCK_PAGE + 10)) / (G_N_ZONES/G_COPY_BACK_CONT);
01886                // block_zone = ((page add >> 16) * G_COPY_BACK_CONT) / G_N_ZONES;
01887                zone_A = (MSB1(g_copy_src)*G_COPY_BACK_CONT)/G_N_ZONES;
01888                zone_B = (MSB1(copy_dst  )*G_COPY_BACK_CONT)/G_N_ZONES;
01889             }else{
01890                // block_zone = page add >> (G_SHIFT_BLOCK_PAGE + 10) / (G_N_ZONES/G_COPY_BACK_CONT);
01891                zone_A = ((U8)(g_copy_src>>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES;
01892                zone_B = ((U8)(copy_dst  >>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES;
01893             }
01894             if( zone_A != zone_B )
01895                b_copy_fast = 0;     // no possible
01896          }
01897          if( 1 != G_COPY_BACK_DISCONT )
01898          {
01899 // define mandatory to delete compile error on MODULO 0
01900 #if (NF_GENERIC_DRIVER==TRUE) || (NF_AUTO_DETECT_2KB==TRUE) || (NF_AUTO_DETECT_512B==TRUE)
01901             zone_A = ((U16)g_copy_src>>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT;
01902             zone_B = ((U16)copy_dst  >>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT;
01903 #elif ( G_COPY_BACK_DISCONT != 0 )
01904             zone_A = ((U16)g_copy_src>>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT;
01905             zone_B = ((U16)copy_dst  >>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT;
01906 #endif
01907             if( zone_A != zone_B )
01908                b_copy_fast = 0;     // no possible
01909          }
01910       }
01911    }
01912       
01913    // Start copy
01914    if( !b_copy_fast )
01915    {
01916       // copy the page of the old block in buffer
01917       nfc_open_page_read( g_copy_src, 0 );
01918       nf_upload(                                // Works by packet of 16 bytes
01919          g_page_buffer
01920       ,     ((U16)1<<(G_SHIFT_PAGE_BYTE-4))     // Data zone (Page size / 16)
01921          +  ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4))); // Spare zone (Page size / 32 / 16)
01922 
01923       // Add LBA markers to help recovery function
01924       // Need to explain a bit why LBA are written: 
01925       // nf_copy is called from copy_head and copy_tail.
01926       // - copy_head: need to write all the LBA of the pages to help recovery finding
01927       //   where the last sector is written.
01928       //   Moreover, in case that nf_copy is called from copy_head and source block at page 0
01929       //   does not contain LBA.
01930       // - copy_tail: no need to mark the last LBA of the last page to identify the source
01931       //   block since we use another method
01932       g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3] = NFC_OFST_3_DATA_DST;  // 3- [SW] Source block (recovery) (HW capability not used)
01933       g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA   ] = MSB(g_log_block_id);  // 6- LBA
01934       g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA+1 ] = LSB(g_log_block_id);  // 7- LBA
01935       if( Is_nf_2k() )
01936       {
01937          g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA  ] =
01938          g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA  ] =
01939          g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA  ] = MSB(g_log_block_id);  // 6- LBA
01940          g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA+1] =
01941          g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA+1] =
01942          g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA+1] = LSB(g_log_block_id);  // 7- LBA
01943       }
01944 
01945       // copy the buffer in the page of the new block
01946       nfc_open_page_write( copy_dst, 0 );
01947       nf_download(                                // Works by packet of 16 bytes
01948          g_page_buffer
01949       ,     ((U16)1<<(G_SHIFT_PAGE_BYTE-4))       // Data zone (Page size / 16)
01950          +  ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4)));  // Spare zone (Page size / 32 / 16)
01951       Nfc_set_cmd(NF_PAGE_PROGRAM_CMD);
01952    }
01953    else
01954    {
01955       nfc_copy_back_init( g_copy_src );
01956 
01957       Nfc_unprotect_all_flash();                              // WP may be actif due to block protection
01958       Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD);
01959       Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)%256 );
01960       Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)/256 );
01961       Nfc_set_adr( LSB0(copy_dst) );
01962       Nfc_set_adr( LSB1(copy_dst) );
01963       if ( 3==G_N_ROW_CYCLES )
01964       {
01965          Nfc_set_adr( MSB1(copy_dst) );
01966       }
01967 
01968       // Remove Source block mask
01969       Nfc_wr_data( NFC_OFST_3_DATA_DST );
01970 
01971       // Add LBA markers to help recovery function
01972       Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD);
01973       Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)%256 );
01974       Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)/256 );
01975       Nfc_wr_data( MSB(g_log_block_id) );
01976       Nfc_wr_data( LSB(g_log_block_id) );
01977 
01978       if( Is_nf_2k() )
01979       {
01980          Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD);
01981          Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)%256 );
01982          Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)/256 );
01983          Nfc_wr_data( MSB(g_log_block_id) );
01984          Nfc_wr_data( LSB(g_log_block_id) );
01985 
01986          Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD);
01987          Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)%256 );
01988          Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)/256 );
01989          Nfc_wr_data( MSB(g_log_block_id) );
01990          Nfc_wr_data( LSB(g_log_block_id) );
01991 
01992          Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD);
01993          Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)%256 );
01994          Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)/256 );
01995          Nfc_wr_data( MSB(g_log_block_id) );
01996          Nfc_wr_data( LSB(g_log_block_id) );
01997       }
01998       Nfc_set_cmd(NF_PAGE_PROGRAM_CMD);
01999    }
02000 }

Here is the call graph for this function:

Status_bool nf_write_lut ( U8  pos,
U8  i_sub_lut,
U16  sub_lut_log_sz 
)

Writes a LUT in memory from a buffer.

Parameters:
pos offset of the lub-lut in the buffer
i_sub_lut id of the sub-LUT
sub_lut_log_sz Size of the sub-LUT, in logical block unit
Returns:
nothing

Definition at line 1210 of file nf_mngt.c.

References _debug, _MEM_TYPE_SLOW_, Assert, FAIL, G_N_BLOCKS, G_SHIFT_PAGE_BYTE, LSB, MSB, nf_block_2_page(), NF_N_DEVICES, NF_PAGE_BUFFER_SIZE, NF_PAGE_PROGRAM_CMD, NFC_ACT_DEV_SELECT, Nfc_action, NFC_BLK_ID_SUBLUT, nfc_check_status(), nfc_open_page_write(), Nfc_set_cmd, Nfc_wr_data, PASS, S_MNGT_DEV, trace(), trace_hex(), trace_hex16(), and trace_nl().

01214 {
01215    U16  block_addr; // Physical block number
01216    U8 _MEM_TYPE_SLOW_ * p_buf=g_page_buffer + (U16)pos*((U16)1<<(G_SHIFT_PAGE_BYTE));
01217 
01218    Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV);
01219    // The buffer is built as:
01220    // |    512    |    512    |    512    |    512    |
01221    //
01222    // The page is built as:
01223    // |    512    |    512    |    512    |    512    |SZ|
01224    //
01225    // The LUT fits in a physical page.
01226    //
01227    nfc_open_page_write(
01228       nf_block_2_page( g_lut_block_addr[i_sub_lut] ) // base address
01229    +  (U32)(g_lut_block_index[i_sub_lut])            // offset to sub-LUT
01230    ,  0 );
01231 
01232    trace("nf_write_lut;");trace_hex16(g_lut_block_addr[i_sub_lut]); trace(";"); trace_hex16(g_lut_block_index[i_sub_lut]);trace_nl();
01233    for( block_addr=0 ; block_addr<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; block_addr+=1 )
01234    {
01235       if ( block_addr<(sub_lut_log_sz*NF_N_DEVICES) )
01236       {
01237 #if (_ASSERT_==ENABLE)
01238          Assert(           ( block_addr*2)<(NF_PAGE_BUFFER_SIZE-1) );
01239          MSB(_debug)= p_buf[ block_addr*2   ] ;
01240          LSB(_debug)= p_buf[ block_addr*2 +1] ;
01241          Assert( _debug>=g_nf_first_block );
01242          Assert( _debug< G_N_BLOCKS       );
01243 #endif
01244          Nfc_wr_data( p_buf[ block_addr*2   ] );
01245          Nfc_wr_data( p_buf[ block_addr*2 +1] );
01246          trace_hex(p_buf[ block_addr*2   ]);
01247          trace_hex(p_buf[ block_addr*2 +1]);
01248          trace("-");
01249       }
01250       else
01251       {
01252          Nfc_wr_data( 0xFF );
01253          Nfc_wr_data( 0xFF );
01254          trace("FFFF-");
01255       }
01256    }
01257    trace_nl();
01258 
01259    // Write the spare information
01260    //
01261    Nfc_wr_data( 0xFF              );                              // 0- block is valid (for 2048 compatibility)
01262    Nfc_wr_data( NFC_BLK_ID_SUBLUT );                              // 1- sub-LUT
01263    Nfc_wr_data( i_sub_lut         );                              // 2- sub-LUT id
01264    Nfc_wr_data( 0xFF              );                              // 3- unused
01265    Nfc_wr_data( g_n_sub_lut       );                              // 4- number of sub-LUT
01266    Nfc_wr_data( 0xFF              );                              // 5- block is valid (for 512 compatibility)
01267    Nfc_wr_data( MSB(sub_lut_log_sz) );                            // 6-7 Number of log blocks in sub-LUT
01268    Nfc_wr_data( LSB(sub_lut_log_sz) );
01269    Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10-   ECC2
01270    Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF );                      // 11-12-    LBA
01271    Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- ECC1
01272 
01273    Nfc_set_cmd( NF_PAGE_PROGRAM_CMD );
01274    if ( FAIL==nfc_check_status() ) { return FAIL; }
01275 
01276    return PASS;
01277 } // end of nf_write_lut

Here is the call graph for this function:

Status_bool nf_write_fbb ( void   ) 

Writes the Free-blocks block into the Nand Flash.

Parameters:
none 
Returns:
nothing

Definition at line 1414 of file nf_mngt.c.

References FAIL, G_SHIFT_PAGE_BYTE, LSB, MSB, nf_block_2_page(), NF_PAGE_PROGRAM_CMD, NFC_ACT_DEV_SELECT, Nfc_action, NFC_BLK_ID_FBB, nfc_check_status(), NFC_OFST_4_FBB_DRIVER_RELEASE, NFC_OFST_6_FBB_VALID, nfc_open_page_write(), Nfc_set_cmd, Nfc_wr_data, PASS, and S_MNGT_DEV.

01415 {
01416    U16 u16_tmp;
01417 
01418    Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV);
01419    nfc_open_page_write(
01420       nf_block_2_page( g_fbb_block_addr )  // base address
01421    +  (U32)g_fbb_block_index               // offset to Free-blocks block entry
01422    , 0 );
01423    for ( u16_tmp=0 ; u16_tmp<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; )
01424    {
01425       if ( u16_tmp<g_n_free_blocks )
01426       {
01427          Nfc_wr_data( g_page_buffer[2*u16_tmp   ] );
01428          Nfc_wr_data( g_page_buffer[2*u16_tmp +1] );
01429       }
01430       else
01431       {
01432          Nfc_wr_data( 0xFF );
01433          Nfc_wr_data( 0xFF );
01434       }
01435       u16_tmp++;
01436    }
01437    // Write the spare information
01438    //
01439    Nfc_wr_data( 0xFF );                                           // 0- block is valid (for 2048 compatibility)
01440    Nfc_wr_data( NFC_BLK_ID_FBB );                                 // 1- Free-blocks block
01441    Nfc_wr_data( MSB(g_n_free_blocks));                            // 2-3 Number of free blocks
01442    Nfc_wr_data( LSB(g_n_free_blocks));
01443    Nfc_wr_data( NFC_OFST_4_FBB_DRIVER_RELEASE );                  // 4- Nand-Flash driver ID
01444    Nfc_wr_data( 0xFF );                                           // 5- block is valid (for 512 compatibility)
01445    Nfc_wr_data( NFC_OFST_6_FBB_VALID );                           // 6- FBB-LUTs valid
01446    Nfc_wr_data( 0xFF );                                           // 7- Unused
01447    Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10-   Unused
01448    Nfc_wr_data( MSB(g_n_export_blocks));                          // 11-12- Number of exported blocks
01449    Nfc_wr_data( LSB(g_n_export_blocks));
01450    Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- Unused
01451 
01452    Nfc_set_cmd( NF_PAGE_PROGRAM_CMD );
01453    if ( FAIL==nfc_check_status() ) { return FAIL; }
01454    return PASS;
01455 } // end of nf_write_fbb

Here is the call graph for this function:

void nf_cache_fbb_refill ( void   ) 

Reload the FBB cache memory, starting from 0.

The cache is filled with physical blocks.

Parameters:
none 
Returns:
nothing

Definition at line 1046 of file nf_mngt.c.

References _MEM_TYPE_SLOW_, Assert, CACHE_FBB_SIZE, FALSE, G_N_BLOCKS, LSB, Min, MSB, nf_block_2_page(), NF_CACHE_FBB_LOG_SZ, NF_N_DEVICES, NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), Nfc_rd_data_fetch_next, S_MNGT_DEV, SIZE_PAGE_BYTE, trace(), trace_hex16(), trace_nl(), and TRUE.

01047 {
01048    U8  u8_tmp;
01049    U16 byte_addr;
01050    _MEM_TYPE_SLOW_ U32 page_addr;
01051 
01052    Assert(g_cache_fbb.ctrl.dirty==FALSE); // No refill if the cache is dirty
01053    g_cache_fbb.p   = 0;
01054 
01055    trace("nf_cache_fbb_refill;"); trace_hex16(g_fbb_block_addr);trace_nl();
01056 
01057    // Ensure that the cache is bigger than the real number of free blocks
01058    //
01059    g_cache_fbb.max = Min(NF_CACHE_FBB_LOG_SZ, (g_n_free_blocks>>NF_SHIFT_N_DEVICES) ); // Last included
01060 
01061    Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV);
01062 
01063    page_addr =
01064       nf_block_2_page( g_fbb_block_addr  ) // base address
01065    +  (U32)g_fbb_block_index               // offset to Free-blocks block entry
01066    ;
01067    byte_addr=0;
01068 
01069    nfc_open_page_read(page_addr, 0);
01070 
01071    for ( u8_tmp=0 ; u8_tmp<g_cache_fbb.max*NF_N_DEVICES ; u8_tmp++ )
01072    { // fill the cache buffer
01073       Assert( u8_tmp<CACHE_FBB_SIZE);
01074       MSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next();
01075       LSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next();
01076       Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block );
01077       Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS       );
01078       byte_addr+=2;
01079       Assert( byte_addr<SIZE_PAGE_BYTE); // Should stay in the page. Algo limitation.
01080    }
01081    g_cache_fbb.ctrl.valid = TRUE;
01082 } // end of nf_cache_fbb_refill

Here is the call graph for this function:

void nf_swap ( U8  dev_id,
U8  u8_ofst_lut,
U8  u8_ofst_fbb 
)

Swap 2 blocks from the LUT and the FBB.

This function swaps 2 blocks: one taken into the LUT according to the LBA, and one from the FBB. This is used when modifying a block. The g_block_to_kill[] holds the block address source (LUT) that will be erased after processing.

Parameters:
dev_id Device Id of recipient page
u8_ofst_lut block offset in LUT
u8_ofst_fbb block offset in FBB
Returns:
none

Definition at line 2018 of file nf_mngt.c.

References Assert, CACHE_FBB_SIZE, CACHE_LUT_SIZE, G_N_BLOCKS, NF_N_DEVICES, trace(), trace_hex32(), trace_nl(), trace_u8(), and TRUE.

02019 {
02020    Assert( dev_id      < NF_N_DEVICES  );
02021    Assert( u8_ofst_lut < CACHE_LUT_SIZE);
02022    Assert( u8_ofst_fbb < CACHE_FBB_SIZE);
02023    Assert( g_cache_lut.mem[u8_ofst_lut]  >=g_nf_first_block );
02024    Assert( g_cache_lut.mem[u8_ofst_lut]  < G_N_BLOCKS       );
02025    Assert( g_cache_fbb.mem[u8_ofst_fbb]  >=g_nf_first_block );
02026    Assert( g_cache_fbb.mem[u8_ofst_fbb]  < G_N_BLOCKS       );
02027    g_block_to_kill[dev_id     ] = g_cache_lut.mem[u8_ofst_lut] ;
02028    g_cache_lut.mem[u8_ofst_lut] = g_cache_fbb.mem[u8_ofst_fbb] ;
02029    g_cache_fbb.mem[u8_ofst_fbb] = g_block_to_kill[dev_id]      ;
02030    trace("g_cache_lut.mem["); trace_u8(u8_ofst_lut); trace("] = "); trace_hex32(g_cache_lut.mem[u8_ofst_lut]); trace_nl();
02031    trace("g_cache_fbb.mem["); trace_u8(u8_ofst_fbb); trace("] = "); trace_hex32(g_cache_fbb.mem[u8_ofst_fbb]); trace_nl();
02032 
02033    // both FBB and LUT caches becomes invalid
02034    g_cache_lut.ctrl.dirty=TRUE;
02035    g_cache_fbb.ctrl.dirty=TRUE;
02036 }

Here is the call graph for this function:

void nf_cache_fbb_flush ( Bool  b_ecc_err  ) 

Flushes the FBB cache into a new FBB entry.

A copy of the current FBB is made in a new page, taking into account the last FBB modification in its cache. If the block containing the FBB is full, a new block is taken from the FBB itself.

Parameters:
b_ecc_err FALSE: normal operation, b_ecc_err TRUE: remove a block from list (p)
Returns:
nothing

Definition at line 1292 of file nf_mngt.c.

References _debug, _MEM_TYPE_SLOW_, Assert, CACHE_FBB_SIZE, FALSE, G_N_BLOCKS, G_SHIFT_BLOCK_PAGE, LSB, MSB, nf_block_2_page(), Nf_check_fbb, Nf_check_lut, NF_FULL_PAGE_BUFFER_SIZE, NF_N_DEVICES, NF_PAGE_BUFFER_SIZE, nf_write_fbb(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_erase_block(), nfc_open_page_read(), Nfc_rd_data_fetch_next, S_MNGT_DEV, SIZE_PAGE_BYTE, trace(), trace_hex16(), trace_nl(), and TRUE.

01293 {
01294    _MEM_TYPE_SLOW_ U32  page_addr;
01295    _MEM_TYPE_SLOW_ U16  byte_addr;
01296    _MEM_TYPE_SLOW_ U16 u16_delete=0;
01297    _MEM_TYPE_SLOW_ U16  u16_tmp;
01298    U8   u8_tmp;
01299    _MEM_TYPE_SLOW_ U8   u8_pos;
01300    Bool bool_delete=FALSE;
01301 
01302    Assert(TRUE==g_cache_fbb.ctrl.valid);
01303    Assert(TRUE==g_cache_fbb.ctrl.dirty);
01304    // Assert(g_cache_fbb.p==(g_cache_fbb.max-1)); This is no more the case for ECC error not correctable
01305 
01306    Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV);
01307 
01308    trace("nf_cache_fbb_flush;"); trace_hex16(g_fbb_block_addr);trace_nl();
01309 
01310    page_addr=
01311       nf_block_2_page( g_fbb_block_addr  )  // base address
01312    +  (U32)g_fbb_block_index                // offset to page
01313    ;
01314 
01315    g_fbb_block_index++;
01316 
01317    if ( g_fbb_block_index ==  (1<<G_SHIFT_BLOCK_PAGE)/(1<<0) )
01318    {  // Need to recycle the FBB block itself, using a free-block ! This is always possible
01319       // since there is always a free block (.p=.max-1) specially for that purpose.
01320       byte_addr = ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV);
01321 
01322       Assert( g_cache_fbb.mem[byte_addr]>=g_nf_first_block );
01323       Assert( g_cache_fbb.mem[byte_addr]< G_N_BLOCKS       );
01324       u16_delete                 = g_fbb_block_addr           ;
01325       g_fbb_block_addr           = g_cache_fbb.mem[byte_addr] ;
01326       g_cache_fbb.mem[byte_addr] = u16_delete;
01327       g_fbb_block_index = 0;
01328 
01329       trace("nf_cache_fbb_flush;swap;"); trace_hex16(g_fbb_block_addr);trace_nl();
01330       
01331       // g_cache_fbb.ctrl.dirty=TRUE; This is already the case !
01332 
01333       g_cache_fbb.p++;
01334       bool_delete=TRUE;
01335    }
01336 
01337    if( !b_ecc_err )  { u8_pos = g_cache_fbb.p;   }
01338    else              { u8_pos = g_cache_fbb.max; }
01339 
01340    byte_addr = ((U16)NF_N_DEVICES*2*u8_pos);
01341 
01342    Assert( byte_addr<SIZE_PAGE_BYTE );
01343 
01344    nfc_open_page_read( page_addr, byte_addr);
01345 
01346    Assert( g_cache_fbb.p<=(g_n_free_blocks/NF_N_DEVICES) );
01347    for (
01348       u16_tmp=0
01349    ;  u16_tmp<((g_n_free_blocks/NF_N_DEVICES)-u8_pos)*NF_N_DEVICES*2
01350    ; )
01351    {  // Move the free-blocks after <pos> to the beginning of the buffer.
01352       Assert( u16_tmp<(NF_PAGE_BUFFER_SIZE-3) );
01353       g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next();
01354       g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next();
01355 #if (_ASSERT_==ENABLE)
01356       MSB(_debug)= g_page_buffer[u16_tmp-2];
01357       LSB(_debug)= g_page_buffer[u16_tmp-1];
01358       Assert( _debug>=g_nf_first_block );
01359       Assert( _debug< G_N_BLOCKS       );
01360 #endif
01361    }
01362 
01363    for ( u8_tmp=0 ; u8_tmp<(u8_pos*NF_N_DEVICES); u8_tmp++ )
01364    {  // Then add the cache content
01365       Assert( u8_tmp < CACHE_FBB_SIZE );
01366       Assert( u16_tmp< NF_FULL_PAGE_BUFFER_SIZE );
01367 #if (_ASSERT_==ENABLE)
01368       // When coming from ECC 2-bits error, an entry has been removed
01369       // from the cache, so the last entry is 0xffff
01370       if( !b_ecc_err )
01371       {
01372          Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block );
01373          Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS       );
01374       }
01375 #endif
01376       g_page_buffer[u16_tmp++] = MSB(g_cache_fbb.mem[u8_tmp]);
01377       g_page_buffer[u16_tmp++] = LSB(g_cache_fbb.mem[u8_tmp]);
01378    }
01379 #if (_ASSERT_==ENABLE)
01380    // Ensure that, when there is no fbb recycle, the blocks in the cache at
01381    // position p are identical to the blocks in the beginning of the new line.
01382    if( (FALSE==bool_delete) && ( !b_ecc_err ))
01383    {
01384       for ( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ )
01385       {
01386          MSB(_debug)= g_page_buffer[u8_tmp*2   ];
01387          LSB(_debug)= g_page_buffer[u8_tmp*2 +1];
01388          Assert( _debug==g_cache_fbb.mem[(g_cache_fbb.p)*NF_N_DEVICES + u8_tmp] );
01389       }
01390    }
01391 #endif
01392 
01393    nf_write_fbb(); // Should test the result
01394    Nf_check_fbb( b_ecc_err );
01395    Nf_check_lut();
01396 
01397    if( TRUE==bool_delete )
01398    {
01399       nfc_erase_block( nf_block_2_page( u16_delete ), TRUE );
01400    }
01401 
01402    Assert( u16_tmp==(g_n_free_blocks*2) ); // All the list should have been processed
01403    g_cache_fbb.ctrl.dirty=FALSE;
01404 } // end of nf_cache_fbb_flush

Here is the call graph for this function:

void nf_recovery ( U16  block_1,
U16  block_2 
)

void nf_copy_tail ( void   ) 

Definition at line 1555 of file nf_mngt.c.

References _MEM_TYPE_SLOW_, Is_not_nf_512, LSB0, nf_block_2_page(), nf_copy(), nf_download(), nf_erase_old_blocks(), NF_N_DEVICES, NF_PAGE_PROGRAM_CMD, NF_RANDOM_DATA_INPUT_CMD, NF_SPARE_POS, nf_upload(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), nfc_open_page_write(), Nfc_set_adc, Nfc_set_cmd, S_SHIFT_LOG_BLOCK_SECTOR, SIZE_BLOCK_PAGE, SIZE_PAGE_SECTOR, SIZE_SECTOR_BYTE, trace(), trace_hex32(), and trace_nl().

01556 {
01557    _MEM_TYPE_SLOW_ U8  u8_tmp;
01558                    U8  u8_tmp2;
01559    _MEM_TYPE_SLOW_ U16 u16_tmp;
01560    _MEM_TYPE_SLOW_ U16 byte_addr;
01561 
01562    // Test if we do not reach the end of the logical block
01563    //
01564    if( 0!=((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1)) )
01565    {
01566       trace("nf_copy_tail;"); trace_hex32(g_last_log_sector); trace_nl();
01567       if( Is_not_nf_512() )
01568       {  // Following is not possible on 512B Nand
01569 
01570          u8_tmp = // current offset sector in the current page
01571             LSB0(g_last_log_sector)
01572          &  ( SIZE_PAGE_SECTOR-1 )
01573          ;
01574 
01575          u8_tmp2 = SIZE_PAGE_SECTOR -u8_tmp;
01576          if( 0!=u8_tmp )
01577          {  // Copy the rest of the current line
01578 
01579             byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE);
01580             Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);  // open the current device
01581             nfc_open_page_read(                                                       // Open the old block at :
01582                   nf_block_2_page( g_block_to_kill[g_curr_dev_id] )                   // adresse of the beginning of the old block
01583                +  (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1))        // current offset page in the old and new block
01584             ,  byte_addr );                                                           // current offset sector in the current page
01585             // for each sector in the physical page
01586             u16_tmp = u8_tmp2 * SIZE_SECTOR_BYTE;
01587             g_last_log_sector += u8_tmp2;                                             // update the current logical sector
01588 
01589             // read the sector of the old page
01590             nf_upload(g_page_buffer+byte_addr, u16_tmp/16 );
01591 
01592             // Read the associated spare zone
01593             byte_addr= NF_SPARE_POS + (((U16)u8_tmp)*16);
01594             nfc_open_page_read(                                                       // Open the old block at :
01595                   nf_block_2_page( g_block_to_kill[g_curr_dev_id] )                   // adresse of the beginning of the old block
01596                +  (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1))        // current offset page in the old and new block
01597             ,  byte_addr );                                                           // current offset sector in the current page
01598             nf_upload(g_page_buffer+byte_addr, u8_tmp2 );
01599 
01600             byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE);
01601             nfc_open_page_write( // Open the new block at the current position
01602                g_phys_page_addr[g_curr_dev_id]
01603             ,  byte_addr );
01604 
01605             // write the sector in the new page
01606             nf_download(g_page_buffer+byte_addr, (U8)(u16_tmp/16) );
01607 
01608             // write the associated spare zone
01609             byte_addr=NF_SPARE_POS + (((U16)u8_tmp)*16);
01610             Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD);
01611             Nfc_set_adc( (byte_addr)%256 );
01612             Nfc_set_adc( (byte_addr)/256 );
01613             nf_download(g_page_buffer+byte_addr, u8_tmp2 );
01614             Nfc_set_cmd(NF_PAGE_PROGRAM_CMD);
01615 
01616             g_phys_page_addr[g_curr_dev_id]++;                                                   // update the current physical page of the current device
01617             g_curr_dev_id++;                                                                     // update the current device
01618             if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; }
01619          }
01620       }
01621 
01622       // then copy the rest of the logical block
01623       //
01624       while( 0!=((U16)g_last_log_sector & (((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR))-1)) )
01625       {
01626          Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);  // open the current device
01627 
01628          g_copy_src=
01629             nf_block_2_page(g_block_to_kill[g_curr_dev_id])                     // adresse of the beginning of the old block
01630          +  (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1))        // current offset page in the old and new block
01631          ;
01632          nf_copy(g_phys_page_addr[g_curr_dev_id]);
01633          g_phys_page_addr[g_curr_dev_id]++;
01634 
01635          g_last_log_sector+=SIZE_PAGE_SECTOR;                            // update the current logical sector
01636          g_curr_dev_id++;                                                          // update the current device
01637          if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; }
01638       }
01639 
01640       // Delete old blocks
01641       //
01642       nf_erase_old_blocks();
01643    }else{
01644       trace("nf_copy_tail empty??;"); trace_hex32(g_last_log_sector); trace_nl();
01645    }
01646    g_last_log_sector= 0xFFFFFFFF;
01647 }

Here is the call graph for this function:

Ctrl_status nf_read_10 ( U32  log_sector,
U16  n_sectors 
)

This function initializes the Nand Flash for a read operation.

Parameters:
log_sector Logical sector address to start read
nb_sector Number of sectors to transfer
Returns:
CTRL_GOOD if ok, CTRL_FAIL if read outside memory

Definition at line 317 of file nf_mngt.c.

References CTRL_FAIL, CTRL_GOOD, FALSE, LSB0, Nf_access_signal_off, Nf_access_signal_on, nf_get_sectors_number(), nf_open_read(), nf_read_sector_to_usb(), nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, Nfc_open_page_read, nfc_open_page_read(), SIZE_BLOCK_PAGE, trace(), trace_hex16(), trace_hex32(), trace_nl(), and TRUE.

00318 {
00319   U8  status;
00320   
00321    if ( !g_nf_init )
00322       while(1);   // You shall call once mem_test_unit_ready() before.
00323 
00324    // Test that the logical sector address is valid
00325    //
00326    if ( 0==n_sectors )                                   { return CTRL_GOOD; }
00327    if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; }
00328 
00329 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00330    nf_XMCR_enable();
00331 #endif
00332 
00333    s_n_sectors       = n_sectors;
00334    s_curr_log_sector = log_sector;
00335    trace("rd;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl();
00336    s_save_log_addr   = log_sector + n_sectors;
00337    g_fatal           = FALSE;
00338    s_mem             = TRUE;
00339    s_start           = TRUE;
00340 
00341    // First read operation
00342    Nf_access_signal_on();
00343    nf_open_read(TRUE);
00344    Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);
00345    nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte );
00346    nf_read_sector_to_usb(s_nb_sectors_step);
00347    status = nf_xfer_update_vars();
00348 
00349    // Next read operations
00350    while (status == FALSE)    // exit when last page read
00351    {
00352       if (!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1))    // new block
00353       && (g_curr_dev_id==0                                  ))    // on device 0. Should this case be implicit ? If yes, we can remove it.
00354       {
00355          nf_open_read(FALSE);
00356       }
00357       Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);
00358       Nfc_open_page_read( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution
00359       nf_read_sector_to_usb(s_nb_sectors_step);                   // read the concerned sectors of the selected page
00360       status = nf_xfer_update_vars();                             // check if last page or not
00361    }
00362 
00363    Nf_access_signal_off();
00364 
00365 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00366    nf_XMCR_disable();
00367 #endif
00368 
00369    return CTRL_GOOD;
00370 }

Here is the call graph for this function:

Ctrl_status nf_write_10 ( U32  log_sector,
U16  n_sectors 
)

This function initializes the Nand Flash for a write operation.

Parameters:
log_sector Logical sector address to start read
nb_sector Number of sectors to transfer
Returns:
CTRL_GOOD if ok, CTRL_FAIL if read outside memory

Definition at line 381 of file nf_mngt.c.

References CTRL_FAIL, CTRL_GOOD, FALSE, G_CACHE_PROG, G_SHIFT_PAGE_BYTE, Is_nf_2k, LSB0, Nf_access_signal_off, Nf_access_signal_on, NF_CACHE_PROGRAM_CMD, nf_dfc_write_stop(), nf_erase_old_blocks(), nf_get_sectors_number(), nf_open_write(), NF_PAGE_PROGRAM_CMD, NF_TRANS_NORMAL, nf_translate(), nf_update_spare_zone(), nf_write_sector_from_usb(), nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, Nfc_open_page_write, nfc_open_page_write(), Nfc_set_cmd, S_SHIFT_LOG_BLOCK_SECTOR, S_SHIFT_SECTOR_BYTE, SIZE_BLOCK_PAGE, trace(), trace_hex16(), trace_hex32(), trace_nl(), and TRUE.

00382 {
00383   U8 status;
00384   Ctrl_status tmp_bool;
00385 
00386    // Test that the logical sector address is valid
00387    if ( 0==n_sectors )                                   { return CTRL_GOOD; }
00388    if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; }
00389 
00390 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00391    nf_XMCR_enable();
00392 #endif
00393 
00394    s_n_sectors       = n_sectors;
00395    s_curr_log_sector = log_sector;
00396    s_save_log_addr   = log_sector + n_sectors;
00397    g_fatal           = FALSE;
00398    s_mem             = TRUE;
00399    s_start           = TRUE;
00400 
00401    trace("wr;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl();
00402    
00403    // First write operation
00404    Nf_access_signal_on();
00405    if(( s_curr_log_sector==g_last_log_sector )                                           // New write is just after to the last write
00406    && (!(  ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1)))   // Not on a logical block boundary
00407       && ( g_curr_dev_id==0                                                        ))))
00408    {
00409       trace("continue");trace_nl();
00410       nf_translate( NF_TRANS_NORMAL );
00411       Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);  // open the current device
00412       nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte );
00413    }
00414    else
00415    {      
00416       nf_open_write( TRUE );
00417    }
00418    nf_write_sector_from_usb(s_nb_sectors_step);    // s_nb_sectors_step has been calculated in nf_translate()
00419    if (Is_nf_2k())
00420    {
00421       nf_update_spare_zone((U8)(1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-s_nb_sectors_step, s_nb_sectors_step);    // update the spare zone once the page has been filled in
00422    }
00423    else
00424    {
00425      nf_update_spare_zone(0, 1);    // update the spare zone once the page has been filled in
00426    }
00427    g_last_log_sector  = s_curr_log_sector + s_nb_sectors_step;    // Memorize next logical sector to be managed
00428    status = nf_xfer_update_vars();
00429 
00430    // Next write operations
00431    while (status == FALSE)    // exit when operation finished
00432    {
00433       if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1))  // new block
00434       && (g_curr_dev_id==0                                  )) // on device 0.
00435       {
00436          Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page
00437          nf_erase_old_blocks();
00438          nf_open_write( FALSE );
00439       }
00440       else
00441       {
00442          if( G_CACHE_PROG )
00443          {
00444             Nfc_set_cmd(NF_CACHE_PROGRAM_CMD);
00445          }else{
00446             Nfc_set_cmd(NF_PAGE_PROGRAM_CMD);
00447          }
00448          Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);
00449          Nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution
00450       }
00451       nf_write_sector_from_usb(s_nb_sectors_step);
00452       if (Is_nf_2k())
00453       {
00454          nf_update_spare_zone(0, s_nb_sectors_step);
00455       }
00456       else
00457       {
00458          nf_update_spare_zone(0, 1);    // update the spare zone once the page has been filled in
00459       }
00460       g_last_log_sector  = s_curr_log_sector + s_nb_sectors_step;    // Memorize next logical sector to be managed
00461       status = nf_xfer_update_vars();  // check if last block or not
00462    }
00463 
00464    tmp_bool = nf_dfc_write_stop(0);   // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement
00465    Nf_access_signal_off();
00466 
00467 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00468    nf_XMCR_disable();
00469 #endif
00470 
00471    return tmp_bool;
00472 }

Here is the call graph for this function:

Ctrl_status nf_ram_2_nf ( U32  addr,
U8 ram 
)

This fonction initialise the memory for a write operation from ram buffer.

DATA FLOW is: RAM => NF

(sector = 512B)

Parameters:
addr Sector address to write
ram Ram buffer pointer
Returns:
Ctrl_status It is ready -> CTRL_GOOD A error occur -> CTRL_FAIL

Definition at line 2114 of file nf_mngt.c.

References FALSE, G_SHIFT_PAGE_BYTE, Is_nf_2k, Nf_access_signal_off, Nf_access_signal_on, nf_dfc_write_stop(), nf_open_write(), NF_TRANS_NORMAL, nf_translate(), nf_update_spare_zone(), Nf_wr_byte, nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_write(), S_SHIFT_LOG_BLOCK_SECTOR, S_SHIFT_SECTOR_BYTE, and TRUE.

02115 {
02116   Ctrl_status tmp_bool;
02117   U16 i;
02118 
02119 #if (NF_XMCR_MODULE_SHARED == ENABLED)
02120    nf_XMCR_enable();
02121 #endif
02122 
02123    s_n_sectors       = 1;
02124    s_curr_log_sector = addr;
02125    s_save_log_addr   = addr + 1;
02126    g_fatal           = FALSE;
02127    s_mem             = TRUE;
02128    s_start           = TRUE;
02129 
02130    // First write operation
02131    Nf_access_signal_on();
02132    if(( s_curr_log_sector==g_last_log_sector )                                           // New write is just after to the last write
02133    && (!(  ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1)))   // Not on a logical block boundary
02134       && ( g_curr_dev_id==0                                                        ))))
02135    {
02136       nf_translate( NF_TRANS_NORMAL );
02137       Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);  // open the current device
02138       nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte );
02139    }
02140    else
02141    {      
02142       nf_open_write( TRUE );
02143    }
02144    
02145    for(i=0;i<512;i++)
02146    {
02147       Nf_wr_byte(*ram);
02148       ram++;
02149    }
02150 
02151    if (Is_nf_2k())
02152    {
02153       nf_update_spare_zone((U8)(1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-s_nb_sectors_step, s_nb_sectors_step);    // update the spare zone once the page has been filled in
02154    }
02155    else
02156    {
02157      nf_update_spare_zone(0, 1);    // update the spare zone once the page has been filled in
02158    }
02159    nf_xfer_update_vars();
02160 
02161    tmp_bool = nf_dfc_write_stop(0);   // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement
02162    Nf_access_signal_off();
02163 
02164 #if (NF_XMCR_MODULE_SHARED == ENABLED)
02165    nf_XMCR_disable();
02166 #endif
02167 
02168    return tmp_bool;
02169 }

Here is the call graph for this function:

Ctrl_status nf_nf_2_ram ( U32  addr,
U8 ram 
)

This fonction read 1 sector from NF to ram buffer.

DATA FLOW is: NF => RAM

(sector = 512B)

Parameters:
addr Sector address to read
ram Ram buffer pointer
Returns:
Ctrl_status It is ready -> CTRL_GOOD A error occur -> CTRL_FAIL

Definition at line 2183 of file nf_mngt.c.

References CTRL_GOOD, FALSE, G_SHIFT_PAGE_BYTE, Min, Nf_access_signal_off, Nf_access_signal_on, nf_open_read(), Nf_rd_byte, nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), S_SHIFT_SECTOR_BYTE, and TRUE.

02184 {
02185   U16 i;
02186 
02187 #if (NF_XMCR_MODULE_SHARED == ENABLED)
02188    nf_XMCR_enable();
02189 #endif
02190 
02191    s_n_sectors       = 1;
02192    s_curr_log_sector = addr;
02193    s_save_log_addr   = addr + 1;
02194    g_fatal           = FALSE;
02195    s_mem             = TRUE;
02196    s_start           = TRUE;
02197 
02198    // First read operation
02199    Nf_access_signal_on();
02200    nf_open_read(TRUE);
02201    Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);
02202    nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte );
02203    s_nb_sectors_step = (U8)                              // determine number of sectors to be read
02204                        (Min(                             // on this first page
02205                              1,
02206                              ((1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-(s_curr_n_byte >> 9))
02207                            )
02208                        );
02209    
02210    Disable_interrupt();  
02211    for(i=0;i<512;i++)
02212    {
02213       *ram=Nf_rd_byte();
02214       ram++;
02215    }
02216    Enable_interrupt();  
02217    nf_xfer_update_vars();
02218    Nf_access_signal_off();
02219 
02220 #if (NF_XMCR_MODULE_SHARED == ENABLED)
02221    nf_XMCR_disable();
02222 #endif
02223 
02224    return CTRL_GOOD;   
02225 }

Here is the call graph for this function:


Variable Documentation

_MEM_TYPE_SLOW_ U16 _debug

Definition at line 115 of file nf_mngt.h.

Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_check_fbb(), nf_check_lut(), and nf_write_lut().


Generated on Fri Oct 31 14:31:37 2008 for ATMEL by  doxygen 1.5.3