#include "config.h"#include "conf_nf.h"#include "nf.h"#include "nf_drv.h"
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] |
Definition in file nf_drv.c.
| __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 }
Tests the Nand Flash configuration.
The function verifies that the NF connected to device are properly declared in conf_nf.h.
| none |
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 }
| void nfc_reset_nands | ( | U8 | nb_dev | ) |
Reset all the NF devices.
| 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 }
| 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 }
| 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 }
| Status_bool nfc_check_status | ( | void | ) |
Check the status of the selected device.
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 }
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 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 }
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 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 }
| void nfc_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 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 }
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 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 }
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 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 }
| 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 }
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 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 }
| static Bool nfc_nf_is_ready | ( | void | ) | [static] |
Check the status Ready/Busy of the Nand Flash.
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 }
| U8 nfc_detect | ( | void | ) |
Read the ID of the Nand-Flash and update the global variable.
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 }
| void nfc_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 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 }
| U16 bad_block_table[100] |
1.5.3