⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nf_unusual.c

📁 mp3播放器
💻 C
📖 第 1 页 / 共 2 页
字号:
//! @file nf_unusual.c,v
//!
//! Copyright (c) 2004 Atmel.
//!
//! Please read file license.txt for copyright notice.
//!
//! @brief This file contains the high level management for nand-flash
//! memory devices which are rarely used. The code is put in a bank
//! in order to save code space.
//!
//! @version 1.22 snd3-refd1-1_9_5 $Id: nf_unusual.c,v 1.22 2007/07/27 12:57:17 sguyon Exp $
//!
//! @todo
//! @bug

// TODO: remplacer les s_shift_xxx en (1<<s_shift_xxx): et ainsi faire des DIV/MUL plutot que des shift
// TODO: decomposer g_phys_page_addr en s_phys_block et s_phys_page (offset dans le block)

//_____  I N C L U D E S ___________________________________________________

//#define _TRACE_        (DISABLE)
#include "config.h"
#include "conf\conf_nf.h"
#include "lib_mcu\nfc\nfc_drv.h"
#include "nf_mngt.h"

#include "conf\conf_clock.h"
#include "lib_mcu\debug.h"
#include "lib_mcu\clock\clock_drv.h"

//_____ P R I V A T E    D E C L A R A T I O N _____________________________

#if (NF_GENERIC_DRIVER==TRUE) || (defined NF_AUTO_DETECT_2KB) ||(defined NF_AUTO_DETECT_512B)
extern _MEM_TYPE_SLOW_       U8   g_n_zones               ; // number of zones (=1024 blocks) per device
extern _MEM_TYPE_SLOW_       U16  g_n_blocks              ; // number of blocks per device
#endif
extern _MEM_TYPE_SLOW_ U8   g_page_buffer[NF_FULL_PAGE_BUFFER_SIZE] ; // Used to bufferize a page
extern _MEM_TYPE_BIT_  bit  g_nf_init                               ; // Boolean set when driver is initialized
extern _MEM_TYPE_SLOW_ U16  g_last_sub_lut_log_sz                   ; // Size of the last sub-LUT. Unit in number of logical blocks
extern _MEM_TYPE_SLOW_ U16  g_sub_lut_log_sz                        ; // Size of the sub-LUT. Unit in number of logical blocks
                       Bool g_is_found_lut                          ;
                       Bool g_is_found_fbb                          ;
extern                 Bool g_fatal                                 ; // Used in LUT/FBB building and ECC management...
       _MEM_TYPE_SLOW_ U8   g_n_real_sub_lut;
       _MEM_TYPE_SLOW_ U16  g_curr_block_addr[    NF_N_DEVICES]; // holds the last block address for each device
       _MEM_TYPE_SLOW_ U8   g_byte[16]                              ; // Buffer which holds spare bytes
extern _MEM_TYPE_SLOW_ U8   g_n_sub_lut                             ; // Holds the number of sub-Lut
extern _MEM_TYPE_SLOW_ U16  g_lut_block_addr [ N_SUBLUT ]           ; // LUT block address
extern _MEM_TYPE_SLOW_ U8   g_lut_block_index[ N_SUBLUT ]           ; // LUT index, unit in (LUT size/page size)
static _MEM_TYPE_SLOW_ U8   s_nfd_rev                               ; // Nand Flash Driver revision;
extern _MEM_TYPE_SLOW_ U16  g_nf_first_block                        ; // Block addr of the beginning of dynamic area
static _MEM_TYPE_SLOW_ U8   s_n_quarantine_blocks[NF_N_DEVICES]     ; // count quarantine blocks (ECC error discovered in them, but block not yet bad) for each device
static _MEM_TYPE_SLOW_ U16  s_n_invalid_blocks[   NF_N_DEVICES]     ; // count invalid blocks (bad, management, LUT, ...) for each device
extern _MEM_TYPE_SLOW_ U16  g_n_export_blocks                       ; // Number of physical blocks exported for mass-storage use
extern _MEM_TYPE_SLOW_ U16  g_n_free_blocks                         ; // Number of free physical blocks
extern _MEM_TYPE_SLOW_ U16  g_fbb_block_addr                        ; // Free-Blocks block address
extern _MEM_TYPE_SLOW_ U8   g_fbb_block_index                       ; // Free-Blocks block index
extern _MEM_TYPE_SLOW_ U32  g_last_log_sector                       ; // Holds the last logical sector number
extern _MEM_TYPE_SLOW_ U32  g_copy_src                              ; // Used to copy NF pages (source page)
extern _MEM_TYPE_SLOW_ U16  g_block_to_kill[ NF_N_DEVICES]          ; // Holds the blocks number which will be erased
extern _MEM_TYPE_FAST_ U32  g_phys_page_addr[NF_N_DEVICES]          ; // Holds the current phys page number for each device
extern _MEM_TYPE_FAST_ U8   g_curr_dev_id                           ; // Holds the current device number that is used

extern _MEM_TYPE_MEDFAST_ U16 g_log_block_id                        ; // Logical Block address

extern _MEM_TYPE_SLOW_ Cache_lut g_cache_lut; // LUT cache
extern _MEM_TYPE_SLOW_ Cache_fbb g_cache_fbb; // Free-Blocks block cache


//#undef ERASING_ALL
//#define ERASING_ALL ENABLE
#if (ERASING_ALL==ENABLE)
U8 g_forever=TRUE;
static void        ut_nfc_erase_all( void );
#endif


static void        nf_init_buffer(      void );
static Status_bool nf_scan(             void );
static Status_bool nf_rebuild(          void );
static Bool        is_nf_invalid(       void );
#if (ISP_VERSION<0x04) // Static area with fixed length
static void        nf_scan_static_area( void );
#endif

static U16         nf_fetch_free_block( U8 i_dev );

static U8          nf_refine_index( U16 block_addr, U8 inc, U8 pattern) ;


//! Clears the internal buffer.
//!
//! @return nothing
//!
static void nf_init_buffer( void )
{
   U16 u16_tmp;
   for ( u16_tmp=NF_FULL_PAGE_BUFFER_SIZE ; u16_tmp!=0 ; u16_tmp-=2 )
   {
      g_page_buffer[u16_tmp-1]=0 ;
      g_page_buffer[u16_tmp-2]=0 ;
   }
}



//! Initializes the nand flash memory driver.
//!
//! The device identification is performed to initialize the
//! driver accordingly
//!
//! @param none
//!
//! @return none
//!
void nf_init ( void )
{
   g_nf_init=FALSE;
//   s_pending_write=FALSE;

#if (NF_GENERIC_DRIVER==TRUE)
#error Check this init...
   g_n_zones             = NF_N_ZONES;
   g_n_blocks            = NF_N_BLOCKS;
   g_shift_block_page    = NF_SHIFT_BLOCK_PAGE;
   g_shift_page_byte     = NF_SHIFT_PAGE_BYTE;
   s_shift_sector_byte   = NF_SHIFT_SECTOR_BYTE;
   g_n_row_cycles        = NF_N_ROW_CYCLES;

   if ( Is_nf_2k() ) // 2KB pages
   {
      g_ofst_blk_status     = 0;
   }
   if ( Is_nf_512() ) // 512B pages
   {
      g_ofst_blk_status     = 5;
   }

   s_shift_log_page_sector  = G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE + NF_SHIFT_N_DEVICES;
   s_shift_log_block_sector = s_shift_log_page_sector + G_SHIFT_BLOCK_PAGE;
#endif

   g_cache_lut.ctrl.valid = FALSE; g_cache_lut.ctrl.dirty = FALSE;
   g_cache_fbb.ctrl.valid = FALSE; g_cache_fbb.ctrl.dirty = FALSE;
}


//! 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.
//!
//! @param none
//!
//! @return a status:
//!           PASS if the command has been succesfully executed;
//!           FAIL else
//!
Status_bool nf_verify_resume( void )
{
   U8 u8_nb_loop;
   Bool status_bool;

   // Speed-up NF initialization
   pll_on();
   clk_cpu_boost(CLK_CPU_BOOST);

#if (ISP_VERSION<0x04) // Static area with fixed length
   nf_scan_static_area();    // Look for static area limit
#endif

   status_bool = nf_scan();

#if (ISP_VERSION>=0x04) // Static area length may vary
   nfc_put_conf( NF_N_DEVICES, TRUE, g_nf_first_block-1 );  // NF locked (system zone only)
#endif

#if (ERASING_ALL==ENABLE)
   ut_nfc_erase_all();
   while(g_forever);
   status_bool = nf_scan();
#endif

   if(( PASS!=status_bool )
   || ( is_nf_invalid()   )  // The NF is not cleanly built
   ) {
      // The NF seems not cleanly built, or not built at all.
      //
      u8_nb_loop = 0;
      while( 1 )
      {
         u8_nb_loop++;
         if( u8_nb_loop > 2 )
         {
            status_bool=FAIL;
            break;  // Error NF access or control
         }
         nf_cleanup_memory();
         if( PASS != nf_scan() )
            continue;
         if( PASS != nf_rebuild() )
            continue;
		   status_bool = PASS;
         break;
      }
   }
   if (status_bool==PASS)
   {
      g_nf_init = TRUE;
      Nf_check_lut();
      Nf_check_fbb( FALSE );
   }
   clk_cpu_boost(CLK_CPU_NORMAL);
   pll_off();
   return status_bool;
}



//! 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.
//!
//! @param none
//!
void nf_cleanup_memory(void)
{
   U8   i_dev  =0;
   U16  i_block=0;
   U8   block_valid;
   U8   block_id;

   // Scan all the devices and looks for:
   // - the sub-LUT
   // - the recovery block
   // - the free-blocks block
   //
   for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
   {
      // Select the devices
      //
      Nfc_action(NFC_ACT_DEV_SELECT, i_dev);

      for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -