#include "config.h"#include "conf_nf.h"#include "nf.h"#include "modules/control_access/ctrl_status.h"#include "nf_drv.h"
Go to the source code of this file.
Data Structures | |
| struct | Cache_lut |
| struct | Cache_fbb |
Defines | |
| #define | NF_BLK_RCV_NO_RECOVERY 0xA5 |
| #define | NF_BLK_RCV_PENDING_RECOVERY 0x5A |
| #define | NF_LOW_N_FREE_THRESHOLD 5 |
| #define | NF_PAGE_BUFFER_SIZE 2048 |
| #define | NF_FULL_PAGE_BUFFER_SIZE ( (NF_PAGE_BUFFER_SIZE) + (NF_PAGE_BUFFER_SIZE)/32 ) |
| #define | NF_SHIFT_SUBLUT_PHYS ( (G_SHIFT_PAGE_BYTE)-1 ) |
| #define | NF_SUBLUT_SIZE ( 1L<<(NF_SHIFT_SUBLUT_PHYS) ) |
| #define | NF_N_MAX_BLOCKS (8*1024) |
| #define | N_SUBLUT (NF_N_DEVICES*NF_N_MAX_BLOCKS/(512/2)) |
| #define | S_SHIFT_SECTOR_BYTE s_shift_sector_byte |
| #define | S_SHIFT_LOG_PAGE_SECTOR s_shift_log_page_sector |
| #define | S_SHIFT_LOG_BLOCK_SECTOR s_shift_log_block_sector |
| #define | S_MNGT_DEV ((NF_N_DEVICES)-1) |
| #define | Nf_check_fbb(x) nf_check_fbb(x) |
| #define | Nf_check_lut() nf_check_lut() |
| #define | CACHE_LUT_SIZE (NF_CACHE_LUT_LOG_SZ*NF_N_DEVICES) |
| #define | CACHE_FBB_SIZE (NF_CACHE_FBB_LOG_SZ*NF_N_DEVICES) |
Enumerations | |
| enum | Nf_sense { NF_READ = 0, NF_WRITE } |
Functions | |
| static void | nf_check_fbb (Bool b_ecc_err) |
| static void | nf_check_lut (void) |
| Ctrl_status | nf_test_unit_ready (void) |
| Initializes the NF driver on the first USB Test Unit Ready. | |
| Ctrl_status | nf_read_capacity (U32 *) |
| Returns the address of the last valid logical sector. | |
| Bool | nf_wr_protect (void) |
| Bool | nf_removal (void) |
| Ctrl_status | nf_10 (U32 addr, U16 nb_sector, Nf_sense) |
| Ctrl_status | nf_dfc_read_resume (void) |
| Ctrl_status | nf_dfc_write_resume (void) |
| Ctrl_status | nf_dfc_read_stop (U16 remaining_sectors) |
| Ctrl_status | nf_dfc_write_stop (U16 remaining_sectors) |
| This function must be called when a write10 operation (from USB) is finished Last page written is programmed and environment is saved. | |
| void | nf_dfc_read_standby (U16) |
| void | nf_dfc_read_restart (void) |
| U32 | nf_get_sectors_number (void) |
| Returns a pointer on the internal buffer address. | |
| U8 * | nf_get_buffer_addr (void) |
| void | nf_init (void) |
| Initializes the nand flash memory driver. | |
| Status_bool | nf_verify (void) |
| Ensure that the memory is in a good state before starting to use it. | |
| Status_bool | nf_verify_resume (void) |
| Ensure that the memory is in a good state before starting to use it. | |
| void | nf_cleanup_memory (void) |
| Cleanup the memory by erasing all the management blocks. | |
| void | nf_upload (U8 _MEM_TYPE_SLOW_ *, U8) |
| Upload packets of 16 bytes from the NAND Flash to RAM. | |
| void | nf_download (U8 _MEM_TYPE_SLOW_ *, U8) |
| Download packets of 16 bytes from RAM to the NAND Flash. | |
| U32 | nf_block_2_page (U16 block_addr) |
| void | nf_ecc_mngt (void) |
| void | nf_sync (void) |
| void | nf_copy (U32 copy_dst) |
| Copy a NF page to a new one. | |
| Status_bool | nf_write_lut (U8 pos, U8 i_sub_lut, U16 sub_lut_log_sz) |
| Writes a LUT in memory from a buffer. | |
| Status_bool | nf_write_fbb (void) |
| Writes the Free-blocks block into the Nand Flash. | |
| void | nf_cache_fbb_refill (void) |
| Reload the FBB cache memory, starting from 0. | |
| void | nf_swap (U8 dev_id, U8 u8_ofst_lut, U8 u8_ofst_fbb) |
| Swap 2 blocks from the LUT and the FBB. | |
| void | nf_cache_fbb_flush (Bool) |
| Flushes the FBB cache into a new FBB entry. | |
| void | nf_recovery (U16 block_1, U16 block_2) |
| void | nf_copy_tail (void) |
| Ctrl_status | nf_read_10 (U32 log_sector, U16 n_sectors) |
| This function initializes the Nand Flash for a read operation. | |
| Ctrl_status | nf_write_10 (U32 log_sector, U16 n_sectors) |
| This function initializes the Nand Flash for a write operation. | |
| Ctrl_status | nf_ram_2_nf (U32 addr, U8 *ram) |
| This fonction initialise the memory for a write operation from ram buffer. | |
| Ctrl_status | nf_nf_2_ram (U32 addr, U8 *ram) |
| This fonction read 1 sector from NF to ram buffer. | |
Variables | |
| _MEM_TYPE_SLOW_ U16 | _debug |
Definition in file nf_mngt.h.
| #define NF_LOW_N_FREE_THRESHOLD 5 |
| #define NF_PAGE_BUFFER_SIZE 2048 |
Definition at line 74 of file nf_mngt.h.
Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_rebuild(), and nf_write_lut().
| #define NF_FULL_PAGE_BUFFER_SIZE ( (NF_PAGE_BUFFER_SIZE) + (NF_PAGE_BUFFER_SIZE)/32 ) |
| #define NF_SHIFT_SUBLUT_PHYS ( (G_SHIFT_PAGE_BYTE)-1 ) |
Definition at line 80 of file nf_mngt.h.
Referenced by nf_cache_lut_flush(), nf_cache_lut_refill(), and nf_rebuild().
| #define NF_SUBLUT_SIZE ( 1L<<(NF_SHIFT_SUBLUT_PHYS) ) |
Definition at line 81 of file nf_mngt.h.
Referenced by nf_cache_lut_flush(), nf_rebuild(), and nf_scan().
| #define N_SUBLUT (NF_N_DEVICES*NF_N_MAX_BLOCKS/(512/2)) |
| #define S_SHIFT_SECTOR_BYTE s_shift_sector_byte |
Definition at line 101 of file nf_mngt.h.
Referenced by nf_get_sectors_number(), nf_init(), nf_nf_2_ram(), nf_ram_2_nf(), nf_translate(), and nf_write_10().
| #define S_SHIFT_LOG_PAGE_SECTOR s_shift_log_page_sector |
| #define S_SHIFT_LOG_BLOCK_SECTOR s_shift_log_block_sector |
Definition at line 103 of file nf_mngt.h.
Referenced by nf_copy_tail(), nf_ram_2_nf(), nf_rebuild(), nf_translate(), and nf_write_10().
| #define S_MNGT_DEV ((NF_N_DEVICES)-1) |
Definition at line 112 of file nf_mngt.h.
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_open_write(), nf_rebuild(), nf_scan(), nf_write_fbb(), and nf_write_lut().
| #define Nf_check_fbb | ( | x | ) | nf_check_fbb(x) |
Definition at line 118 of file nf_mngt.h.
Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_dfc_write_stop(), nf_translate(), and nf_verify_resume().
| #define Nf_check_lut | ( | ) | nf_check_lut() |
Definition at line 119 of file nf_mngt.h.
Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_dfc_write_stop(), nf_translate(), and nf_verify_resume().
| #define CACHE_LUT_SIZE (NF_CACHE_LUT_LOG_SZ*NF_N_DEVICES) |
Definition at line 134 of file nf_mngt.h.
Referenced by nf_cache_lut_flush(), nf_cache_lut_refill(), and nf_swap().
| #define CACHE_FBB_SIZE (NF_CACHE_FBB_LOG_SZ*NF_N_DEVICES) |
Definition at line 147 of file nf_mngt.h.
Referenced by nf_cache_fbb_flush(), nf_cache_fbb_refill(), and nf_swap().
| enum Nf_sense |
| static void nf_check_fbb | ( | Bool | b_ecc_err | ) | [static] |
| static void nf_check_lut | ( | void | ) | [static] |
| Ctrl_status nf_test_unit_ready | ( | void | ) |
Initializes the NF driver on the first USB Test Unit Ready.
| none |
Definition at line 215 of file nf_mngt.c.
References CTRL_FAIL, CTRL_GOOD, nf_verify(), nf_XMCR_disable(), nf_XMCR_enable(), and PASS.
00216 { 00217 Status_bool tmp_bool; 00218 00219 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00220 nf_XMCR_enable(); 00221 #endif 00222 00223 tmp_bool = nf_verify(); 00224 00225 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00226 nf_XMCR_disable(); 00227 #endif 00228 00229 return ( tmp_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL; 00230 }
| Ctrl_status nf_read_capacity | ( | U32 * | u32_nb_sector | ) |
Returns the address of the last valid logical sector.
| none |
Definition at line 240 of file nf_mngt.c.
References CTRL_FAIL, CTRL_GOOD, nf_get_sectors_number(), nf_verify(), nf_XMCR_disable(), nf_XMCR_enable(), and PASS.
00241 { 00242 Status_bool status_bool; 00243 00244 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00245 nf_XMCR_enable(); 00246 #endif 00247 00248 status_bool = nf_verify(); 00249 00250 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00251 nf_XMCR_disable(); 00252 #endif 00253 00254 *u32_nb_sector = nf_get_sectors_number()-1; 00255 return ( status_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL; 00256 }
| Bool nf_wr_protect | ( | void | ) |
| Bool nf_removal | ( | void | ) |
| Ctrl_status nf_10 | ( | U32 | addr, | |
| U16 | nb_sector, | |||
| Nf_sense | ||||
| ) |
| Ctrl_status nf_dfc_read_resume | ( | void | ) |
| Ctrl_status nf_dfc_write_resume | ( | void | ) |
| Ctrl_status nf_dfc_read_stop | ( | U16 | remaining_sectors | ) |
| Ctrl_status nf_dfc_write_stop | ( | U16 | u16_nb_sector_remaining | ) |
This function must be called when a write10 operation (from USB) is finished Last page written is programmed and environment is saved.
| log_sector | Logical sector address to start read | |
| nb_sector | Number of sectors to transfer |
Definition at line 767 of file nf_mngt.c.
References CTRL_GOOD, FALSE, LSB0, Nf_check_fbb, Nf_check_lut, nf_erase_old_blocks(), NF_N_DEVICES, NF_PAGE_PROGRAM_CMD, NF_TRANS_NORMAL, nf_translate(), nfc_reset_nands(), Nfc_set_cmd, SIZE_BLOCK_PAGE, trace(), trace_hex32(), and trace_nl().
00768 { 00769 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page 00770 // Note that if the page is not completely filled in yet but still programmed, the next copy tail will allow partial page program 00771 00772 // retreive exact logical/physical position (in case that transfer 00773 // did not perform the exact number of sectors) 00774 s_curr_log_sector = s_save_log_addr - u16_nb_sector_remaining; 00775 if( 0!=u16_nb_sector_remaining ) 00776 { 00777 nf_translate( NF_TRANS_NORMAL ); 00778 } 00779 g_last_log_sector = s_curr_log_sector; // Memorize next logical sector to be managed 00780 00781 // Test if transfer stop at end of logical blocks. 00782 if( s_n_sectors==0 ) 00783 { 00784 if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00785 && (g_curr_dev_id==0 )) // on device 0. 00786 { 00787 // Delete old blocks 00788 // 00789 nf_erase_old_blocks(); 00790 } 00791 } 00792 trace("nf_dfc_write_stop;"); trace_hex32(g_last_log_sector); trace_nl(); 00793 00794 // Ensure that all internal programming are complete, since we are 00795 // using cache programming (WP may be asserted for icons or fonts 00796 // loading). Moreover, on some NFs (ST, Samsung) 00797 // it is necessary to reset the devices after copy-back commands 00798 // If not, strange behaviour may happen: no busy when opening 00799 // a page for reading... 00800 nfc_reset_nands( NF_N_DEVICES ); // Reset all the NF devices 00801 00802 Nf_check_fbb( FALSE ); 00803 Nf_check_lut(); 00804 00805 return CTRL_GOOD; 00806 } // end of nf_dfc_write_stop
| void nf_dfc_read_standby | ( | U16 | ) |
| void nf_dfc_read_restart | ( | void | ) |
| U32 nf_get_sectors_number | ( | void | ) |
Returns a pointer on the internal buffer address.
This function is used for test only.
| none |
| none |
Definition at line 293 of file nf_mngt.c.
References G_SHIFT_BLOCK_PAGE, G_SHIFT_PAGE_BYTE, and S_SHIFT_SECTOR_BYTE.
00294 { 00295 return 00296 (U32)g_n_export_blocks 00297 << (G_SHIFT_BLOCK_PAGE +G_SHIFT_PAGE_BYTE -S_SHIFT_SECTOR_BYTE) 00298 ; 00299 }
| U8* nf_get_buffer_addr | ( | void | ) |
| void nf_init | ( | void | ) |
Initializes the nand flash memory driver.
The device identification is performed to initialize the driver accordingly
| none |
Definition at line 148 of file nf_unusual.c.
Referenced by main().
00149 { 00150 g_nf_init=FALSE; 00151 // s_pending_write=FALSE; 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() ) // 2KB pages 00163 { 00164 g_ofst_blk_status = 0; 00165 } 00166 if ( Is_nf_512() ) // 512B pages 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 }
| Status_bool nf_verify | ( | void | ) |
Ensure that the memory is in a good state before starting to use it.
| none |
Definition at line 199 of file nf_mngt.c.
References nf_verify_resume(), and PASS.
00200 { 00201 if ( g_nf_init ) return PASS; 00202 00203 return nf_verify_resume(); 00204 }
| Status_bool nf_verify_resume | ( | void | ) |
Ensure that the memory is in a good state before starting to use it.
The function will scan the memory, test if the memory is valid, clean it if it has to and rebuild all the management blocks. This function shall be called prior to any use of the memory after a power-up.
| none |
Definition at line 193 of file nf_unusual.c.
Referenced by nf_verify().
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() ) // The NF is not cleanly built 00207 ) { 00208 // The NF seems not cleanly built, or not built at all. 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; // Error NF access or control 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 }
| void nf_cleanup_memory | ( | void | ) |
Cleanup the memory by erasing all the management blocks.
The sub-LUT blocks, the recovery block and the free-blocks block will be erased on any devices.
| none |
Definition at line 247 of file nf_unusual.c.
Referenced by nf_verify_resume().
00248 { 00249 U8 i_dev =0; 00250 U16 i_block=0; 00251 U8 block_valid; 00252 U8 block_id; 00253 00254 // Scan all the devices and looks for: 00255 // - the sub-LUT 00256 // - the recovery block 00257 // - the free-blocks block 00258 // 00259 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ ) 00260 { 00261 // Select the devices 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; // The block is bad 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 } // for( i_block... 00287 } // for( i_dev... 00288 } // nf_cleanup_memory
Upload packets of 16 bytes from the NAND Flash to RAM.
| U8 | * datbuf pointer to RAM U8 loop number of 16 bytes packets |
Definition at line 1696 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, and Nf_rd_byte.
01697 { 01698 U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf; 01699 U8 i = loop; 01700 01701 while (i != 0) 01702 { 01703 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01704 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01705 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01706 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01707 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01708 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01709 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01710 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01711 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01712 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01713 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01714 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01715 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01716 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01717 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01718 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01719 i--; 01720 } 01721 }
Download packets of 16 bytes from RAM to the NAND Flash.
| U8 | * datbuf pointer to RAM U8 loop number of 16 bytes packets |
Definition at line 1660 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, and Nf_wr_byte.
01661 { 01662 U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf; 01663 U8 i = loop; 01664 01665 while (i != 0) 01666 { 01667 Nf_wr_byte(*(tempbuf)); tempbuf++; 01668 Nf_wr_byte(*(tempbuf)); tempbuf++; 01669 Nf_wr_byte(*(tempbuf)); tempbuf++; 01670 Nf_wr_byte(*(tempbuf)); tempbuf++; 01671 Nf_wr_byte(*(tempbuf)); tempbuf++; 01672 Nf_wr_byte(*(tempbuf)); tempbuf++; 01673 Nf_wr_byte(*(tempbuf)); tempbuf++; 01674 Nf_wr_byte(*(tempbuf)); tempbuf++; 01675 Nf_wr_byte(*(tempbuf)); tempbuf++; 01676 Nf_wr_byte(*(tempbuf)); tempbuf++; 01677 Nf_wr_byte(*(tempbuf)); tempbuf++; 01678 Nf_wr_byte(*(tempbuf)); tempbuf++; 01679 Nf_wr_byte(*(tempbuf)); tempbuf++; 01680 Nf_wr_byte(*(tempbuf)); tempbuf++; 01681 Nf_wr_byte(*(tempbuf)); tempbuf++; 01682 Nf_wr_byte(*(tempbuf)); tempbuf++; 01683 i--; 01684 } 01685 }
Definition at line 303 of file nf_mngt.c.
References G_SHIFT_BLOCK_PAGE.
00304 { 00305 return (U32)block_addr<<G_SHIFT_BLOCK_PAGE; 00306 }
| void nf_ecc_mngt | ( | void | ) |
| void nf_sync | ( | void | ) |
| void nf_copy | ( | U32 | copy_dst | ) |
Copy a NF page to a new one.
This function copies a NF page into a new page. It uses the copy-back command if it is possible.
| g_copy_src | (global) Source page address | |
| copy_dst | Recipient page address |
Definition at line 1856 of file nf_mngt.c.
References G_COPY_BACK_CONT, G_COPY_BACK_DISCONT, G_N_ROW_CYCLES, G_N_ZONES, G_SHIFT_BLOCK_PAGE, G_SHIFT_PAGE_BYTE, Is_nf_2k, LSB, LSB0, LSB1, MSB, MSB1, nf_download(), NF_PAGE_PROGRAM_CMD, NF_RANDOM_DATA_INPUT_CMD, NF_SPARE_POS, nf_upload(), nfc_copy_back_init(), NFC_OFST_3_DATA_DST, nfc_open_page_read(), nfc_open_page_write(), Nfc_set_adc, Nfc_set_adr, Nfc_set_cmd, NFC_SPARE_OFST_3_BYTE_3, NFC_SPARE_OFST_6_LBA, Nfc_unprotect_all_flash, and Nfc_wr_data.
01857 { 01858 Bool b_copy_fast; 01859 U8 zone_A, zone_B; 01860 01861 // Compute the possibility of fast copy 01862 if( 0 == G_COPY_BACK_CONT ) 01863 { 01864 b_copy_fast = 0; // never possible 01865 } 01866 else 01867 { 01868 if( (1 == G_COPY_BACK_CONT) && (1==G_COPY_BACK_DISCONT) ) 01869 { 01870 b_copy_fast = 1; // always possible 01871 } 01872 else 01873 { 01874 // Check block address 01875 b_copy_fast = 1; // by default possible 01876 if( 1 != G_COPY_BACK_CONT ) 01877 { 01878 /* 01879 zone_A = (g_copy_src>>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT); 01880 zone_B = (copy_dst >>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT); 01881 */ 01882 // block_zone = page add / number of page / 1024 01883 if( Is_nf_2k() ) 01884 { 01885 // block_zone = (page add >> (G_SHIFT_BLOCK_PAGE + 10)) / (G_N_ZONES/G_COPY_BACK_CONT); 01886 // block_zone = ((page add >> 16) * G_COPY_BACK_CONT) / G_N_ZONES; 01887 zone_A = (MSB1(g_copy_src)*G_COPY_BACK_CONT)/G_N_ZONES; 01888 zone_B = (MSB1(copy_dst )*G_COPY_BACK_CONT)/G_N_ZONES; 01889 }else{ 01890 // block_zone = page add >> (G_SHIFT_BLOCK_PAGE + 10) / (G_N_ZONES/G_COPY_BACK_CONT); 01891 zone_A = ((U8)(g_copy_src>>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES; 01892 zone_B = ((U8)(copy_dst >>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES; 01893 } 01894 if( zone_A != zone_B ) 01895 b_copy_fast = 0; // no possible 01896 } 01897 if( 1 != G_COPY_BACK_DISCONT ) 01898 { 01899 // define mandatory to delete compile error on MODULO 0 01900 #if (NF_GENERIC_DRIVER==TRUE) || (NF_AUTO_DETECT_2KB==TRUE) || (NF_AUTO_DETECT_512B==TRUE) 01901 zone_A = ((U16)g_copy_src>>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01902 zone_B = ((U16)copy_dst >>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01903 #elif ( G_COPY_BACK_DISCONT != 0 ) 01904 zone_A = ((U16)g_copy_src>>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01905 zone_B = ((U16)copy_dst >>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01906 #endif 01907 if( zone_A != zone_B ) 01908 b_copy_fast = 0; // no possible 01909 } 01910 } 01911 } 01912 01913 // Start copy 01914 if( !b_copy_fast ) 01915 { 01916 // copy the page of the old block in buffer 01917 nfc_open_page_read( g_copy_src, 0 ); 01918 nf_upload( // Works by packet of 16 bytes 01919 g_page_buffer 01920 , ((U16)1<<(G_SHIFT_PAGE_BYTE-4)) // Data zone (Page size / 16) 01921 + ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4))); // Spare zone (Page size / 32 / 16) 01922 01923 // Add LBA markers to help recovery function 01924 // Need to explain a bit why LBA are written: 01925 // nf_copy is called from copy_head and copy_tail. 01926 // - copy_head: need to write all the LBA of the pages to help recovery finding 01927 // where the last sector is written. 01928 // Moreover, in case that nf_copy is called from copy_head and source block at page 0 01929 // does not contain LBA. 01930 // - copy_tail: no need to mark the last LBA of the last page to identify the source 01931 // block since we use another method 01932 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3] = NFC_OFST_3_DATA_DST; // 3- [SW] Source block (recovery) (HW capability not used) 01933 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA ] = MSB(g_log_block_id); // 6- LBA 01934 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA+1 ] = LSB(g_log_block_id); // 7- LBA 01935 if( Is_nf_2k() ) 01936 { 01937 g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA ] = 01938 g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA ] = 01939 g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA ] = MSB(g_log_block_id); // 6- LBA 01940 g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA+1] = 01941 g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA+1] = 01942 g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA+1] = LSB(g_log_block_id); // 7- LBA 01943 } 01944 01945 // copy the buffer in the page of the new block 01946 nfc_open_page_write( copy_dst, 0 ); 01947 nf_download( // Works by packet of 16 bytes 01948 g_page_buffer 01949 , ((U16)1<<(G_SHIFT_PAGE_BYTE-4)) // Data zone (Page size / 16) 01950 + ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4))); // Spare zone (Page size / 32 / 16) 01951 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01952 } 01953 else 01954 { 01955 nfc_copy_back_init( g_copy_src ); 01956 01957 Nfc_unprotect_all_flash(); // WP may be actif due to block protection 01958 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01959 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)%256 ); 01960 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)/256 ); 01961 Nfc_set_adr( LSB0(copy_dst) ); 01962 Nfc_set_adr( LSB1(copy_dst) ); 01963 if ( 3==G_N_ROW_CYCLES ) 01964 { 01965 Nfc_set_adr( MSB1(copy_dst) ); 01966 } 01967 01968 // Remove Source block mask 01969 Nfc_wr_data( NFC_OFST_3_DATA_DST ); 01970 01971 // Add LBA markers to help recovery function 01972 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01973 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)%256 ); 01974 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)/256 ); 01975 Nfc_wr_data( MSB(g_log_block_id) ); 01976 Nfc_wr_data( LSB(g_log_block_id) ); 01977 01978 if( Is_nf_2k() ) 01979 { 01980 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01981 Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)%256 ); 01982 Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)/256 ); 01983 Nfc_wr_data( MSB(g_log_block_id) ); 01984 Nfc_wr_data( LSB(g_log_block_id) ); 01985 01986 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01987 Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)%256 ); 01988 Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)/256 ); 01989 Nfc_wr_data( MSB(g_log_block_id) ); 01990 Nfc_wr_data( LSB(g_log_block_id) ); 01991 01992 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01993 Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)%256 ); 01994 Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)/256 ); 01995 Nfc_wr_data( MSB(g_log_block_id) ); 01996 Nfc_wr_data( LSB(g_log_block_id) ); 01997 } 01998 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01999 } 02000 }
| Status_bool nf_write_lut | ( | U8 | pos, | |
| U8 | i_sub_lut, | |||
| U16 | sub_lut_log_sz | |||
| ) |
Writes a LUT in memory from a buffer.
| pos | offset of the lub-lut in the buffer | |
| i_sub_lut | id of the sub-LUT | |
| sub_lut_log_sz | Size of the sub-LUT, in logical block unit |
Definition at line 1210 of file nf_mngt.c.
References _debug, _MEM_TYPE_SLOW_, Assert, FAIL, G_N_BLOCKS, G_SHIFT_PAGE_BYTE, LSB, MSB, nf_block_2_page(), NF_N_DEVICES, NF_PAGE_BUFFER_SIZE, NF_PAGE_PROGRAM_CMD, NFC_ACT_DEV_SELECT, Nfc_action, NFC_BLK_ID_SUBLUT, nfc_check_status(), nfc_open_page_write(), Nfc_set_cmd, Nfc_wr_data, PASS, S_MNGT_DEV, trace(), trace_hex(), trace_hex16(), and trace_nl().
01214 { 01215 U16 block_addr; // Physical block number 01216 U8 _MEM_TYPE_SLOW_ * p_buf=g_page_buffer + (U16)pos*((U16)1<<(G_SHIFT_PAGE_BYTE)); 01217 01218 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01219 // The buffer is built as: 01220 // | 512 | 512 | 512 | 512 | 01221 // 01222 // The page is built as: 01223 // | 512 | 512 | 512 | 512 |SZ| 01224 // 01225 // The LUT fits in a physical page. 01226 // 01227 nfc_open_page_write( 01228 nf_block_2_page( g_lut_block_addr[i_sub_lut] ) // base address 01229 + (U32)(g_lut_block_index[i_sub_lut]) // offset to sub-LUT 01230 , 0 ); 01231 01232 trace("nf_write_lut;");trace_hex16(g_lut_block_addr[i_sub_lut]); trace(";"); trace_hex16(g_lut_block_index[i_sub_lut]);trace_nl(); 01233 for( block_addr=0 ; block_addr<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; block_addr+=1 ) 01234 { 01235 if ( block_addr<(sub_lut_log_sz*NF_N_DEVICES) ) 01236 { 01237 #if (_ASSERT_==ENABLE) 01238 Assert( ( block_addr*2)<(NF_PAGE_BUFFER_SIZE-1) ); 01239 MSB(_debug)= p_buf[ block_addr*2 ] ; 01240 LSB(_debug)= p_buf[ block_addr*2 +1] ; 01241 Assert( _debug>=g_nf_first_block ); 01242 Assert( _debug< G_N_BLOCKS ); 01243 #endif 01244 Nfc_wr_data( p_buf[ block_addr*2 ] ); 01245 Nfc_wr_data( p_buf[ block_addr*2 +1] ); 01246 trace_hex(p_buf[ block_addr*2 ]); 01247 trace_hex(p_buf[ block_addr*2 +1]); 01248 trace("-"); 01249 } 01250 else 01251 { 01252 Nfc_wr_data( 0xFF ); 01253 Nfc_wr_data( 0xFF ); 01254 trace("FFFF-"); 01255 } 01256 } 01257 trace_nl(); 01258 01259 // Write the spare information 01260 // 01261 Nfc_wr_data( 0xFF ); // 0- block is valid (for 2048 compatibility) 01262 Nfc_wr_data( NFC_BLK_ID_SUBLUT ); // 1- sub-LUT 01263 Nfc_wr_data( i_sub_lut ); // 2- sub-LUT id 01264 Nfc_wr_data( 0xFF ); // 3- unused 01265 Nfc_wr_data( g_n_sub_lut ); // 4- number of sub-LUT 01266 Nfc_wr_data( 0xFF ); // 5- block is valid (for 512 compatibility) 01267 Nfc_wr_data( MSB(sub_lut_log_sz) ); // 6-7 Number of log blocks in sub-LUT 01268 Nfc_wr_data( LSB(sub_lut_log_sz) ); 01269 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10- ECC2 01270 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 11-12- LBA 01271 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- ECC1 01272 01273 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); 01274 if ( FAIL==nfc_check_status() ) { return FAIL; } 01275 01276 return PASS; 01277 } // end of nf_write_lut
| Status_bool nf_write_fbb | ( | void | ) |
Writes the Free-blocks block into the Nand Flash.
| none |
Definition at line 1414 of file nf_mngt.c.
References FAIL, G_SHIFT_PAGE_BYTE, LSB, MSB, nf_block_2_page(), NF_PAGE_PROGRAM_CMD, NFC_ACT_DEV_SELECT, Nfc_action, NFC_BLK_ID_FBB, nfc_check_status(), NFC_OFST_4_FBB_DRIVER_RELEASE, NFC_OFST_6_FBB_VALID, nfc_open_page_write(), Nfc_set_cmd, Nfc_wr_data, PASS, and S_MNGT_DEV.
01415 { 01416 U16 u16_tmp; 01417 01418 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01419 nfc_open_page_write( 01420 nf_block_2_page( g_fbb_block_addr ) // base address 01421 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01422 , 0 ); 01423 for ( u16_tmp=0 ; u16_tmp<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; ) 01424 { 01425 if ( u16_tmp<g_n_free_blocks ) 01426 { 01427 Nfc_wr_data( g_page_buffer[2*u16_tmp ] ); 01428 Nfc_wr_data( g_page_buffer[2*u16_tmp +1] ); 01429 } 01430 else 01431 { 01432 Nfc_wr_data( 0xFF ); 01433 Nfc_wr_data( 0xFF ); 01434 } 01435 u16_tmp++; 01436 } 01437 // Write the spare information 01438 // 01439 Nfc_wr_data( 0xFF ); // 0- block is valid (for 2048 compatibility) 01440 Nfc_wr_data( NFC_BLK_ID_FBB ); // 1- Free-blocks block 01441 Nfc_wr_data( MSB(g_n_free_blocks)); // 2-3 Number of free blocks 01442 Nfc_wr_data( LSB(g_n_free_blocks)); 01443 Nfc_wr_data( NFC_OFST_4_FBB_DRIVER_RELEASE ); // 4- Nand-Flash driver ID 01444 Nfc_wr_data( 0xFF ); // 5- block is valid (for 512 compatibility) 01445 Nfc_wr_data( NFC_OFST_6_FBB_VALID ); // 6- FBB-LUTs valid 01446 Nfc_wr_data( 0xFF ); // 7- Unused 01447 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10- Unused 01448 Nfc_wr_data( MSB(g_n_export_blocks)); // 11-12- Number of exported blocks 01449 Nfc_wr_data( LSB(g_n_export_blocks)); 01450 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- Unused 01451 01452 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); 01453 if ( FAIL==nfc_check_status() ) { return FAIL; } 01454 return PASS; 01455 } // end of nf_write_fbb
| void nf_cache_fbb_refill | ( | void | ) |
Reload the FBB cache memory, starting from 0.
The cache is filled with physical blocks.
| none |
Definition at line 1046 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, Assert, CACHE_FBB_SIZE, FALSE, G_N_BLOCKS, LSB, Min, MSB, nf_block_2_page(), NF_CACHE_FBB_LOG_SZ, NF_N_DEVICES, NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), Nfc_rd_data_fetch_next, S_MNGT_DEV, SIZE_PAGE_BYTE, trace(), trace_hex16(), trace_nl(), and TRUE.
01047 { 01048 U8 u8_tmp; 01049 U16 byte_addr; 01050 _MEM_TYPE_SLOW_ U32 page_addr; 01051 01052 Assert(g_cache_fbb.ctrl.dirty==FALSE); // No refill if the cache is dirty 01053 g_cache_fbb.p = 0; 01054 01055 trace("nf_cache_fbb_refill;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01056 01057 // Ensure that the cache is bigger than the real number of free blocks 01058 // 01059 g_cache_fbb.max = Min(NF_CACHE_FBB_LOG_SZ, (g_n_free_blocks>>NF_SHIFT_N_DEVICES) ); // Last included 01060 01061 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01062 01063 page_addr = 01064 nf_block_2_page( g_fbb_block_addr ) // base address 01065 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01066 ; 01067 byte_addr=0; 01068 01069 nfc_open_page_read(page_addr, 0); 01070 01071 for ( u8_tmp=0 ; u8_tmp<g_cache_fbb.max*NF_N_DEVICES ; u8_tmp++ ) 01072 { // fill the cache buffer 01073 Assert( u8_tmp<CACHE_FBB_SIZE); 01074 MSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01075 LSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01076 Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block ); 01077 Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS ); 01078 byte_addr+=2; 01079 Assert( byte_addr<SIZE_PAGE_BYTE); // Should stay in the page. Algo limitation. 01080 } 01081 g_cache_fbb.ctrl.valid = TRUE; 01082 } // end of nf_cache_fbb_refill
Swap 2 blocks from the LUT and the FBB.
This function swaps 2 blocks: one taken into the LUT according to the LBA, and one from the FBB. This is used when modifying a block. The g_block_to_kill[] holds the block address source (LUT) that will be erased after processing.
| dev_id | Device Id of recipient page | |
| u8_ofst_lut | block offset in LUT | |
| u8_ofst_fbb | block offset in FBB |
Definition at line 2018 of file nf_mngt.c.
References Assert, CACHE_FBB_SIZE, CACHE_LUT_SIZE, G_N_BLOCKS, NF_N_DEVICES, trace(), trace_hex32(), trace_nl(), trace_u8(), and TRUE.
02019 { 02020 Assert( dev_id < NF_N_DEVICES ); 02021 Assert( u8_ofst_lut < CACHE_LUT_SIZE); 02022 Assert( u8_ofst_fbb < CACHE_FBB_SIZE); 02023 Assert( g_cache_lut.mem[u8_ofst_lut] >=g_nf_first_block ); 02024 Assert( g_cache_lut.mem[u8_ofst_lut] < G_N_BLOCKS ); 02025 Assert( g_cache_fbb.mem[u8_ofst_fbb] >=g_nf_first_block ); 02026 Assert( g_cache_fbb.mem[u8_ofst_fbb] < G_N_BLOCKS ); 02027 g_block_to_kill[dev_id ] = g_cache_lut.mem[u8_ofst_lut] ; 02028 g_cache_lut.mem[u8_ofst_lut] = g_cache_fbb.mem[u8_ofst_fbb] ; 02029 g_cache_fbb.mem[u8_ofst_fbb] = g_block_to_kill[dev_id] ; 02030 trace("g_cache_lut.mem["); trace_u8(u8_ofst_lut); trace("] = "); trace_hex32(g_cache_lut.mem[u8_ofst_lut]); trace_nl(); 02031 trace("g_cache_fbb.mem["); trace_u8(u8_ofst_fbb); trace("] = "); trace_hex32(g_cache_fbb.mem[u8_ofst_fbb]); trace_nl(); 02032 02033 // both FBB and LUT caches becomes invalid 02034 g_cache_lut.ctrl.dirty=TRUE; 02035 g_cache_fbb.ctrl.dirty=TRUE; 02036 }
| void nf_cache_fbb_flush | ( | Bool | b_ecc_err | ) |
Flushes the FBB cache into a new FBB entry.
A copy of the current FBB is made in a new page, taking into account the last FBB modification in its cache. If the block containing the FBB is full, a new block is taken from the FBB itself.
| b_ecc_err | FALSE: normal operation, b_ecc_err TRUE: remove a block from list (p) |
Definition at line 1292 of file nf_mngt.c.
References _debug, _MEM_TYPE_SLOW_, Assert, CACHE_FBB_SIZE, FALSE, G_N_BLOCKS, G_SHIFT_BLOCK_PAGE, LSB, MSB, nf_block_2_page(), Nf_check_fbb, Nf_check_lut, NF_FULL_PAGE_BUFFER_SIZE, NF_N_DEVICES, NF_PAGE_BUFFER_SIZE, nf_write_fbb(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_erase_block(), nfc_open_page_read(), Nfc_rd_data_fetch_next, S_MNGT_DEV, SIZE_PAGE_BYTE, trace(), trace_hex16(), trace_nl(), and TRUE.
01293 { 01294 _MEM_TYPE_SLOW_ U32 page_addr; 01295 _MEM_TYPE_SLOW_ U16 byte_addr; 01296 _MEM_TYPE_SLOW_ U16 u16_delete=0; 01297 _MEM_TYPE_SLOW_ U16 u16_tmp; 01298 U8 u8_tmp; 01299 _MEM_TYPE_SLOW_ U8 u8_pos; 01300 Bool bool_delete=FALSE; 01301 01302 Assert(TRUE==g_cache_fbb.ctrl.valid); 01303 Assert(TRUE==g_cache_fbb.ctrl.dirty); 01304 // Assert(g_cache_fbb.p==(g_cache_fbb.max-1)); This is no more the case for ECC error not correctable 01305 01306 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01307 01308 trace("nf_cache_fbb_flush;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01309 01310 page_addr= 01311 nf_block_2_page( g_fbb_block_addr ) // base address 01312 + (U32)g_fbb_block_index // offset to page 01313 ; 01314 01315 g_fbb_block_index++; 01316 01317 if ( g_fbb_block_index == (1<<G_SHIFT_BLOCK_PAGE)/(1<<0) ) 01318 { // Need to recycle the FBB block itself, using a free-block ! This is always possible 01319 // since there is always a free block (.p=.max-1) specially for that purpose. 01320 byte_addr = ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV); 01321 01322 Assert( g_cache_fbb.mem[byte_addr]>=g_nf_first_block ); 01323 Assert( g_cache_fbb.mem[byte_addr]< G_N_BLOCKS ); 01324 u16_delete = g_fbb_block_addr ; 01325 g_fbb_block_addr = g_cache_fbb.mem[byte_addr] ; 01326 g_cache_fbb.mem[byte_addr] = u16_delete; 01327 g_fbb_block_index = 0; 01328 01329 trace("nf_cache_fbb_flush;swap;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01330 01331 // g_cache_fbb.ctrl.dirty=TRUE; This is already the case ! 01332 01333 g_cache_fbb.p++; 01334 bool_delete=TRUE; 01335 } 01336 01337 if( !b_ecc_err ) { u8_pos = g_cache_fbb.p; } 01338 else { u8_pos = g_cache_fbb.max; } 01339 01340 byte_addr = ((U16)NF_N_DEVICES*2*u8_pos); 01341 01342 Assert( byte_addr<SIZE_PAGE_BYTE ); 01343 01344 nfc_open_page_read( page_addr, byte_addr); 01345 01346 Assert( g_cache_fbb.p<=(g_n_free_blocks/NF_N_DEVICES) ); 01347 for ( 01348 u16_tmp=0 01349 ; u16_tmp<((g_n_free_blocks/NF_N_DEVICES)-u8_pos)*NF_N_DEVICES*2 01350 ; ) 01351 { // Move the free-blocks after <pos> to the beginning of the buffer. 01352 Assert( u16_tmp<(NF_PAGE_BUFFER_SIZE-3) ); 01353 g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next(); 01354 g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next(); 01355 #if (_ASSERT_==ENABLE) 01356 MSB(_debug)= g_page_buffer[u16_tmp-2]; 01357 LSB(_debug)= g_page_buffer[u16_tmp-1]; 01358 Assert( _debug>=g_nf_first_block ); 01359 Assert( _debug< G_N_BLOCKS ); 01360 #endif 01361 } 01362 01363 for ( u8_tmp=0 ; u8_tmp<(u8_pos*NF_N_DEVICES); u8_tmp++ ) 01364 { // Then add the cache content 01365 Assert( u8_tmp < CACHE_FBB_SIZE ); 01366 Assert( u16_tmp< NF_FULL_PAGE_BUFFER_SIZE ); 01367 #if (_ASSERT_==ENABLE) 01368 // When coming from ECC 2-bits error, an entry has been removed 01369 // from the cache, so the last entry is 0xffff 01370 if( !b_ecc_err ) 01371 { 01372 Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block ); 01373 Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS ); 01374 } 01375 #endif 01376 g_page_buffer[u16_tmp++] = MSB(g_cache_fbb.mem[u8_tmp]); 01377 g_page_buffer[u16_tmp++] = LSB(g_cache_fbb.mem[u8_tmp]); 01378 } 01379 #if (_ASSERT_==ENABLE) 01380 // Ensure that, when there is no fbb recycle, the blocks in the cache at 01381 // position p are identical to the blocks in the beginning of the new line. 01382 if( (FALSE==bool_delete) && ( !b_ecc_err )) 01383 { 01384 for ( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ ) 01385 { 01386 MSB(_debug)= g_page_buffer[u8_tmp*2 ]; 01387 LSB(_debug)= g_page_buffer[u8_tmp*2 +1]; 01388 Assert( _debug==g_cache_fbb.mem[(g_cache_fbb.p)*NF_N_DEVICES + u8_tmp] ); 01389 } 01390 } 01391 #endif 01392 01393 nf_write_fbb(); // Should test the result 01394 Nf_check_fbb( b_ecc_err ); 01395 Nf_check_lut(); 01396 01397 if( TRUE==bool_delete ) 01398 { 01399 nfc_erase_block( nf_block_2_page( u16_delete ), TRUE ); 01400 } 01401 01402 Assert( u16_tmp==(g_n_free_blocks*2) ); // All the list should have been processed 01403 g_cache_fbb.ctrl.dirty=FALSE; 01404 } // end of nf_cache_fbb_flush
| void nf_copy_tail | ( | void | ) |
Definition at line 1555 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, Is_not_nf_512, LSB0, nf_block_2_page(), nf_copy(), nf_download(), nf_erase_old_blocks(), NF_N_DEVICES, NF_PAGE_PROGRAM_CMD, NF_RANDOM_DATA_INPUT_CMD, NF_SPARE_POS, nf_upload(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), nfc_open_page_write(), Nfc_set_adc, Nfc_set_cmd, S_SHIFT_LOG_BLOCK_SECTOR, SIZE_BLOCK_PAGE, SIZE_PAGE_SECTOR, SIZE_SECTOR_BYTE, trace(), trace_hex32(), and trace_nl().
01556 { 01557 _MEM_TYPE_SLOW_ U8 u8_tmp; 01558 U8 u8_tmp2; 01559 _MEM_TYPE_SLOW_ U16 u16_tmp; 01560 _MEM_TYPE_SLOW_ U16 byte_addr; 01561 01562 // Test if we do not reach the end of the logical block 01563 // 01564 if( 0!=((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1)) ) 01565 { 01566 trace("nf_copy_tail;"); trace_hex32(g_last_log_sector); trace_nl(); 01567 if( Is_not_nf_512() ) 01568 { // Following is not possible on 512B Nand 01569 01570 u8_tmp = // current offset sector in the current page 01571 LSB0(g_last_log_sector) 01572 & ( SIZE_PAGE_SECTOR-1 ) 01573 ; 01574 01575 u8_tmp2 = SIZE_PAGE_SECTOR -u8_tmp; 01576 if( 0!=u8_tmp ) 01577 { // Copy the rest of the current line 01578 01579 byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE); 01580 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 01581 nfc_open_page_read( // Open the old block at : 01582 nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) // adresse of the beginning of the old block 01583 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01584 , byte_addr ); // current offset sector in the current page 01585 // for each sector in the physical page 01586 u16_tmp = u8_tmp2 * SIZE_SECTOR_BYTE; 01587 g_last_log_sector += u8_tmp2; // update the current logical sector 01588 01589 // read the sector of the old page 01590 nf_upload(g_page_buffer+byte_addr, u16_tmp/16 ); 01591 01592 // Read the associated spare zone 01593 byte_addr= NF_SPARE_POS + (((U16)u8_tmp)*16); 01594 nfc_open_page_read( // Open the old block at : 01595 nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) // adresse of the beginning of the old block 01596 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01597 , byte_addr ); // current offset sector in the current page 01598 nf_upload(g_page_buffer+byte_addr, u8_tmp2 ); 01599 01600 byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE); 01601 nfc_open_page_write( // Open the new block at the current position 01602 g_phys_page_addr[g_curr_dev_id] 01603 , byte_addr ); 01604 01605 // write the sector in the new page 01606 nf_download(g_page_buffer+byte_addr, (U8)(u16_tmp/16) ); 01607 01608 // write the associated spare zone 01609 byte_addr=NF_SPARE_POS + (((U16)u8_tmp)*16); 01610 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01611 Nfc_set_adc( (byte_addr)%256 ); 01612 Nfc_set_adc( (byte_addr)/256 ); 01613 nf_download(g_page_buffer+byte_addr, u8_tmp2 ); 01614 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01615 01616 g_phys_page_addr[g_curr_dev_id]++; // update the current physical page of the current device 01617 g_curr_dev_id++; // update the current device 01618 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 01619 } 01620 } 01621 01622 // then copy the rest of the logical block 01623 // 01624 while( 0!=((U16)g_last_log_sector & (((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR))-1)) ) 01625 { 01626 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 01627 01628 g_copy_src= 01629 nf_block_2_page(g_block_to_kill[g_curr_dev_id]) // adresse of the beginning of the old block 01630 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01631 ; 01632 nf_copy(g_phys_page_addr[g_curr_dev_id]); 01633 g_phys_page_addr[g_curr_dev_id]++; 01634 01635 g_last_log_sector+=SIZE_PAGE_SECTOR; // update the current logical sector 01636 g_curr_dev_id++; // update the current device 01637 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 01638 } 01639 01640 // Delete old blocks 01641 // 01642 nf_erase_old_blocks(); 01643 }else{ 01644 trace("nf_copy_tail empty??;"); trace_hex32(g_last_log_sector); trace_nl(); 01645 } 01646 g_last_log_sector= 0xFFFFFFFF; 01647 }
| Ctrl_status nf_read_10 | ( | U32 | log_sector, | |
| U16 | n_sectors | |||
| ) |
This function initializes the Nand Flash for a read operation.
| log_sector | Logical sector address to start read | |
| nb_sector | Number of sectors to transfer |
Definition at line 317 of file nf_mngt.c.
References CTRL_FAIL, CTRL_GOOD, FALSE, LSB0, Nf_access_signal_off, Nf_access_signal_on, nf_get_sectors_number(), nf_open_read(), nf_read_sector_to_usb(), nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, Nfc_open_page_read, nfc_open_page_read(), SIZE_BLOCK_PAGE, trace(), trace_hex16(), trace_hex32(), trace_nl(), and TRUE.
00318 { 00319 U8 status; 00320 00321 if ( !g_nf_init ) 00322 while(1); // You shall call once mem_test_unit_ready() before. 00323 00324 // Test that the logical sector address is valid 00325 // 00326 if ( 0==n_sectors ) { return CTRL_GOOD; } 00327 if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; } 00328 00329 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00330 nf_XMCR_enable(); 00331 #endif 00332 00333 s_n_sectors = n_sectors; 00334 s_curr_log_sector = log_sector; 00335 trace("rd;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl(); 00336 s_save_log_addr = log_sector + n_sectors; 00337 g_fatal = FALSE; 00338 s_mem = TRUE; 00339 s_start = TRUE; 00340 00341 // First read operation 00342 Nf_access_signal_on(); 00343 nf_open_read(TRUE); 00344 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00345 nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte ); 00346 nf_read_sector_to_usb(s_nb_sectors_step); 00347 status = nf_xfer_update_vars(); 00348 00349 // Next read operations 00350 while (status == FALSE) // exit when last page read 00351 { 00352 if (!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00353 && (g_curr_dev_id==0 )) // on device 0. Should this case be implicit ? If yes, we can remove it. 00354 { 00355 nf_open_read(FALSE); 00356 } 00357 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00358 Nfc_open_page_read( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution 00359 nf_read_sector_to_usb(s_nb_sectors_step); // read the concerned sectors of the selected page 00360 status = nf_xfer_update_vars(); // check if last page or not 00361 } 00362 00363 Nf_access_signal_off(); 00364 00365 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00366 nf_XMCR_disable(); 00367 #endif 00368 00369 return CTRL_GOOD; 00370 }
| Ctrl_status nf_write_10 | ( | U32 | log_sector, | |
| U16 | n_sectors | |||
| ) |
This function initializes the Nand Flash for a write operation.
| log_sector | Logical sector address to start read | |
| nb_sector | Number of sectors to transfer |
Definition at line 381 of file nf_mngt.c.
References CTRL_FAIL, CTRL_GOOD, FALSE, G_CACHE_PROG, G_SHIFT_PAGE_BYTE, Is_nf_2k, LSB0, Nf_access_signal_off, Nf_access_signal_on, NF_CACHE_PROGRAM_CMD, nf_dfc_write_stop(), nf_erase_old_blocks(), nf_get_sectors_number(), nf_open_write(), NF_PAGE_PROGRAM_CMD, NF_TRANS_NORMAL, nf_translate(), nf_update_spare_zone(), nf_write_sector_from_usb(), nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, Nfc_open_page_write, nfc_open_page_write(), Nfc_set_cmd, S_SHIFT_LOG_BLOCK_SECTOR, S_SHIFT_SECTOR_BYTE, SIZE_BLOCK_PAGE, trace(), trace_hex16(), trace_hex32(), trace_nl(), and TRUE.
00382 { 00383 U8 status; 00384 Ctrl_status tmp_bool; 00385 00386 // Test that the logical sector address is valid 00387 if ( 0==n_sectors ) { return CTRL_GOOD; } 00388 if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; } 00389 00390 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00391 nf_XMCR_enable(); 00392 #endif 00393 00394 s_n_sectors = n_sectors; 00395 s_curr_log_sector = log_sector; 00396 s_save_log_addr = log_sector + n_sectors; 00397 g_fatal = FALSE; 00398 s_mem = TRUE; 00399 s_start = TRUE; 00400 00401 trace("wr;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl(); 00402 00403 // First write operation 00404 Nf_access_signal_on(); 00405 if(( s_curr_log_sector==g_last_log_sector ) // New write is just after to the last write 00406 && (!( ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1))) // Not on a logical block boundary 00407 && ( g_curr_dev_id==0 )))) 00408 { 00409 trace("continue");trace_nl(); 00410 nf_translate( NF_TRANS_NORMAL ); 00411 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 00412 nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); 00413 } 00414 else 00415 { 00416 nf_open_write( TRUE ); 00417 } 00418 nf_write_sector_from_usb(s_nb_sectors_step); // s_nb_sectors_step has been calculated in nf_translate() 00419 if (Is_nf_2k()) 00420 { 00421 nf_update_spare_zone((U8)(1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-s_nb_sectors_step, s_nb_sectors_step); // update the spare zone once the page has been filled in 00422 } 00423 else 00424 { 00425 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 00426 } 00427 g_last_log_sector = s_curr_log_sector + s_nb_sectors_step; // Memorize next logical sector to be managed 00428 status = nf_xfer_update_vars(); 00429 00430 // Next write operations 00431 while (status == FALSE) // exit when operation finished 00432 { 00433 if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00434 && (g_curr_dev_id==0 )) // on device 0. 00435 { 00436 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page 00437 nf_erase_old_blocks(); 00438 nf_open_write( FALSE ); 00439 } 00440 else 00441 { 00442 if( G_CACHE_PROG ) 00443 { 00444 Nfc_set_cmd(NF_CACHE_PROGRAM_CMD); 00445 }else{ 00446 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 00447 } 00448 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00449 Nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution 00450 } 00451 nf_write_sector_from_usb(s_nb_sectors_step); 00452 if (Is_nf_2k()) 00453 { 00454 nf_update_spare_zone(0, s_nb_sectors_step); 00455 } 00456 else 00457 { 00458 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 00459 } 00460 g_last_log_sector = s_curr_log_sector + s_nb_sectors_step; // Memorize next logical sector to be managed 00461 status = nf_xfer_update_vars(); // check if last block or not 00462 } 00463 00464 tmp_bool = nf_dfc_write_stop(0); // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement 00465 Nf_access_signal_off(); 00466 00467 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00468 nf_XMCR_disable(); 00469 #endif 00470 00471 return tmp_bool; 00472 }
| Ctrl_status nf_ram_2_nf | ( | U32 | addr, | |
| U8 * | ram | |||
| ) |
This fonction initialise the memory for a write operation from ram buffer.
DATA FLOW is: RAM => NF
(sector = 512B)
| addr | Sector address to write | |
| ram | Ram buffer pointer |
Definition at line 2114 of file nf_mngt.c.
References FALSE, G_SHIFT_PAGE_BYTE, Is_nf_2k, Nf_access_signal_off, Nf_access_signal_on, nf_dfc_write_stop(), nf_open_write(), NF_TRANS_NORMAL, nf_translate(), nf_update_spare_zone(), Nf_wr_byte, nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_write(), S_SHIFT_LOG_BLOCK_SECTOR, S_SHIFT_SECTOR_BYTE, and TRUE.
02115 { 02116 Ctrl_status tmp_bool; 02117 U16 i; 02118 02119 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02120 nf_XMCR_enable(); 02121 #endif 02122 02123 s_n_sectors = 1; 02124 s_curr_log_sector = addr; 02125 s_save_log_addr = addr + 1; 02126 g_fatal = FALSE; 02127 s_mem = TRUE; 02128 s_start = TRUE; 02129 02130 // First write operation 02131 Nf_access_signal_on(); 02132 if(( s_curr_log_sector==g_last_log_sector ) // New write is just after to the last write 02133 && (!( ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1))) // Not on a logical block boundary 02134 && ( g_curr_dev_id==0 )))) 02135 { 02136 nf_translate( NF_TRANS_NORMAL ); 02137 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 02138 nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); 02139 } 02140 else 02141 { 02142 nf_open_write( TRUE ); 02143 } 02144 02145 for(i=0;i<512;i++) 02146 { 02147 Nf_wr_byte(*ram); 02148 ram++; 02149 } 02150 02151 if (Is_nf_2k()) 02152 { 02153 nf_update_spare_zone((U8)(1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-s_nb_sectors_step, s_nb_sectors_step); // update the spare zone once the page has been filled in 02154 } 02155 else 02156 { 02157 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 02158 } 02159 nf_xfer_update_vars(); 02160 02161 tmp_bool = nf_dfc_write_stop(0); // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement 02162 Nf_access_signal_off(); 02163 02164 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02165 nf_XMCR_disable(); 02166 #endif 02167 02168 return tmp_bool; 02169 }
| Ctrl_status nf_nf_2_ram | ( | U32 | addr, | |
| U8 * | ram | |||
| ) |
This fonction read 1 sector from NF to ram buffer.
DATA FLOW is: NF => RAM
(sector = 512B)
| addr | Sector address to read | |
| ram | Ram buffer pointer |
Definition at line 2183 of file nf_mngt.c.
References CTRL_GOOD, FALSE, G_SHIFT_PAGE_BYTE, Min, Nf_access_signal_off, Nf_access_signal_on, nf_open_read(), Nf_rd_byte, nf_xfer_update_vars(), nf_XMCR_disable(), nf_XMCR_enable(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), S_SHIFT_SECTOR_BYTE, and TRUE.
02184 { 02185 U16 i; 02186 02187 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02188 nf_XMCR_enable(); 02189 #endif 02190 02191 s_n_sectors = 1; 02192 s_curr_log_sector = addr; 02193 s_save_log_addr = addr + 1; 02194 g_fatal = FALSE; 02195 s_mem = TRUE; 02196 s_start = TRUE; 02197 02198 // First read operation 02199 Nf_access_signal_on(); 02200 nf_open_read(TRUE); 02201 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 02202 nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte ); 02203 s_nb_sectors_step = (U8) // determine number of sectors to be read 02204 (Min( // on this first page 02205 1, 02206 ((1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-(s_curr_n_byte >> 9)) 02207 ) 02208 ); 02209 02210 Disable_interrupt(); 02211 for(i=0;i<512;i++) 02212 { 02213 *ram=Nf_rd_byte(); 02214 ram++; 02215 } 02216 Enable_interrupt(); 02217 nf_xfer_update_vars(); 02218 Nf_access_signal_off(); 02219 02220 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02221 nf_XMCR_disable(); 02222 #endif 02223 02224 return CTRL_GOOD; 02225 }
Definition at line 115 of file nf_mngt.h.
Referenced by nf_cache_fbb_flush(), nf_cache_lut_flush(), nf_check_fbb(), nf_check_lut(), and nf_write_lut().
1.5.3