nf_example.c File Reference


Detailed Description

Nand Flash example program.

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

Definition in file nf_example.c.

#include <avr32/io.h>
#include <stdio.h>
#include <nlao_cpu.h>
#include <nlao_usart.h>
#include "print_funcs.h"
#include "cycle_counter.h"
#include "board.h"
#include "intc.h"
#include "flashc.h"
#include "pm.h"
#include "gpio.h"
#include "nf.h"

Go to the source code of this file.

Functions

int _init_startup (void)
 Low-level initialization routine called during startup, before the main function.
static void init_exceptions (void)
 Initializes MCU exceptions.
static void init_hmatrix (void)
 Initializes the HSB bus matrix.
static void init_interrupts (void)
 Initializes MCU interrupts.
static void init_stdio (void)
 Initializes STDIO.
static void init_sys_clocks (void)
 Initializes the MCU system clocks.
int main (void)
 Main function.
U32 nf_block_2_page (U16 block_addr)
 Convert a block number into a page number.

Variables

pm_freq_param_t pm_freq_param
U16 valid_block_addr [NF_N_DEVICES]


Function Documentation

int _init_startup ( void   ) 

Low-level initialization routine called during startup, before the main function.

Definition at line 198 of file nf_example.c.

References init_exceptions(), init_hmatrix(), and init_interrupts().

00202 {
00203   init_exceptions();
00204   init_hmatrix();
00205   init_interrupts();
00206 
00207   // EWAVR32: Request initialization of data segments.
00208   // GCC: Don't-care value.
00209   return 1;
00210 }

static void init_exceptions ( void   )  [static]

Initializes MCU exceptions.

Definition at line 106 of file nf_example.c.

Referenced by _init_startup().

00107 {
00108 #if __GNUC__ && __AVR32__
00109   // Import the Exception Vector Base Address.
00110   extern void _evba;
00111 
00112   // Load the Exception Vector Base Address in the corresponding system
00113   // register.
00114   Set_system_register(AVR32_EVBA, (int)&_evba);
00115 #endif
00116 
00117   // Enable exceptions globally.
00118   Enable_global_exception();
00119 }

static void init_hmatrix ( void   )  [static]

Initializes the HSB bus matrix.

Definition at line 124 of file nf_example.c.

Referenced by _init_startup().

00125 {
00126   // Set flashc master type to last default to save one cycle for
00127   // each branch.
00128   avr32_hmatrix_scfg_t scfg;
00129 
00130   scfg = AVR32_HMATRIX.SCFG[AVR32_HMATRIX_SLAVE_FLASH];
00131   scfg.defmstr_type = AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT;
00132   AVR32_HMATRIX.SCFG[AVR32_HMATRIX_SLAVE_FLASH] = scfg;
00133 
00134   scfg = AVR32_HMATRIX.SCFG[AVR32_HMATRIX_SLAVE_EBI];
00135   scfg.defmstr_type = AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT;
00136   AVR32_HMATRIX.SCFG[AVR32_HMATRIX_SLAVE_EBI] = scfg;
00137 }

static void init_interrupts ( void   )  [static]

Initializes MCU interrupts.

Definition at line 184 of file nf_example.c.

Referenced by _init_startup().

00185 {
00186   // Initialize interrupt handling.
00187   INTC_init_interrupts();
00188 
00189   // Enable interrupts globally.
00190   Enable_global_interrupt();
00191 }

static void init_stdio ( void   )  [static]

Initializes STDIO.

Definition at line 162 of file nf_example.c.

References pm_freq_param.

Referenced by main().

00163 {
00164 #if __GNUC__ && __AVR32__
00165 
00166   // Initialize the USART used for STDIO.
00167   set_usart_base((void *)DBG_USART);
00168 
00169 #elif __ICCAVR32__
00170 
00171   // Initialize the USART used for STDIO.
00172   extern volatile avr32_usart_t *volatile stdio_usart_base;
00173   stdio_usart_base = DBG_USART;
00174 
00175 #endif
00176 
00177   // Initialize debug RS232 with PBA clock
00178   init_dbg_rs232(pm_freq_param.pba_f);
00179 }

static void init_sys_clocks ( void   )  [static]

Initializes the MCU system clocks.

Definition at line 142 of file nf_example.c.

References pm_freq_param.

Referenced by main().

00143 {
00144   // Set CPU and PBA clocks. A Flash wait state is added if necessarily
00145   pm_freq_param.cpu_f  =       12000000;
00146   pm_freq_param.pba_f    =     12000000;
00147   pm_freq_param.osc0_f     =   FOSC0;
00148   pm_freq_param.osc0_startup = OSC0_STARTUP;
00149 
00150   if( PM_FREQ_STATUS_FAIL==pm_configure_clocks(&pm_freq_param) )
00151     while(1);
00152 
00153 #if __GNUC__ && __AVR32__
00154   // Give the used PBA clock frequency to Newlib, so it can work properly.
00155   set_cpu_hz(pm_freq_param.pba_f);
00156 #endif
00157 }

int main ( void   ) 

Main function.

Definition at line 227 of file nf_example.c.

References G_N_BLOCKS, G_OFST_BLK_STATUS, init_stdio(), init_sys_clocks(), M_ID_MICRON, nf_block_2_page(), nf_erase_block(), nf_init(), NF_N_DEVICES, nf_open_page_read(), nf_open_page_write(), NF_PAGE_PROGRAM_CMD, nf_rd_data(), nf_read_id(), NF_READ_ID_CMD, nf_reset_nands(), nf_select(), NF_SPARE_POS, nf_unprotect(), nf_wait_busy(), nf_wr_cmd(), nf_wr_data(), and pm_freq_param.

00228 {
00229   Bool   valid_block_found[NF_N_DEVICES];
00230   U32    u32_nf_ids, i_dev, i_block;
00231   U8     maker_id, device_id, byte3;
00232   U32    i, time_s, time_e;
00233   U8     data;
00234 
00235   // start init
00236   init_sys_clocks();
00237   init_stdio();
00238   
00239 #ifdef NF_ADDON
00240   // Unselect NF on board
00241   gpio_set_gpio_pin(AVR32_PIN_PX53);
00242   gpio_set_gpio_pin(AVR32_PIN_PX52);
00243 #endif
00244     
00245   nf_init(pm_freq_param.cpu_f);
00246   nf_unprotect();
00247 
00248   printf("\x0C");
00249   printf("Nand Flash example.\r\n===================\r\n\r\n");
00250 
00251   // - Simple test of the NF communication through the SMC.
00252   // - Find all bad blocks.
00253   // - Find a valid block for the remaining tests.
00254   nf_reset_nands(NF_N_DEVICES);
00255 
00256   printf("\tDetecting Nand Flash device(s).\r\n");
00257   for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00258   {
00259     // Performs some init here...
00260     valid_block_found[i_dev] = FALSE;
00261 
00262     // Test Maker and Device ids
00263     u32_nf_ids = nf_read_id( NF_READ_ID_CMD, i_dev );
00264     maker_id  = MSB0(u32_nf_ids);
00265     device_id = MSB1(u32_nf_ids);
00266     byte3     = MSB3(u32_nf_ids);
00267     printf("\t\tNF %ld: [Maker=0x%02x] [Device=0x%02x] [byte3=0x%02x]\r\n", i_dev, maker_id, device_id, byte3);
00268     if( maker_id==M_ID_MICRON )
00269     {
00270       printf("\t\t       Micron chip");
00271       if( (device_id==0xDA) && (byte3==0x15) )
00272         printf("- MT29F2G08AACWP device\r\n");
00273       else if( (device_id==0xDA) && (byte3==0x95) )
00274         printf("- MT29F2G08AADWP device\r\n");
00275       else
00276       {
00277         printf("- *** Error: unexpected chip detected. Please check the board settings and hardware.\r\n");
00278         return -1;
00279       }
00280     }
00281     else
00282     {
00283       printf("\t\t       *** Error: unexpected chip detected. Please check the board settings and hardware.\r\n");
00284       return -1;
00285     }
00286   }
00287 
00288   printf("\r\n\tTesting bad blocks.\r\n");
00289   for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00290   {
00291     printf("\t\tNF %ld:\r\n", i_dev);
00292     nf_select(i_dev);
00293     for( i_block=0 ; i_block<G_N_BLOCKS ; i_block++ )
00294     {
00295       nf_open_page_read( nf_block_2_page(i_block), NF_SPARE_POS + G_OFST_BLK_STATUS );
00296       if( (nf_rd_data()!=0xFF) )
00297       { // The block is bad.
00298         printf("\t\t\tBlock %ld (0x%lx) is bad.\r\n", i_block, i_block);
00299       }
00300       else
00301       {
00302         if( !valid_block_found[i_dev] )
00303         {
00304           valid_block_found[i_dev]= TRUE;
00305           valid_block_addr[i_dev] = i_block;
00306           printf("\t\t\tFirst valid block is at address %ld (0x%lx).\r\n", i_block, i_block);
00307         }
00308       }
00309     }
00310   }
00311 
00312   for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00313     if( !valid_block_found[i_dev] )
00314     {
00315       printf("Error %d\r\n", __LINE__);
00316       return 0;
00317     }
00318 
00319 
00320 
00321   // - Ensure good NF behaviour through simple commands.
00322   //   Erase, Program, Read
00323   // - Measures NF timings.
00324   printf("\r\n\tMeasuring NF timings.\r\n");
00325   for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00326   {
00327     printf("\t\tNF %ld:\r\n", i_dev);
00328     nf_select(i_dev);
00329     nf_erase_block( nf_block_2_page(valid_block_addr[0]), FALSE);
00330     time_s = Get_sys_count();
00331     nf_wait_busy();
00332     time_e = Get_sys_count();
00333 
00334     // Verify that the block is erased.
00335     nf_open_page_read( nf_block_2_page(valid_block_addr[0]), 0);
00336     for( i= 0; i<2048 ; i++ )
00337     {
00338       data = nf_rd_data();
00339       if( data!=0xFF )
00340       {
00341         printf("\tError: offset %d is not erased (read %d).\r\n", (U8)i, data);
00342         return 0;
00343       }
00344     }
00345     printf("\t\t\tTime to erase a page:%ld cy (%ld us)\r\n", time_e-time_s, cpu_cy_2_us(time_e-time_s, pm_freq_param.cpu_f));
00346 
00347     nf_open_page_write( nf_block_2_page(valid_block_addr[0]), 0);
00348     for( i=0 ; i<2048 ; i++ )
00349       nf_wr_data(i%256);
00350     nf_wr_cmd(NF_PAGE_PROGRAM_CMD);
00351 
00352     time_s = Get_sys_count();
00353     nf_wait_busy();
00354     time_e = Get_sys_count();
00355     printf("\t\t\tTime to program a page:%ld cy (%ld us)\r\n", time_e-time_s, cpu_cy_2_us(time_e-time_s, pm_freq_param.cpu_f));
00356 
00357     time_s = Get_sys_count();
00358     nf_open_page_read( nf_block_2_page(valid_block_addr[0]), 0);
00359     time_e = Get_sys_count();
00360     printf("\t\t\tTime to access to a page:%ld cy (%ld us)\r\n", time_e-time_s, cpu_cy_2_us(time_e-time_s, pm_freq_param.cpu_f));
00361     for( i= 0; i<2048 ; i++ )
00362     {
00363       data = nf_rd_data();
00364       if( data!= i%256)
00365       {
00366         printf("\tError: expect %d, read %d\r\n", (U8)i, data);
00367         return 0;
00368       }
00369     }
00370   }
00371  
00372   printf("Example DONE\r\n");
00373 
00374   return 0;
00375 }

U32 nf_block_2_page ( U16  block_addr  ) 

Convert a block number into a page number.

Definition at line 216 of file nf_example.c.

References G_SHIFT_BLOCK_PAGE.

Referenced by main().

00217 {
00218    //#define G_SHIFT_BLOCK_PAGE 6
00219    return (U32)block_addr<<G_SHIFT_BLOCK_PAGE;
00220 }


Variable Documentation

pm_freq_param_t pm_freq_param

Definition at line 102 of file nf_example.c.

Referenced by init_stdio(), init_sys_clocks(), and main().

U16 valid_block_addr[NF_N_DEVICES]

Definition at line 222 of file nf_example.c.


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