00001
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #define _TRACE_ (DISABLE)
00050 #include "config.h"
00051 #include "conf_nf.h"
00052 #include "nf.h"
00053 #include "nf_drv.h"
00054 #include "nf_mngt.h"
00055 #include "lib_mcu/debug.h"
00056
00057
00058 #ifndef __GNUC__
00059 extern __no_init volatile xdata Byte nf_send_cmd At(NF_CMD_LATCH_ENABLE_ADD);
00060 extern __no_init volatile xdata Byte nf_send_add At(NF_ADD_LATCH_ENABLE_ADD);
00061 extern __no_init volatile xdata Byte nf_data At(NF_ADDRESS_CMD_DATA);
00062 #else
00063 extern volatile unsigned char nf_send_cmd __attribute__ ((section (".nf_cmd")));
00064 extern volatile unsigned char nf_send_add __attribute__ ((section (".nf_add")));
00065 extern volatile unsigned char nf_data __attribute__ ((section (".nf_dat")));
00066 #endif
00067
00068
00069
00070
00071 #if (NF_GENERIC_DRIVER==TRUE) || (defined NF_AUTO_DETECT_2KB) ||(defined NF_AUTO_DETECT_512B)
00072 extern _MEM_TYPE_SLOW_ U8 g_n_zones ;
00073 extern _MEM_TYPE_SLOW_ U16 g_n_blocks ;
00074 #endif
00075 extern _MEM_TYPE_SLOW_ U8 g_page_buffer[NF_FULL_PAGE_BUFFER_SIZE] ;
00076 extern _MEM_TYPE_BIT_ bit g_nf_init ;
00077 extern _MEM_TYPE_SLOW_ U16 g_last_sub_lut_log_sz ;
00078 extern _MEM_TYPE_SLOW_ U16 g_sub_lut_log_sz ;
00079 Bool g_is_found_lut ;
00080 Bool g_is_found_fbb ;
00081 extern Bool g_fatal ;
00082 _MEM_TYPE_SLOW_ U8 g_n_real_sub_lut;
00083 _MEM_TYPE_SLOW_ U16 g_curr_block_addr[ NF_N_DEVICES];
00084 _MEM_TYPE_SLOW_ U8 g_byte[16] ;
00085 extern _MEM_TYPE_SLOW_ U8 g_n_sub_lut ;
00086 extern _MEM_TYPE_SLOW_ U16 g_lut_block_addr [ N_SUBLUT ] ;
00087 extern _MEM_TYPE_SLOW_ U8 g_lut_block_index[ N_SUBLUT ] ;
00088 static _MEM_TYPE_SLOW_ U8 s_nfd_rev ;
00089 extern _MEM_TYPE_SLOW_ U16 g_nf_first_block ;
00090 static _MEM_TYPE_SLOW_ U8 s_n_quarantine_blocks[NF_N_DEVICES] ;
00091 static _MEM_TYPE_SLOW_ U16 s_n_invalid_blocks[ NF_N_DEVICES] ;
00092 extern _MEM_TYPE_SLOW_ U16 g_n_export_blocks ;
00093 extern _MEM_TYPE_SLOW_ U16 g_n_free_blocks ;
00094 extern _MEM_TYPE_SLOW_ U16 g_fbb_block_addr ;
00095 extern _MEM_TYPE_SLOW_ U8 g_fbb_block_index ;
00096 extern _MEM_TYPE_SLOW_ U32 g_last_log_sector ;
00097 extern _MEM_TYPE_SLOW_ U32 g_copy_src ;
00098 extern _MEM_TYPE_SLOW_ U16 g_block_to_kill[ NF_N_DEVICES] ;
00099 extern _MEM_TYPE_FAST_ U32 g_phys_page_addr[NF_N_DEVICES] ;
00100 extern _MEM_TYPE_FAST_ U8 g_curr_dev_id ;
00101
00102 extern _MEM_TYPE_MEDFAST_ U16 g_log_block_id ;
00103
00104 extern _MEM_TYPE_SLOW_ Cache_lut g_cache_lut;
00105 extern _MEM_TYPE_SLOW_ Cache_fbb g_cache_fbb;
00106
00107
00108 #if (ERASING_ALL==ENABLE)
00109 static void ut_nfc_erase_all( void );
00110 #endif
00111
00112
00113 static void nf_init_buffer( void );
00114 static Status_bool nf_scan( void );
00115 static Status_bool nf_rebuild( void );
00116 static Bool is_nf_invalid( void );
00117
00118 static U16 nf_fetch_free_block( U8 i_dev );
00119
00120 static U8 nf_refine_index( U16 block_addr, U8 inc, U8 pattern) ;
00121
00122
00127 static void nf_init_buffer( void )
00128 {
00129 U16 u16_tmp;
00130 for ( u16_tmp=NF_FULL_PAGE_BUFFER_SIZE ; u16_tmp!=0 ; u16_tmp-=2 )
00131 {
00132 g_page_buffer[u16_tmp-1]=0xFF;
00133 g_page_buffer[u16_tmp-2]=0xFF;
00134 }
00135 }
00136
00137
00138
00148 void nf_init ( void )
00149 {
00150 g_nf_init=FALSE;
00151
00152
00153 #if (NF_GENERIC_DRIVER==TRUE)
00154 #error Check this init...
00155 g_n_zones = NF_N_ZONES;
00156 g_n_blocks = NF_N_BLOCKS;
00157 g_shift_block_page = NF_SHIFT_BLOCK_PAGE;
00158 g_shift_page_byte = NF_SHIFT_PAGE_BYTE;
00159 s_shift_sector_byte = NF_SHIFT_SECTOR_BYTE;
00160 g_n_row_cycles = NF_N_ROW_CYCLES;
00161
00162 if ( Is_nf_2k() )
00163 {
00164 g_ofst_blk_status = 0;
00165 }
00166 if ( Is_nf_512() )
00167 {
00168 g_ofst_blk_status = 5;
00169 }
00170
00171 s_shift_log_page_sector = G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE + NF_SHIFT_N_DEVICES;
00172 s_shift_log_block_sector = s_shift_log_page_sector + G_SHIFT_BLOCK_PAGE;
00173 #endif
00174
00175 g_cache_lut.ctrl.valid = FALSE; g_cache_lut.ctrl.dirty = FALSE;
00176 g_cache_fbb.ctrl.valid = FALSE; g_cache_fbb.ctrl.dirty = FALSE;
00177 g_last_log_sector= 0xFFFFFFFF;
00178 }
00179
00180
00193 Status_bool nf_verify_resume( void )
00194 {
00195 U8 u8_nb_loop;
00196 Bool status_bool;
00197
00198
00199 #if (ERASING_ALL==ENABLE)
00200 ut_nfc_erase_all();
00201 #endif
00202
00203 status_bool = nf_scan();
00204
00205 if(( PASS!=status_bool )
00206 || ( is_nf_invalid() )
00207 ) {
00208
00209
00210 u8_nb_loop = 0;
00211 while( 1 )
00212 {
00213 u8_nb_loop++;
00214 if( u8_nb_loop > 2 )
00215 {
00216 status_bool=FAIL;
00217 break;
00218 }
00219 nf_cleanup_memory();
00220 if( PASS != nf_scan() )
00221 continue;
00222 if( PASS != nf_rebuild() )
00223 continue;
00224 status_bool = PASS;
00225 break;
00226 }
00227 }
00228 if (status_bool==PASS)
00229 {
00230 g_nf_init = TRUE;
00231 Nf_check_lut();
00232 Nf_check_fbb( FALSE );
00233 }
00234
00235 return status_bool;
00236 }
00237
00238
00239
00247 void nf_cleanup_memory(void)
00248 {
00249 U8 i_dev =0;
00250 U16 i_block=0;
00251 U8 block_valid;
00252 U8 block_id;
00253
00254
00255
00256
00257
00258
00259 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00260 {
00261
00262
00263 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00264
00265 for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00266 {
00267
00268 nfc_open_page_read( nf_block_2_page(i_block), NF_SPARE_POS);
00269 block_valid = Nfc_rd_data_fetch_next();
00270 block_id = Nfc_rd_data() ;
00271
00272 if ( block_valid!=0xFF )
00273 {
00274 continue;
00275 }
00276
00277 if(( NFC_BLK_ID_SUBLUT==block_id )
00278 || ( NFC_BLK_ID_FBB ==block_id ))
00279 {
00280 nfc_erase_block( nf_block_2_page(i_block), TRUE ) ;
00281 if ( FAIL==nfc_check_status() )
00282 {
00283 nfc_mark_bad_block( nf_block_2_page(i_block) );
00284 }
00285 }
00286 }
00287 }
00288 }
00289
00290
00291
00300 static Status_bool nf_scan( void )
00301 {
00302 U8 i_dev =0;
00303 U16 i_block=0;
00304 U8 n_quarantine_blocks=0;
00305 U16 n_invalid_blocks=0;
00306
00307 g_last_sub_lut_log_sz =(U16)-1;
00308 g_sub_lut_log_sz =(U16)NF_SUBLUT_SIZE/NF_N_DEVICES;
00309
00310
00311
00312
00313 g_is_found_lut =FALSE;
00314 g_is_found_fbb =FALSE;
00315 g_fatal =FALSE;
00316 g_n_real_sub_lut=0;
00317
00318
00319
00320
00321
00322
00323 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00324 {
00325 n_invalid_blocks = 0;
00326 n_quarantine_blocks= 0;
00327 g_curr_block_addr[i_dev]= G_N_BLOCKS -1;
00328
00329 trace("Device "); trace_hex(i_dev); trace("\n\r");
00330 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00331
00332 for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00333 {
00334 nfc_read_spare_byte( g_byte, 16, nf_block_2_page(i_block) );
00335 if ( g_byte[G_OFST_BLK_STATUS]!=0xFF )
00336 {
00337 n_invalid_blocks +=1 ;
00338 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): bad Block\n\r");
00339 continue;
00340 }
00341
00342 if(( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_SUBLUT )
00343 && ( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_FBB )
00344 && ( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_QUARANTINE )
00345 && ( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_DATA ))
00346 {
00347 n_invalid_blocks +=1;
00348 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): Unknown\n\r");
00349 continue;
00350 }
00351 else if ( g_byte[NFC_SPARE_OFST_1_BLK_ID]==NFC_BLK_ID_QUARANTINE )
00352 {
00353 n_quarantine_blocks +=1;
00354 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): Quarantine\n\r");
00355 continue;
00356 }
00357 else if ( g_byte[NFC_SPARE_OFST_1_BLK_ID]==NFC_BLK_ID_SUBLUT )
00358 {
00359 n_invalid_blocks +=1;
00360 if ( i_dev==S_MNGT_DEV )
00361 {
00362 U8 sub_lut_id = g_byte[NFC_SPARE_OFST_2_BYTE_2];
00363 g_n_sub_lut = g_byte[NFC_SPARE_OFST_4_BYTE_4];
00364 g_is_found_lut = TRUE;
00365 g_n_real_sub_lut++;
00366 g_lut_block_addr[sub_lut_id] = i_block;
00367 if ( sub_lut_id==(g_n_sub_lut-1) )
00368 {
00369 MSB(g_last_sub_lut_log_sz)= g_byte[NFC_SPARE_OFST_6_LBA ];
00370 LSB(g_last_sub_lut_log_sz)= g_byte[NFC_SPARE_OFST_6_LBA+1];
00371 }
00372 g_lut_block_index[sub_lut_id]= nf_refine_index(i_block, 1, NFC_BLK_ID_SUBLUT);
00373 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): SUB-LUT (id ");trace_hex(sub_lut_id);trace(" ofst "); trace_hex(g_lut_block_index[sub_lut_id]); trace(")\n\r");
00374 continue ;
00375 }
00376 else
00377 {
00378 g_fatal=TRUE;
00379 break;
00380 }
00381 }
00382
00383 else if ( g_byte[NFC_SPARE_OFST_1_BLK_ID]==NFC_BLK_ID_FBB )
00384 {
00385 n_invalid_blocks +=1;
00386 if ( i_dev==S_MNGT_DEV )
00387 {
00388 if ( TRUE==g_is_found_fbb )
00389 {
00390 g_fatal=TRUE;
00391 break;
00392 }
00393 g_fbb_block_addr = i_block;
00394 g_fbb_block_index = nf_refine_index(i_block, 1, NFC_BLK_ID_FBB);
00395 nfc_read_spare_byte( g_byte, 16, nf_block_2_page(i_block) + (U32)g_fbb_block_index );
00396 if( NFC_OFST_6_FBB_VALID!=g_byte[NFC_SPARE_OFST_6_LBA] )
00397 {
00398 g_fatal=TRUE;
00399 break;
00400 }
00401
00402 MSB(g_n_free_blocks) = g_byte[NFC_SPARE_OFST_2_BYTE_2];
00403 LSB(g_n_free_blocks) = g_byte[NFC_SPARE_OFST_3_BYTE_3];
00404 s_nfd_rev = g_byte[NFC_SPARE_OFST_4_BYTE_4];
00405 MSB(g_n_export_blocks) = g_byte[NFC_SPARE_OFST_EXPORT];
00406 LSB(g_n_export_blocks) = g_byte[NFC_SPARE_OFST_EXPORT+1];
00407 trace(" g_n_free_blocks="); trace_hex16(g_n_free_blocks); trace_nl();
00408 trace(" g_n_export_blocks="); trace_hex16(g_n_export_blocks); trace_nl();
00409 g_is_found_fbb=TRUE;
00410 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): FBB (ofst "); trace_hex( g_fbb_block_index ); trace(")\n\r");
00411 continue ;
00412 }
00413 else
00414 {
00415 g_fatal=TRUE;
00416 break;
00417 }
00418 }
00419 }
00420
00421
00422
00423 s_n_invalid_blocks[ i_dev]= n_invalid_blocks;
00424 s_n_quarantine_blocks[i_dev]= n_quarantine_blocks;
00425
00426 if ( TRUE==g_fatal ) { break; }
00427 }
00428
00429 return (g_fatal==TRUE) ? FAIL: PASS;
00430 }
00431
00432
00441 static Bool is_nf_invalid ( void )
00442 {
00443 if(
00444 ( FALSE==g_is_found_lut )
00445 || ( FALSE==g_is_found_fbb )
00446 ) {
00447 g_fatal=TRUE;
00448 }
00449
00450
00451
00452 if(( TRUE ==g_is_found_lut )
00453 && ( g_n_sub_lut!=g_n_real_sub_lut ))
00454 {
00455 g_fatal=TRUE;
00456 }
00457
00458
00459 if ( (U16)-1==g_n_export_blocks ) { g_fatal=TRUE; }
00460 if ( 0==g_n_export_blocks ) { g_fatal=TRUE; }
00461 if ( (U16)-1==g_last_sub_lut_log_sz ) { g_fatal=TRUE; }
00462
00463
00464
00465 if ( s_nfd_rev!=NFC_OFST_4_FBB_DRIVER_RELEASE )
00466 {
00467 g_fatal=TRUE;
00468 }
00469
00470 return g_fatal;
00471 }
00472
00473
00474
00487 static Status_bool nf_rebuild ( void )
00488 {
00489 Status_bool status_bool=PASS;
00490 Bool b_duplicate;
00491 U8 i_sub_lut;
00492 U8 i_dev =0;
00493 _MEM_TYPE_SLOW_ U16 i_block=0;
00494 _MEM_TYPE_SLOW_ U16 u16_tmp;
00495 _MEM_TYPE_SLOW_ U16 sub_lut_log_sz;
00496 _MEM_TYPE_SLOW_ U16 log_block_addr;
00497 _MEM_TYPE_SLOW_ U16 log_block_addr_min;
00498 _MEM_TYPE_SLOW_ U16 log_block_addr_max;
00499
00500
00501
00502 s_n_invalid_blocks[S_MNGT_DEV] +=
00503 1
00504 + (G_N_BLOCKS*NF_N_DEVICES)/NF_SUBLUT_SIZE
00505 ;
00506
00507
00508
00509 u16_tmp=s_n_invalid_blocks[0] ;
00510 for ( i_dev=1 ; i_dev<NF_N_DEVICES ; i_dev++ )
00511 {
00512 u16_tmp=Max( u16_tmp, s_n_invalid_blocks[i_dev] );
00513 }
00514
00515
00516
00517 i_sub_lut=s_n_quarantine_blocks[0] ;
00518 for ( i_dev=1 ; i_dev<NF_N_DEVICES ; i_dev++ )
00519 {
00520 i_sub_lut=Max( i_sub_lut, s_n_quarantine_blocks[i_dev] );
00521 }
00522
00523 sub_lut_log_sz = (U16)NF_N_DEVICES*(G_N_BLOCKS -g_nf_first_block -u16_tmp);
00524
00525
00526
00527 Assert( u16_tmp<(G_N_BLOCKS -g_nf_first_block) );
00528 g_n_export_blocks= (U16)( ((U32)( (U32)sub_lut_log_sz ) * 1000) / 1024);
00529 g_n_export_blocks= Align_down( g_n_export_blocks, NF_N_DEVICES);
00530
00531 g_n_free_blocks = (U16)sub_lut_log_sz - g_n_export_blocks;
00532 g_n_free_blocks -= (U16)NF_N_DEVICES*i_sub_lut;
00533
00534 if( g_n_free_blocks<=NF_LOW_N_FREE_THRESHOLD )
00535 {
00536 while(1);
00537 }
00538
00539 Assert( g_n_free_blocks>0 );
00540 Assert( g_n_free_blocks<(1L<<NF_SHIFT_PAGE_BYTE) );
00541
00542
00543
00544
00545 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV);
00546 g_fbb_block_addr = nf_fetch_free_block(S_MNGT_DEV);
00547 nfc_erase_block( nf_block_2_page( g_fbb_block_addr ), TRUE );
00548 g_n_sub_lut= 0;
00549 u16_tmp = g_n_export_blocks;
00550
00551 while(1)
00552 {
00553 Assert( g_n_sub_lut<N_SUBLUT );
00554 g_lut_block_addr [g_n_sub_lut]=nf_fetch_free_block(S_MNGT_DEV);
00555 g_lut_block_index[g_n_sub_lut]=0;
00556 nfc_erase_block( nf_block_2_page( g_lut_block_addr [g_n_sub_lut] ), TRUE );
00557 g_n_sub_lut++;
00558 if( u16_tmp>NF_SUBLUT_SIZE ) u16_tmp-=NF_SUBLUT_SIZE;
00559 else break;
00560 }
00561 g_last_sub_lut_log_sz=u16_tmp/NF_N_DEVICES;
00562
00563
00564
00565 for ( i_sub_lut=0 ; i_sub_lut<g_n_sub_lut ; )
00566 {
00567 U8 n_sublut_in_buf = g_n_sub_lut - i_sub_lut;
00568
00569 log_block_addr_max =
00570 log_block_addr_min = (U16)i_sub_lut<<(NF_SHIFT_SUBLUT_PHYS-NF_SHIFT_N_DEVICES);
00571
00572 if( n_sublut_in_buf>(NF_PAGE_BUFFER_SIZE/(2*NF_SUBLUT_SIZE)) )
00573 {
00574 n_sublut_in_buf = NF_PAGE_BUFFER_SIZE/(2*NF_SUBLUT_SIZE);
00575 log_block_addr_max += ((U16)n_sublut_in_buf)*g_sub_lut_log_sz;
00576 }
00577 else
00578 {
00579 log_block_addr_max += ((U16)n_sublut_in_buf-1)*g_sub_lut_log_sz +g_last_sub_lut_log_sz;
00580 }
00581
00582 nf_init_buffer();
00583
00584
00585
00586 u16_tmp=g_n_export_blocks/NF_N_DEVICES;
00587
00588 b_duplicate=FALSE;
00589
00590 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00591 {
00592 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00593
00594 g_block_to_kill[i_dev]=0xFFFF;
00595
00596 for ( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00597 {
00598 nfc_read_spare_byte( g_byte, 8, nf_block_2_page(i_block) );
00599 if(( 0xFF !=g_byte[G_OFST_BLK_STATUS ] )
00600 || ( NFC_BLK_ID_DATA!=g_byte[NFC_SPARE_OFST_1_BLK_ID ] )
00601 || ( ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA ] )
00602 && ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA+1 ] )
00603 )
00604 ) {
00605 continue;
00606 }
00607
00608 MSB(log_block_addr) = g_byte[NFC_SPARE_OFST_6_LBA ];
00609 LSB(log_block_addr) = g_byte[NFC_SPARE_OFST_6_LBA+1];
00610
00611 if( log_block_addr>=u16_tmp )
00612 {
00613
00614
00615 nfc_erase_block( nf_block_2_page(i_block), TRUE );
00616 status_bool=FAIL;
00617 }
00618
00619 if(( log_block_addr>=log_block_addr_min )
00620 && ( log_block_addr< log_block_addr_max ))
00621 {
00622 U16 ofst=2*((U16)i_dev + (log_block_addr%((U16)NF_PAGE_BUFFER_SIZE/2/NF_N_DEVICES))*NF_N_DEVICES) ;
00623 if(
00624 ( 0xFF==g_page_buffer[ ofst ] )
00625 && ( 0xFF==g_page_buffer[ ofst +1 ] )
00626 )
00627 {
00628 Assert( ( ofst +1 ) < NF_PAGE_BUFFER_SIZE );
00629 g_page_buffer[ ofst ] = MSB(i_block);
00630 g_page_buffer[ ofst +1 ] = LSB(i_block);
00631 }
00632 else
00633 {
00634
00635 _MEM_TYPE_SLOW_ U16 tmp_addr;
00636 MSB(tmp_addr)=g_page_buffer[ ofst ];
00637 LSB(tmp_addr)=g_page_buffer[ ofst +1 ];
00638
00639
00640 if(0xFFFF!=g_block_to_kill[i_dev])
00641 {
00642 nfc_erase_block( nf_block_2_page(g_block_to_kill[i_dev]), TRUE );
00643 return FAIL;
00644 }
00645
00646 b_duplicate=TRUE;
00647 g_log_block_id=log_block_addr;
00648
00649 nfc_open_page_read(
00650 nf_block_2_page(i_block)
00651 , NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3
00652 );
00653 if( NFC_OFST_3_DATA_DST!=Nfc_rd_data_fetch_next() )
00654 {
00655 trace("1. Src block="); trace_hex16(i_block); trace_nl();
00656 trace("1. Dst block="); trace_hex16(tmp_addr); trace_nl();
00657
00658
00659
00660 g_block_to_kill[i_dev]=i_block;
00661 g_phys_page_addr[i_dev] = nf_block_2_page( tmp_addr );
00662 }
00663 else
00664 {
00665 trace("2. Src block="); trace_hex16(tmp_addr); trace_nl();
00666 trace("2. Dst block="); trace_hex16(i_block); trace_nl();
00667
00668
00669
00670 g_block_to_kill[i_dev]= tmp_addr ;
00671 g_page_buffer[ ofst ]=MSB(i_block);
00672 g_page_buffer[ ofst +1 ]=LSB(i_block);
00673 g_phys_page_addr[i_dev] = nf_block_2_page( i_block );
00674 }
00675 }
00676 }
00677 }
00678 }
00679
00680 if( b_duplicate )
00681 {
00682 U8 i_page;
00683 U8 i_sect;
00684
00685 trace("recovery\n\r");
00686
00687 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00688 {
00689 if( 0xFFFF==g_block_to_kill[i_dev] )
00690 {
00691
00692 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00693 {
00694 if( 0xFFFF!=g_block_to_kill[i_dev] )
00695 {
00696 nfc_erase_block( nf_block_2_page(g_block_to_kill[i_dev]), TRUE );
00697 }
00698 }
00699 return FAIL;
00700 }
00701 }
00702
00703
00704 g_curr_dev_id=0;
00705 g_last_log_sector= ((U32)g_log_block_id) << S_SHIFT_LOG_BLOCK_SECTOR;
00706
00707
00708 for( i_page=0 ; i_page<SIZE_BLOCK_PAGE ; i_page++ )
00709 {
00710 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);
00711 for( i_sect=0 ; i_sect<SIZE_PAGE_SECTOR ; i_sect++ )
00712 {
00713 nfc_open_page_read(
00714 g_phys_page_addr[g_curr_dev_id]
00715 , NF_SPARE_POS + (((U16)i_sect)*16) + NFC_SPARE_OFST_6_LBA
00716 );
00717 if(( 0xFF==Nfc_rd_data_fetch_next() )
00718 && ( 0xFF==Nfc_rd_data_fetch_next() ))
00719 goto recovery_exit;
00720 else
00721 {
00722 g_last_log_sector++;
00723 trace("g_last_log_sector="); trace_hex32(g_last_log_sector); trace_nl();
00724 }
00725 }
00726 g_phys_page_addr[g_curr_dev_id]++;
00727 g_curr_dev_id++;
00728 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; }
00729 trace("g_curr_dev_id="); trace_hex(g_curr_dev_id); trace_nl();
00730 trace("g_phys_page_addr="); trace_hex32(g_phys_page_addr[g_curr_dev_id]); trace_nl();
00731 }
00732 recovery_exit:
00733 trace("recovery stop on g_last_log_sector="); trace_hex32(g_last_log_sector); trace_nl();
00734 trace("g_curr_dev_id="); trace_hex(g_curr_dev_id); trace_nl();
00735 trace("g_phys_page_addr="); trace_hex32(g_phys_page_addr[g_curr_dev_id]); trace_nl();
00736
00737 nf_copy_tail();
00738 return FAIL;
00739 }
00740
00741
00742
00743 if( PASS!=status_bool ) { return FAIL; }
00744
00745
00746
00747 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00748 {
00749 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00750
00751 for(u16_tmp=0
00752 ; u16_tmp<(log_block_addr_max-log_block_addr_min)
00753 ; u16_tmp++ )
00754 {
00755 U16 ofst=2*((U16)i_dev + u16_tmp*NF_N_DEVICES);
00756 if(( 0xFF==g_page_buffer[ofst ] )
00757 && ( 0xFF==g_page_buffer[ofst+1] ))
00758 {
00759 i_block=nf_fetch_free_block(i_dev);
00760 Assert( ofst+1<NF_PAGE_BUFFER_SIZE);
00761 g_page_buffer[ofst ] = MSB(i_block);
00762 g_page_buffer[ofst+1] = LSB(i_block);
00763 }
00764 }
00765 }
00766
00767
00768
00769
00770 for( ; n_sublut_in_buf!=0 ; n_sublut_in_buf--, i_sub_lut++ )
00771 {
00772 sub_lut_log_sz= ( i_sub_lut==(g_n_sub_lut-1) ) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ;
00773
00774
00775
00776 status_bool = nf_write_lut(i_sub_lut%(NF_PAGE_BUFFER_SIZE/(2*NF_SUBLUT_SIZE)), i_sub_lut, sub_lut_log_sz);
00777 if ( PASS!=status_bool )
00778 {
00779 nfc_mark_bad_block( nf_block_2_page( g_lut_block_addr[i_sub_lut] ) );
00780 return FAIL;
00781 }
00782 }
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00794 {
00795 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00796
00797 for ( u16_tmp=0 ; u16_tmp<(g_n_free_blocks/NF_N_DEVICES) ; u16_tmp++ )
00798 {
00799
00800 #define OFST (2*(i_dev + u16_tmp*NF_N_DEVICES))
00801 i_block=nf_fetch_free_block(i_dev);
00802 nfc_erase_block( nf_block_2_page(i_block), TRUE );
00803 Assert( OFST <NF_PAGE_BUFFER_SIZE);
00804 Assert( OFST +1<NF_PAGE_BUFFER_SIZE);
00805 Assert( i_block>=g_nf_first_block );
00806 Assert( i_block< G_N_BLOCKS );
00807 g_page_buffer[OFST ] = MSB(i_block);
00808 g_page_buffer[OFST +1] = LSB(i_block);
00809 #undef OFST
00810 }
00811 }
00812
00813
00814
00815
00816
00817 g_fbb_block_index=0;
00818 status_bool = nf_write_fbb();
00819 if ( PASS!=status_bool )
00820 {
00821 nfc_mark_bad_block( nf_block_2_page( g_fbb_block_addr ) );
00822 return FAIL;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831 return PASS;
00832 }
00833
00834
00835
00844 static U16 nf_fetch_free_block(U8 i_dev)
00845 {
00846
00847 U16 block_addr= g_curr_block_addr[i_dev];
00848
00849 while ( block_addr>=g_nf_first_block )
00850 {
00851 nfc_read_spare_byte( g_byte, 8, nf_block_2_page( block_addr ) );
00852 if(( 0xFF ==g_byte[G_OFST_BLK_STATUS ] )
00853 && ( NFC_BLK_ID_DATA==g_byte[NFC_SPARE_OFST_1_BLK_ID ] )
00854 && ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA ] )
00855 && ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA+1 ] ))
00856 {
00857
00858
00859 Assert( NFC_BLK_ID_SUBLUT!=g_byte[NFC_SPARE_OFST_1_BLK_ID] );
00860 Assert( NFC_BLK_ID_FBB !=g_byte[NFC_SPARE_OFST_1_BLK_ID] );
00861
00862
00863
00864 g_curr_block_addr[i_dev] = block_addr-1;
00865 return block_addr;
00866 }
00867 block_addr-=1 ;
00868 }
00869
00870
00871 nfc_erase_block( nf_block_2_page( g_fbb_block_addr ), TRUE );
00872 while(1);
00873 Assert( FALSE ) ;
00874 }
00875
00876
00877
00891 static U8 nf_refine_index(
00892 U16 block_addr
00893 , U8 inc
00894 , U8 pattern)
00895 {
00896 _MEM_TYPE_SLOW_ U8 u8_tmp;
00897 _MEM_TYPE_SLOW_ U8 val=0;
00898 do
00899 {
00900 val+= inc;
00901 if( val>=SIZE_BLOCK_PAGE )
00902 { break; }
00903 nfc_open_page_read(
00904 nf_block_2_page(block_addr) + val
00905 , NF_SPARE_POS+NFC_SPARE_OFST_1_BLK_ID
00906 );
00907 u8_tmp = Nfc_rd_data();
00908 } while( pattern==u8_tmp );
00909 val-= inc;
00910 Assert( val<(1<<G_SHIFT_BLOCK_PAGE) );
00911 return val;
00912 }
00913
00914
00915
00916 #if (ERASING_ALL==ENABLE)
00917 static void ut_nfc_erase_all( void )
00918 {
00919 _MEM_TYPE_SLOW_ U8 i_dev =0;
00920 _MEM_TYPE_SLOW_ U16 i_block=0;
00921 _MEM_TYPE_SLOW_ U32 page_addr;
00922
00923 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00924 {
00925
00926
00927 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00928
00929 for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00930 {
00931 page_addr= (U32)i_block<<NF_SHIFT_BLOCK_PAGE;
00932 nfc_erase_block( page_addr, FALSE ) ;
00933 }
00934 }
00935 }
00936 #endif
00937