nf_drv.c File Reference

#include "config.h"
#include "conf_nf.h"
#include "nf.h"
#include "nf_drv.h"

Include dependency graph for nf_drv.c:

Go to the source code of this file.

Defines

#define _nfc_drv_c_
#define NF_XMCR_MODULE_SHARED   DISABLED
#define BAD_BLOCK_OFFSET   0

Functions

__no_init volatile
xdata Byte
nf_send_cmd 
At (0x3900)
__no_init volatile
xdata Byte
nf_send_add 
At (0x3A00)
__no_init volatile
xdata Byte nf_data 
At (0x3800)
void nfc_select_dev (U8 dev)
U8 nfc_check_type (U8 nb_dev)
 Tests the Nand Flash configuration.
void nfc_reset_nands (U8 nb_dev)
 Reset all the NF devices.
void nf_XMCR_enable (void)
 Enable the XMCR (Extending Memory Module) of the AVR to drive the NAND Flash.
void nf_XMCR_disable (void)
 Disable the XMCR module of the AVR, to allow access to others peripherals that may be connected on this same bus.
Status_bool nfc_check_status (void)
 Check the status of the selected device.
void nfc_open_page_read (U32 page_addr, U16 byte_addr)
 Opens a page for read.
void nfc_open_page_write (U32 page_addr, U16 byte_addr)
 Opens a page for write.
void nfc_mark_bad_block (U32 page_addr)
 Mark a block as 'invalid' by clearing it entirely.
void nfc_erase_block (U32 page_addr, U8 force_erase)
 Erases a block.
void nfc_read_spare_byte (U8 _MEM_TYPE_SLOW_ *p_byte, U8 n_byte, U32 page_addr)
 Reads the number spare bytes specified and stores them in a array.
void nfc_wait_busy (void)
 Tests the true busy.
U32 nfc_read_id (U8 read_id_cmd, U8 nf_num)
 Read the ID of the Nand-Flash.
static Bool nfc_nf_is_ready (void)
 Check the status Ready/Busy of the Nand Flash.
U8 nfc_detect (void)
 Read the ID of the Nand-Flash and update the global variable.
void nfc_copy_back_init (U32 page_addr)
 Prepare a copy-back session.

Variables

U16 bad_block_table [100]


Detailed Description

This file contains the low level functions for the Nand-Flash Controller.

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

Definition in file nf_drv.c.


Define Documentation

#define _nfc_drv_c_

Definition at line 45 of file nf_drv.c.

#define NF_XMCR_MODULE_SHARED   DISABLED

Definition at line 67 of file nf_drv.c.

#define BAD_BLOCK_OFFSET   0

Definition at line 70 of file nf_drv.c.


Function Documentation

__no_init volatile xdata Byte nf_send_cmd At ( 0x3900   ) 

__no_init volatile xdata Byte nf_send_add At ( 0x3A00   ) 

__no_init volatile xdata Byte nf_data At ( 0x3800   ) 

void nfc_select_dev ( U8  dev  ) 

Definition at line 82 of file nf_drv.c.

00083 {
00084    if(0==dev)
00085    {
00086       Nandflash1_unselect();
00087       Nandflash0_select();
00088    }else{
00089       Nandflash0_unselect();
00090       Nandflash1_select();
00091    }
00092 }

U8 nfc_check_type ( U8  nb_dev  ) 

Tests the Nand Flash configuration.

The function verifies that the NF connected to device are properly declared in conf_nf.h.

Parameters:
none 
Returns:
The number of device connected and corresponding to NF identifiers.

Definition at line 106 of file nf_drv.c.

Referenced by main().

00107 {
00108    U8 i_dev;
00109    if( 2 < nb_dev )
00110       nb_dev = 2; // Only 1 or 2 for this driver
00111 
00112 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00113    nf_XMCR_enable();
00114 #endif
00115    nfc_init(        nb_dev, 0 );
00116    nfc_reset_nands( nb_dev ); // Reset all the NF devices
00117 
00118    // Test NF configuration
00119    //
00120    for( i_dev=0 ; i_dev<nb_dev ; i_dev++ )
00121    {
00122       Nfc_action( NFC_ACT_DEV_SELECT, i_dev);
00123       nfc_wait_busy();
00124       Nfc_action( NFC_ACT_ASSERT_CE, NFC_EXT_CELOW);
00125       Nfc_set_cmd(NF_READ_ID_CMD);
00126       Nfc_set_adc( 0 );
00127       if(( Nfc_rd_data_fetch_next()!=G_DEV_MAKER  )
00128       || ( Nfc_rd_data_fetch_next()!=G_DEV_ID     ))
00129       {
00130          return i_dev;
00131       }
00132       if( G_CE_TOGGLE )
00133       {
00134          // disable CE Low
00135          Nfc_action( NFC_ACT_ASSERT_CE, NFC_EXT_NOP);
00136       }
00137    }
00138 
00139 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00140    nf_XMCR_disable();
00141 #endif
00142    return nb_dev;
00143 }

Here is the caller graph for this function:

void nfc_reset_nands ( U8  nb_dev  ) 

Reset all the NF devices.

Parameters:
none 

Definition at line 151 of file nf_drv.c.

Referenced by nf_dfc_write_stop(), nfc_check_type(), and nfc_detect().

00152 {
00153    U8 i_dev;
00154    Mcu_set_sfr_page_nfc();
00155    for( i_dev=0 ; i_dev<nb_dev ; i_dev++ )
00156    {
00157       Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00158       // The wait is mandatory here since the function is used to wait any
00159       // pending internal programmation (Cache Program cmd).
00160       nfc_wait_busy();
00161       Nfc_set_cmd(NF_RESET_CMD);
00162       nfc_wait_busy();
00163    }
00164 }

Here is the caller graph for this function:

void nf_XMCR_enable ( void   ) 

Enable the XMCR (Extending Memory Module) of the AVR to drive the NAND Flash.

Definition at line 171 of file nf_drv.c.

Referenced by nf_nf_2_ram(), nf_ram_2_nf(), nf_read_10(), nf_read_capacity(), nf_test_unit_ready(), nf_usb_stop(), nf_write_10(), nfc_check_type(), and nfc_detect().

00172 {
00173 #if (NF_CLE_ALE_MANUAL == ENABLED)
00174   XMCRB |= ((1<<XMM2) | (1<<XMM1) | (1<<XMM0));   // limit XRAM interface to A7 (release PC0..7)
00175 #else
00176   XMCRB |= ((1<<XMM2) | (1<<XMM1));                // limit XRAM interface to A9 (release PC2..7)
00177 #endif  
00178   XMCRA |= (1<<SRE);                  // enable the external memory
00179 }

Here is the caller graph for this function:

void nf_XMCR_disable ( void   ) 

Disable the XMCR module of the AVR, to allow access to others peripherals that may be connected on this same bus.

Definition at line 184 of file nf_drv.c.

Referenced by nf_nf_2_ram(), nf_ram_2_nf(), nf_read_10(), nf_read_capacity(), nf_test_unit_ready(), nf_usb_stop(), nf_write_10(), nfc_check_type(), and nfc_detect().

00185 {
00186   Nandflash0_unselect();
00187   Nandflash1_unselect();
00188   XMCRA &= ~(1<<SRE);  // disable the external memory
00189 }

Here is the caller graph for this function:

Status_bool nfc_check_status ( void   ) 

Check the status of the selected device.

Returns:
a status: PASS if the status is PASS; FAIL if the status is FAIL

Definition at line 202 of file nf_drv.c.

Referenced by nf_cleanup_memory(), nf_write_fbb(), and nf_write_lut().

00203 {
00204    Mcu_set_sfr_page_nfc();
00205    nfc_wait_busy(); // Send a status command and wait the completion of the last command
00206    if ( (Nfc_rd_data()&NF_MASK_STATUS_FAIL)==0 ) { return PASS; } // I/O 0   Pass:0  Fail:1
00207    else                                          { return FAIL; }
00208 }

Here is the caller graph for this function:

void nfc_open_page_read ( U32  page_addr,
U16  byte_addr 
)

Opens a page for read.

The function will adapt the commands according to the type of flash memory. The busy is polled at the end of the function.

Parameters:
page_addr absolute page address of the block
byte_addr relative byte address inside the page.
Precondition:
nf_init() should have been called before. The NF device should have been selected before with Nfc_action(NFC_ACT_DEV_SELECT, id).

Definition at line 220 of file nf_drv.c.

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_cleanup_memory(), nf_copy(), nf_copy_tail(), nf_nf_2_ram(), nf_open_write(), nf_read_10(), nf_rebuild(), nf_refine_index(), nfc_erase_block(), and nfc_read_spare_byte().

00221 {
00222    Mcu_set_sfr_page_nfc();
00223    nfc_wait_busy();
00224    Nfc_open_page_read( page_addr, byte_addr);
00225 }

Here is the caller graph for this function:

void nfc_open_page_write ( U32  page_addr,
U16  byte_addr 
)

Opens a page for write.

The function will adapt the commands according to the type of flash memory.

Parameters:
page_addr absolute page address of the block
byte_addr relative byte address inside the page.
Precondition:
nf_init() should have been called before. The NF device should have been selected before with Nfc_action(NFC_ACT_DEV_SELECT, id).

Definition at line 238 of file nf_drv.c.

Referenced by nf_copy(), nf_copy_tail(), nf_open_write(), nf_ram_2_nf(), nf_write_10(), nf_write_fbb(), nf_write_lut(), and nfc_mark_bad_block().

00239 {
00240    Mcu_set_sfr_page_nfc();
00241    Nfc_open_page_write( page_addr, byte_addr);
00242 }

Here is the caller graph for this function:

void nfc_mark_bad_block ( U32  page_addr  ) 

Mark a block as 'invalid' by clearing it entirely.

Parameters:
page_addr absolute page address of the block
Precondition:
nf_init() should have been called before. The device which holds this bad block should have been selected before with Nfc_action(NFC_ACT_DEV_SELECT, id).

Definition at line 254 of file nf_drv.c.

Referenced by nf_cleanup_memory(), and nf_rebuild().

00255 {
00256    U8  n_bytes;
00257    U8  i_byte;
00258    U8  i_page;
00259 
00260    Mcu_set_sfr_page_nfc();
00261 
00262    n_bytes= ( Is_nf_512() )
00263    ?  16  // 512B page access
00264    :  64  // 2KB  page access
00265    ;
00266 
00267    // Erasing the block is mandatory to prevent partial programming
00268    // (some 512B NF does support partial prog, but not after a copy back command).
00269    nfc_erase_block( page_addr, TRUE );
00270    for ( i_page=(U8)1<<G_SHIFT_BLOCK_PAGE ; i_page!=0 ; i_page--, page_addr++ )
00271    {
00272       nfc_open_page_write( page_addr, NF_SPARE_POS-8 );
00273       Nfc_wr_data('A'); Nfc_wr_data('t');
00274       Nfc_wr_data('m'); Nfc_wr_data('e');
00275       Nfc_wr_data('l'); Nfc_wr_data(' ');
00276       Nfc_wr_data(' '); Nfc_wr_data(' ');
00277       for ( i_byte=n_bytes ; i_byte!=0 ; i_byte-=4 )
00278       {
00279          Nfc_wr_data(0);
00280          Nfc_wr_data(0);
00281          Nfc_wr_data(0);
00282          Nfc_wr_data(0);
00283       }
00284       Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Confirm programmation
00285    }
00286 }

Here is the caller graph for this function:

void nfc_erase_block ( U32  page_addr,
U8  force_erase 
)

Erases a block.

The erase will be done only if the block is not bad

Parameters:
page_addr absolute page address of the block
force_erase TRUE forces erasing, FALSE erases the block (if not bad)
Precondition:
nf_init() should have been called before. The device which holds the block to delete should have been selected before with Nfc_action(NFC_ACT_DEV_SELECT, id).

Definition at line 301 of file nf_drv.c.

Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_cleanup_memory(), nf_erase_all_blocks(), nf_erase_old_blocks(), nf_fetch_free_block(), nf_rebuild(), nfc_mark_bad_block(), and ut_nfc_erase_all().

00302 {
00303    Mcu_set_sfr_page_nfc();
00304    if (FALSE == force_erase)
00305    {
00306       nfc_open_page_read( page_addr, NF_SPARE_POS + G_OFST_BLK_STATUS );
00307       if( (Nfc_rd_data() != 0xFF) ) return;    // The block is bad. We can not erase it
00308    }
00309    nfc_wait_busy();
00310    Nfc_unprotect_all_flash();                    // WP may be actif due to block protection
00311    Nfc_set_cmd (NF_BLOCK_ERASE_CMD);             // Auto Block Erase Setup
00312    Nfc_set_adr( LSB0(page_addr) );
00313    Nfc_set_adr( LSB1(page_addr) );
00314    if (3 == G_N_ROW_CYCLES)
00315    {
00316       Nfc_set_adr( MSB1(page_addr) );
00317    }
00318    Nfc_set_cmd(NF_BLOCK_ERASE_CONFIRM_CMD);      // Erase command
00319 }

Here is the caller graph for this function:

void nfc_read_spare_byte ( U8 _MEM_TYPE_SLOW_ *  p_byte,
U8  n_byte,
U32  page_addr 
)

Reads the number spare bytes specified and stores them in a array.

Parameters:
p_byte pointer on the array in which are stored the spare bytes.
n_byte number of spare bytes to read.
page_addr absolute page address of the block.
Precondition:
nf_init() should have been called before. The NF device should have been selected before with Nfc_action(NFC_ACT_DEV_SELECT, id).

Definition at line 332 of file nf_drv.c.

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

00336 {
00337    U8  i;
00338 
00339    Mcu_set_sfr_page_nfc();
00340    nfc_open_page_read( page_addr, NF_SPARE_POS);
00341 
00342    for ( i=0 ; i!=n_byte ; i++ )
00343    {
00344       p_byte[i] = Nfc_rd_data_fetch_next();
00345    }
00346 }

Here is the caller graph for this function:

void nfc_wait_busy ( void   ) 

Tests the true busy.

Note that we test twice the ready, since there is an hardware minimum requirement between the end of the busy and the first read cycle. Since the busy is not wired, the ready is tested twice.

Definition at line 352 of file nf_drv.c.

Referenced by nfc_check_status(), nfc_check_type(), nfc_copy_back_init(), nfc_erase_block(), nfc_open_page_read(), nfc_read_id(), and nfc_reset_nands().

00353 {
00354    register int Reg;
00355    Nfc_set_cmd(NF_READ_STATUS_CMD);
00356    Reg = Nfc_rd_status();
00357    if( Is_nf_2k() )
00358    {
00359       if( G_CACHE_PROG )
00360       {
00361          while( (Nfc_rd_status() & NF_MASK_STATUS_T_RDY_2KB )==0 );
00362          while( (Nfc_rd_status() & NF_MASK_STATUS_T_RDY_2KB )==0 );
00363       }
00364       else
00365       {
00366          while( (Nfc_rd_status() & NF_MASK_STATUS_READY     )==0 );
00367          while( (Nfc_rd_status() & NF_MASK_STATUS_READY     )==0 );
00368       }
00369    }
00370    if( Is_nf_512() )
00371    {
00372       while( (Nfc_rd_status() & NF_MASK_STATUS_T_RDY_512B )==0 );
00373       while( (Nfc_rd_status() & NF_MASK_STATUS_T_RDY_512B )==0 );
00374    }
00375 }

Here is the caller graph for this function:

U32 nfc_read_id ( U8  read_id_cmd,
U8  nf_num 
)

Read the ID of the Nand-Flash.

Parameters:
read_id_cmd Read_id command (NF_READ_ID_CMD, NF_READ_ID2_CMD)
nf_num Nand Flash number
Returns:
: MSB0(ret) (MSB) is the Maker Code, MSB1(ret) is the Device Id, MSB2(ret) is 3rd byte returned, MSB3(ret) (LSB) is 4th byte returned.
Precondition:
nf_init() should have been called before.

Definition at line 396 of file nf_drv.c.

Referenced by nfc_detect().

00397 {
00398    U32 ret;
00399 
00400    Mcu_set_sfr_page_nfc();
00401    Nfc_action(NFC_ACT_DEV_SELECT, nf_num);
00402    nfc_wait_busy();
00403    Nfc_action( NFC_ACT_ASSERT_CE, NFC_EXT_CELOW);
00404    Nfc_set_cmd (read_id_cmd);
00405    Nfc_set_adc( 0 );
00406 
00407    MSB0(ret)= Nfc_rd_data_fetch_next(); // Maker Code
00408    MSB1(ret)= Nfc_rd_data_fetch_next(); // Device Id
00409    MSB2(ret)= Nfc_rd_data_fetch_next(); // extra
00410    MSB3(ret)= Nfc_rd_data_fetch_next(); // extra (Multi Plane Support)
00411 
00412    Nfc_action( NFC_ACT_ASSERT_CE, NFC_EXT_NOP);
00413    return ret;
00414 }

Here is the caller graph for this function:

static Bool nfc_nf_is_ready ( void   )  [static]

Check the status Ready/Busy of the Nand Flash.

Returns:
Bool TRUE -> The Nand Flash is ready and connected FALSE -> The Nand Flash must be no connected (timeout)

Definition at line 422 of file nf_drv.c.

References FALSE, NF_MASK_STATUS_READY, NF_MAX_RB_TIMEOUT, NF_READ_STATUS_CMD, Nfc_rd_status, Nfc_set_cmd, and TRUE.

Referenced by nfc_detect().

00423 {
00424    register Reg;
00425    U8 u8_timeout;
00426 
00427    Nfc_set_cmd( NF_READ_STATUS_CMD );  // send status for each read, because the NF must be in reset sequence
00428    Reg = Nfc_rd_status();            // active first read
00429 
00430    for (u8_timeout=NF_MAX_RB_TIMEOUT ; u8_timeout!=0 ; u8_timeout--)
00431    {
00432       if(( (Nfc_rd_status() & NF_MASK_STATUS_READY) !=0 )    // the busy pin is not tested, and the bit ready may be wrong penddind the rise of busy pin
00433       && ( (Nfc_rd_status() & NF_MASK_STATUS_READY) !=0 ) )  // To not read a wrong status, we check the status after 6 cycles (300ns)
00434       {
00435             return TRUE;  // NF READY
00436       }
00437    }
00438    return FALSE;          // TIMEOUT
00439 }

Here is the caller graph for this function:

U8 nfc_detect ( void   ) 

Read the ID of the Nand-Flash and update the global variable.

Returns:
: nf index of listing "nf_listing" otherwise : NO_NF_CONNECTED or NF_UNKNOW

Definition at line 448 of file nf_drv.c.

Referenced by main().

00449 {
00450    U32   u32_nf_ids;
00451    U8    u8_i, u8_conf;
00452 
00453 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00454    nf_XMCR_enable();
00455 #endif
00456 
00457    // Init the Nand Flash Controller
00458    nfc_init(        NF_MAX_DEVICES, 0 );
00459    nfc_reset_nands( NF_MAX_DEVICES ); // Reset all the NF devices
00460 
00461    // Check the presence of device 0
00462    if ( FALSE == nfc_nf_is_ready() )
00463    {
00464       #if (NF_XMCR_MODULE_SHARED == ENABLED)
00465          nf_XMCR_disable();
00466       #endif
00467       return NO_NF_CONNECTED;
00468    }
00469 
00470    // Read the Nand Flash IDs of device 0
00471    u32_nf_ids = nfc_read_id( NF_READ_ID_CMD, 0 );
00472 
00473    // Identify the Nand Flash (device 0)
00474    for( u8_i=0 ; u8_i < (sizeof(nf_list_id)/sizeof(St_nf_id)) ; u8_i++)
00475    {
00476       if((nf_list_id[u8_i].manuf == MSB0(u32_nf_ids))
00477       && (nf_list_id[u8_i].dev   == MSB1(u32_nf_ids)))
00478          break; // here, ID is know
00479    }
00480    if( u8_i == (sizeof(nf_list_id)/sizeof(St_nf_id)) )
00481    {
00482       #if (NF_XMCR_MODULE_SHARED == ENABLED)
00483          nf_XMCR_disable();
00484       #endif
00485       return NF_UNKNOW;
00486    }
00487 
00488    // Set NF configuration parameters for initialisation and access
00489 #if (NF_GENERIC_DRIVER==TRUE)
00490 #  error Test me...
00491    g_shift_page_byte    =;
00492    g_shift_block_page   =;
00493 #endif
00494 
00495 #if (NF_GENERIC_DRIVER==TRUE) || (NF_AUTO_DETECT_2KB==TRUE) ||(NF_AUTO_DETECT_512B==TRUE)
00496 
00497    // Record info
00498    u8_conf     =  nf_list_id[u8_i].conf;
00499    g_dev_maker =  MSB0(u32_nf_ids); // Device maker
00500    g_dev_id    =  MSB1(u32_nf_ids); // Device ID
00501 
00502    // Search the number of block of device
00503    for( u8_i=0 ; u8_i < (sizeof(nf_list_link_id_block)/sizeof(St_nf_link_id_block)) ; u8_i++)
00504    {
00505       if( nf_list_link_id_block[u8_i].dev_id == g_dev_id )
00506          break; // ID found
00507    }
00508    if( u8_i == (sizeof(nf_list_link_id_block)/sizeof(St_nf_link_id_block)) )
00509       while(1);   // Error in NF definition
00510 
00511    g_n_zones            =  nf_list_link_id_block[u8_i].nb_zones;
00512 #if (NF_AUTO_DETECT_2KB==TRUE)
00513    if( 1 == g_n_zones )
00514       g_n_row_cycles    =  2;
00515    else
00516       g_n_row_cycles    =  3;
00517 #endif
00518 #if (NF_AUTO_DETECT_512B==TRUE)
00519    if( 2 >= g_n_zones )
00520       g_n_row_cycles    =  2;
00521    else
00522       g_n_row_cycles    =  3;
00523 #endif
00524    g_n_blocks           =  g_n_zones*1024L;
00525 
00526    g_copy_back_cont     = nf_list_conf[u8_conf].copy_back_cont   ;
00527    g_copy_back_discont  = nf_list_conf[u8_conf].copy_back_discont;
00528    g_cache_program      = nf_list_conf[u8_conf].cache_program    ;
00529    g_ce_toggle             = nf_list_conf[u8_conf].ce_toggle;
00530 /*   
00531    g_clock_dfc_nfc      = (nf_list_conf[u8_conf].dfc_nfc_clock<<5) & MSK_DNFCKS;
00532 
00533    Mcu_set_sfr_page_nfc();
00534    Nfc_set_read_timing((U8)nf_list_conf[u8_conf].timing_read );
00535    if( !g_ce_toggle )
00536    {
00537       // Enable CE low
00538       Nfc_action( NFC_ACT_ASSERT_CE, NFC_EXT_CELOW);
00539    }
00540 */
00541 #endif
00542 
00543 #if (NF_XMCR_MODULE_SHARED == ENABLED)
00544    nf_XMCR_disable();
00545 #endif
00546    return u8_i;
00547 }

Here is the caller graph for this function:

void nfc_copy_back_init ( U32  page_addr  ) 

Prepare a copy-back session.

Parameters:
page_addr absolute source page address of the block
Precondition:
nf_init() should have been called before.

Definition at line 557 of file nf_drv.c.

Referenced by nf_copy().

00558 {
00559    Mcu_set_sfr_page_nfc();
00560    nfc_wait_busy();
00561    Nfc_unprotect_all_flash(); // WP may be actif due to block protection
00562    Nfc_set_cmd(NF_READ_CMD);
00563    Nfc_set_adc( 0 );
00564    Nfc_set_adc( 0 );
00565    Nfc_set_adr( LSB0(page_addr) );
00566    Nfc_set_adr( LSB1(page_addr) );
00567    if ( 3==G_N_ROW_CYCLES )
00568    {
00569       Nfc_set_adr( MSB1(page_addr) );
00570    }
00571    Nfc_set_cmd(NF_COPY_BACK_CMD);
00572    nfc_wait_busy();
00573 }

Here is the caller graph for this function:


Variable Documentation

U16 bad_block_table[100]


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