nf.c File Reference


Detailed Description

Nand Flash driver for AVR32 UC3.

This file contains basic functions to interface a nandflash through the SMC.

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

Definition in file nf.c.

#include "compiler.h"
#include "conf_nf.h"
#include "nf.h"
#include "gpio.h"
#include "smc.h"

Go to the source code of this file.

Defines

#define _NF_C_

Functions

Bool nf_check_status (void)
 Check the status of the selected device.
U8 nf_check_type (U8 nb_dev)
 Tests the Nand Flash configuration.
void nf_copy_back_init (U32 page_addr)
 Prepare a copy-back session.
void nf_erase_block (U32 page_addr, U8 force_erase)
 Erases a block.
U8 nf_get_freq (void)
 returns the frequency supported by the selected NF.
void nf_init (U32 hsb_f_hz)
 Initializes the Nand Flash Controller and low level driver.
void nf_mark_bad_block (U32 page_addr)
 Mark a block as 'invalid' by clearing it entirely.
void nf_open_page_read (U32 page_addr, U16 byte_addr)
 Opens a page for read.
void nf_open_page_write (U32 page_addr, U16 byte_addr)
 Opens a page for write.
void nf_protect (void)
 Protect all the flashes.
U32 nf_read_id (U8 read_id_cmd, U8 nf_num)
 Read the ID of the Nand-Flash.
void nf_reset_nands (U8 nb_dev)
 Reset all the NF devices.
void nf_unprotect (void)
 unprotect all the flashes
void nf_wait_busy (void)
 Tests the true busy.
U8 nfc_detect (void)
 Read the ID of the Nand-Flash and update the global variable.
static Bool nfc_nf_is_ready (void)
 Check the status Ready/Busy of the Nand Flash.
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.


Define Documentation

#define _NF_C_

Definition at line 54 of file nf.c.


Function Documentation

Bool nf_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 183 of file nf.c.

References NF_MASK_STATUS_FAIL, nf_rd_data(), and nf_wait_busy().

00184 {
00185   U8 data;
00186   nf_wait_busy(); // Send a status command and wait the completion of the last command
00187 
00188   ecchrs_freeze(&AVR32_ECCHRS);
00189   data = nf_rd_data();
00190   ecchrs_unfreeze(&AVR32_ECCHRS);
00191   if ( (data&NF_MASK_STATUS_FAIL)==0 ) { return PASS; } // I/O 0   Pass:0  Fail:1
00192   else                                 { return FAIL; }
00193 }

U8 nf_check_type ( U8  nb_dev  ) 

Tests the Nand Flash configuration.

The function verifies that the connected NF is properly declared in conf_nf.h.

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

Definition at line 78 of file nf.c.

References G_CE_LOW, G_DEV_ID, G_DEV_MAKER, nf_force_CE, nf_rd_data(), NF_READ_ID_CMD, nf_reset_nands(), nf_select(), nf_wait_busy(), nf_wr_addr(), and nf_wr_cmd().

00079 {
00080    U8 i_dev;
00081 
00082    //nf_init(        nb_dev, 0 );
00083 #warning Update for full support.
00084    nf_reset_nands( nb_dev ); // Reset all the NF devices
00085 
00086    // Test NF configuration
00087    //
00088    for( i_dev=0 ; i_dev<nb_dev ; i_dev++ )
00089    {
00090       nf_select( i_dev );
00091       nf_wait_busy();
00092       nf_force_CE();
00093       nf_wr_cmd(NF_READ_ID_CMD);
00094       nf_wr_addr( 0 );
00095       if(( nf_rd_data()!=G_DEV_MAKER  )
00096       || ( nf_rd_data()!=G_DEV_ID     ))
00097       {
00098          Assert( FALSE );
00099          return i_dev;
00100       }
00101       if( G_CE_LOW )
00102       {
00103          // Activate CE Low if needed. This config is static
00104          // and we supposed that it is no more deactivated in firmware.
00105          nf_force_CE();
00106       }
00107    }
00108    return nb_dev;
00109 }

void nf_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 497 of file nf.c.

References G_N_ROW_CYCLES, NF_COPY_BACK_CMD, NF_READ_CMD, nf_wait_busy(), nf_wr_addr(), and nf_wr_cmd().

00498 {
00499    nf_wait_busy();
00500    nf_wr_cmd(NF_READ_CMD);
00501    nf_wr_addr( 0 );
00502    nf_wr_addr( 0 );
00503    nf_wr_addr( LSB0(page_addr) );
00504    nf_wr_addr( LSB1(page_addr) );
00505    if ( 3==G_N_ROW_CYCLES )
00506    {
00507       nf_wr_addr( MSB1(page_addr) );
00508    }
00509    nf_wr_cmd(NF_COPY_BACK_CMD);
00510    nf_wait_busy();
00511 }

void nf_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 nf_select( id ).

Definition at line 275 of file nf.c.

References G_N_ROW_CYCLES, G_OFST_BLK_STATUS, NF_BLOCK_ERASE_CMD, NF_BLOCK_ERASE_CONFIRM_CMD, nf_open_page_read(), nf_rd_data(), NF_SPARE_POS, nf_wait_busy(), nf_wr_addr(), and nf_wr_cmd().

Referenced by main(), and nf_mark_bad_block().

00276 {
00277    if( FALSE==force_erase )
00278    {
00279       nf_open_page_read( page_addr, NF_SPARE_POS + G_OFST_BLK_STATUS );
00280       if( (nf_rd_data()!=0xFF) ) return; // The block is bad. We can not erase it
00281    }
00282    nf_wait_busy();
00283    nf_wr_cmd(NF_BLOCK_ERASE_CMD);          // Auto Block Erase Setup
00284    nf_wr_addr( LSB0(page_addr) );
00285    nf_wr_addr( LSB1(page_addr) );
00286    if ( 3==G_N_ROW_CYCLES )
00287    {
00288       nf_wr_addr( MSB1(page_addr) );
00289    }
00290    nf_wr_cmd(NF_BLOCK_ERASE_CONFIRM_CMD);      // Erase command
00291 }

U8 nf_get_freq ( void   ) 

returns the frequency supported by the selected NF.

Returns:
the frequency

Definition at line 168 of file nf.c.

00169 {
00170    #warning Update for full support.
00171    return 0;
00172    //return G_CLK_DFC_NFC;
00173 }

void nf_init ( U32  hsb_f_hz  ) 

Initializes the Nand Flash Controller and low level driver.

Parameters:
hsb_f_hz HSB frequency in Hertz

Definition at line 137 of file nf.c.

References EBI_NANDOE, and EBI_NANDWE.

Referenced by main(), and nfc_detect().

00138 {
00139   static const gpio_map_t SMC_NF_EBI_GPIO_MAP =
00140   {
00141     {ATPASTE2(EBI_NANDOE,_PIN),ATPASTE2(EBI_NANDOE,_FUNCTION)},
00142     {ATPASTE2(EBI_NANDWE,_PIN),ATPASTE2(EBI_NANDWE,_FUNCTION)},
00143  };
00144 
00145   gpio_enable_module(SMC_NF_EBI_GPIO_MAP, sizeof(SMC_NF_EBI_GPIO_MAP) / sizeof(SMC_NF_EBI_GPIO_MAP[0]));
00146   smc_init(hsb_f_hz);
00147 
00148   // Enable Nand Flash Chip Select
00149   AVR32_HMATRIX.sfr[AVR32_EBI_HMATRIX_NR] |= (1 << AVR32_EBI_NAND_CS);
00150 
00151 /*
00152    Nfc_disable();           // Reset the macro
00153    Nfc_enable();
00154    Nfc_ecc_disable();
00155    Nfc_spzone_disable();
00156 #if (defined NF_TIMING_READ)
00157    Nfc_set_read_timing( NF_TIMING_READ );
00158 #endif
00159 */
00160 }

void nf_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 nf_select( id ).

Definition at line 232 of file nf.c.

References G_SHIFT_BLOCK_PAGE, Is_nf_512, nf_erase_block(), nf_open_page_write(), NF_PAGE_PROGRAM_CMD, NF_SPARE_POS, nf_wr_cmd(), and nf_wr_data().

00233 {
00234    U8  n_bytes;
00235    U8  i_byte;
00236    U8  i_page;
00237 
00238 
00239    n_bytes= ( Is_nf_512() )
00240    ?  16  // 512B page access
00241    :  64  // 2KB  page access
00242    ;
00243    // Erasing the block is mandatory to prevent partial programming
00244    // (some 512B NF does support partial prog, but not after a copy back command).
00245    nf_erase_block( page_addr, TRUE );
00246    for ( i_page=(U8)1<<G_SHIFT_BLOCK_PAGE ; i_page!=0 ; i_page--, page_addr++ )
00247    {
00248       nf_open_page_write( page_addr, NF_SPARE_POS-8 );
00249       nf_wr_data('A'); nf_wr_data('t');
00250       nf_wr_data('m'); nf_wr_data('e');
00251       nf_wr_data('l'); nf_wr_data(' ');
00252       nf_wr_data(' '); nf_wr_data(' ');
00253       for ( i_byte=n_bytes ; i_byte!=0 ; i_byte-=4 )
00254       {
00255          nf_wr_data(0);
00256          nf_wr_data(0);
00257          nf_wr_data(0);
00258          nf_wr_data(0);
00259       }
00260       nf_wr_cmd(NF_PAGE_PROGRAM_CMD); // Confirm programmation
00261    }
00262 }

void nf_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 nf_select( id ).

Definition at line 204 of file nf.c.

References Nf_open_page_read, and nf_wait_busy().

Referenced by main(), nf_erase_block(), and nfc_read_spare_byte().

00205 {
00206    nf_wait_busy();
00207    Nf_open_page_read( page_addr, byte_addr);
00208 }

void nf_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 nf_select( id ).

Definition at line 219 of file nf.c.

References Nf_open_page_write.

Referenced by main(), and nf_mark_bad_block().

00220 {
00221    Nf_open_page_write( page_addr, byte_addr);
00222 }

void nf_protect ( void   ) 

Protect all the flashes.

Definition at line 545 of file nf.c.

References NF_N_DEVICES, nf_select(), and nf_wait_busy().

00546 {
00547   U32 i_dev;
00548 
00549   // Wait until the end of any pending internal programmation (Cache Program cmd).
00550   for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00551   {
00552     nf_select( i_dev );
00553     nf_wait_busy();
00554   }
00555   gpio_clr_gpio_pin(NF_WP_PIN);
00556 }

U32 nf_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 359 of file nf.c.

References nf_rd_data(), nf_select(), nf_wait_busy(), nf_wr_addr(), and nf_wr_cmd().

Referenced by main(), and nfc_detect().

00360 {
00361    U32 ret;
00362 
00363    nf_select( nf_num );
00364    nf_wait_busy();
00365    //nf_force_CE();
00366    nf_wr_cmd (read_id_cmd);
00367    nf_wr_addr( 0 );
00368 
00369    MSB0(ret)= nf_rd_data(); // Maker Code
00370    MSB1(ret)= nf_rd_data(); // Device Id
00371    MSB2(ret)= nf_rd_data(); // extra
00372    MSB3(ret)= nf_rd_data(); // extra (Multi Plane Support)
00373 
00374    //Nfc_action( NFC_ACT_ASSERT_CE, NFC_EXT_NOP);
00375    return ret;
00376 }

void nf_reset_nands ( U8  nb_dev  ) 

Reset all the NF devices.

Parameters:
nb_dev Number of device

Definition at line 117 of file nf.c.

References NF_RESET_CMD, nf_select(), nf_wait_busy(), and nf_wr_cmd().

Referenced by main(), nf_check_type(), and nfc_detect().

00118 {
00119    U8 i_dev;
00120    for( i_dev=0 ; i_dev<nb_dev ; i_dev++ )
00121    {
00122       nf_select( i_dev );
00123       // The wait is mandatory here since the function is used to wait any
00124       // pending internal programmation (Cache Program cmd).
00125       nf_wait_busy();
00126       nf_wr_cmd(NF_RESET_CMD);
00127       nf_wait_busy();
00128    }
00129 }

void nf_unprotect ( void   ) 

unprotect all the flashes

Definition at line 538 of file nf.c.

Referenced by main().

00539 {
00540   gpio_set_gpio_pin(NF_WP_PIN);
00541 }

void nf_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 319 of file nf.c.

References G_CACHE_PROG, Is_nf_2k, Is_nf_512, NF_MASK_STATUS_READY, NF_MASK_STATUS_T_RDY_2KB, NF_MASK_STATUS_T_RDY_512B, nf_rd_data(), NF_READ_STATUS_CMD, and nf_wr_cmd().

Referenced by main(), nf_check_status(), nf_check_type(), nf_copy_back_init(), nf_erase_block(), nf_open_page_read(), nf_protect(), nf_read_id(), and nf_reset_nands().

00320 {
00321    ecchrs_freeze(&AVR32_ECCHRS);
00322    nf_wr_cmd(NF_READ_STATUS_CMD);
00323    if( Is_nf_2k() )
00324    {
00325       if( G_CACHE_PROG )
00326       {
00327          while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_2KB )==0 );
00328          while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_2KB )==0 );
00329       }
00330       else
00331       {
00332          while( (nf_rd_data() & NF_MASK_STATUS_READY     )==0 );
00333          while( (nf_rd_data() & NF_MASK_STATUS_READY     )==0 );
00334       }
00335    }
00336    if( Is_nf_512() )
00337    {
00338       while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_512B )==0 );
00339       while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_512B )==0 );
00340    }
00341    ecchrs_unfreeze(&AVR32_ECCHRS);
00342 }

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 410 of file nf.c.

References St_nf_conf::cache_program, St_nf_conf::ce_low, St_nf_id::conf, St_nf_conf::copy_back_cont, St_nf_conf::copy_back_discont, St_nf_conf::dfc_nfc_clock, g_cache_program, g_ce_low, g_clock_dfc_nfc, g_copy_back_cont, g_copy_back_discont, g_dev_id, g_dev_maker, g_n_blocks, g_n_row_cycles, g_n_zones, g_shift_block_page, g_shift_page_byte, St_nf_link_id_block::nb_zones, nf_force_CE, nf_init(), nf_list_conf, nf_list_id, nf_list_link_id_block, NF_MAX_DEVICES, nf_read_id(), NF_READ_ID_CMD, nf_reset_nands(), and nfc_nf_is_ready().

00411 {
00412    U32   u32_nf_ids;
00413    U8    u8_i, u8_conf;
00414 
00415    // Init the Nand Flash Controller
00416    nf_init(        NF_MAX_DEVICES, 0 );
00417    nf_reset_nands( NF_MAX_DEVICES ); // Reset all the NF devices
00418 
00419    // Check the presence of device 0
00420    if ( FALSE == nfc_nf_is_ready() )
00421       return NO_NF_CONNECTED;
00422 
00423    // Read the Nand Flash IDs of device 0
00424    u32_nf_ids = nf_read_id( NF_READ_ID_CMD, 0 );
00425 
00426    // Identify the Nand Flash (device 0)
00427    for( u8_i=0 ; u8_i < (sizeof(nf_list_id)/sizeof(St_nf_id)) ; u8_i++)
00428    {
00429       if((nf_list_id[u8_i].manuf == MSB0(u32_nf_ids))
00430       && (nf_list_id[u8_i].dev   == MSB1(u32_nf_ids)))
00431          break; // here, ID is know
00432    }
00433    if( u8_i == (sizeof(nf_list_id)/sizeof(St_nf_id)) )
00434       return NF_UNKNOW;
00435 
00436    // Set NF configuration parameters for initialisation and access
00437 #if (NF_GENERIC_DRIVER==TRUE)
00438 #  error Test me...
00439    g_shift_page_byte    =;
00440    g_shift_block_page   =;
00441 #endif
00442 
00443 #if (NF_GENERIC_DRIVER==TRUE) || (NF_AUTO_DETECT_2KB==TRUE) ||(NF_AUTO_DETECT_512B==TRUE)
00444 
00445    // Record info
00446    u8_conf     =  nf_list_id[u8_i].conf;
00447    g_dev_maker =  MSB0(u32_nf_ids); // Device maker
00448    g_dev_id    =  MSB1(u32_nf_ids); // Device ID
00449 
00450    // Search the number of block of device
00451    for( u8_i=0 ; u8_i < (sizeof(nf_list_link_id_block)/sizeof(St_nf_link_id_block)) ; u8_i++)
00452    {
00453       if( nf_list_link_id_block[u8_i].dev_id == g_dev_id )
00454          break; // ID found
00455    }
00456    if( u8_i == (sizeof(nf_list_link_id_block)/sizeof(St_nf_link_id_block)) )
00457       while(1);   // Error in NF definition
00458 
00459    g_n_zones            =  nf_list_link_id_block[u8_i].nb_zones;
00460 #if (NF_AUTO_DETECT_2KB==TRUE)
00461    if( 1 == g_n_zones )
00462       g_n_row_cycles    =  2;
00463    else
00464       g_n_row_cycles    =  3;
00465 #endif
00466 #if (NF_AUTO_DETECT_512B==TRUE)
00467    if( 2 >= g_n_zones )
00468       g_n_row_cycles    =  2;
00469    else
00470       g_n_row_cycles    =  3;
00471 #endif
00472    g_n_blocks           =  g_n_zones*1024L;
00473 
00474    g_copy_back_cont     = nf_list_conf[u8_conf].copy_back_cont   ;
00475    g_copy_back_discont  = nf_list_conf[u8_conf].copy_back_discont;
00476    g_cache_program      = nf_list_conf[u8_conf].cache_program    ;
00477    g_ce_low             = nf_list_conf[u8_conf].ce_low;
00478    g_clock_dfc_nfc      = (nf_list_conf[u8_conf].dfc_nfc_clock<<5) & MSK_DNFCKS;
00479 
00480    Nfc_set_read_timing((U8)nf_list_conf[u8_conf].timing_read );
00481    if( g_ce_low )
00482    {
00483       nf_force_CE();
00484    }
00485 #endif
00486    return u8_i;
00487 }

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 385 of file nf.c.

References NF_MASK_STATUS_READY, NF_READ_STATUS_CMD, and nf_wr_cmd().

Referenced by nfc_detect().

00386 {
00387    U8 u8_timeout;
00388    U8 dummy;
00389    nf_wr_cmd( NF_READ_STATUS_CMD );  // send status for each read, because the NF must be in reset sequence
00390    dummy = Nfc_rd_status();     // active first read
00391 
00392    for (u8_timeout=NF_MAX_RB_TIMEOUT ; u8_timeout!=0 ; u8_timeout--)
00393    {
00394       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
00395       && ( (Nfc_rd_status() & NF_MASK_STATUS_READY) !=0 ) )  // To not read a wrong status, we check the status after 6 cycles (300ns)
00396       {
00397             return TRUE;  // NF READY
00398       }
00399    }
00400    return FALSE;          // TIMEOUT
00401 }

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 nf_select( id ).

Definition at line 302 of file nf.c.

References nf_open_page_read(), nf_rd_data(), and NF_SPARE_POS.

00306 {
00307    U8  i;
00308 
00309    nf_open_page_read( page_addr, NF_SPARE_POS);
00310 
00311    for ( i=0 ; i!=n_byte ; i++ )
00312       p_byte[i] = nf_rd_data();
00313 }


Generated on Fri Feb 19 02:23:49 2010 for AVR32 - Nand Flash using EBI by  doxygen 1.5.5