This file contains basic functions to interface a nandflash through the SMC.
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. |
Bool nf_check_status | ( | void | ) |
Check the status of the selected device.
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.
nb_dev | number of device |
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.
page_addr | absolute source page address of the block |
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
page_addr | absolute page address of the block | |
force_erase | TRUE forces erasing, FALSE erases the block (if not bad) |
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 | ) |
void nf_init | ( | U32 | hsb_f_hz | ) |
Initializes the Nand Flash Controller and low level driver.
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.
page_addr | absolute page address of the block |
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.
page_addr | absolute page address of the block | |
byte_addr | relative byte address inside the page. |
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.
page_addr | absolute page address of the block | |
byte_addr | relative byte address inside the page. |
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.
read_id_cmd | Read_id command (NF_READ_ID_CMD, NF_READ_ID2_CMD) | |
nf_num | Nand Flash number |
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.
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 | ) |
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.
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.
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.
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. |
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 }