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 61 of file nf_mngt.h.

#define NF_BLK_RCV_PENDING_RECOVERY   0x5A

Definition at line 62 of file nf_mngt.h.

#define NF_LOW_N_FREE_THRESHOLD   5

Definition at line 64 of file nf_mngt.h.

Referenced by nf_rebuild().

#define NF_PAGE_BUFFER_SIZE   2048

Definition at line 77 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 82 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 83 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 84 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 88 of file nf_mngt.h.

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

Definition at line 89 of file nf_mngt.h.

Referenced by nf_rebuild().

#define S_SHIFT_SECTOR_BYTE   s_shift_sector_byte

Definition at line 104 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 105 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 106 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 115 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 121 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 122 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 137 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 150 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 154 of file nf_mngt.h.

00155 {
00156    NF_READ=0
00157 ,  NF_WRITE
00158 } 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 218 of file nf_mngt.c.

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

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

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 243 of file nf_mngt.c.

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

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

Here is the call graph for this function:

Bool nf_wr_protect ( void   ) 

Definition at line 262 of file nf_mngt.c.

References FALSE.

00263 {
00264     return FALSE;
00265 }

Bool nf_removal ( void   ) 

Definition at line 267 of file nf_mngt.c.

References TRUE.

00268 {
00269     return TRUE;
00270 }

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 770 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().

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

References G_SHIFT_BLOCK_PAGE, G_SHIFT_PAGE_BYTE, and S_SHIFT_SECTOR_BYTE.

00297 {
00298    return
00299       (U32)g_n_export_blocks
00300    << (G_SHIFT_BLOCK_PAGE +G_SHIFT_PAGE_BYTE -S_SHIFT_SECTOR_BYTE)
00301    ;
00302 }

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 151 of file nf_unusual.c.

Referenced by main().

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

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 202 of file nf_mngt.c.

References nf_verify_resume(), and PASS.

00203 {
00204    if ( g_nf_init ) return PASS;
00205 
00206    return nf_verify_resume();
00207 }

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 196 of file nf_unusual.c.

Referenced by nf_verify().

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

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 250 of file nf_unusual.c.

Referenced by nf_verify_resume().

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

References _MEM_TYPE_SLOW_, i, and Nf_rd_byte.

01700 {
01701   U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf;
01702   U8 i = loop;
01703 
01704   while (i != 0)
01705   {
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      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01720      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01721      *(tempbuf) = Nf_rd_byte(); tempbuf++;
01722      i--;
01723   }
01724 }

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 1663 of file nf_mngt.c.

References _MEM_TYPE_SLOW_, i, and Nf_wr_byte.

01664 {
01665   U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf;
01666   U8 i = loop;
01667 
01668   while (i != 0)
01669   {
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      Nf_wr_byte(*(tempbuf)); tempbuf++;
01684      Nf_wr_byte(*(tempbuf)); tempbuf++;
01685      Nf_wr_byte(*(tempbuf)); tempbuf++;
01686      i--;
01687   }
01688 }

U32 nf_block_2_page ( U16  block_addr  ) 

Definition at line 306 of file nf_mngt.c.

References G_SHIFT_BLOCK_PAGE.

00307 {
00308    return (U32)block_addr<<G_SHIFT_BLOCK_PAGE;
00309 }

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 1859 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.

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

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 1213 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().

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

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

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

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

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 1295 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.

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

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

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 320 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.

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

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 384 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.

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

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 2117 of file nf_mngt.c.

References FALSE, G_SHIFT_PAGE_BYTE, i, 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.

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

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 2186 of file nf_mngt.c.

References CTRL_GOOD, FALSE, G_SHIFT_PAGE_BYTE, i, 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.

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

Here is the call graph for this function:


Variable Documentation

_MEM_TYPE_SLOW_ U16 _debug

Definition at line 118 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 Wed Sep 23 09:17:14 2009 for ATMEL by  doxygen 1.5.3