#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 77 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 83 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 84 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 104 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 106 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 115 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 121 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 122 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 137 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 150 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 218 of file nf_mngt.c.
References CTRL_FAIL, CTRL_GOOD, nf_verify(), nf_XMCR_disable(), nf_XMCR_enable(), and PASS.
00219 { 00220 Status_bool tmp_bool; 00221 00222 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00223 nf_XMCR_enable(); 00224 #endif 00225 00226 tmp_bool = nf_verify(); 00227 00228 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00229 nf_XMCR_disable(); 00230 #endif 00231 00232 return ( tmp_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL; 00233 }
Ctrl_status nf_read_capacity | ( | U32 * | u32_nb_sector | ) |
Returns the address of the last valid logical sector.
none |
Definition at line 243 of file nf_mngt.c.
References CTRL_FAIL, CTRL_GOOD, nf_get_sectors_number(), nf_verify(), nf_XMCR_disable(), nf_XMCR_enable(), and PASS.
00244 { 00245 Status_bool status_bool; 00246 00247 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00248 nf_XMCR_enable(); 00249 #endif 00250 00251 status_bool = nf_verify(); 00252 00253 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00254 nf_XMCR_disable(); 00255 #endif 00256 00257 *u32_nb_sector = nf_get_sectors_number()-1; 00258 return ( status_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL; 00259 }
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 770 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().
00771 { 00772 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page 00773 // Note that if the page is not completely filled in yet but still programmed, the next copy tail will allow partial page program 00774 00775 // retreive exact logical/physical position (in case that transfer 00776 // did not perform the exact number of sectors) 00777 s_curr_log_sector = s_save_log_addr - u16_nb_sector_remaining; 00778 if( 0!=u16_nb_sector_remaining ) 00779 { 00780 nf_translate( NF_TRANS_NORMAL ); 00781 } 00782 g_last_log_sector = s_curr_log_sector; // Memorize next logical sector to be managed 00783 00784 // Test if transfer stop at end of logical blocks. 00785 if( s_n_sectors==0 ) 00786 { 00787 if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00788 && (g_curr_dev_id==0 )) // on device 0. 00789 { 00790 // Delete old blocks 00791 // 00792 nf_erase_old_blocks(); 00793 } 00794 } 00795 trace("nf_dfc_write_stop;"); trace_hex32(g_last_log_sector); trace_nl(); 00796 00797 // Ensure that all internal programming are complete, since we are 00798 // using cache programming (WP may be asserted for icons or fonts 00799 // loading). Moreover, on some NFs (ST, Samsung) 00800 // it is necessary to reset the devices after copy-back commands 00801 // If not, strange behaviour may happen: no busy when opening 00802 // a page for reading... 00803 nfc_reset_nands( NF_N_DEVICES ); // Reset all the NF devices 00804 00805 Nf_check_fbb( FALSE ); 00806 Nf_check_lut(); 00807 00808 return CTRL_GOOD; 00809 } // 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 296 of file nf_mngt.c.
References G_SHIFT_BLOCK_PAGE, G_SHIFT_PAGE_BYTE, and S_SHIFT_SECTOR_BYTE.
00297 { 00298 return 00299 (U32)g_n_export_blocks 00300 << (G_SHIFT_BLOCK_PAGE +G_SHIFT_PAGE_BYTE -S_SHIFT_SECTOR_BYTE) 00301 ; 00302 }
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 151 of file nf_unusual.c.
Referenced by main().
00152 { 00153 g_nf_init=FALSE; 00154 // s_pending_write=FALSE; 00155 00156 #if (NF_GENERIC_DRIVER==TRUE) 00157 #error Check this init... 00158 g_n_zones = NF_N_ZONES; 00159 g_n_blocks = NF_N_BLOCKS; 00160 g_shift_block_page = NF_SHIFT_BLOCK_PAGE; 00161 g_shift_page_byte = NF_SHIFT_PAGE_BYTE; 00162 s_shift_sector_byte = NF_SHIFT_SECTOR_BYTE; 00163 g_n_row_cycles = NF_N_ROW_CYCLES; 00164 00165 if ( Is_nf_2k() ) // 2KB pages 00166 { 00167 g_ofst_blk_status = 0; 00168 } 00169 if ( Is_nf_512() ) // 512B pages 00170 { 00171 g_ofst_blk_status = 5; 00172 } 00173 00174 s_shift_log_page_sector = G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE + NF_SHIFT_N_DEVICES; 00175 s_shift_log_block_sector = s_shift_log_page_sector + G_SHIFT_BLOCK_PAGE; 00176 #endif 00177 00178 g_cache_lut.ctrl.valid = FALSE; g_cache_lut.ctrl.dirty = FALSE; 00179 g_cache_fbb.ctrl.valid = FALSE; g_cache_fbb.ctrl.dirty = FALSE; 00180 g_last_log_sector= 0xFFFFFFFF; 00181 }
Status_bool nf_verify | ( | void | ) |
Ensure that the memory is in a good state before starting to use it.
none |
Definition at line 202 of file nf_mngt.c.
References nf_verify_resume(), and PASS.
00203 { 00204 if ( g_nf_init ) return PASS; 00205 00206 return nf_verify_resume(); 00207 }
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 196 of file nf_unusual.c.
Referenced by nf_verify().
00197 { 00198 U8 u8_nb_loop; 00199 Bool status_bool; 00200 00201 00202 #if (ERASING_ALL==ENABLE) 00203 ut_nfc_erase_all(); 00204 #endif 00205 00206 status_bool = nf_scan(); 00207 00208 if(( PASS!=status_bool ) 00209 || ( is_nf_invalid() ) // The NF is not cleanly built 00210 ) { 00211 // The NF seems not cleanly built, or not built at all. 00212 // 00213 u8_nb_loop = 0; 00214 while( 1 ) 00215 { 00216 u8_nb_loop++; 00217 if( u8_nb_loop > 2 ) 00218 { 00219 status_bool=FAIL; 00220 break; // Error NF access or control 00221 } 00222 nf_cleanup_memory(); 00223 if( PASS != nf_scan() ) 00224 continue; 00225 if( PASS != nf_rebuild() ) 00226 continue; 00227 status_bool = PASS; 00228 break; 00229 } 00230 } 00231 if (status_bool==PASS) 00232 { 00233 g_nf_init = TRUE; 00234 Nf_check_lut(); 00235 Nf_check_fbb( FALSE ); 00236 } 00237 00238 return status_bool; 00239 }
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 250 of file nf_unusual.c.
Referenced by nf_verify_resume().
00251 { 00252 U8 i_dev =0; 00253 U16 i_block=0; 00254 U8 block_valid; 00255 U8 block_id; 00256 00257 // Scan all the devices and looks for: 00258 // - the sub-LUT 00259 // - the recovery block 00260 // - the free-blocks block 00261 // 00262 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ ) 00263 { 00264 // Select the devices 00265 // 00266 Nfc_action(NFC_ACT_DEV_SELECT, i_dev); 00267 00268 for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ ) 00269 { 00270 00271 nfc_open_page_read( nf_block_2_page(i_block), NF_SPARE_POS); 00272 block_valid = Nfc_rd_data_fetch_next(); 00273 block_id = Nfc_rd_data() ; 00274 00275 if ( block_valid!=0xFF ) 00276 { 00277 continue; // The block is bad 00278 } 00279 00280 if(( NFC_BLK_ID_SUBLUT==block_id ) 00281 || ( NFC_BLK_ID_FBB ==block_id )) 00282 { 00283 nfc_erase_block( nf_block_2_page(i_block), TRUE ) ; 00284 if ( FAIL==nfc_check_status() ) 00285 { 00286 nfc_mark_bad_block( nf_block_2_page(i_block) ); 00287 } 00288 } 00289 } // for( i_block... 00290 } // for( i_dev... 00291 } // 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 1699 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, i, and Nf_rd_byte.
01700 { 01701 U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf; 01702 U8 i = loop; 01703 01704 while (i != 0) 01705 { 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 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01720 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01721 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01722 i--; 01723 } 01724 }
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 1663 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, i, and Nf_wr_byte.
01664 { 01665 U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf; 01666 U8 i = loop; 01667 01668 while (i != 0) 01669 { 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 Nf_wr_byte(*(tempbuf)); tempbuf++; 01684 Nf_wr_byte(*(tempbuf)); tempbuf++; 01685 Nf_wr_byte(*(tempbuf)); tempbuf++; 01686 i--; 01687 } 01688 }
Definition at line 306 of file nf_mngt.c.
References G_SHIFT_BLOCK_PAGE.
00307 { 00308 return (U32)block_addr<<G_SHIFT_BLOCK_PAGE; 00309 }
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 1859 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.
01860 { 01861 Bool b_copy_fast; 01862 U8 zone_A, zone_B; 01863 01864 // Compute the possibility of fast copy 01865 if( 0 == G_COPY_BACK_CONT ) 01866 { 01867 b_copy_fast = 0; // never possible 01868 } 01869 else 01870 { 01871 if( (1 == G_COPY_BACK_CONT) && (1==G_COPY_BACK_DISCONT) ) 01872 { 01873 b_copy_fast = 1; // always possible 01874 } 01875 else 01876 { 01877 // Check block address 01878 b_copy_fast = 1; // by default possible 01879 if( 1 != G_COPY_BACK_CONT ) 01880 { 01881 /* 01882 zone_A = (g_copy_src>>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT); 01883 zone_B = (copy_dst >>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT); 01884 */ 01885 // block_zone = page add / number of page / 1024 01886 if( Is_nf_2k() ) 01887 { 01888 // block_zone = (page add >> (G_SHIFT_BLOCK_PAGE + 10)) / (G_N_ZONES/G_COPY_BACK_CONT); 01889 // block_zone = ((page add >> 16) * G_COPY_BACK_CONT) / G_N_ZONES; 01890 zone_A = (MSB1(g_copy_src)*G_COPY_BACK_CONT)/G_N_ZONES; 01891 zone_B = (MSB1(copy_dst )*G_COPY_BACK_CONT)/G_N_ZONES; 01892 }else{ 01893 // block_zone = page add >> (G_SHIFT_BLOCK_PAGE + 10) / (G_N_ZONES/G_COPY_BACK_CONT); 01894 zone_A = ((U8)(g_copy_src>>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES; 01895 zone_B = ((U8)(copy_dst >>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES; 01896 } 01897 if( zone_A != zone_B ) 01898 b_copy_fast = 0; // no possible 01899 } 01900 if( 1 != G_COPY_BACK_DISCONT ) 01901 { 01902 // define mandatory to delete compile error on MODULO 0 01903 #if (NF_GENERIC_DRIVER==TRUE) || (NF_AUTO_DETECT_2KB==TRUE) || (NF_AUTO_DETECT_512B==TRUE) 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 #elif ( G_COPY_BACK_DISCONT != 0 ) 01907 zone_A = ((U16)g_copy_src>>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01908 zone_B = ((U16)copy_dst >>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01909 #endif 01910 if( zone_A != zone_B ) 01911 b_copy_fast = 0; // no possible 01912 } 01913 } 01914 } 01915 01916 // Start copy 01917 if( !b_copy_fast ) 01918 { 01919 // copy the page of the old block in buffer 01920 nfc_open_page_read( g_copy_src, 0 ); 01921 nf_upload( // Works by packet of 16 bytes 01922 g_page_buffer 01923 , ((U16)1<<(G_SHIFT_PAGE_BYTE-4)) // Data zone (Page size / 16) 01924 + ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4))); // Spare zone (Page size / 32 / 16) 01925 01926 // Add LBA markers to help recovery function 01927 // Need to explain a bit why LBA are written: 01928 // nf_copy is called from copy_head and copy_tail. 01929 // - copy_head: need to write all the LBA of the pages to help recovery finding 01930 // where the last sector is written. 01931 // Moreover, in case that nf_copy is called from copy_head and source block at page 0 01932 // does not contain LBA. 01933 // - copy_tail: no need to mark the last LBA of the last page to identify the source 01934 // block since we use another method 01935 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) 01936 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA ] = MSB(g_log_block_id); // 6- LBA 01937 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA+1 ] = LSB(g_log_block_id); // 7- LBA 01938 if( Is_nf_2k() ) 01939 { 01940 g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA ] = 01941 g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA ] = 01942 g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA ] = MSB(g_log_block_id); // 6- LBA 01943 g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA+1] = 01944 g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA+1] = 01945 g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA+1] = LSB(g_log_block_id); // 7- LBA 01946 } 01947 01948 // copy the buffer in the page of the new block 01949 nfc_open_page_write( copy_dst, 0 ); 01950 nf_download( // Works by packet of 16 bytes 01951 g_page_buffer 01952 , ((U16)1<<(G_SHIFT_PAGE_BYTE-4)) // Data zone (Page size / 16) 01953 + ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4))); // Spare zone (Page size / 32 / 16) 01954 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01955 } 01956 else 01957 { 01958 nfc_copy_back_init( g_copy_src ); 01959 01960 Nfc_unprotect_all_flash(); // WP may be actif due to block protection 01961 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01962 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)%256 ); 01963 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)/256 ); 01964 Nfc_set_adr( LSB0(copy_dst) ); 01965 Nfc_set_adr( LSB1(copy_dst) ); 01966 if ( 3==G_N_ROW_CYCLES ) 01967 { 01968 Nfc_set_adr( MSB1(copy_dst) ); 01969 } 01970 01971 // Remove Source block mask 01972 Nfc_wr_data( NFC_OFST_3_DATA_DST ); 01973 01974 // Add LBA markers to help recovery function 01975 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01976 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)%256 ); 01977 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)/256 ); 01978 Nfc_wr_data( MSB(g_log_block_id) ); 01979 Nfc_wr_data( LSB(g_log_block_id) ); 01980 01981 if( Is_nf_2k() ) 01982 { 01983 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01984 Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)%256 ); 01985 Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)/256 ); 01986 Nfc_wr_data( MSB(g_log_block_id) ); 01987 Nfc_wr_data( LSB(g_log_block_id) ); 01988 01989 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01990 Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)%256 ); 01991 Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)/256 ); 01992 Nfc_wr_data( MSB(g_log_block_id) ); 01993 Nfc_wr_data( LSB(g_log_block_id) ); 01994 01995 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01996 Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)%256 ); 01997 Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)/256 ); 01998 Nfc_wr_data( MSB(g_log_block_id) ); 01999 Nfc_wr_data( LSB(g_log_block_id) ); 02000 } 02001 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 02002 } 02003 }
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 1213 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().
01217 { 01218 U16 block_addr; // Physical block number 01219 U8 _MEM_TYPE_SLOW_ * p_buf=g_page_buffer + (U16)pos*((U16)1<<(G_SHIFT_PAGE_BYTE)); 01220 01221 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01222 // The buffer is built as: 01223 // | 512 | 512 | 512 | 512 | 01224 // 01225 // The page is built as: 01226 // | 512 | 512 | 512 | 512 |SZ| 01227 // 01228 // The LUT fits in a physical page. 01229 // 01230 nfc_open_page_write( 01231 nf_block_2_page( g_lut_block_addr[i_sub_lut] ) // base address 01232 + (U32)(g_lut_block_index[i_sub_lut]) // offset to sub-LUT 01233 , 0 ); 01234 01235 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(); 01236 for( block_addr=0 ; block_addr<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; block_addr+=1 ) 01237 { 01238 if ( block_addr<(sub_lut_log_sz*NF_N_DEVICES) ) 01239 { 01240 #if (_ASSERT_==ENABLE) 01241 Assert( ( block_addr*2)<(NF_PAGE_BUFFER_SIZE-1) ); 01242 MSB(_debug)= p_buf[ block_addr*2 ] ; 01243 LSB(_debug)= p_buf[ block_addr*2 +1] ; 01244 Assert( _debug>=g_nf_first_block ); 01245 Assert( _debug< G_N_BLOCKS ); 01246 #endif 01247 Nfc_wr_data( p_buf[ block_addr*2 ] ); 01248 Nfc_wr_data( p_buf[ block_addr*2 +1] ); 01249 trace_hex(p_buf[ block_addr*2 ]); 01250 trace_hex(p_buf[ block_addr*2 +1]); 01251 trace("-"); 01252 } 01253 else 01254 { 01255 Nfc_wr_data( 0xFF ); 01256 Nfc_wr_data( 0xFF ); 01257 trace("FFFF-"); 01258 } 01259 } 01260 trace_nl(); 01261 01262 // Write the spare information 01263 // 01264 Nfc_wr_data( 0xFF ); // 0- block is valid (for 2048 compatibility) 01265 Nfc_wr_data( NFC_BLK_ID_SUBLUT ); // 1- sub-LUT 01266 Nfc_wr_data( i_sub_lut ); // 2- sub-LUT id 01267 Nfc_wr_data( 0xFF ); // 3- unused 01268 Nfc_wr_data( g_n_sub_lut ); // 4- number of sub-LUT 01269 Nfc_wr_data( 0xFF ); // 5- block is valid (for 512 compatibility) 01270 Nfc_wr_data( MSB(sub_lut_log_sz) ); // 6-7 Number of log blocks in sub-LUT 01271 Nfc_wr_data( LSB(sub_lut_log_sz) ); 01272 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10- ECC2 01273 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 11-12- LBA 01274 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- ECC1 01275 01276 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); 01277 if ( FAIL==nfc_check_status() ) { return FAIL; } 01278 01279 return PASS; 01280 } // end of nf_write_lut
Status_bool nf_write_fbb | ( | void | ) |
Writes the Free-blocks block into the Nand Flash.
none |
Definition at line 1417 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.
01418 { 01419 U16 u16_tmp; 01420 01421 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01422 nfc_open_page_write( 01423 nf_block_2_page( g_fbb_block_addr ) // base address 01424 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01425 , 0 ); 01426 for ( u16_tmp=0 ; u16_tmp<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; ) 01427 { 01428 if ( u16_tmp<g_n_free_blocks ) 01429 { 01430 Nfc_wr_data( g_page_buffer[2*u16_tmp ] ); 01431 Nfc_wr_data( g_page_buffer[2*u16_tmp +1] ); 01432 } 01433 else 01434 { 01435 Nfc_wr_data( 0xFF ); 01436 Nfc_wr_data( 0xFF ); 01437 } 01438 u16_tmp++; 01439 } 01440 // Write the spare information 01441 // 01442 Nfc_wr_data( 0xFF ); // 0- block is valid (for 2048 compatibility) 01443 Nfc_wr_data( NFC_BLK_ID_FBB ); // 1- Free-blocks block 01444 Nfc_wr_data( MSB(g_n_free_blocks)); // 2-3 Number of free blocks 01445 Nfc_wr_data( LSB(g_n_free_blocks)); 01446 Nfc_wr_data( NFC_OFST_4_FBB_DRIVER_RELEASE ); // 4- Nand-Flash driver ID 01447 Nfc_wr_data( 0xFF ); // 5- block is valid (for 512 compatibility) 01448 Nfc_wr_data( NFC_OFST_6_FBB_VALID ); // 6- FBB-LUTs valid 01449 Nfc_wr_data( 0xFF ); // 7- Unused 01450 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10- Unused 01451 Nfc_wr_data( MSB(g_n_export_blocks)); // 11-12- Number of exported blocks 01452 Nfc_wr_data( LSB(g_n_export_blocks)); 01453 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- Unused 01454 01455 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); 01456 if ( FAIL==nfc_check_status() ) { return FAIL; } 01457 return PASS; 01458 } // 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 1049 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.
01050 { 01051 U8 u8_tmp; 01052 U16 byte_addr; 01053 _MEM_TYPE_SLOW_ U32 page_addr; 01054 01055 Assert(g_cache_fbb.ctrl.dirty==FALSE); // No refill if the cache is dirty 01056 g_cache_fbb.p = 0; 01057 01058 trace("nf_cache_fbb_refill;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01059 01060 // Ensure that the cache is bigger than the real number of free blocks 01061 // 01062 g_cache_fbb.max = Min(NF_CACHE_FBB_LOG_SZ, (g_n_free_blocks>>NF_SHIFT_N_DEVICES) ); // Last included 01063 01064 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01065 01066 page_addr = 01067 nf_block_2_page( g_fbb_block_addr ) // base address 01068 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01069 ; 01070 byte_addr=0; 01071 01072 nfc_open_page_read(page_addr, 0); 01073 01074 for ( u8_tmp=0 ; u8_tmp<g_cache_fbb.max*NF_N_DEVICES ; u8_tmp++ ) 01075 { // fill the cache buffer 01076 Assert( u8_tmp<CACHE_FBB_SIZE); 01077 MSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01078 LSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01079 Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block ); 01080 Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS ); 01081 byte_addr+=2; 01082 Assert( byte_addr<SIZE_PAGE_BYTE); // Should stay in the page. Algo limitation. 01083 } 01084 g_cache_fbb.ctrl.valid = TRUE; 01085 } // 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 2021 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.
02022 { 02023 Assert( dev_id < NF_N_DEVICES ); 02024 Assert( u8_ofst_lut < CACHE_LUT_SIZE); 02025 Assert( u8_ofst_fbb < CACHE_FBB_SIZE); 02026 Assert( g_cache_lut.mem[u8_ofst_lut] >=g_nf_first_block ); 02027 Assert( g_cache_lut.mem[u8_ofst_lut] < G_N_BLOCKS ); 02028 Assert( g_cache_fbb.mem[u8_ofst_fbb] >=g_nf_first_block ); 02029 Assert( g_cache_fbb.mem[u8_ofst_fbb] < G_N_BLOCKS ); 02030 g_block_to_kill[dev_id ] = g_cache_lut.mem[u8_ofst_lut] ; 02031 g_cache_lut.mem[u8_ofst_lut] = g_cache_fbb.mem[u8_ofst_fbb] ; 02032 g_cache_fbb.mem[u8_ofst_fbb] = g_block_to_kill[dev_id] ; 02033 trace("g_cache_lut.mem["); trace_u8(u8_ofst_lut); trace("] = "); trace_hex32(g_cache_lut.mem[u8_ofst_lut]); trace_nl(); 02034 trace("g_cache_fbb.mem["); trace_u8(u8_ofst_fbb); trace("] = "); trace_hex32(g_cache_fbb.mem[u8_ofst_fbb]); trace_nl(); 02035 02036 // both FBB and LUT caches becomes invalid 02037 g_cache_lut.ctrl.dirty=TRUE; 02038 g_cache_fbb.ctrl.dirty=TRUE; 02039 }
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 1295 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.
01296 { 01297 _MEM_TYPE_SLOW_ U32 page_addr; 01298 _MEM_TYPE_SLOW_ U16 byte_addr; 01299 _MEM_TYPE_SLOW_ U16 u16_delete=0; 01300 _MEM_TYPE_SLOW_ U16 u16_tmp; 01301 U8 u8_tmp; 01302 _MEM_TYPE_SLOW_ U8 u8_pos; 01303 Bool bool_delete=FALSE; 01304 01305 Assert(TRUE==g_cache_fbb.ctrl.valid); 01306 Assert(TRUE==g_cache_fbb.ctrl.dirty); 01307 // Assert(g_cache_fbb.p==(g_cache_fbb.max-1)); This is no more the case for ECC error not correctable 01308 01309 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01310 01311 trace("nf_cache_fbb_flush;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01312 01313 page_addr= 01314 nf_block_2_page( g_fbb_block_addr ) // base address 01315 + (U32)g_fbb_block_index // offset to page 01316 ; 01317 01318 g_fbb_block_index++; 01319 01320 if ( g_fbb_block_index == (1<<G_SHIFT_BLOCK_PAGE)/(1<<0) ) 01321 { // Need to recycle the FBB block itself, using a free-block ! This is always possible 01322 // since there is always a free block (.p=.max-1) specially for that purpose. 01323 byte_addr = ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV); 01324 01325 Assert( g_cache_fbb.mem[byte_addr]>=g_nf_first_block ); 01326 Assert( g_cache_fbb.mem[byte_addr]< G_N_BLOCKS ); 01327 u16_delete = g_fbb_block_addr ; 01328 g_fbb_block_addr = g_cache_fbb.mem[byte_addr] ; 01329 g_cache_fbb.mem[byte_addr] = u16_delete; 01330 g_fbb_block_index = 0; 01331 01332 trace("nf_cache_fbb_flush;swap;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01333 01334 // g_cache_fbb.ctrl.dirty=TRUE; This is already the case ! 01335 01336 g_cache_fbb.p++; 01337 bool_delete=TRUE; 01338 } 01339 01340 if( !b_ecc_err ) { u8_pos = g_cache_fbb.p; } 01341 else { u8_pos = g_cache_fbb.max; } 01342 01343 byte_addr = ((U16)NF_N_DEVICES*2*u8_pos); 01344 01345 Assert( byte_addr<SIZE_PAGE_BYTE ); 01346 01347 nfc_open_page_read( page_addr, byte_addr); 01348 01349 Assert( g_cache_fbb.p<=(g_n_free_blocks/NF_N_DEVICES) ); 01350 for ( 01351 u16_tmp=0 01352 ; u16_tmp<((g_n_free_blocks/NF_N_DEVICES)-u8_pos)*NF_N_DEVICES*2 01353 ; ) 01354 { // Move the free-blocks after <pos> to the beginning of the buffer. 01355 Assert( u16_tmp<(NF_PAGE_BUFFER_SIZE-3) ); 01356 g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next(); 01357 g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next(); 01358 #if (_ASSERT_==ENABLE) 01359 MSB(_debug)= g_page_buffer[u16_tmp-2]; 01360 LSB(_debug)= g_page_buffer[u16_tmp-1]; 01361 Assert( _debug>=g_nf_first_block ); 01362 Assert( _debug< G_N_BLOCKS ); 01363 #endif 01364 } 01365 01366 for ( u8_tmp=0 ; u8_tmp<(u8_pos*NF_N_DEVICES); u8_tmp++ ) 01367 { // Then add the cache content 01368 Assert( u8_tmp < CACHE_FBB_SIZE ); 01369 Assert( u16_tmp< NF_FULL_PAGE_BUFFER_SIZE ); 01370 #if (_ASSERT_==ENABLE) 01371 // When coming from ECC 2-bits error, an entry has been removed 01372 // from the cache, so the last entry is 0xffff 01373 if( !b_ecc_err ) 01374 { 01375 Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block ); 01376 Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS ); 01377 } 01378 #endif 01379 g_page_buffer[u16_tmp++] = MSB(g_cache_fbb.mem[u8_tmp]); 01380 g_page_buffer[u16_tmp++] = LSB(g_cache_fbb.mem[u8_tmp]); 01381 } 01382 #if (_ASSERT_==ENABLE) 01383 // Ensure that, when there is no fbb recycle, the blocks in the cache at 01384 // position p are identical to the blocks in the beginning of the new line. 01385 if( (FALSE==bool_delete) && ( !b_ecc_err )) 01386 { 01387 for ( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ ) 01388 { 01389 MSB(_debug)= g_page_buffer[u8_tmp*2 ]; 01390 LSB(_debug)= g_page_buffer[u8_tmp*2 +1]; 01391 Assert( _debug==g_cache_fbb.mem[(g_cache_fbb.p)*NF_N_DEVICES + u8_tmp] ); 01392 } 01393 } 01394 #endif 01395 01396 nf_write_fbb(); // Should test the result 01397 Nf_check_fbb( b_ecc_err ); 01398 Nf_check_lut(); 01399 01400 if( TRUE==bool_delete ) 01401 { 01402 nfc_erase_block( nf_block_2_page( u16_delete ), TRUE ); 01403 } 01404 01405 Assert( u16_tmp==(g_n_free_blocks*2) ); // All the list should have been processed 01406 g_cache_fbb.ctrl.dirty=FALSE; 01407 } // end of nf_cache_fbb_flush
void nf_copy_tail | ( | void | ) |
Definition at line 1558 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().
01559 { 01560 _MEM_TYPE_SLOW_ U8 u8_tmp; 01561 U8 u8_tmp2; 01562 _MEM_TYPE_SLOW_ U16 u16_tmp; 01563 _MEM_TYPE_SLOW_ U16 byte_addr; 01564 01565 // Test if we do not reach the end of the logical block 01566 // 01567 if( 0!=((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1)) ) 01568 { 01569 trace("nf_copy_tail;"); trace_hex32(g_last_log_sector); trace_nl(); 01570 if( Is_not_nf_512() ) 01571 { // Following is not possible on 512B Nand 01572 01573 u8_tmp = // current offset sector in the current page 01574 LSB0(g_last_log_sector) 01575 & ( SIZE_PAGE_SECTOR-1 ) 01576 ; 01577 01578 u8_tmp2 = SIZE_PAGE_SECTOR -u8_tmp; 01579 if( 0!=u8_tmp ) 01580 { // Copy the rest of the current line 01581 01582 byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE); 01583 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 01584 nfc_open_page_read( // Open the old block at : 01585 nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) // adresse of the beginning of the old block 01586 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01587 , byte_addr ); // current offset sector in the current page 01588 // for each sector in the physical page 01589 u16_tmp = u8_tmp2 * SIZE_SECTOR_BYTE; 01590 g_last_log_sector += u8_tmp2; // update the current logical sector 01591 01592 // read the sector of the old page 01593 nf_upload(g_page_buffer+byte_addr, u16_tmp/16 ); 01594 01595 // Read the associated spare zone 01596 byte_addr= NF_SPARE_POS + (((U16)u8_tmp)*16); 01597 nfc_open_page_read( // Open the old block at : 01598 nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) // adresse of the beginning of the old block 01599 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01600 , byte_addr ); // current offset sector in the current page 01601 nf_upload(g_page_buffer+byte_addr, u8_tmp2 ); 01602 01603 byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE); 01604 nfc_open_page_write( // Open the new block at the current position 01605 g_phys_page_addr[g_curr_dev_id] 01606 , byte_addr ); 01607 01608 // write the sector in the new page 01609 nf_download(g_page_buffer+byte_addr, (U8)(u16_tmp/16) ); 01610 01611 // write the associated spare zone 01612 byte_addr=NF_SPARE_POS + (((U16)u8_tmp)*16); 01613 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01614 Nfc_set_adc( (byte_addr)%256 ); 01615 Nfc_set_adc( (byte_addr)/256 ); 01616 nf_download(g_page_buffer+byte_addr, u8_tmp2 ); 01617 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01618 01619 g_phys_page_addr[g_curr_dev_id]++; // update the current physical page of the current device 01620 g_curr_dev_id++; // update the current device 01621 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 01622 } 01623 } 01624 01625 // then copy the rest of the logical block 01626 // 01627 while( 0!=((U16)g_last_log_sector & (((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR))-1)) ) 01628 { 01629 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 01630 01631 g_copy_src= 01632 nf_block_2_page(g_block_to_kill[g_curr_dev_id]) // adresse of the beginning of the old block 01633 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01634 ; 01635 nf_copy(g_phys_page_addr[g_curr_dev_id]); 01636 g_phys_page_addr[g_curr_dev_id]++; 01637 01638 g_last_log_sector+=SIZE_PAGE_SECTOR; // update the current logical sector 01639 g_curr_dev_id++; // update the current device 01640 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 01641 } 01642 01643 // Delete old blocks 01644 // 01645 nf_erase_old_blocks(); 01646 }else{ 01647 trace("nf_copy_tail empty??;"); trace_hex32(g_last_log_sector); trace_nl(); 01648 } 01649 g_last_log_sector= 0xFFFFFFFF; 01650 }
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 320 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.
00321 { 00322 U8 status; 00323 00324 if ( !g_nf_init ) 00325 while(1); // You shall call once mem_test_unit_ready() before. 00326 00327 // Test that the logical sector address is valid 00328 // 00329 if ( 0==n_sectors ) { return CTRL_GOOD; } 00330 if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; } 00331 00332 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00333 nf_XMCR_enable(); 00334 #endif 00335 00336 s_n_sectors = n_sectors; 00337 s_curr_log_sector = log_sector; 00338 trace("rd;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl(); 00339 s_save_log_addr = log_sector + n_sectors; 00340 g_fatal = FALSE; 00341 s_mem = TRUE; 00342 s_start = TRUE; 00343 00344 // First read operation 00345 Nf_access_signal_on(); 00346 nf_open_read(TRUE); 00347 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00348 nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte ); 00349 nf_read_sector_to_usb(s_nb_sectors_step); 00350 status = nf_xfer_update_vars(); 00351 00352 // Next read operations 00353 while (status == FALSE) // exit when last page read 00354 { 00355 if (!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00356 && (g_curr_dev_id==0 )) // on device 0. Should this case be implicit ? If yes, we can remove it. 00357 { 00358 nf_open_read(FALSE); 00359 } 00360 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00361 Nfc_open_page_read( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution 00362 nf_read_sector_to_usb(s_nb_sectors_step); // read the concerned sectors of the selected page 00363 status = nf_xfer_update_vars(); // check if last page or not 00364 } 00365 00366 Nf_access_signal_off(); 00367 00368 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00369 nf_XMCR_disable(); 00370 #endif 00371 00372 return CTRL_GOOD; 00373 }
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 384 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.
00385 { 00386 U8 status; 00387 Ctrl_status tmp_bool; 00388 00389 // Test that the logical sector address is valid 00390 if ( 0==n_sectors ) { return CTRL_GOOD; } 00391 if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; } 00392 00393 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00394 nf_XMCR_enable(); 00395 #endif 00396 00397 s_n_sectors = n_sectors; 00398 s_curr_log_sector = log_sector; 00399 s_save_log_addr = log_sector + n_sectors; 00400 g_fatal = FALSE; 00401 s_mem = TRUE; 00402 s_start = TRUE; 00403 00404 trace("wr;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl(); 00405 00406 // First write operation 00407 Nf_access_signal_on(); 00408 if(( s_curr_log_sector==g_last_log_sector ) // New write is just after to the last write 00409 && (!( ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1))) // Not on a logical block boundary 00410 && ( g_curr_dev_id==0 )))) 00411 { 00412 trace("continue");trace_nl(); 00413 nf_translate( NF_TRANS_NORMAL ); 00414 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 00415 nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); 00416 } 00417 else 00418 { 00419 nf_open_write( TRUE ); 00420 } 00421 nf_write_sector_from_usb(s_nb_sectors_step); // s_nb_sectors_step has been calculated in nf_translate() 00422 if (Is_nf_2k()) 00423 { 00424 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 00425 } 00426 else 00427 { 00428 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 00429 } 00430 g_last_log_sector = s_curr_log_sector + s_nb_sectors_step; // Memorize next logical sector to be managed 00431 status = nf_xfer_update_vars(); 00432 00433 // Next write operations 00434 while (status == FALSE) // exit when operation finished 00435 { 00436 if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00437 && (g_curr_dev_id==0 )) // on device 0. 00438 { 00439 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page 00440 nf_erase_old_blocks(); 00441 nf_open_write( FALSE ); 00442 } 00443 else 00444 { 00445 if( G_CACHE_PROG ) 00446 { 00447 Nfc_set_cmd(NF_CACHE_PROGRAM_CMD); 00448 }else{ 00449 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 00450 } 00451 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00452 Nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution 00453 } 00454 nf_write_sector_from_usb(s_nb_sectors_step); 00455 if (Is_nf_2k()) 00456 { 00457 nf_update_spare_zone(0, s_nb_sectors_step); 00458 } 00459 else 00460 { 00461 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 00462 } 00463 g_last_log_sector = s_curr_log_sector + s_nb_sectors_step; // Memorize next logical sector to be managed 00464 status = nf_xfer_update_vars(); // check if last block or not 00465 } 00466 00467 tmp_bool = nf_dfc_write_stop(0); // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement 00468 Nf_access_signal_off(); 00469 00470 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00471 nf_XMCR_disable(); 00472 #endif 00473 00474 return tmp_bool; 00475 }
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 2117 of file nf_mngt.c.
References FALSE, G_SHIFT_PAGE_BYTE, i, 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.
02118 { 02119 Ctrl_status tmp_bool; 02120 U16 i; 02121 02122 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02123 nf_XMCR_enable(); 02124 #endif 02125 02126 s_n_sectors = 1; 02127 s_curr_log_sector = addr; 02128 s_save_log_addr = addr + 1; 02129 g_fatal = FALSE; 02130 s_mem = TRUE; 02131 s_start = TRUE; 02132 02133 // First write operation 02134 Nf_access_signal_on(); 02135 if(( s_curr_log_sector==g_last_log_sector ) // New write is just after to the last write 02136 && (!( ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1))) // Not on a logical block boundary 02137 && ( g_curr_dev_id==0 )))) 02138 { 02139 nf_translate( NF_TRANS_NORMAL ); 02140 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 02141 nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); 02142 } 02143 else 02144 { 02145 nf_open_write( TRUE ); 02146 } 02147 02148 for(i=0;i<512;i++) 02149 { 02150 Nf_wr_byte(*ram); 02151 ram++; 02152 } 02153 02154 if (Is_nf_2k()) 02155 { 02156 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 02157 } 02158 else 02159 { 02160 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 02161 } 02162 nf_xfer_update_vars(); 02163 02164 tmp_bool = nf_dfc_write_stop(0); // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement 02165 Nf_access_signal_off(); 02166 02167 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02168 nf_XMCR_disable(); 02169 #endif 02170 02171 return tmp_bool; 02172 }
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 2186 of file nf_mngt.c.
References CTRL_GOOD, FALSE, G_SHIFT_PAGE_BYTE, i, 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.
02187 { 02188 U16 i; 02189 02190 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02191 nf_XMCR_enable(); 02192 #endif 02193 02194 s_n_sectors = 1; 02195 s_curr_log_sector = addr; 02196 s_save_log_addr = addr + 1; 02197 g_fatal = FALSE; 02198 s_mem = TRUE; 02199 s_start = TRUE; 02200 02201 // First read operation 02202 Nf_access_signal_on(); 02203 nf_open_read(TRUE); 02204 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 02205 nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte ); 02206 s_nb_sectors_step = (U8) // determine number of sectors to be read 02207 (Min( // on this first page 02208 1, 02209 ((1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-(s_curr_n_byte >> 9)) 02210 ) 02211 ); 02212 02213 Disable_interrupt(); 02214 for(i=0;i<512;i++) 02215 { 02216 *ram=Nf_rd_byte(); 02217 ram++; 02218 } 02219 Enable_interrupt(); 02220 nf_xfer_update_vars(); 02221 Nf_access_signal_off(); 02222 02223 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02224 nf_XMCR_disable(); 02225 #endif 02226 02227 return CTRL_GOOD; 02228 }
Definition at line 118 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().