#include "config.h"
#include "conf_nf.h"
#include "nf.h"
#include "nf_drv.h"
#include "nf_mngt.h"
#include "lib_mcu/usb/usb_drv.h"
#include "lib_mcu/debug.h"
Go to the source code of this file.
Defines | |
#define | _TRACE_ (DISABLE) |
#define | NF_ECC_MNGT (DISABLE) |
#define | U16_FBB_OFST ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV) |
Enumerations | |
enum | Nf_state { STATE_READ_INIT = 0, STATE_READ_RESUME_PAGE, STATE_WRITE_INIT, STATE_WRITE_RESUME_PAGE, STATE_COMPLETE } |
enum | Nf_translate_mode { NF_TRANS_NORMAL, NF_TRANS_FLUSH, NF_TRANS_SWAP } |
Functions | |
__no_init volatile xdata Byte nf_send_cmd | At (0x3900) |
__no_init volatile xdata Byte nf_send_add | At (0x3A00) |
__no_init volatile xdata Byte nf_data | At (0x3800) |
static void | nf_translate (Nf_translate_mode mode) |
Translate a logical sector to physical parameters. | |
static Status_bool | nf_open_read (bit check_pending_write) |
Prepare a read session on the flash memory. | |
static Status_bool | nf_open_write (bit check_pending_write) |
Prepare a write session on the flash memory. | |
static void | nf_cache_lut_refill (U16 log_block_id) |
Reload the LUT cache memory, starting from the specified logical block number given. | |
static void | nf_cache_lut_flush (void) |
Flushes the LUT cache into a new LUT entry. | |
static void | nf_erase_old_blocks (void) |
Erase the source blocks. | |
U8 | nf_xfer_update_vars (void) |
This function update transfer variables, check if operation (read/write) is finished This function may be used either with READ and WRITE operations. | |
void | nf_write_sector_from_usb (U8 nb_sectors) |
This function transfers USB data to the NF page The number of sectors to be read can be 1 up to 4 (more than 1 is available only for memories with 2kb pages). | |
void | nf_read_sector_to_usb (U8 nb_sectors) |
This function transfers a page content (NF) to the USB macro The number of sectors to be read can be 1 up to 4 (more than 1 is available only for memories with 2kb pages). | |
void | nf_update_spare_zone (U8 sect_start, U8 nb_sect) |
This function updates the spare zone of each page that has been finished to be written. | |
Status_bool | nf_verify (void) |
Ensure that the memory is in a good state before starting to use it. | |
Ctrl_status | nf_test_unit_ready (void) |
Initializes the NF driver on the first USB Test Unit Ready. | |
Ctrl_status | nf_read_capacity (U32 *u32_nb_sector) |
Returns the address of the last valid logical sector. | |
Bool | nf_wr_protect (void) |
Bool | nf_removal (void) |
U32 | nf_get_sectors_number (void) |
Returns a pointer on the internal buffer address. | |
U32 | nf_block_2_page (U16 block_addr) |
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_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. | |
void | nf_cache_fbb_refill (void) |
Reload the FBB cache memory, starting from 0. | |
Status_bool | nf_write_lut (U8 pos, U8 i_sub_lut, U16 sub_lut_log_sz) |
Writes a LUT in memory from a buffer. | |
void | nf_cache_fbb_flush (Bool b_ecc_err) |
Flushes the FBB cache into a new FBB entry. | |
Status_bool | nf_write_fbb (void) |
Writes the Free-blocks block into the Nand Flash. | |
static void | nf_check_fbb (Bool b_ecc_err) |
static void | nf_check_lut (void) |
void | nf_copy_tail (void) |
void | nf_download (U8 _MEM_TYPE_SLOW_ *datbuf, U8 loop) |
Download packets of 16 bytes from RAM to the NAND Flash. | |
void | nf_upload (U8 _MEM_TYPE_SLOW_ *datbuf, U8 loop) |
Upload packets of 16 bytes from the NAND Flash to RAM. | |
void | nf_copy (U32 copy_dst) |
Copy a NF page to a new one. | |
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_usb_stop (void) |
This function perform a last copy tail if required, when USB enters suspend or is disconnected This function may be declared in "conf_usb.h" for "Usb_suspend_action()" and "Usb_vbus_off_action()" /!\ "g_last_log_sector" must be initialized to "0xFFFFFFFF" at startup to avoid spurious writes on during USB plug-in. | |
void | nf_erase_all_blocks (void) |
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_ U8 | g_n_zones |
_MEM_TYPE_SLOW_ U16 | g_n_blocks |
_MEM_TYPE_FAST_ U8 | g_n_row_cycles |
_MEM_TYPE_SLOW_ U8 | g_copy_back_cont |
_MEM_TYPE_SLOW_ U8 | g_copy_back_discont |
_MEM_TYPE_FAST_ U8 | g_shift_page_byte |
_MEM_TYPE_FAST_ U8 | g_shift_block_page |
_MEM_TYPE_SLOW_ U8 | g_ofst_blk_status |
static _MEM_TYPE_SLOW_ U8 | s_shift_sector_byte |
static _MEM_TYPE_SLOW_ U8 | s_shift_log_page_sector |
static _MEM_TYPE_SLOW_ U8 | s_shift_log_block_sector |
Bool | g_fatal |
static Bool | s_mem |
static Bool | s_start |
_MEM_TYPE_SLOW_ U32 | g_copy_src |
_MEM_TYPE_SLOW_ U16 | g_nf_first_block = 0 |
_MEM_TYPE_SLOW_ Cache_lut | g_cache_lut |
_MEM_TYPE_SLOW_ Cache_fbb | g_cache_fbb |
_MEM_TYPE_SLOW_ U8 | g_page_buffer [((2048)+(2048)/32)] |
static _MEM_TYPE_SLOW_ U32 | s_save_log_addr |
_MEM_TYPE_BIT_ bit | g_nf_init |
_MEM_TYPE_MEDFAST_ U16 | g_log_block_id |
_MEM_TYPE_SLOW_ U16 | g_n_export_blocks = 0xFFFF |
_MEM_TYPE_SLOW_ U16 | g_n_free_blocks |
_MEM_TYPE_SLOW_ U8 | g_n_sub_lut |
_MEM_TYPE_SLOW_ U16 | g_sub_lut_log_sz |
_MEM_TYPE_SLOW_ U16 | g_last_sub_lut_log_sz |
_MEM_TYPE_SLOW_ U16 | g_fbb_block_addr |
_MEM_TYPE_SLOW_ U8 | g_fbb_block_index |
_MEM_TYPE_SLOW_ U16 | g_lut_block_addr [(NF_N_DEVICES *(8 *1024)/(512/2))] |
_MEM_TYPE_SLOW_ U8 | g_lut_block_index [(NF_N_DEVICES *(8 *1024)/(512/2))] |
static _MEM_TYPE_FAST_ U16 | s_n_sectors |
static _MEM_TYPE_FAST_ U8 | s_nb_sectors_step |
_MEM_TYPE_FAST_ U8 | g_curr_dev_id |
static _MEM_TYPE_FAST_ U16 | s_curr_n_byte |
static _MEM_TYPE_FAST_ U32 | s_curr_log_sector |
_MEM_TYPE_SLOW_ U32 | g_last_log_sector = 0xFFFFFFFF |
static _MEM_TYPE_FAST_ Nf_state | s_state |
_MEM_TYPE_SLOW_ U16 | g_block_to_kill [NF_N_DEVICES] |
_MEM_TYPE_FAST_ U32 | g_phys_page_addr [NF_N_DEVICES] |
_MEM_TYPE_SLOW_ U32 | g_save_phys_page_addr |
_MEM_TYPE_SLOW_ U8 | g_save_curr_dev_id |
_MEM_TYPE_FAST_ U32 | g_next_phys_page_addr |
Definition in file nf_mngt.c.
#define U16_FBB_OFST ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV) |
Referenced by nf_cache_lut_flush().
enum Nf_state |
STATE_READ_INIT | |
STATE_READ_RESUME_PAGE | |
STATE_WRITE_INIT | |
STATE_WRITE_RESUME_PAGE | |
STATE_COMPLETE |
Definition at line 119 of file nf_mngt.c.
00120 { 00121 STATE_READ_INIT=0 // The very first open_read must be done 00122 , STATE_READ_RESUME_PAGE // A page has been read 00123 , STATE_WRITE_INIT // The very first open_write must be done 00124 , STATE_WRITE_RESUME_PAGE // A page has been written 00125 , STATE_COMPLETE // The read or write session is over. 00126 } Nf_state;
enum Nf_translate_mode |
Definition at line 169 of file nf_mngt.c.
00170 { 00171 NF_TRANS_NORMAL // make simple translation. 00172 , NF_TRANS_FLUSH // make simple translation. Force flush of LUT and FBB caches. 00173 , NF_TRANS_SWAP // Swap blocks LUT <-> FBB 00174 } Nf_translate_mode;
__no_init volatile xdata Byte nf_send_cmd At | ( | 0x3900 | ) |
__no_init volatile xdata Byte nf_send_add At | ( | 0x3A00 | ) |
__no_init volatile xdata Byte nf_data At | ( | 0x3800 | ) |
static void nf_translate | ( | Nf_translate_mode | mode | ) | [static] |
Translate a logical sector to physical parameters.
This function translates the logical sector address to a physical page number. Then, the block used are swapped with free blocks. The LUT and FBB caches are used for that purpose. Assumption is made that there is at least 2 free entries in the FBB cache: one to swap the LUT blocks, and another one to recycle the FBB block itself (if needed).
modify_lut | FALSE for simple translation, TRUE if LUT shall be modified (write session) <global parameters>=""> |
Definition at line 1743 of file nf_mngt.c.
References _MEM_TYPE_MEDFAST_, FALSE, G_SHIFT_PAGE_BYTE, Min, nf_block_2_page(), nf_cache_fbb_flush(), nf_cache_fbb_refill(), nf_cache_lut_flush(), nf_cache_lut_refill(), Nf_check_fbb, Nf_check_lut, NF_N_DEVICES, nf_swap(), NF_TRANS_FLUSH, NF_TRANS_SWAP, S_SHIFT_LOG_BLOCK_SECTOR, S_SHIFT_LOG_PAGE_SECTOR, S_SHIFT_SECTOR_BYTE, SIZE_BLOCK_PAGE, SIZE_PAGE_SECTOR, trace(), trace_hex32(), trace_nl(), trace_u8(), and TRUE.
Referenced by nf_dfc_write_stop(), nf_open_read(), nf_open_write(), nf_ram_2_nf(), and nf_write_10().
01744 { 01745 _MEM_TYPE_MEDFAST_ U8 u8_tmp = (s_curr_log_sector & (SIZE_PAGE_SECTOR -1) ); 01746 _MEM_TYPE_MEDFAST_ U8 u8_shift; 01747 _MEM_TYPE_MEDFAST_ U8 u8_curr_page; 01748 _MEM_TYPE_MEDFAST_ U8 u8_last_page; 01749 01750 // Here begins the translation: 01751 // logical sector number (s_curr_log_sector): 01752 // 01753 // -> logical block number (g_log_block_id) 01754 // -> device number (g_curr_dev_id) 01755 // -> position in page (s_curr_n_byte) 01756 // -> nb of sectors in first page(s_nb_sectors_step) 01757 // 01758 g_log_block_id = s_curr_log_sector >> S_SHIFT_LOG_BLOCK_SECTOR; 01759 g_curr_dev_id = (s_curr_log_sector >> (G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE)) % NF_N_DEVICES; 01760 s_curr_n_byte = ((U16)u8_tmp) << S_SHIFT_SECTOR_BYTE; 01761 s_nb_sectors_step = SIZE_PAGE_SECTOR - u8_tmp; 01762 s_nb_sectors_step = Min(s_n_sectors, s_nb_sectors_step); // Adapt if nb sector to read is lower than a page 01763 01764 // Nfc_put_lba(g_log_block_id); 01765 01766 Nf_check_fbb( FALSE ); 01767 Nf_check_lut(); 01768 01769 if ( TRUE==g_cache_lut.ctrl.valid ) 01770 { 01771 if( NF_TRANS_FLUSH==mode ) 01772 { 01773 if ( TRUE==g_cache_lut.ctrl.dirty ) 01774 { 01775 nf_cache_lut_flush(); 01776 nf_cache_lut_refill(g_log_block_id); 01777 } 01778 } 01779 01780 if(( g_log_block_id<g_cache_lut.first ) 01781 || ( g_log_block_id>g_cache_lut.last )) 01782 { // MISS: need to refill the cache 01783 01784 if ( TRUE==g_cache_lut.ctrl.dirty ) { nf_cache_lut_flush(); } 01785 nf_cache_lut_refill(g_log_block_id); 01786 } 01787 } 01788 else { nf_cache_lut_refill(g_log_block_id); } // The cache is not valid. Just re-fill it. 01789 01790 01791 01792 if ( TRUE==g_cache_fbb.ctrl.valid ) 01793 { 01794 if( NF_TRANS_FLUSH==mode ) 01795 { 01796 if ( TRUE==g_cache_fbb.ctrl.dirty ) 01797 { 01798 nf_cache_fbb_flush( FALSE ); 01799 nf_cache_fbb_refill(); 01800 } 01801 } 01802 } 01803 else { nf_cache_fbb_refill(); } 01804 01805 01806 01807 u8_curr_page = (g_log_block_id-g_cache_lut.first)*NF_N_DEVICES; 01808 u8_last_page = (U16)g_cache_fbb.p*NF_N_DEVICES; 01809 01810 for( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++, u8_curr_page++, u8_last_page++) 01811 { 01812 if( NF_TRANS_SWAP==mode ) 01813 { 01814 nf_swap(u8_tmp, u8_curr_page, u8_last_page); 01815 } 01816 01817 g_phys_page_addr[u8_tmp] = nf_block_2_page( g_cache_lut.mem[u8_curr_page] ); // ... Then adapt it to page number 01818 } 01819 01820 if( NF_TRANS_SWAP==mode ) 01821 { 01822 g_cache_fbb.p++; 01823 if( g_cache_fbb.p==(g_cache_fbb.max-1) ) 01824 { // Only 1 remaining entry in FBB cache 01825 nf_cache_fbb_flush( FALSE ); // No dirty test, since we know that the cache is dirty 01826 nf_cache_fbb_refill(); 01827 } 01828 } 01829 else 01830 { 01831 // Build the physical memory address 01832 // 01833 u8_shift = // page offset is 01834 ( s_curr_log_sector >> S_SHIFT_LOG_PAGE_SECTOR ) // convert sector id to page id 01835 & ( SIZE_BLOCK_PAGE -1 ) // modulo number of phys pages in a phys block 01836 ; 01837 01838 for ( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ ) 01839 { 01840 if ( u8_tmp<g_curr_dev_id ) { g_phys_page_addr[u8_tmp] += u8_shift + 1 ; } // already read 01841 else { g_phys_page_addr[u8_tmp] += u8_shift ; } // to be read 01842 } 01843 } 01844 01845 g_next_phys_page_addr=g_phys_page_addr[g_curr_dev_id]; 01846 trace("nf_translate;g_phys_page_addr["); trace_u8(g_curr_dev_id); trace("] = "); trace_hex32(g_phys_page_addr[g_curr_dev_id]); trace_nl(); 01847 }
static Status_bool nf_open_read | ( | bit | check_pending_write | ) | [static] |
Prepare a read session on the flash memory.
This function translate the logical sector address to a physical page number. The LUT cache is used.
s_curr_log_sector | static that should be initialized before |
Definition at line 847 of file nf_mngt.c.
References nf_copy_tail(), NF_TRANS_FLUSH, nf_translate(), and PASS.
Referenced by nf_nf_2_ram(), and nf_read_10().
00848 { 00849 if(( check_pending_write ) 00850 && ( 0xFFFFFFFF!=g_last_log_sector )) 00851 { 00852 nf_copy_tail(); 00853 } 00854 00855 // Both LUT and FBB caches are flushed. Why? 00856 // - Avoid LUT/FBB caches flush and refill during audio playback 00857 // - Avoid recovery on power-on 00858 nf_translate( NF_TRANS_FLUSH ); 00859 00860 return PASS; 00861 }
static Status_bool nf_open_write | ( | bit | check_pending_write | ) | [static] |
Prepare a write session on the flash memory.
This function translates the logical sector address to a physical page number. Then, the block used are swapped with free blocks. The LUT and FBB caches are used for that purpose. The head of the used block(s) are copied into the free block(s). Assumption is made that there is at least 2 free entries in the FBB cache: one to swap the LUT blocks, and another one to recycle the FBB block itself (if needed).
static | that should be initialized before |
Definition at line 880 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, nf_block_2_page(), nf_copy(), nf_copy_tail(), nf_download(), NF_N_DEVICES, NF_PAGE_PROGRAM_CMD, NF_SPARE_POS, NF_TRANS_SWAP, nf_translate(), nf_upload(), NFC_ACT_DEV_SELECT, Nfc_action, NFC_OFST_3_DATA_SRC, NFC_OFST_6_FBB_INVALID, nfc_open_page_read(), nfc_open_page_write(), Nfc_set_cmd, NFC_SPARE_OFST_3_BYTE_3, NFC_SPARE_OFST_6_LBA, Nfc_wr_data, PASS, S_MNGT_DEV, S_SHIFT_LOG_PAGE_SECTOR, SIZE_BLOCK_PAGE, SIZE_PAGE_SECTOR, and SIZE_SECTOR_BYTE.
Referenced by nf_ram_2_nf(), and nf_write_10().
00881 { 00882 U8 u8_tmp; 00883 _MEM_TYPE_SLOW_ U8 u8_curr_page; 00884 _MEM_TYPE_SLOW_ U8 u8_last_page; 00885 U16 u16_tmp; 00886 00887 if(( check_pending_write ) 00888 && ( 0xFFFFFFFF!=g_last_log_sector )) 00889 { 00890 nf_copy_tail(); 00891 } 00892 00893 nf_translate( NF_TRANS_SWAP ); 00894 00895 // both FBB and LUT blocks are invalid 00896 // Mark FBB only. Warning: Partial Prog 00897 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 00898 nfc_open_page_write( 00899 nf_block_2_page( g_fbb_block_addr ) // base address 00900 + (U32)g_fbb_block_index // offset to Free-blocks block entry 00901 , NF_SPARE_POS+NFC_SPARE_OFST_6_LBA ); 00902 Nfc_wr_data( NFC_OFST_6_FBB_INVALID ); // 6- FBB-LUTs are invalid 00903 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); // Warning: Partial Programming 00904 00905 // Mark sources blocks (recovery). Warning: Partial Prog 00906 for( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ ) 00907 { 00908 Nfc_action(NFC_ACT_DEV_SELECT, u8_tmp); 00909 nfc_open_page_write( 00910 nf_block_2_page( g_block_to_kill[u8_tmp] ) 00911 , NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3 ); 00912 Nfc_wr_data( NFC_OFST_3_DATA_SRC ); // 3- [SW] Mark as source block (recovery) (HW capability not used) 00913 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); // Warning: Partial Programming 00914 } 00915 00916 // Copy the head of the buffer 00917 // 00918 // for each logical page (current included) 00919 u8_last_page= (s_curr_log_sector >>S_SHIFT_LOG_PAGE_SECTOR) & (SIZE_BLOCK_PAGE -1); 00920 for( u8_curr_page=0 00921 ; u8_curr_page <= u8_last_page 00922 ; u8_curr_page++ ) 00923 { 00924 // If the last page (current) 00925 if ( u8_last_page==u8_curr_page ) { u8_tmp = g_curr_dev_id; } // then copy this physical page only for the device before the current device 00926 else { u8_tmp = NF_N_DEVICES; } // else copy this physical page for all device 00927 00928 while( u8_tmp!=0 ) // for each device 00929 { 00930 u8_tmp--; 00931 Nfc_action(NFC_ACT_DEV_SELECT, u8_tmp); 00932 00933 g_copy_src= nf_block_2_page( g_block_to_kill[u8_tmp] ) + u8_curr_page; 00934 nf_copy(g_phys_page_addr[u8_tmp]); 00935 g_phys_page_addr[u8_tmp]++; 00936 } 00937 // end of loop, for each device 00938 } 00939 // end of loop, for each logical page 00940 00941 u16_tmp= 00942 (SIZE_SECTOR_BYTE) // size (unit byte) of the sector (spare zone excluded) 00943 * ( s_curr_log_sector // current sector in physical page 00944 & (SIZE_PAGE_SECTOR -1) 00945 ); 00946 00947 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00948 if( u16_tmp ) 00949 { 00950 //** copy the head of the current physical page 00951 nfc_open_page_read( nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) + u8_last_page, 0 ); 00952 // copy the head page of the old block in buffer 00953 nf_upload(g_page_buffer, (U8)(u16_tmp/16)); 00954 } 00955 00956 // copy the buffer in the head page of the new block 00957 nfc_open_page_write( g_phys_page_addr[g_curr_dev_id], 0 ); 00958 00959 // write the first byte to the current byte position in the physical page 00960 nf_download(g_page_buffer, (U8)(u16_tmp/16)); 00961 // END of the copy head 00962 00963 return PASS; 00964 } // nf_open_write
static void nf_cache_lut_refill | ( | U16 | log_block_id | ) | [static] |
Reload the LUT cache memory, starting from the specified logical block number given.
The cache is filled with physical blocks. The cache does only work inside a sub-LUT. If the logical number is 'near' to the end of the sub-LUT, the cache starts before the logical number, in order to be filled untill the end of the sub-LUT.
log_block_id | logical block number. |
Definition at line 980 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, Assert, CACHE_LUT_SIZE, FALSE, G_N_BLOCKS, LSB, MSB, nf_block_2_page(), NF_CACHE_LUT_LOG_SZ, NF_N_DEVICES, NF_SHIFT_SUBLUT_PHYS, 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_hex32(), trace_nl(), and TRUE.
Referenced by nf_translate(), and nf_usb_stop().
00981 { 00982 U8 u8_tmp; 00983 U8 sub_lut_id; 00984 00985 U16 byte_addr; 00986 _MEM_TYPE_SLOW_ U32 page_addr; 00987 _MEM_TYPE_SLOW_ U16 sub_lut_log_sz; // size of the sub-LUT. Unit in logical blocks. 00988 _MEM_TYPE_SLOW_ U16 sub_lut_log_first; // number of the first logical block of the sub-lut. 00989 00990 Assert( g_cache_lut.ctrl.dirty==FALSE ); // No refill if the cache is dirty 00991 00992 sub_lut_id = log_block_id>>( NF_SHIFT_SUBLUT_PHYS - NF_SHIFT_N_DEVICES); 00993 sub_lut_log_sz = ( sub_lut_id==(g_n_sub_lut-1) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ); 00994 sub_lut_log_first = (U16)sub_lut_id<<( NF_SHIFT_SUBLUT_PHYS - NF_SHIFT_N_DEVICES); 00995 00996 trace("nf_cache_lut_refill;"); trace_hex16(g_lut_block_addr[sub_lut_id]);trace_nl(); 00997 00998 if (sub_lut_log_sz<NF_CACHE_LUT_LOG_SZ) 00999 { // The cache is bigger than the sub LUT 01000 g_cache_lut.first = log_block_id; // First included 01001 g_cache_lut.last = log_block_id + (sub_lut_log_sz-1); // Last included 01002 } 01003 else if ( (log_block_id+NF_CACHE_LUT_LOG_SZ) <= (sub_lut_log_first+sub_lut_log_sz) ) 01004 { // The cache is done starting from the logical block number 01005 g_cache_lut.first = log_block_id; // First included 01006 g_cache_lut.last = log_block_id + (NF_CACHE_LUT_LOG_SZ-1); // Last included 01007 } 01008 else 01009 { // The cache is done starting from the last logical block of the sub-LUT 01010 g_cache_lut.last = sub_lut_log_first +sub_lut_log_sz -1; // Last included 01011 g_cache_lut.first = g_cache_lut.last - (NF_CACHE_LUT_LOG_SZ-1); // First included 01012 } 01013 01014 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01015 01016 page_addr = 01017 nf_block_2_page( g_lut_block_addr[sub_lut_id]) // base address 01018 + (U32)(g_lut_block_index[sub_lut_id]) // offset to sub-LUT 01019 ; 01020 byte_addr = ( (g_cache_lut.first-sub_lut_log_first)*NF_N_DEVICES*2 ); // logical position of the block 01021 Assert( byte_addr<SIZE_PAGE_BYTE ); 01022 01023 nfc_open_page_read( page_addr, byte_addr); 01024 trace_hex32(page_addr); trace(";"); trace_hex16(byte_addr);trace_nl(); 01025 for ( u8_tmp=0 ; u8_tmp<(g_cache_lut.last+1-g_cache_lut.first)*NF_N_DEVICES ; u8_tmp++ ) 01026 { // fill the cache buffer 01027 Assert( u8_tmp<CACHE_LUT_SIZE); 01028 MSB(g_cache_lut.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01029 LSB(g_cache_lut.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01030 trace_hex16(g_cache_lut.mem[u8_tmp]); 01031 trace("-"); 01032 Assert( g_cache_lut.mem[u8_tmp]>=g_nf_first_block ); 01033 Assert( g_cache_lut.mem[u8_tmp]< G_N_BLOCKS ); 01034 } 01035 trace_nl(); 01036 g_cache_lut.ctrl.valid = TRUE; 01037 } // end of nf_cache_lut_refill
static void nf_cache_lut_flush | ( | void | ) | [static] |
Flushes the LUT cache into a new LUT entry.
A copy of the current LUT is made in a new page, taking into account the last LUT modification in its cache. If the block containing the LUT is full, a new block is taken from the FBB.
none |
Definition at line 1099 of file nf_mngt.c.
References _debug, _MEM_TYPE_SLOW_, Assert, CACHE_LUT_SIZE, FALSE, G_N_BLOCKS, G_SHIFT_BLOCK_PAGE, LSB, MSB, nf_block_2_page(), nf_cache_fbb_flush(), nf_cache_fbb_refill(), Nf_check_fbb, Nf_check_lut, NF_N_DEVICES, NF_PAGE_BUFFER_SIZE, NF_SHIFT_SUBLUT_PHYS, NF_SUBLUT_SIZE, nf_write_lut(), NFC_ACT_DEV_SELECT, Nfc_action, nfc_erase_block(), nfc_open_page_read(), Nfc_rd_data_fetch_next, S_MNGT_DEV, trace(), trace_hex16(), trace_nl(), TRUE, and U16_FBB_OFST.
Referenced by nf_translate(), and nf_usb_stop().
01100 { 01101 _MEM_TYPE_SLOW_ U32 page_addr; 01102 U16 byte_addr; 01103 _MEM_TYPE_SLOW_ U16 sub_lut_log_sz; 01104 _MEM_TYPE_SLOW_ U8 sub_lut_id; 01105 U8 u8_tmp; 01106 01107 Assert(TRUE==g_cache_lut.ctrl.valid); 01108 Assert(TRUE==g_cache_lut.ctrl.dirty); 01109 01110 sub_lut_id = g_cache_lut.first>>(NF_SHIFT_SUBLUT_PHYS-NF_SHIFT_N_DEVICES); 01111 sub_lut_log_sz = ( sub_lut_id==(g_n_sub_lut-1) ) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ; 01112 01113 trace("nf_cache_lut_flush;"); trace_hex16(g_lut_block_addr[sub_lut_id]);trace_nl(); 01114 01115 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01116 01117 page_addr= 01118 nf_block_2_page( g_lut_block_addr[sub_lut_id] ) // base address 01119 + (U32)(g_lut_block_index[sub_lut_id]) // offset to sub-LUT 01120 ; 01121 01122 nfc_open_page_read( page_addr, 0); 01123 01124 for ( byte_addr=0 /* used as block address! */ ; byte_addr<(sub_lut_log_sz*NF_N_DEVICES) ; ) 01125 { // Read the LUT stored in Nand 01126 g_page_buffer[2*byte_addr ] = Nfc_rd_data_fetch_next(); 01127 g_page_buffer[2*byte_addr +1] = Nfc_rd_data_fetch_next(); 01128 #if (_ASSERT_==ENABLE) 01129 MSB(_debug)= g_page_buffer[2*byte_addr ]; 01130 LSB(_debug)= g_page_buffer[2*byte_addr +1]; 01131 Assert( _debug>=g_nf_first_block ); 01132 Assert( _debug< G_N_BLOCKS ); 01133 #endif 01134 byte_addr ++; 01135 } 01136 01137 // Modify the page 01138 // 01139 byte_addr = // logical position of the block 01140 ( g_cache_lut.first // Absolute logical block number... 01141 & ( (U16)NF_SUBLUT_SIZE/NF_N_DEVICES -1) // ...Modulo the number of logical block in a LUT 01142 ) 01143 * NF_N_DEVICES*2; 01144 01145 Assert( byte_addr<2048 ); 01146 01147 for ( u8_tmp=0 ; u8_tmp<(g_cache_lut.last+1-g_cache_lut.first)*NF_N_DEVICES ; u8_tmp++ ) 01148 { // flush the cache buffer in the buffer 01149 Assert( u8_tmp<CACHE_LUT_SIZE ); 01150 Assert( byte_addr<(NF_PAGE_BUFFER_SIZE-1) ); 01151 Assert( g_cache_lut.mem[u8_tmp]>=g_nf_first_block ); 01152 Assert( g_cache_lut.mem[u8_tmp]< G_N_BLOCKS ); 01153 g_page_buffer[byte_addr++] = MSB(g_cache_lut.mem[u8_tmp]) ; 01154 g_page_buffer[byte_addr++] = LSB(g_cache_lut.mem[u8_tmp]) ; 01155 } 01156 01157 // Program the page 01158 // 01159 g_lut_block_index[sub_lut_id]++; 01160 01161 if ( g_lut_block_index[sub_lut_id] == (1<<G_SHIFT_BLOCK_PAGE) ) 01162 { // Need a new block for the flush 01163 _MEM_TYPE_SLOW_ U16 u16_swap; 01164 01165 if ( FALSE==g_cache_fbb.ctrl.valid ) { nf_cache_fbb_refill(); } 01166 01167 #define U16_FBB_OFST ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV) 01168 Assert( g_cache_fbb.mem[U16_FBB_OFST]>=g_nf_first_block ); 01169 Assert( g_cache_fbb.mem[U16_FBB_OFST]< G_N_BLOCKS ); 01170 u16_swap = g_lut_block_addr[ sub_lut_id] ; 01171 g_lut_block_addr[ sub_lut_id] = g_cache_fbb.mem[U16_FBB_OFST] ; 01172 g_cache_fbb.mem[U16_FBB_OFST] = u16_swap ; 01173 g_lut_block_index[sub_lut_id] = 0; 01174 #undef U16_FBB_OFST 01175 01176 trace("nf_cache_lut_flush;swap;"); trace_hex16(g_lut_block_addr[sub_lut_id]);trace_nl(); 01177 g_cache_fbb.ctrl.dirty=TRUE; 01178 01179 nf_write_lut(0, sub_lut_id, sub_lut_log_sz); // TODO: we should test the status returned 01180 01181 nfc_erase_block( nf_block_2_page( u16_swap ), TRUE ); 01182 01183 g_cache_fbb.p++; 01184 if( g_cache_fbb.p==(g_cache_fbb.max-1) ) 01185 { // Only 1 remaining entry in FBB cache 01186 nf_cache_fbb_flush( FALSE ); // No dirty test, since we know that the cache is dirty 01187 nf_cache_fbb_refill(); 01188 } 01189 } 01190 else 01191 { 01192 nf_write_lut(0, sub_lut_id, sub_lut_log_sz); // TODO: we should test the status returned 01193 } 01194 01195 g_cache_lut.ctrl.dirty=FALSE; 01196 01197 Nf_check_fbb( FALSE ); 01198 Nf_check_lut(); 01199 } // end of nf_cache_lut_flush
static void nf_erase_old_blocks | ( | void | ) | [static] |
Erase the source blocks.
none |
Definition at line 819 of file nf_mngt.c.
References i, nf_block_2_page(), NF_N_DEVICES, NFC_ACT_DEV_SELECT, Nfc_action, nfc_erase_block(), trace(), trace_hex16(), trace_nl(), and TRUE.
Referenced by nf_copy_tail(), nf_dfc_write_stop(), and nf_write_10().
00820 { 00821 U8 i; 00822 00823 // Delete old blocks 00824 // 00825 for ( i=0 ; i<NF_N_DEVICES ; i++ ) 00826 { 00827 Nfc_action(NFC_ACT_DEV_SELECT, i); 00828 trace("nf_erase_old_blocks;"); trace_hex16(g_block_to_kill[i]);trace_nl(); 00829 nfc_erase_block( nf_block_2_page(g_block_to_kill[i]), TRUE ); 00830 } 00831 }
U8 nf_xfer_update_vars | ( | void | ) |
This function update transfer variables, check if operation (read/write) is finished This function may be used either with READ and WRITE operations.
none |
Definition at line 490 of file nf_mngt.c.
References FALSE, NF_N_DEVICES, SIZE_PAGE_SECTOR, STATE_COMPLETE, and TRUE.
Referenced by nf_nf_2_ram(), nf_ram_2_nf(), nf_read_10(), and nf_write_10().
00491 { 00492 if ( // Are we processing the last page ? 00493 ( (s_curr_log_sector & (SIZE_PAGE_SECTOR-1)) 00494 + s_n_sectors 00495 ) 00496 < SIZE_PAGE_SECTOR 00497 ) { 00498 s_state = STATE_COMPLETE; 00499 return TRUE; 00500 } 00501 00502 // Update position variables 00503 s_n_sectors -= s_nb_sectors_step; 00504 s_curr_log_sector += s_nb_sectors_step; 00505 s_curr_n_byte = 0; 00506 if (s_n_sectors < SIZE_PAGE_SECTOR) 00507 s_nb_sectors_step = (U8) (s_n_sectors); // next page must be read as partial (not all sectors remaining) 00508 else 00509 s_nb_sectors_step = SIZE_PAGE_SECTOR; // next page to be read considered as entire (all sectors requested) 00510 00511 // Save current parameters 00512 g_save_curr_dev_id = g_curr_dev_id; 00513 g_save_phys_page_addr = g_phys_page_addr[g_curr_dev_id]; 00514 00515 // Fetch the next device id 00516 // 00517 g_phys_page_addr[g_curr_dev_id]+=1; 00518 g_curr_dev_id ++; 00519 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 00520 00521 g_next_phys_page_addr = g_phys_page_addr[g_curr_dev_id]; 00522 00523 if( s_n_sectors==0 ) // Operation complete ! 00524 { 00525 s_state = STATE_COMPLETE; 00526 return TRUE; 00527 } 00528 00529 return FALSE; 00530 }
void nf_write_sector_from_usb | ( | U8 | nb_sectors | ) |
This function transfers USB data to the NF page The number of sectors to be read can be 1 up to 4 (more than 1 is available only for memories with 2kb pages).
nb_sectors | number of sectors to be read from USB (1 sector = 512 bytes) |
Definition at line 632 of file nf_mngt.c.
References Is_usb_endpoint_enabled, Is_usb_read_enabled, j, Nf_wr_byte, Usb_ack_receive_out, and Usb_read_byte.
Referenced by nf_write_10().
00633 { 00634 U8 j; 00635 for (j = 8*nb_sectors ; j != 0 ; j--) // 8 * 64 bytes = 512 bytes 00636 { 00637 while(!Is_usb_read_enabled()) 00638 { 00639 if(!Is_usb_endpoint_enabled()) 00640 return; // USB Reset 00641 } 00642 Disable_interrupt(); // Global disable. 00643 00644 Nf_wr_byte(Usb_read_byte()); // write 64 bytes to the card 00645 Nf_wr_byte(Usb_read_byte()); 00646 Nf_wr_byte(Usb_read_byte()); 00647 Nf_wr_byte(Usb_read_byte()); 00648 Nf_wr_byte(Usb_read_byte()); 00649 Nf_wr_byte(Usb_read_byte()); 00650 Nf_wr_byte(Usb_read_byte()); 00651 Nf_wr_byte(Usb_read_byte()); 00652 Nf_wr_byte(Usb_read_byte()); 00653 Nf_wr_byte(Usb_read_byte()); 00654 Nf_wr_byte(Usb_read_byte()); 00655 Nf_wr_byte(Usb_read_byte()); 00656 Nf_wr_byte(Usb_read_byte()); 00657 Nf_wr_byte(Usb_read_byte()); 00658 Nf_wr_byte(Usb_read_byte()); 00659 Nf_wr_byte(Usb_read_byte()); 00660 Nf_wr_byte(Usb_read_byte()); 00661 Nf_wr_byte(Usb_read_byte()); 00662 Nf_wr_byte(Usb_read_byte()); 00663 Nf_wr_byte(Usb_read_byte()); 00664 Nf_wr_byte(Usb_read_byte()); 00665 Nf_wr_byte(Usb_read_byte()); 00666 Nf_wr_byte(Usb_read_byte()); 00667 Nf_wr_byte(Usb_read_byte()); 00668 Nf_wr_byte(Usb_read_byte()); 00669 Nf_wr_byte(Usb_read_byte()); 00670 Nf_wr_byte(Usb_read_byte()); 00671 Nf_wr_byte(Usb_read_byte()); 00672 Nf_wr_byte(Usb_read_byte()); 00673 Nf_wr_byte(Usb_read_byte()); 00674 Nf_wr_byte(Usb_read_byte()); 00675 Nf_wr_byte(Usb_read_byte()); 00676 Nf_wr_byte(Usb_read_byte()); 00677 Nf_wr_byte(Usb_read_byte()); 00678 Nf_wr_byte(Usb_read_byte()); 00679 Nf_wr_byte(Usb_read_byte()); 00680 Nf_wr_byte(Usb_read_byte()); 00681 Nf_wr_byte(Usb_read_byte()); 00682 Nf_wr_byte(Usb_read_byte()); 00683 Nf_wr_byte(Usb_read_byte()); 00684 Nf_wr_byte(Usb_read_byte()); 00685 Nf_wr_byte(Usb_read_byte()); 00686 Nf_wr_byte(Usb_read_byte()); 00687 Nf_wr_byte(Usb_read_byte()); 00688 Nf_wr_byte(Usb_read_byte()); 00689 Nf_wr_byte(Usb_read_byte()); 00690 Nf_wr_byte(Usb_read_byte()); 00691 Nf_wr_byte(Usb_read_byte()); 00692 Nf_wr_byte(Usb_read_byte()); 00693 Nf_wr_byte(Usb_read_byte()); 00694 Nf_wr_byte(Usb_read_byte()); 00695 Nf_wr_byte(Usb_read_byte()); 00696 Nf_wr_byte(Usb_read_byte()); 00697 Nf_wr_byte(Usb_read_byte()); 00698 Nf_wr_byte(Usb_read_byte()); 00699 Nf_wr_byte(Usb_read_byte()); 00700 Nf_wr_byte(Usb_read_byte()); 00701 Nf_wr_byte(Usb_read_byte()); 00702 Nf_wr_byte(Usb_read_byte()); 00703 Nf_wr_byte(Usb_read_byte()); 00704 Nf_wr_byte(Usb_read_byte()); 00705 Nf_wr_byte(Usb_read_byte()); 00706 Nf_wr_byte(Usb_read_byte()); 00707 Nf_wr_byte(Usb_read_byte()); 00708 00709 Usb_ack_receive_out(); // USB EPOUT read acknowledgement. 00710 Enable_interrupt(); // Global re-enable. 00711 } 00712 }
void nf_read_sector_to_usb | ( | U8 | nb_sectors | ) |
This function transfers a page content (NF) to the USB macro The number of sectors to be read can be 1 up to 4 (more than 1 is available only for memories with 2kb pages).
nb_sectors | number of sectors to be read from NF (1 sector = 512 bytes) |
Definition at line 540 of file nf_mngt.c.
References FALSE, Is_usb_endpoint_enabled, Is_usb_write_enabled, j, Nf_rd_byte, Usb_send_in, and Usb_write_byte.
Referenced by nf_read_10().
00541 { 00542 U8 j; 00543 00544 for (j = 8*nb_sectors; j != 0; j--) // 8 * 64 bytes = 512 bytes 00545 { 00546 Disable_interrupt(); 00547 00548 Usb_write_byte(Nf_rd_byte()); // read 64 bytes from card 00549 Usb_write_byte(Nf_rd_byte()); 00550 Usb_write_byte(Nf_rd_byte()); 00551 Usb_write_byte(Nf_rd_byte()); 00552 Usb_write_byte(Nf_rd_byte()); 00553 Usb_write_byte(Nf_rd_byte()); 00554 Usb_write_byte(Nf_rd_byte()); 00555 Usb_write_byte(Nf_rd_byte()); 00556 Usb_write_byte(Nf_rd_byte()); 00557 Usb_write_byte(Nf_rd_byte()); 00558 Usb_write_byte(Nf_rd_byte()); 00559 Usb_write_byte(Nf_rd_byte()); 00560 Usb_write_byte(Nf_rd_byte()); 00561 Usb_write_byte(Nf_rd_byte()); 00562 Usb_write_byte(Nf_rd_byte()); 00563 Usb_write_byte(Nf_rd_byte()); 00564 Usb_write_byte(Nf_rd_byte()); 00565 Usb_write_byte(Nf_rd_byte()); 00566 Usb_write_byte(Nf_rd_byte()); 00567 Usb_write_byte(Nf_rd_byte()); 00568 Usb_write_byte(Nf_rd_byte()); 00569 Usb_write_byte(Nf_rd_byte()); 00570 Usb_write_byte(Nf_rd_byte()); 00571 Usb_write_byte(Nf_rd_byte()); 00572 Usb_write_byte(Nf_rd_byte()); 00573 Usb_write_byte(Nf_rd_byte()); 00574 Usb_write_byte(Nf_rd_byte()); 00575 Usb_write_byte(Nf_rd_byte()); 00576 Usb_write_byte(Nf_rd_byte()); 00577 Usb_write_byte(Nf_rd_byte()); 00578 Usb_write_byte(Nf_rd_byte()); 00579 Usb_write_byte(Nf_rd_byte()); 00580 Usb_write_byte(Nf_rd_byte()); 00581 Usb_write_byte(Nf_rd_byte()); 00582 Usb_write_byte(Nf_rd_byte()); 00583 Usb_write_byte(Nf_rd_byte()); 00584 Usb_write_byte(Nf_rd_byte()); 00585 Usb_write_byte(Nf_rd_byte()); 00586 Usb_write_byte(Nf_rd_byte()); 00587 Usb_write_byte(Nf_rd_byte()); 00588 Usb_write_byte(Nf_rd_byte()); 00589 Usb_write_byte(Nf_rd_byte()); 00590 Usb_write_byte(Nf_rd_byte()); 00591 Usb_write_byte(Nf_rd_byte()); 00592 Usb_write_byte(Nf_rd_byte()); 00593 Usb_write_byte(Nf_rd_byte()); 00594 Usb_write_byte(Nf_rd_byte()); 00595 Usb_write_byte(Nf_rd_byte()); 00596 Usb_write_byte(Nf_rd_byte()); 00597 Usb_write_byte(Nf_rd_byte()); 00598 Usb_write_byte(Nf_rd_byte()); 00599 Usb_write_byte(Nf_rd_byte()); 00600 Usb_write_byte(Nf_rd_byte()); 00601 Usb_write_byte(Nf_rd_byte()); 00602 Usb_write_byte(Nf_rd_byte()); 00603 Usb_write_byte(Nf_rd_byte()); 00604 Usb_write_byte(Nf_rd_byte()); 00605 Usb_write_byte(Nf_rd_byte()); 00606 Usb_write_byte(Nf_rd_byte()); 00607 Usb_write_byte(Nf_rd_byte()); 00608 Usb_write_byte(Nf_rd_byte()); 00609 Usb_write_byte(Nf_rd_byte()); 00610 Usb_write_byte(Nf_rd_byte()); 00611 Usb_write_byte(Nf_rd_byte()); 00612 Enable_interrupt(); 00613 00614 Usb_send_in(); // validate transfer 00615 while(Is_usb_write_enabled()==FALSE) 00616 { 00617 if(!Is_usb_endpoint_enabled()) 00618 return; // USB Reset 00619 } 00620 } 00621 }
This function updates the spare zone of each page that has been finished to be written.
U8 | sect_start (0..3) indicates which sector has started to be written U8 nb_sect (1..4) indicates the number of sectors concerned |
Definition at line 724 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, i, Is_nf_2k, LSB, MSB, NF_RANDOM_DATA_INPUT_CMD, NF_SPARE_POS, NFC_BLK_ID_DATA, NFC_OFST_3_DATA_DST, Nfc_set_adc, Nfc_set_cmd, NFC_SPARE_DATA_VALID, and Nfc_wr_data.
Referenced by nf_ram_2_nf(), and nf_write_10().
00725 { 00726 // Calculate first spare zone address 00727 U8 i; 00728 _MEM_TYPE_SLOW_ U16 byte_addr = NF_SPARE_POS + ((U16)sect_start)*16; 00729 00730 // Send command + address if 2kb' page model 00731 if (Is_nf_2k()) 00732 { 00733 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 00734 Nfc_set_adc( (byte_addr)%256 ); 00735 Nfc_set_adc( (byte_addr)/256 ); 00736 } 00737 00738 // Send data (spare zone x sectors written) 00739 for( i=nb_sect ; i!=0 ; i-- ) 00740 { 00741 Nfc_wr_data( 0xFF ); // 0- [FW] block is valid (for 2048 compatibility) 00742 Nfc_wr_data( NFC_BLK_ID_DATA ); // 1- [FW] Free-blocks block 00743 Nfc_wr_data( 0 ); // 2- [HW] ECC is valid 00744 Nfc_wr_data( NFC_OFST_3_DATA_DST ); // 3- [SW] Source block (recovery) (HW capability not used) 00745 Nfc_wr_data( NFC_SPARE_DATA_VALID ); // 4- [FW] Data is valid 00746 Nfc_wr_data( 0xFF ); // 5- [FW] block is valid (for 512 compatibility) 00747 Nfc_wr_data( MSB(g_log_block_id) ); // 6- [HW] LBA 00748 Nfc_wr_data( LSB(g_log_block_id) ); // 7- [HW] LBA 00749 Nfc_wr_data( 0xFF ); // 8-9-10- [HW] ECC2 00750 Nfc_wr_data( 0xFF ); 00751 Nfc_wr_data( 0xFF ); 00752 Nfc_wr_data( 0xFF ); // 11-12- [HW] LBA 00753 Nfc_wr_data( 0xFF ); 00754 Nfc_wr_data( 0xFF ); 00755 Nfc_wr_data( 0xFF ); 00756 Nfc_wr_data( 0xFF ); // 13-14-15- [HW] ECC1 00757 } 00758 }
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.
Referenced by nf_read_capacity(), and nf_test_unit_ready().
00203 { 00204 if ( g_nf_init ) return PASS; 00205 00206 return nf_verify_resume(); 00207 }
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.
Referenced by main().
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.
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 | ) |
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.
Referenced by nf_read_10(), nf_read_capacity(), and nf_write_10().
00297 { 00298 return 00299 (U32)g_n_export_blocks 00300 << (G_SHIFT_BLOCK_PAGE +G_SHIFT_PAGE_BYTE -S_SHIFT_SECTOR_BYTE) 00301 ; 00302 }
Definition at line 306 of file nf_mngt.c.
Referenced by nf_cache_fbb_flush(), nf_cache_fbb_refill(), nf_cache_lut_flush(), nf_cache_lut_refill(), nf_check_fbb(), nf_check_lut(), nf_cleanup_memory(), nf_copy_tail(), nf_erase_all_blocks(), nf_erase_old_blocks(), nf_fetch_free_block(), nf_open_write(), nf_rebuild(), nf_refine_index(), nf_scan(), nf_translate(), nf_write_fbb(), and nf_write_lut().
00307 { 00308 return (U32)block_addr<<G_SHIFT_BLOCK_PAGE; 00309 }
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.
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.
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_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.
Referenced by nf_ram_2_nf(), and nf_write_10().
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_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.
Referenced by nf_cache_lut_flush(), nf_translate(), and nf_usb_stop().
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
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.
Referenced by nf_cache_lut_flush(), and nf_rebuild().
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
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.
Referenced by nf_cache_lut_flush(), nf_translate(), and nf_usb_stop().
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
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.
Referenced by nf_cache_fbb_flush(), and nf_rebuild().
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
static void nf_check_fbb | ( | Bool | b_ecc_err | ) | [static] |
Definition at line 1463 of file nf_mngt.c.
References _debug, Assert, G_N_BLOCKS, LSB, MSB, nf_block_2_page(), NF_N_DEVICES, NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), Nfc_rd_data_fetch_next, S_MNGT_DEV, trace(), trace_hex(), trace_hex16(), trace_nl(), and trace_u16().
01464 { 01465 U16 u16_tmp; 01466 01467 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01468 trace("nf_check_fbb\n\r"); 01469 trace("g_fbb_block_addr "); trace_hex16(g_fbb_block_addr); 01470 trace("\n\rs_fbb_block_index= "); trace_hex(g_fbb_block_index); trace("\n\r"); 01471 nfc_open_page_read( 01472 nf_block_2_page( g_fbb_block_addr ) // base address 01473 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01474 , 0 ); 01475 trace("n free blocks: "); trace_u16(g_n_free_blocks); trace_nl(); 01476 for ( u16_tmp=0 ; u16_tmp<g_n_free_blocks ; ) 01477 { 01478 #if (_TRACE_==ENABLE) 01479 if( u16_tmp>=2048 ) break; 01480 if( !(u16_tmp% 8) ) { 01481 trace("\n\r"); 01482 trace_u16(u16_tmp); 01483 } 01484 #endif 01485 MSB(_debug)= Nfc_rd_data_fetch_next(); 01486 LSB(_debug)= Nfc_rd_data_fetch_next(); 01487 trace(" 0x"); trace_hex( MSB(_debug) ); trace_hex( LSB(_debug) ); 01488 // When coming from ECC 2-bits error, an entry has been removed 01489 // from the cache, so the last entry is 0xffff 01490 if( !b_ecc_err ) 01491 { 01492 Assert( _debug>=g_nf_first_block ); 01493 Assert( _debug< G_N_BLOCKS ); 01494 } 01495 #if 0 01496 This tests have been commented out: when the cache are dirty, we can not just check the memory 01497 with possible protected block address (fbb, lut). 01498 Ex: FBB is dirty, a recycle have been done between on of the free block and g_lut_block_addr[x]. 01499 In the FBB memory, the (new) lut address is still present, even if it is not the case in the cache. 01500 if ( (u16_tmp%NF_N_DEVICES)==S_MNGT_DEV ) 01501 { // Check dangerous address collision for NF_MNGT only 01502 Assert( _debug!=g_fbb_block_addr ); 01503 for ( u8_tmp=0 ; u8_tmp<g_n_sub_lut ; u8_tmp++ ) { 01504 Assert( _debug!=g_lut_block_addr[u8_tmp] ); 01505 } 01506 } 01507 #endif 01508 u16_tmp++; 01509 } 01510 trace_nl(); 01511 } // nf_check_fbb
static void nf_check_lut | ( | void | ) | [static] |
Definition at line 1514 of file nf_mngt.c.
References _debug, Assert, G_N_BLOCKS, LSB, MSB, nf_block_2_page(), NF_N_DEVICES, NFC_ACT_DEV_SELECT, Nfc_action, nfc_open_page_read(), Nfc_rd_data_fetch_next, and S_MNGT_DEV.
01515 { 01516 U16 u16_tmp; 01517 U8 sub_lut_id; 01518 U16 sub_lut_log_sz; 01519 01520 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01521 for ( sub_lut_id=0 ; sub_lut_id<g_n_sub_lut ; sub_lut_id++ ) 01522 { 01523 nfc_open_page_read( 01524 nf_block_2_page( g_lut_block_addr[sub_lut_id] ) // base address 01525 + (U32)g_lut_block_index[sub_lut_id] // offset to LUT block entry 01526 , 0 ); 01527 01528 sub_lut_log_sz = ( sub_lut_id==(g_n_sub_lut-1) ) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ; 01529 for ( u16_tmp=0 ; u16_tmp<(sub_lut_log_sz*NF_N_DEVICES) ; ) 01530 { 01531 MSB(_debug)= Nfc_rd_data_fetch_next(); 01532 LSB(_debug)= Nfc_rd_data_fetch_next(); 01533 Assert( _debug>=g_nf_first_block ); 01534 Assert( _debug< G_N_BLOCKS ); 01535 #if 0 01536 if ( (u16_tmp%NF_N_DEVICES)==S_MNGT_DEV ) 01537 { // Check dangerous address collision for NF_MNGT only 01538 Assert( _debug!=g_fbb_block_addr ); 01539 for ( u8_tmp=0 ; u8_tmp<g_n_sub_lut ; u8_tmp++ ) { 01540 Assert( _debug!=g_lut_block_addr[u8_tmp] ); 01541 } 01542 } 01543 #endif 01544 u16_tmp++; 01545 } 01546 } 01547 }
void nf_copy_tail | ( | void | ) |
Definition at line 1558 of file nf_mngt.c.
Referenced by nf_open_read(), nf_open_write(), nf_rebuild(), and nf_usb_stop().
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 }
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.
Referenced by nf_copy(), nf_copy_tail(), and nf_open_write().
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 }
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.
Referenced by nf_copy(), nf_copy_tail(), and nf_open_write().
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 }
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.
Referenced by nf_copy_tail(), and nf_open_write().
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 }
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.
Referenced by nf_translate().
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_usb_stop | ( | void | ) |
This function perform a last copy tail if required, when USB enters suspend or is disconnected This function may be declared in "conf_usb.h" for "Usb_suspend_action()" and "Usb_vbus_off_action()" /!\ "g_last_log_sector" must be initialized to "0xFFFFFFFF" at startup to avoid spurious writes on during USB plug-in.
=> Don't forget to eject (windows) the peripheral from the PC before unpluggin it to avoid uncomplete writing (FAT not actualized)
none |
Definition at line 2053 of file nf_mngt.c.
References FALSE, Nf_access_signal_off, Nf_access_signal_on, nf_cache_fbb_flush(), nf_cache_fbb_refill(), nf_cache_lut_flush(), nf_cache_lut_refill(), nf_copy_tail(), nf_XMCR_disable(), nf_XMCR_enable(), and TRUE.
02054 { 02055 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02056 nf_XMCR_enable(); 02057 #endif 02058 02059 if ( 0xFFFFFFFF!=g_last_log_sector ) 02060 { 02061 Nf_access_signal_on(); 02062 nf_copy_tail(); 02063 02064 if ( TRUE==g_cache_lut.ctrl.dirty ) 02065 { 02066 nf_cache_lut_flush(); 02067 nf_cache_lut_refill(0); 02068 } 02069 if ( TRUE==g_cache_fbb.ctrl.dirty ) 02070 { 02071 nf_cache_fbb_flush( FALSE ); 02072 nf_cache_fbb_refill(); 02073 } 02074 Nf_access_signal_off(); 02075 } 02076 02077 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02078 nf_XMCR_disable(); 02079 #endif 02080 }
void nf_erase_all_blocks | ( | void | ) |
Definition at line 2091 of file nf_mngt.c.
References G_N_BLOCKS, nf_block_2_page(), nfc_erase_block(), and TRUE.
02092 { 02093 U16 i_block; 02094 02095 for (i_block = G_N_BLOCKS ; i_block != 0 ; i_block--) 02096 { 02097 nfc_erase_block( nf_block_2_page(i_block), TRUE ); 02098 } 02099 }
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.
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.
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 }
_MEM_TYPE_SLOW_ U16 g_n_blocks |
_MEM_TYPE_FAST_ U8 g_n_row_cycles |
_MEM_TYPE_SLOW_ U8 g_copy_back_cont |
_MEM_TYPE_SLOW_ U8 g_copy_back_discont |
_MEM_TYPE_FAST_ U8 g_shift_page_byte |
_MEM_TYPE_FAST_ U8 g_shift_block_page |
_MEM_TYPE_SLOW_ U8 g_ofst_blk_status |
_MEM_TYPE_SLOW_ U8 s_shift_sector_byte [static] |
_MEM_TYPE_SLOW_ U8 s_shift_log_page_sector [static] |
_MEM_TYPE_SLOW_ U8 s_shift_log_block_sector [static] |
_MEM_TYPE_SLOW_ U32 g_copy_src |
_MEM_TYPE_SLOW_ U16 g_nf_first_block = 0 |
_MEM_TYPE_SLOW_ Cache_lut g_cache_lut |
_MEM_TYPE_SLOW_ Cache_fbb g_cache_fbb |
_MEM_TYPE_SLOW_ U8 g_page_buffer[((2048)+(2048)/32)] |
_MEM_TYPE_SLOW_ U32 s_save_log_addr [static] |
_MEM_TYPE_MEDFAST_ U16 g_log_block_id |
_MEM_TYPE_SLOW_ U16 g_n_export_blocks = 0xFFFF |
_MEM_TYPE_SLOW_ U16 g_n_free_blocks |
_MEM_TYPE_SLOW_ U8 g_n_sub_lut |
_MEM_TYPE_SLOW_ U16 g_sub_lut_log_sz |
_MEM_TYPE_SLOW_ U16 g_last_sub_lut_log_sz |
_MEM_TYPE_SLOW_ U16 g_fbb_block_addr |
_MEM_TYPE_SLOW_ U8 g_fbb_block_index |
_MEM_TYPE_SLOW_ U16 g_lut_block_addr[(NF_N_DEVICES *(8 *1024)/(512/2))] |
_MEM_TYPE_SLOW_ U8 g_lut_block_index[(NF_N_DEVICES *(8 *1024)/(512/2))] |
_MEM_TYPE_FAST_ U16 s_n_sectors [static] |
_MEM_TYPE_FAST_ U8 s_nb_sectors_step [static] |
_MEM_TYPE_FAST_ U8 g_curr_dev_id |
_MEM_TYPE_FAST_ U16 s_curr_n_byte [static] |
_MEM_TYPE_FAST_ U32 s_curr_log_sector [static] |
_MEM_TYPE_SLOW_ U32 g_last_log_sector = 0xFFFFFFFF |
_MEM_TYPE_SLOW_ U16 g_block_to_kill[NF_N_DEVICES] |
_MEM_TYPE_FAST_ U32 g_phys_page_addr[NF_N_DEVICES] |
_MEM_TYPE_SLOW_ U32 g_save_phys_page_addr |
_MEM_TYPE_SLOW_ U8 g_save_curr_dev_id |
_MEM_TYPE_FAST_ U32 g_next_phys_page_addr |