#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 116 of file nf_mngt.c.
00117 { 00118 STATE_READ_INIT=0 // The very first open_read must be done 00119 , STATE_READ_RESUME_PAGE // A page has been read 00120 , STATE_WRITE_INIT // The very first open_write must be done 00121 , STATE_WRITE_RESUME_PAGE // A page has been written 00122 , STATE_COMPLETE // The read or write session is over. 00123 } Nf_state;
| enum Nf_translate_mode |
Definition at line 166 of file nf_mngt.c.
00167 { 00168 NF_TRANS_NORMAL // make simple translation. 00169 , NF_TRANS_FLUSH // make simple translation. Force flush of LUT and FBB caches. 00170 , NF_TRANS_SWAP // Swap blocks LUT <-> FBB 00171 } 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 1740 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().
01741 { 01742 _MEM_TYPE_MEDFAST_ U8 u8_tmp = (s_curr_log_sector & (SIZE_PAGE_SECTOR -1) ); 01743 _MEM_TYPE_MEDFAST_ U8 u8_shift; 01744 _MEM_TYPE_MEDFAST_ U8 u8_curr_page; 01745 _MEM_TYPE_MEDFAST_ U8 u8_last_page; 01746 01747 // Here begins the translation: 01748 // logical sector number (s_curr_log_sector): 01749 // 01750 // -> logical block number (g_log_block_id) 01751 // -> device number (g_curr_dev_id) 01752 // -> position in page (s_curr_n_byte) 01753 // -> nb of sectors in first page(s_nb_sectors_step) 01754 // 01755 g_log_block_id = s_curr_log_sector >> S_SHIFT_LOG_BLOCK_SECTOR; 01756 g_curr_dev_id = (s_curr_log_sector >> (G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE)) % NF_N_DEVICES; 01757 s_curr_n_byte = ((U16)u8_tmp) << S_SHIFT_SECTOR_BYTE; 01758 s_nb_sectors_step = SIZE_PAGE_SECTOR - u8_tmp; 01759 s_nb_sectors_step = Min(s_n_sectors, s_nb_sectors_step); // Adapt if nb sector to read is lower than a page 01760 01761 // Nfc_put_lba(g_log_block_id); 01762 01763 Nf_check_fbb( FALSE ); 01764 Nf_check_lut(); 01765 01766 if ( TRUE==g_cache_lut.ctrl.valid ) 01767 { 01768 if( NF_TRANS_FLUSH==mode ) 01769 { 01770 if ( TRUE==g_cache_lut.ctrl.dirty ) 01771 { 01772 nf_cache_lut_flush(); 01773 nf_cache_lut_refill(g_log_block_id); 01774 } 01775 } 01776 01777 if(( g_log_block_id<g_cache_lut.first ) 01778 || ( g_log_block_id>g_cache_lut.last )) 01779 { // MISS: need to refill the cache 01780 01781 if ( TRUE==g_cache_lut.ctrl.dirty ) { nf_cache_lut_flush(); } 01782 nf_cache_lut_refill(g_log_block_id); 01783 } 01784 } 01785 else { nf_cache_lut_refill(g_log_block_id); } // The cache is not valid. Just re-fill it. 01786 01787 01788 01789 if ( TRUE==g_cache_fbb.ctrl.valid ) 01790 { 01791 if( NF_TRANS_FLUSH==mode ) 01792 { 01793 if ( TRUE==g_cache_fbb.ctrl.dirty ) 01794 { 01795 nf_cache_fbb_flush( FALSE ); 01796 nf_cache_fbb_refill(); 01797 } 01798 } 01799 } 01800 else { nf_cache_fbb_refill(); } 01801 01802 01803 01804 u8_curr_page = (g_log_block_id-g_cache_lut.first)*NF_N_DEVICES; 01805 u8_last_page = (U16)g_cache_fbb.p*NF_N_DEVICES; 01806 01807 for( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++, u8_curr_page++, u8_last_page++) 01808 { 01809 if( NF_TRANS_SWAP==mode ) 01810 { 01811 nf_swap(u8_tmp, u8_curr_page, u8_last_page); 01812 } 01813 01814 g_phys_page_addr[u8_tmp] = nf_block_2_page( g_cache_lut.mem[u8_curr_page] ); // ... Then adapt it to page number 01815 } 01816 01817 if( NF_TRANS_SWAP==mode ) 01818 { 01819 g_cache_fbb.p++; 01820 if( g_cache_fbb.p==(g_cache_fbb.max-1) ) 01821 { // Only 1 remaining entry in FBB cache 01822 nf_cache_fbb_flush( FALSE ); // No dirty test, since we know that the cache is dirty 01823 nf_cache_fbb_refill(); 01824 } 01825 } 01826 else 01827 { 01828 // Build the physical memory address 01829 // 01830 u8_shift = // page offset is 01831 ( s_curr_log_sector >> S_SHIFT_LOG_PAGE_SECTOR ) // convert sector id to page id 01832 & ( SIZE_BLOCK_PAGE -1 ) // modulo number of phys pages in a phys block 01833 ; 01834 01835 for ( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ ) 01836 { 01837 if ( u8_tmp<g_curr_dev_id ) { g_phys_page_addr[u8_tmp] += u8_shift + 1 ; } // already read 01838 else { g_phys_page_addr[u8_tmp] += u8_shift ; } // to be read 01839 } 01840 } 01841 01842 g_next_phys_page_addr=g_phys_page_addr[g_curr_dev_id]; 01843 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(); 01844 }
| 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 844 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().
00845 { 00846 if(( check_pending_write ) 00847 && ( 0xFFFFFFFF!=g_last_log_sector )) 00848 { 00849 nf_copy_tail(); 00850 } 00851 00852 // Both LUT and FBB caches are flushed. Why? 00853 // - Avoid LUT/FBB caches flush and refill during audio playback 00854 // - Avoid recovery on power-on 00855 nf_translate( NF_TRANS_FLUSH ); 00856 00857 return PASS; 00858 }
| 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 877 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().
00878 { 00879 U8 u8_tmp; 00880 _MEM_TYPE_SLOW_ U8 u8_curr_page; 00881 _MEM_TYPE_SLOW_ U8 u8_last_page; 00882 U16 u16_tmp; 00883 00884 if(( check_pending_write ) 00885 && ( 0xFFFFFFFF!=g_last_log_sector )) 00886 { 00887 nf_copy_tail(); 00888 } 00889 00890 nf_translate( NF_TRANS_SWAP ); 00891 00892 // both FBB and LUT blocks are invalid 00893 // Mark FBB only. Warning: Partial Prog 00894 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 00895 nfc_open_page_write( 00896 nf_block_2_page( g_fbb_block_addr ) // base address 00897 + (U32)g_fbb_block_index // offset to Free-blocks block entry 00898 , NF_SPARE_POS+NFC_SPARE_OFST_6_LBA ); 00899 Nfc_wr_data( NFC_OFST_6_FBB_INVALID ); // 6- FBB-LUTs are invalid 00900 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); // Warning: Partial Programming 00901 00902 // Mark sources blocks (recovery). Warning: Partial Prog 00903 for( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ ) 00904 { 00905 Nfc_action(NFC_ACT_DEV_SELECT, u8_tmp); 00906 nfc_open_page_write( 00907 nf_block_2_page( g_block_to_kill[u8_tmp] ) 00908 , NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3 ); 00909 Nfc_wr_data( NFC_OFST_3_DATA_SRC ); // 3- [SW] Mark as source block (recovery) (HW capability not used) 00910 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); // Warning: Partial Programming 00911 } 00912 00913 // Copy the head of the buffer 00914 // 00915 // for each logical page (current included) 00916 u8_last_page= (s_curr_log_sector >>S_SHIFT_LOG_PAGE_SECTOR) & (SIZE_BLOCK_PAGE -1); 00917 for( u8_curr_page=0 00918 ; u8_curr_page <= u8_last_page 00919 ; u8_curr_page++ ) 00920 { 00921 // If the last page (current) 00922 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 00923 else { u8_tmp = NF_N_DEVICES; } // else copy this physical page for all device 00924 00925 while( u8_tmp!=0 ) // for each device 00926 { 00927 u8_tmp--; 00928 Nfc_action(NFC_ACT_DEV_SELECT, u8_tmp); 00929 00930 g_copy_src= nf_block_2_page( g_block_to_kill[u8_tmp] ) + u8_curr_page; 00931 nf_copy(g_phys_page_addr[u8_tmp]); 00932 g_phys_page_addr[u8_tmp]++; 00933 } 00934 // end of loop, for each device 00935 } 00936 // end of loop, for each logical page 00937 00938 u16_tmp= 00939 (SIZE_SECTOR_BYTE) // size (unit byte) of the sector (spare zone excluded) 00940 * ( s_curr_log_sector // current sector in physical page 00941 & (SIZE_PAGE_SECTOR -1) 00942 ); 00943 00944 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00945 if( u16_tmp ) 00946 { 00947 //** copy the head of the current physical page 00948 nfc_open_page_read( nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) + u8_last_page, 0 ); 00949 // copy the head page of the old block in buffer 00950 nf_upload(g_page_buffer, (U8)(u16_tmp/16)); 00951 } 00952 00953 // copy the buffer in the head page of the new block 00954 nfc_open_page_write( g_phys_page_addr[g_curr_dev_id], 0 ); 00955 00956 // write the first byte to the current byte position in the physical page 00957 nf_download(g_page_buffer, (U8)(u16_tmp/16)); 00958 // END of the copy head 00959 00960 return PASS; 00961 } // 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 977 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().
00978 { 00979 U8 u8_tmp; 00980 U8 sub_lut_id; 00981 00982 U16 byte_addr; 00983 _MEM_TYPE_SLOW_ U32 page_addr; 00984 _MEM_TYPE_SLOW_ U16 sub_lut_log_sz; // size of the sub-LUT. Unit in logical blocks. 00985 _MEM_TYPE_SLOW_ U16 sub_lut_log_first; // number of the first logical block of the sub-lut. 00986 00987 Assert( g_cache_lut.ctrl.dirty==FALSE ); // No refill if the cache is dirty 00988 00989 sub_lut_id = log_block_id>>( NF_SHIFT_SUBLUT_PHYS - NF_SHIFT_N_DEVICES); 00990 sub_lut_log_sz = ( sub_lut_id==(g_n_sub_lut-1) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ); 00991 sub_lut_log_first = (U16)sub_lut_id<<( NF_SHIFT_SUBLUT_PHYS - NF_SHIFT_N_DEVICES); 00992 00993 trace("nf_cache_lut_refill;"); trace_hex16(g_lut_block_addr[sub_lut_id]);trace_nl(); 00994 00995 if (sub_lut_log_sz<NF_CACHE_LUT_LOG_SZ) 00996 { // The cache is bigger than the sub LUT 00997 g_cache_lut.first = log_block_id; // First included 00998 g_cache_lut.last = log_block_id + (sub_lut_log_sz-1); // Last included 00999 } 01000 else if ( (log_block_id+NF_CACHE_LUT_LOG_SZ) <= (sub_lut_log_first+sub_lut_log_sz) ) 01001 { // The cache is done starting from the logical block number 01002 g_cache_lut.first = log_block_id; // First included 01003 g_cache_lut.last = log_block_id + (NF_CACHE_LUT_LOG_SZ-1); // Last included 01004 } 01005 else 01006 { // The cache is done starting from the last logical block of the sub-LUT 01007 g_cache_lut.last = sub_lut_log_first +sub_lut_log_sz -1; // Last included 01008 g_cache_lut.first = g_cache_lut.last - (NF_CACHE_LUT_LOG_SZ-1); // First included 01009 } 01010 01011 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01012 01013 page_addr = 01014 nf_block_2_page( g_lut_block_addr[sub_lut_id]) // base address 01015 + (U32)(g_lut_block_index[sub_lut_id]) // offset to sub-LUT 01016 ; 01017 byte_addr = ( (g_cache_lut.first-sub_lut_log_first)*NF_N_DEVICES*2 ); // logical position of the block 01018 Assert( byte_addr<SIZE_PAGE_BYTE ); 01019 01020 nfc_open_page_read( page_addr, byte_addr); 01021 trace_hex32(page_addr); trace(";"); trace_hex16(byte_addr);trace_nl(); 01022 for ( u8_tmp=0 ; u8_tmp<(g_cache_lut.last+1-g_cache_lut.first)*NF_N_DEVICES ; u8_tmp++ ) 01023 { // fill the cache buffer 01024 Assert( u8_tmp<CACHE_LUT_SIZE); 01025 MSB(g_cache_lut.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01026 LSB(g_cache_lut.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01027 trace_hex16(g_cache_lut.mem[u8_tmp]); 01028 trace("-"); 01029 Assert( g_cache_lut.mem[u8_tmp]>=g_nf_first_block ); 01030 Assert( g_cache_lut.mem[u8_tmp]< G_N_BLOCKS ); 01031 } 01032 trace_nl(); 01033 g_cache_lut.ctrl.valid = TRUE; 01034 } // 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 1096 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().
01097 { 01098 _MEM_TYPE_SLOW_ U32 page_addr; 01099 U16 byte_addr; 01100 _MEM_TYPE_SLOW_ U16 sub_lut_log_sz; 01101 _MEM_TYPE_SLOW_ U8 sub_lut_id; 01102 U8 u8_tmp; 01103 01104 Assert(TRUE==g_cache_lut.ctrl.valid); 01105 Assert(TRUE==g_cache_lut.ctrl.dirty); 01106 01107 sub_lut_id = g_cache_lut.first>>(NF_SHIFT_SUBLUT_PHYS-NF_SHIFT_N_DEVICES); 01108 sub_lut_log_sz = ( sub_lut_id==(g_n_sub_lut-1) ) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ; 01109 01110 trace("nf_cache_lut_flush;"); trace_hex16(g_lut_block_addr[sub_lut_id]);trace_nl(); 01111 01112 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01113 01114 page_addr= 01115 nf_block_2_page( g_lut_block_addr[sub_lut_id] ) // base address 01116 + (U32)(g_lut_block_index[sub_lut_id]) // offset to sub-LUT 01117 ; 01118 01119 nfc_open_page_read( page_addr, 0); 01120 01121 for ( byte_addr=0 /* used as block address! */ ; byte_addr<(sub_lut_log_sz*NF_N_DEVICES) ; ) 01122 { // Read the LUT stored in Nand 01123 g_page_buffer[2*byte_addr ] = Nfc_rd_data_fetch_next(); 01124 g_page_buffer[2*byte_addr +1] = Nfc_rd_data_fetch_next(); 01125 #if (_ASSERT_==ENABLE) 01126 MSB(_debug)= g_page_buffer[2*byte_addr ]; 01127 LSB(_debug)= g_page_buffer[2*byte_addr +1]; 01128 Assert( _debug>=g_nf_first_block ); 01129 Assert( _debug< G_N_BLOCKS ); 01130 #endif 01131 byte_addr ++; 01132 } 01133 01134 // Modify the page 01135 // 01136 byte_addr = // logical position of the block 01137 ( g_cache_lut.first // Absolute logical block number... 01138 & ( (U16)NF_SUBLUT_SIZE/NF_N_DEVICES -1) // ...Modulo the number of logical block in a LUT 01139 ) 01140 * NF_N_DEVICES*2; 01141 01142 Assert( byte_addr<2048 ); 01143 01144 for ( u8_tmp=0 ; u8_tmp<(g_cache_lut.last+1-g_cache_lut.first)*NF_N_DEVICES ; u8_tmp++ ) 01145 { // flush the cache buffer in the buffer 01146 Assert( u8_tmp<CACHE_LUT_SIZE ); 01147 Assert( byte_addr<(NF_PAGE_BUFFER_SIZE-1) ); 01148 Assert( g_cache_lut.mem[u8_tmp]>=g_nf_first_block ); 01149 Assert( g_cache_lut.mem[u8_tmp]< G_N_BLOCKS ); 01150 g_page_buffer[byte_addr++] = MSB(g_cache_lut.mem[u8_tmp]) ; 01151 g_page_buffer[byte_addr++] = LSB(g_cache_lut.mem[u8_tmp]) ; 01152 } 01153 01154 // Program the page 01155 // 01156 g_lut_block_index[sub_lut_id]++; 01157 01158 if ( g_lut_block_index[sub_lut_id] == (1<<G_SHIFT_BLOCK_PAGE) ) 01159 { // Need a new block for the flush 01160 _MEM_TYPE_SLOW_ U16 u16_swap; 01161 01162 if ( FALSE==g_cache_fbb.ctrl.valid ) { nf_cache_fbb_refill(); } 01163 01164 #define U16_FBB_OFST ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV) 01165 Assert( g_cache_fbb.mem[U16_FBB_OFST]>=g_nf_first_block ); 01166 Assert( g_cache_fbb.mem[U16_FBB_OFST]< G_N_BLOCKS ); 01167 u16_swap = g_lut_block_addr[ sub_lut_id] ; 01168 g_lut_block_addr[ sub_lut_id] = g_cache_fbb.mem[U16_FBB_OFST] ; 01169 g_cache_fbb.mem[U16_FBB_OFST] = u16_swap ; 01170 g_lut_block_index[sub_lut_id] = 0; 01171 #undef U16_FBB_OFST 01172 01173 trace("nf_cache_lut_flush;swap;"); trace_hex16(g_lut_block_addr[sub_lut_id]);trace_nl(); 01174 g_cache_fbb.ctrl.dirty=TRUE; 01175 01176 nf_write_lut(0, sub_lut_id, sub_lut_log_sz); // TODO: we should test the status returned 01177 01178 nfc_erase_block( nf_block_2_page( u16_swap ), TRUE ); 01179 01180 g_cache_fbb.p++; 01181 if( g_cache_fbb.p==(g_cache_fbb.max-1) ) 01182 { // Only 1 remaining entry in FBB cache 01183 nf_cache_fbb_flush( FALSE ); // No dirty test, since we know that the cache is dirty 01184 nf_cache_fbb_refill(); 01185 } 01186 } 01187 else 01188 { 01189 nf_write_lut(0, sub_lut_id, sub_lut_log_sz); // TODO: we should test the status returned 01190 } 01191 01192 g_cache_lut.ctrl.dirty=FALSE; 01193 01194 Nf_check_fbb( FALSE ); 01195 Nf_check_lut(); 01196 } // end of nf_cache_lut_flush
| static void nf_erase_old_blocks | ( | void | ) | [static] |
Erase the source blocks.
| none |
Definition at line 816 of file nf_mngt.c.
References 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().
00817 { 00818 U8 i; 00819 00820 // Delete old blocks 00821 // 00822 for ( i=0 ; i<NF_N_DEVICES ; i++ ) 00823 { 00824 Nfc_action(NFC_ACT_DEV_SELECT, i); 00825 trace("nf_erase_old_blocks;"); trace_hex16(g_block_to_kill[i]);trace_nl(); 00826 nfc_erase_block( nf_block_2_page(g_block_to_kill[i]), TRUE ); 00827 } 00828 }
| 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 487 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().
00488 { 00489 if ( // Are we processing the last page ? 00490 ( (s_curr_log_sector & (SIZE_PAGE_SECTOR-1)) 00491 + s_n_sectors 00492 ) 00493 < SIZE_PAGE_SECTOR 00494 ) { 00495 s_state = STATE_COMPLETE; 00496 return TRUE; 00497 } 00498 00499 // Update position variables 00500 s_n_sectors -= s_nb_sectors_step; 00501 s_curr_log_sector += s_nb_sectors_step; 00502 s_curr_n_byte = 0; 00503 if (s_n_sectors < SIZE_PAGE_SECTOR) 00504 s_nb_sectors_step = (U8) (s_n_sectors); // next page must be read as partial (not all sectors remaining) 00505 else 00506 s_nb_sectors_step = SIZE_PAGE_SECTOR; // next page to be read considered as entire (all sectors requested) 00507 00508 // Save current parameters 00509 g_save_curr_dev_id = g_curr_dev_id; 00510 g_save_phys_page_addr = g_phys_page_addr[g_curr_dev_id]; 00511 00512 // Fetch the next device id 00513 // 00514 g_phys_page_addr[g_curr_dev_id]+=1; 00515 g_curr_dev_id ++; 00516 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 00517 00518 g_next_phys_page_addr = g_phys_page_addr[g_curr_dev_id]; 00519 00520 if( s_n_sectors==0 ) // Operation complete ! 00521 { 00522 s_state = STATE_COMPLETE; 00523 return TRUE; 00524 } 00525 00526 return FALSE; 00527 }
| 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 629 of file nf_mngt.c.
References Is_usb_endpoint_enabled, Is_usb_read_enabled, Nf_wr_byte, Usb_ack_receive_out, and Usb_read_byte.
Referenced by nf_write_10().
00630 { 00631 U8 j; 00632 for (j = 8*nb_sectors ; j != 0 ; j--) // 8 * 64 bytes = 512 bytes 00633 { 00634 while(!Is_usb_read_enabled()) 00635 { 00636 if(!Is_usb_endpoint_enabled()) 00637 return; // USB Reset 00638 } 00639 Disable_interrupt(); // Global disable. 00640 00641 Nf_wr_byte(Usb_read_byte()); // write 64 bytes to the card 00642 Nf_wr_byte(Usb_read_byte()); 00643 Nf_wr_byte(Usb_read_byte()); 00644 Nf_wr_byte(Usb_read_byte()); 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 00706 Usb_ack_receive_out(); // USB EPOUT read acknowledgement. 00707 Enable_interrupt(); // Global re-enable. 00708 } 00709 }
| 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 537 of file nf_mngt.c.
References FALSE, Is_usb_endpoint_enabled, Is_usb_write_enabled, Nf_rd_byte, Usb_send_in, and Usb_write_byte.
Referenced by nf_read_10().
00538 { 00539 U8 j; 00540 00541 for (j = 8*nb_sectors; j != 0; j--) // 8 * 64 bytes = 512 bytes 00542 { 00543 Disable_interrupt(); 00544 00545 Usb_write_byte(Nf_rd_byte()); // read 64 bytes from card 00546 Usb_write_byte(Nf_rd_byte()); 00547 Usb_write_byte(Nf_rd_byte()); 00548 Usb_write_byte(Nf_rd_byte()); 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 Enable_interrupt(); 00610 00611 Usb_send_in(); // validate transfer 00612 while(Is_usb_write_enabled()==FALSE) 00613 { 00614 if(!Is_usb_endpoint_enabled()) 00615 return; // USB Reset 00616 } 00617 } 00618 }
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 721 of file nf_mngt.c.
References _MEM_TYPE_SLOW_, 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().
00722 { 00723 // Calculate first spare zone address 00724 U8 i; 00725 _MEM_TYPE_SLOW_ U16 byte_addr = NF_SPARE_POS + ((U16)sect_start)*16; 00726 00727 // Send command + address if 2kb' page model 00728 if (Is_nf_2k()) 00729 { 00730 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 00731 Nfc_set_adc( (byte_addr)%256 ); 00732 Nfc_set_adc( (byte_addr)/256 ); 00733 } 00734 00735 // Send data (spare zone x sectors written) 00736 for( i=nb_sect ; i!=0 ; i-- ) 00737 { 00738 Nfc_wr_data( 0xFF ); // 0- [FW] block is valid (for 2048 compatibility) 00739 Nfc_wr_data( NFC_BLK_ID_DATA ); // 1- [FW] Free-blocks block 00740 Nfc_wr_data( 0 ); // 2- [HW] ECC is valid 00741 Nfc_wr_data( NFC_OFST_3_DATA_DST ); // 3- [SW] Source block (recovery) (HW capability not used) 00742 Nfc_wr_data( NFC_SPARE_DATA_VALID ); // 4- [FW] Data is valid 00743 Nfc_wr_data( 0xFF ); // 5- [FW] block is valid (for 512 compatibility) 00744 Nfc_wr_data( MSB(g_log_block_id) ); // 6- [HW] LBA 00745 Nfc_wr_data( LSB(g_log_block_id) ); // 7- [HW] LBA 00746 Nfc_wr_data( 0xFF ); // 8-9-10- [HW] ECC2 00747 Nfc_wr_data( 0xFF ); 00748 Nfc_wr_data( 0xFF ); 00749 Nfc_wr_data( 0xFF ); // 11-12- [HW] LBA 00750 Nfc_wr_data( 0xFF ); 00751 Nfc_wr_data( 0xFF ); 00752 Nfc_wr_data( 0xFF ); 00753 Nfc_wr_data( 0xFF ); // 13-14-15- [HW] ECC1 00754 } 00755 }
| Status_bool nf_verify | ( | void | ) |
Ensure that the memory is in a good state before starting to use it.
| none |
Definition at line 199 of file nf_mngt.c.
Referenced by nf_read_capacity(), and nf_test_unit_ready().
00200 { 00201 if ( g_nf_init ) return PASS; 00202 00203 return nf_verify_resume(); 00204 }
| Ctrl_status nf_test_unit_ready | ( | void | ) |
Initializes the NF driver on the first USB Test Unit Ready.
| none |
Definition at line 215 of file nf_mngt.c.
Referenced by main().
00216 { 00217 Status_bool tmp_bool; 00218 00219 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00220 nf_XMCR_enable(); 00221 #endif 00222 00223 tmp_bool = nf_verify(); 00224 00225 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00226 nf_XMCR_disable(); 00227 #endif 00228 00229 return ( tmp_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL; 00230 }
| Ctrl_status nf_read_capacity | ( | U32 * | u32_nb_sector | ) |
Returns the address of the last valid logical sector.
| none |
Definition at line 240 of file nf_mngt.c.
00241 { 00242 Status_bool status_bool; 00243 00244 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00245 nf_XMCR_enable(); 00246 #endif 00247 00248 status_bool = nf_verify(); 00249 00250 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00251 nf_XMCR_disable(); 00252 #endif 00253 00254 *u32_nb_sector = nf_get_sectors_number()-1; 00255 return ( status_bool==PASS ) ? CTRL_GOOD : CTRL_FAIL; 00256 }
| Bool nf_wr_protect | ( | void | ) |
| Bool nf_removal | ( | void | ) |
| U32 nf_get_sectors_number | ( | void | ) |
Returns a pointer on the internal buffer address.
This function is used for test only.
| none |
| none |
Definition at line 293 of file nf_mngt.c.
Referenced by nf_read_10(), nf_read_capacity(), and nf_write_10().
00294 { 00295 return 00296 (U32)g_n_export_blocks 00297 << (G_SHIFT_BLOCK_PAGE +G_SHIFT_PAGE_BYTE -S_SHIFT_SECTOR_BYTE) 00298 ; 00299 }
Definition at line 303 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().
00304 { 00305 return (U32)block_addr<<G_SHIFT_BLOCK_PAGE; 00306 }
| Ctrl_status nf_read_10 | ( | U32 | log_sector, | |
| U16 | n_sectors | |||
| ) |
This function initializes the Nand Flash for a read operation.
| log_sector | Logical sector address to start read | |
| nb_sector | Number of sectors to transfer |
Definition at line 317 of file nf_mngt.c.
00318 { 00319 U8 status; 00320 00321 if ( !g_nf_init ) 00322 while(1); // You shall call once mem_test_unit_ready() before. 00323 00324 // Test that the logical sector address is valid 00325 // 00326 if ( 0==n_sectors ) { return CTRL_GOOD; } 00327 if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; } 00328 00329 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00330 nf_XMCR_enable(); 00331 #endif 00332 00333 s_n_sectors = n_sectors; 00334 s_curr_log_sector = log_sector; 00335 trace("rd;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl(); 00336 s_save_log_addr = log_sector + n_sectors; 00337 g_fatal = FALSE; 00338 s_mem = TRUE; 00339 s_start = TRUE; 00340 00341 // First read operation 00342 Nf_access_signal_on(); 00343 nf_open_read(TRUE); 00344 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00345 nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte ); 00346 nf_read_sector_to_usb(s_nb_sectors_step); 00347 status = nf_xfer_update_vars(); 00348 00349 // Next read operations 00350 while (status == FALSE) // exit when last page read 00351 { 00352 if (!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00353 && (g_curr_dev_id==0 )) // on device 0. Should this case be implicit ? If yes, we can remove it. 00354 { 00355 nf_open_read(FALSE); 00356 } 00357 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00358 Nfc_open_page_read( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution 00359 nf_read_sector_to_usb(s_nb_sectors_step); // read the concerned sectors of the selected page 00360 status = nf_xfer_update_vars(); // check if last page or not 00361 } 00362 00363 Nf_access_signal_off(); 00364 00365 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00366 nf_XMCR_disable(); 00367 #endif 00368 00369 return CTRL_GOOD; 00370 }
| Ctrl_status nf_write_10 | ( | U32 | log_sector, | |
| U16 | n_sectors | |||
| ) |
This function initializes the Nand Flash for a write operation.
| log_sector | Logical sector address to start read | |
| nb_sector | Number of sectors to transfer |
Definition at line 381 of file nf_mngt.c.
00382 { 00383 U8 status; 00384 Ctrl_status tmp_bool; 00385 00386 // Test that the logical sector address is valid 00387 if ( 0==n_sectors ) { return CTRL_GOOD; } 00388 if ( (log_sector+n_sectors)>nf_get_sectors_number() ) { return CTRL_FAIL; } 00389 00390 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00391 nf_XMCR_enable(); 00392 #endif 00393 00394 s_n_sectors = n_sectors; 00395 s_curr_log_sector = log_sector; 00396 s_save_log_addr = log_sector + n_sectors; 00397 g_fatal = FALSE; 00398 s_mem = TRUE; 00399 s_start = TRUE; 00400 00401 trace("wr;"); trace_hex32(s_curr_log_sector); trace(";"); trace_hex16(s_n_sectors); trace_nl(); 00402 00403 // First write operation 00404 Nf_access_signal_on(); 00405 if(( s_curr_log_sector==g_last_log_sector ) // New write is just after to the last write 00406 && (!( ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1))) // Not on a logical block boundary 00407 && ( g_curr_dev_id==0 )))) 00408 { 00409 trace("continue");trace_nl(); 00410 nf_translate( NF_TRANS_NORMAL ); 00411 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 00412 nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); 00413 } 00414 else 00415 { 00416 nf_open_write( TRUE ); 00417 } 00418 nf_write_sector_from_usb(s_nb_sectors_step); // s_nb_sectors_step has been calculated in nf_translate() 00419 if (Is_nf_2k()) 00420 { 00421 nf_update_spare_zone((U8)(1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-s_nb_sectors_step, s_nb_sectors_step); // update the spare zone once the page has been filled in 00422 } 00423 else 00424 { 00425 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 00426 } 00427 g_last_log_sector = s_curr_log_sector + s_nb_sectors_step; // Memorize next logical sector to be managed 00428 status = nf_xfer_update_vars(); 00429 00430 // Next write operations 00431 while (status == FALSE) // exit when operation finished 00432 { 00433 if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00434 && (g_curr_dev_id==0 )) // on device 0. 00435 { 00436 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page 00437 nf_erase_old_blocks(); 00438 nf_open_write( FALSE ); 00439 } 00440 else 00441 { 00442 if( G_CACHE_PROG ) 00443 { 00444 Nfc_set_cmd(NF_CACHE_PROGRAM_CMD); 00445 }else{ 00446 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 00447 } 00448 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 00449 Nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); // Use macro for fast execution 00450 } 00451 nf_write_sector_from_usb(s_nb_sectors_step); 00452 if (Is_nf_2k()) 00453 { 00454 nf_update_spare_zone(0, s_nb_sectors_step); 00455 } 00456 else 00457 { 00458 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 00459 } 00460 g_last_log_sector = s_curr_log_sector + s_nb_sectors_step; // Memorize next logical sector to be managed 00461 status = nf_xfer_update_vars(); // check if last block or not 00462 } 00463 00464 tmp_bool = nf_dfc_write_stop(0); // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement 00465 Nf_access_signal_off(); 00466 00467 #if (NF_XMCR_MODULE_SHARED == ENABLED) 00468 nf_XMCR_disable(); 00469 #endif 00470 00471 return tmp_bool; 00472 }
| Ctrl_status nf_dfc_write_stop | ( | U16 | u16_nb_sector_remaining | ) |
This function must be called when a write10 operation (from USB) is finished Last page written is programmed and environment is saved.
| log_sector | Logical sector address to start read | |
| nb_sector | Number of sectors to transfer |
Definition at line 767 of file nf_mngt.c.
Referenced by nf_ram_2_nf(), and nf_write_10().
00768 { 00769 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); // Program the page 00770 // Note that if the page is not completely filled in yet but still programmed, the next copy tail will allow partial page program 00771 00772 // retreive exact logical/physical position (in case that transfer 00773 // did not perform the exact number of sectors) 00774 s_curr_log_sector = s_save_log_addr - u16_nb_sector_remaining; 00775 if( 0!=u16_nb_sector_remaining ) 00776 { 00777 nf_translate( NF_TRANS_NORMAL ); 00778 } 00779 g_last_log_sector = s_curr_log_sector; // Memorize next logical sector to be managed 00780 00781 // Test if transfer stop at end of logical blocks. 00782 if( s_n_sectors==0 ) 00783 { 00784 if(!(LSB0(g_next_phys_page_addr) & (SIZE_BLOCK_PAGE-1)) // new block 00785 && (g_curr_dev_id==0 )) // on device 0. 00786 { 00787 // Delete old blocks 00788 // 00789 nf_erase_old_blocks(); 00790 } 00791 } 00792 trace("nf_dfc_write_stop;"); trace_hex32(g_last_log_sector); trace_nl(); 00793 00794 // Ensure that all internal programming are complete, since we are 00795 // using cache programming (WP may be asserted for icons or fonts 00796 // loading). Moreover, on some NFs (ST, Samsung) 00797 // it is necessary to reset the devices after copy-back commands 00798 // If not, strange behaviour may happen: no busy when opening 00799 // a page for reading... 00800 nfc_reset_nands( NF_N_DEVICES ); // Reset all the NF devices 00801 00802 Nf_check_fbb( FALSE ); 00803 Nf_check_lut(); 00804 00805 return CTRL_GOOD; 00806 } // end of nf_dfc_write_stop
| void nf_cache_fbb_refill | ( | void | ) |
Reload the FBB cache memory, starting from 0.
The cache is filled with physical blocks.
| none |
Definition at line 1046 of file nf_mngt.c.
Referenced by nf_cache_lut_flush(), nf_translate(), and nf_usb_stop().
01047 { 01048 U8 u8_tmp; 01049 U16 byte_addr; 01050 _MEM_TYPE_SLOW_ U32 page_addr; 01051 01052 Assert(g_cache_fbb.ctrl.dirty==FALSE); // No refill if the cache is dirty 01053 g_cache_fbb.p = 0; 01054 01055 trace("nf_cache_fbb_refill;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01056 01057 // Ensure that the cache is bigger than the real number of free blocks 01058 // 01059 g_cache_fbb.max = Min(NF_CACHE_FBB_LOG_SZ, (g_n_free_blocks>>NF_SHIFT_N_DEVICES) ); // Last included 01060 01061 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01062 01063 page_addr = 01064 nf_block_2_page( g_fbb_block_addr ) // base address 01065 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01066 ; 01067 byte_addr=0; 01068 01069 nfc_open_page_read(page_addr, 0); 01070 01071 for ( u8_tmp=0 ; u8_tmp<g_cache_fbb.max*NF_N_DEVICES ; u8_tmp++ ) 01072 { // fill the cache buffer 01073 Assert( u8_tmp<CACHE_FBB_SIZE); 01074 MSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01075 LSB(g_cache_fbb.mem[u8_tmp]) = Nfc_rd_data_fetch_next(); 01076 Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block ); 01077 Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS ); 01078 byte_addr+=2; 01079 Assert( byte_addr<SIZE_PAGE_BYTE); // Should stay in the page. Algo limitation. 01080 } 01081 g_cache_fbb.ctrl.valid = TRUE; 01082 } // end of nf_cache_fbb_refill
| Status_bool nf_write_lut | ( | U8 | pos, | |
| U8 | i_sub_lut, | |||
| U16 | sub_lut_log_sz | |||
| ) |
Writes a LUT in memory from a buffer.
| pos | offset of the lub-lut in the buffer | |
| i_sub_lut | id of the sub-LUT | |
| sub_lut_log_sz | Size of the sub-LUT, in logical block unit |
Definition at line 1210 of file nf_mngt.c.
Referenced by nf_cache_lut_flush(), and nf_rebuild().
01214 { 01215 U16 block_addr; // Physical block number 01216 U8 _MEM_TYPE_SLOW_ * p_buf=g_page_buffer + (U16)pos*((U16)1<<(G_SHIFT_PAGE_BYTE)); 01217 01218 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01219 // The buffer is built as: 01220 // | 512 | 512 | 512 | 512 | 01221 // 01222 // The page is built as: 01223 // | 512 | 512 | 512 | 512 |SZ| 01224 // 01225 // The LUT fits in a physical page. 01226 // 01227 nfc_open_page_write( 01228 nf_block_2_page( g_lut_block_addr[i_sub_lut] ) // base address 01229 + (U32)(g_lut_block_index[i_sub_lut]) // offset to sub-LUT 01230 , 0 ); 01231 01232 trace("nf_write_lut;");trace_hex16(g_lut_block_addr[i_sub_lut]); trace(";"); trace_hex16(g_lut_block_index[i_sub_lut]);trace_nl(); 01233 for( block_addr=0 ; block_addr<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; block_addr+=1 ) 01234 { 01235 if ( block_addr<(sub_lut_log_sz*NF_N_DEVICES) ) 01236 { 01237 #if (_ASSERT_==ENABLE) 01238 Assert( ( block_addr*2)<(NF_PAGE_BUFFER_SIZE-1) ); 01239 MSB(_debug)= p_buf[ block_addr*2 ] ; 01240 LSB(_debug)= p_buf[ block_addr*2 +1] ; 01241 Assert( _debug>=g_nf_first_block ); 01242 Assert( _debug< G_N_BLOCKS ); 01243 #endif 01244 Nfc_wr_data( p_buf[ block_addr*2 ] ); 01245 Nfc_wr_data( p_buf[ block_addr*2 +1] ); 01246 trace_hex(p_buf[ block_addr*2 ]); 01247 trace_hex(p_buf[ block_addr*2 +1]); 01248 trace("-"); 01249 } 01250 else 01251 { 01252 Nfc_wr_data( 0xFF ); 01253 Nfc_wr_data( 0xFF ); 01254 trace("FFFF-"); 01255 } 01256 } 01257 trace_nl(); 01258 01259 // Write the spare information 01260 // 01261 Nfc_wr_data( 0xFF ); // 0- block is valid (for 2048 compatibility) 01262 Nfc_wr_data( NFC_BLK_ID_SUBLUT ); // 1- sub-LUT 01263 Nfc_wr_data( i_sub_lut ); // 2- sub-LUT id 01264 Nfc_wr_data( 0xFF ); // 3- unused 01265 Nfc_wr_data( g_n_sub_lut ); // 4- number of sub-LUT 01266 Nfc_wr_data( 0xFF ); // 5- block is valid (for 512 compatibility) 01267 Nfc_wr_data( MSB(sub_lut_log_sz) ); // 6-7 Number of log blocks in sub-LUT 01268 Nfc_wr_data( LSB(sub_lut_log_sz) ); 01269 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10- ECC2 01270 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 11-12- LBA 01271 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- ECC1 01272 01273 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); 01274 if ( FAIL==nfc_check_status() ) { return FAIL; } 01275 01276 return PASS; 01277 } // end of nf_write_lut
| void nf_cache_fbb_flush | ( | Bool | b_ecc_err | ) |
Flushes the FBB cache into a new FBB entry.
A copy of the current FBB is made in a new page, taking into account the last FBB modification in its cache. If the block containing the FBB is full, a new block is taken from the FBB itself.
| b_ecc_err | FALSE: normal operation, b_ecc_err TRUE: remove a block from list (p) |
Definition at line 1292 of file nf_mngt.c.
Referenced by nf_cache_lut_flush(), nf_translate(), and nf_usb_stop().
01293 { 01294 _MEM_TYPE_SLOW_ U32 page_addr; 01295 _MEM_TYPE_SLOW_ U16 byte_addr; 01296 _MEM_TYPE_SLOW_ U16 u16_delete=0; 01297 _MEM_TYPE_SLOW_ U16 u16_tmp; 01298 U8 u8_tmp; 01299 _MEM_TYPE_SLOW_ U8 u8_pos; 01300 Bool bool_delete=FALSE; 01301 01302 Assert(TRUE==g_cache_fbb.ctrl.valid); 01303 Assert(TRUE==g_cache_fbb.ctrl.dirty); 01304 // Assert(g_cache_fbb.p==(g_cache_fbb.max-1)); This is no more the case for ECC error not correctable 01305 01306 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01307 01308 trace("nf_cache_fbb_flush;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01309 01310 page_addr= 01311 nf_block_2_page( g_fbb_block_addr ) // base address 01312 + (U32)g_fbb_block_index // offset to page 01313 ; 01314 01315 g_fbb_block_index++; 01316 01317 if ( g_fbb_block_index == (1<<G_SHIFT_BLOCK_PAGE)/(1<<0) ) 01318 { // Need to recycle the FBB block itself, using a free-block ! This is always possible 01319 // since there is always a free block (.p=.max-1) specially for that purpose. 01320 byte_addr = ((U16)NF_N_DEVICES*g_cache_fbb.p + S_MNGT_DEV); 01321 01322 Assert( g_cache_fbb.mem[byte_addr]>=g_nf_first_block ); 01323 Assert( g_cache_fbb.mem[byte_addr]< G_N_BLOCKS ); 01324 u16_delete = g_fbb_block_addr ; 01325 g_fbb_block_addr = g_cache_fbb.mem[byte_addr] ; 01326 g_cache_fbb.mem[byte_addr] = u16_delete; 01327 g_fbb_block_index = 0; 01328 01329 trace("nf_cache_fbb_flush;swap;"); trace_hex16(g_fbb_block_addr);trace_nl(); 01330 01331 // g_cache_fbb.ctrl.dirty=TRUE; This is already the case ! 01332 01333 g_cache_fbb.p++; 01334 bool_delete=TRUE; 01335 } 01336 01337 if( !b_ecc_err ) { u8_pos = g_cache_fbb.p; } 01338 else { u8_pos = g_cache_fbb.max; } 01339 01340 byte_addr = ((U16)NF_N_DEVICES*2*u8_pos); 01341 01342 Assert( byte_addr<SIZE_PAGE_BYTE ); 01343 01344 nfc_open_page_read( page_addr, byte_addr); 01345 01346 Assert( g_cache_fbb.p<=(g_n_free_blocks/NF_N_DEVICES) ); 01347 for ( 01348 u16_tmp=0 01349 ; u16_tmp<((g_n_free_blocks/NF_N_DEVICES)-u8_pos)*NF_N_DEVICES*2 01350 ; ) 01351 { // Move the free-blocks after <pos> to the beginning of the buffer. 01352 Assert( u16_tmp<(NF_PAGE_BUFFER_SIZE-3) ); 01353 g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next(); 01354 g_page_buffer[u16_tmp++] = Nfc_rd_data_fetch_next(); 01355 #if (_ASSERT_==ENABLE) 01356 MSB(_debug)= g_page_buffer[u16_tmp-2]; 01357 LSB(_debug)= g_page_buffer[u16_tmp-1]; 01358 Assert( _debug>=g_nf_first_block ); 01359 Assert( _debug< G_N_BLOCKS ); 01360 #endif 01361 } 01362 01363 for ( u8_tmp=0 ; u8_tmp<(u8_pos*NF_N_DEVICES); u8_tmp++ ) 01364 { // Then add the cache content 01365 Assert( u8_tmp < CACHE_FBB_SIZE ); 01366 Assert( u16_tmp< NF_FULL_PAGE_BUFFER_SIZE ); 01367 #if (_ASSERT_==ENABLE) 01368 // When coming from ECC 2-bits error, an entry has been removed 01369 // from the cache, so the last entry is 0xffff 01370 if( !b_ecc_err ) 01371 { 01372 Assert( g_cache_fbb.mem[u8_tmp]>=g_nf_first_block ); 01373 Assert( g_cache_fbb.mem[u8_tmp]< G_N_BLOCKS ); 01374 } 01375 #endif 01376 g_page_buffer[u16_tmp++] = MSB(g_cache_fbb.mem[u8_tmp]); 01377 g_page_buffer[u16_tmp++] = LSB(g_cache_fbb.mem[u8_tmp]); 01378 } 01379 #if (_ASSERT_==ENABLE) 01380 // Ensure that, when there is no fbb recycle, the blocks in the cache at 01381 // position p are identical to the blocks in the beginning of the new line. 01382 if( (FALSE==bool_delete) && ( !b_ecc_err )) 01383 { 01384 for ( u8_tmp=0 ; u8_tmp<NF_N_DEVICES ; u8_tmp++ ) 01385 { 01386 MSB(_debug)= g_page_buffer[u8_tmp*2 ]; 01387 LSB(_debug)= g_page_buffer[u8_tmp*2 +1]; 01388 Assert( _debug==g_cache_fbb.mem[(g_cache_fbb.p)*NF_N_DEVICES + u8_tmp] ); 01389 } 01390 } 01391 #endif 01392 01393 nf_write_fbb(); // Should test the result 01394 Nf_check_fbb( b_ecc_err ); 01395 Nf_check_lut(); 01396 01397 if( TRUE==bool_delete ) 01398 { 01399 nfc_erase_block( nf_block_2_page( u16_delete ), TRUE ); 01400 } 01401 01402 Assert( u16_tmp==(g_n_free_blocks*2) ); // All the list should have been processed 01403 g_cache_fbb.ctrl.dirty=FALSE; 01404 } // end of nf_cache_fbb_flush
| Status_bool nf_write_fbb | ( | void | ) |
Writes the Free-blocks block into the Nand Flash.
| none |
Definition at line 1414 of file nf_mngt.c.
Referenced by nf_cache_fbb_flush(), and nf_rebuild().
01415 { 01416 U16 u16_tmp; 01417 01418 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01419 nfc_open_page_write( 01420 nf_block_2_page( g_fbb_block_addr ) // base address 01421 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01422 , 0 ); 01423 for ( u16_tmp=0 ; u16_tmp<((U16)1<<(G_SHIFT_PAGE_BYTE-1)) ; ) 01424 { 01425 if ( u16_tmp<g_n_free_blocks ) 01426 { 01427 Nfc_wr_data( g_page_buffer[2*u16_tmp ] ); 01428 Nfc_wr_data( g_page_buffer[2*u16_tmp +1] ); 01429 } 01430 else 01431 { 01432 Nfc_wr_data( 0xFF ); 01433 Nfc_wr_data( 0xFF ); 01434 } 01435 u16_tmp++; 01436 } 01437 // Write the spare information 01438 // 01439 Nfc_wr_data( 0xFF ); // 0- block is valid (for 2048 compatibility) 01440 Nfc_wr_data( NFC_BLK_ID_FBB ); // 1- Free-blocks block 01441 Nfc_wr_data( MSB(g_n_free_blocks)); // 2-3 Number of free blocks 01442 Nfc_wr_data( LSB(g_n_free_blocks)); 01443 Nfc_wr_data( NFC_OFST_4_FBB_DRIVER_RELEASE ); // 4- Nand-Flash driver ID 01444 Nfc_wr_data( 0xFF ); // 5- block is valid (for 512 compatibility) 01445 Nfc_wr_data( NFC_OFST_6_FBB_VALID ); // 6- FBB-LUTs valid 01446 Nfc_wr_data( 0xFF ); // 7- Unused 01447 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 8-9-10- Unused 01448 Nfc_wr_data( MSB(g_n_export_blocks)); // 11-12- Number of exported blocks 01449 Nfc_wr_data( LSB(g_n_export_blocks)); 01450 Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); Nfc_wr_data( 0xFF ); // 13-14-15- Unused 01451 01452 Nfc_set_cmd( NF_PAGE_PROGRAM_CMD ); 01453 if ( FAIL==nfc_check_status() ) { return FAIL; } 01454 return PASS; 01455 } // end of nf_write_fbb
| static void nf_check_fbb | ( | Bool | b_ecc_err | ) | [static] |
Definition at line 1460 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().
01461 { 01462 U16 u16_tmp; 01463 01464 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01465 trace("nf_check_fbb\n\r"); 01466 trace("g_fbb_block_addr "); trace_hex16(g_fbb_block_addr); 01467 trace("\n\rs_fbb_block_index= "); trace_hex(g_fbb_block_index); trace("\n\r"); 01468 nfc_open_page_read( 01469 nf_block_2_page( g_fbb_block_addr ) // base address 01470 + (U32)g_fbb_block_index // offset to Free-blocks block entry 01471 , 0 ); 01472 trace("n free blocks: "); trace_u16(g_n_free_blocks); trace_nl(); 01473 for ( u16_tmp=0 ; u16_tmp<g_n_free_blocks ; ) 01474 { 01475 #if (_TRACE_==ENABLE) 01476 if( u16_tmp>=2048 ) break; 01477 if( !(u16_tmp% 8) ) { 01478 trace("\n\r"); 01479 trace_u16(u16_tmp); 01480 } 01481 #endif 01482 MSB(_debug)= Nfc_rd_data_fetch_next(); 01483 LSB(_debug)= Nfc_rd_data_fetch_next(); 01484 trace(" 0x"); trace_hex( MSB(_debug) ); trace_hex( LSB(_debug) ); 01485 // When coming from ECC 2-bits error, an entry has been removed 01486 // from the cache, so the last entry is 0xffff 01487 if( !b_ecc_err ) 01488 { 01489 Assert( _debug>=g_nf_first_block ); 01490 Assert( _debug< G_N_BLOCKS ); 01491 } 01492 #if 0 01493 This tests have been commented out: when the cache are dirty, we can not just check the memory 01494 with possible protected block address (fbb, lut). 01495 Ex: FBB is dirty, a recycle have been done between on of the free block and g_lut_block_addr[x]. 01496 In the FBB memory, the (new) lut address is still present, even if it is not the case in the cache. 01497 if ( (u16_tmp%NF_N_DEVICES)==S_MNGT_DEV ) 01498 { // Check dangerous address collision for NF_MNGT only 01499 Assert( _debug!=g_fbb_block_addr ); 01500 for ( u8_tmp=0 ; u8_tmp<g_n_sub_lut ; u8_tmp++ ) { 01501 Assert( _debug!=g_lut_block_addr[u8_tmp] ); 01502 } 01503 } 01504 #endif 01505 u16_tmp++; 01506 } 01507 trace_nl(); 01508 } // nf_check_fbb
| static void nf_check_lut | ( | void | ) | [static] |
Definition at line 1511 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.
01512 { 01513 U16 u16_tmp; 01514 U8 sub_lut_id; 01515 U16 sub_lut_log_sz; 01516 01517 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV); 01518 for ( sub_lut_id=0 ; sub_lut_id<g_n_sub_lut ; sub_lut_id++ ) 01519 { 01520 nfc_open_page_read( 01521 nf_block_2_page( g_lut_block_addr[sub_lut_id] ) // base address 01522 + (U32)g_lut_block_index[sub_lut_id] // offset to LUT block entry 01523 , 0 ); 01524 01525 sub_lut_log_sz = ( sub_lut_id==(g_n_sub_lut-1) ) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ; 01526 for ( u16_tmp=0 ; u16_tmp<(sub_lut_log_sz*NF_N_DEVICES) ; ) 01527 { 01528 MSB(_debug)= Nfc_rd_data_fetch_next(); 01529 LSB(_debug)= Nfc_rd_data_fetch_next(); 01530 Assert( _debug>=g_nf_first_block ); 01531 Assert( _debug< G_N_BLOCKS ); 01532 #if 0 01533 if ( (u16_tmp%NF_N_DEVICES)==S_MNGT_DEV ) 01534 { // Check dangerous address collision for NF_MNGT only 01535 Assert( _debug!=g_fbb_block_addr ); 01536 for ( u8_tmp=0 ; u8_tmp<g_n_sub_lut ; u8_tmp++ ) { 01537 Assert( _debug!=g_lut_block_addr[u8_tmp] ); 01538 } 01539 } 01540 #endif 01541 u16_tmp++; 01542 } 01543 } 01544 }
| void nf_copy_tail | ( | void | ) |
Definition at line 1555 of file nf_mngt.c.
Referenced by nf_open_read(), nf_open_write(), nf_rebuild(), and nf_usb_stop().
01556 { 01557 _MEM_TYPE_SLOW_ U8 u8_tmp; 01558 U8 u8_tmp2; 01559 _MEM_TYPE_SLOW_ U16 u16_tmp; 01560 _MEM_TYPE_SLOW_ U16 byte_addr; 01561 01562 // Test if we do not reach the end of the logical block 01563 // 01564 if( 0!=((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1)) ) 01565 { 01566 trace("nf_copy_tail;"); trace_hex32(g_last_log_sector); trace_nl(); 01567 if( Is_not_nf_512() ) 01568 { // Following is not possible on 512B Nand 01569 01570 u8_tmp = // current offset sector in the current page 01571 LSB0(g_last_log_sector) 01572 & ( SIZE_PAGE_SECTOR-1 ) 01573 ; 01574 01575 u8_tmp2 = SIZE_PAGE_SECTOR -u8_tmp; 01576 if( 0!=u8_tmp ) 01577 { // Copy the rest of the current line 01578 01579 byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE); 01580 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 01581 nfc_open_page_read( // Open the old block at : 01582 nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) // adresse of the beginning of the old block 01583 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01584 , byte_addr ); // current offset sector in the current page 01585 // for each sector in the physical page 01586 u16_tmp = u8_tmp2 * SIZE_SECTOR_BYTE; 01587 g_last_log_sector += u8_tmp2; // update the current logical sector 01588 01589 // read the sector of the old page 01590 nf_upload(g_page_buffer+byte_addr, u16_tmp/16 ); 01591 01592 // Read the associated spare zone 01593 byte_addr= NF_SPARE_POS + (((U16)u8_tmp)*16); 01594 nfc_open_page_read( // Open the old block at : 01595 nf_block_2_page( g_block_to_kill[g_curr_dev_id] ) // adresse of the beginning of the old block 01596 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01597 , byte_addr ); // current offset sector in the current page 01598 nf_upload(g_page_buffer+byte_addr, u8_tmp2 ); 01599 01600 byte_addr=((U16)u8_tmp) * (SIZE_SECTOR_BYTE); 01601 nfc_open_page_write( // Open the new block at the current position 01602 g_phys_page_addr[g_curr_dev_id] 01603 , byte_addr ); 01604 01605 // write the sector in the new page 01606 nf_download(g_page_buffer+byte_addr, (U8)(u16_tmp/16) ); 01607 01608 // write the associated spare zone 01609 byte_addr=NF_SPARE_POS + (((U16)u8_tmp)*16); 01610 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01611 Nfc_set_adc( (byte_addr)%256 ); 01612 Nfc_set_adc( (byte_addr)/256 ); 01613 nf_download(g_page_buffer+byte_addr, u8_tmp2 ); 01614 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01615 01616 g_phys_page_addr[g_curr_dev_id]++; // update the current physical page of the current device 01617 g_curr_dev_id++; // update the current device 01618 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 01619 } 01620 } 01621 01622 // then copy the rest of the logical block 01623 // 01624 while( 0!=((U16)g_last_log_sector & (((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR))-1)) ) 01625 { 01626 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 01627 01628 g_copy_src= 01629 nf_block_2_page(g_block_to_kill[g_curr_dev_id]) // adresse of the beginning of the old block 01630 + (LSB0(g_phys_page_addr[g_curr_dev_id])&(SIZE_BLOCK_PAGE -1)) // current offset page in the old and new block 01631 ; 01632 nf_copy(g_phys_page_addr[g_curr_dev_id]); 01633 g_phys_page_addr[g_curr_dev_id]++; 01634 01635 g_last_log_sector+=SIZE_PAGE_SECTOR; // update the current logical sector 01636 g_curr_dev_id++; // update the current device 01637 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; } 01638 } 01639 01640 // Delete old blocks 01641 // 01642 nf_erase_old_blocks(); 01643 }else{ 01644 trace("nf_copy_tail empty??;"); trace_hex32(g_last_log_sector); trace_nl(); 01645 } 01646 g_last_log_sector= 0xFFFFFFFF; 01647 }
Download packets of 16 bytes from RAM to the NAND Flash.
| U8 | * datbuf pointer to RAM U8 loop number of 16 bytes packets |
Definition at line 1660 of file nf_mngt.c.
Referenced by nf_copy(), nf_copy_tail(), and nf_open_write().
01661 { 01662 U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf; 01663 U8 i = loop; 01664 01665 while (i != 0) 01666 { 01667 Nf_wr_byte(*(tempbuf)); tempbuf++; 01668 Nf_wr_byte(*(tempbuf)); tempbuf++; 01669 Nf_wr_byte(*(tempbuf)); tempbuf++; 01670 Nf_wr_byte(*(tempbuf)); tempbuf++; 01671 Nf_wr_byte(*(tempbuf)); tempbuf++; 01672 Nf_wr_byte(*(tempbuf)); tempbuf++; 01673 Nf_wr_byte(*(tempbuf)); tempbuf++; 01674 Nf_wr_byte(*(tempbuf)); tempbuf++; 01675 Nf_wr_byte(*(tempbuf)); tempbuf++; 01676 Nf_wr_byte(*(tempbuf)); tempbuf++; 01677 Nf_wr_byte(*(tempbuf)); tempbuf++; 01678 Nf_wr_byte(*(tempbuf)); tempbuf++; 01679 Nf_wr_byte(*(tempbuf)); tempbuf++; 01680 Nf_wr_byte(*(tempbuf)); tempbuf++; 01681 Nf_wr_byte(*(tempbuf)); tempbuf++; 01682 Nf_wr_byte(*(tempbuf)); tempbuf++; 01683 i--; 01684 } 01685 }
Upload packets of 16 bytes from the NAND Flash to RAM.
| U8 | * datbuf pointer to RAM U8 loop number of 16 bytes packets |
Definition at line 1696 of file nf_mngt.c.
Referenced by nf_copy(), nf_copy_tail(), and nf_open_write().
01697 { 01698 U8 _MEM_TYPE_SLOW_ * tempbuf = datbuf; 01699 U8 i = loop; 01700 01701 while (i != 0) 01702 { 01703 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01704 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01705 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01706 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01707 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01708 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01709 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01710 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01711 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01712 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01713 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01714 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01715 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01716 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01717 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01718 *(tempbuf) = Nf_rd_byte(); tempbuf++; 01719 i--; 01720 } 01721 }
| void nf_copy | ( | U32 | copy_dst | ) |
Copy a NF page to a new one.
This function copies a NF page into a new page. It uses the copy-back command if it is possible.
| g_copy_src | (global) Source page address | |
| copy_dst | Recipient page address |
Definition at line 1856 of file nf_mngt.c.
Referenced by nf_copy_tail(), and nf_open_write().
01857 { 01858 Bool b_copy_fast; 01859 U8 zone_A, zone_B; 01860 01861 // Compute the possibility of fast copy 01862 if( 0 == G_COPY_BACK_CONT ) 01863 { 01864 b_copy_fast = 0; // never possible 01865 } 01866 else 01867 { 01868 if( (1 == G_COPY_BACK_CONT) && (1==G_COPY_BACK_DISCONT) ) 01869 { 01870 b_copy_fast = 1; // always possible 01871 } 01872 else 01873 { 01874 // Check block address 01875 b_copy_fast = 1; // by default possible 01876 if( 1 != G_COPY_BACK_CONT ) 01877 { 01878 /* 01879 zone_A = (g_copy_src>>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT); 01880 zone_B = (copy_dst >>G_SHIFT_BLOCK_PAGE) / ((U16)G_N_BLOCKS/G_COPY_BACK_CONT); 01881 */ 01882 // block_zone = page add / number of page / 1024 01883 if( Is_nf_2k() ) 01884 { 01885 // block_zone = (page add >> (G_SHIFT_BLOCK_PAGE + 10)) / (G_N_ZONES/G_COPY_BACK_CONT); 01886 // block_zone = ((page add >> 16) * G_COPY_BACK_CONT) / G_N_ZONES; 01887 zone_A = (MSB1(g_copy_src)*G_COPY_BACK_CONT)/G_N_ZONES; 01888 zone_B = (MSB1(copy_dst )*G_COPY_BACK_CONT)/G_N_ZONES; 01889 }else{ 01890 // block_zone = page add >> (G_SHIFT_BLOCK_PAGE + 10) / (G_N_ZONES/G_COPY_BACK_CONT); 01891 zone_A = ((U8)(g_copy_src>>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES; 01892 zone_B = ((U8)(copy_dst >>(G_SHIFT_BLOCK_PAGE + 10)) *G_COPY_BACK_CONT) /G_N_ZONES; 01893 } 01894 if( zone_A != zone_B ) 01895 b_copy_fast = 0; // no possible 01896 } 01897 if( 1 != G_COPY_BACK_DISCONT ) 01898 { 01899 // define mandatory to delete compile error on MODULO 0 01900 #if (NF_GENERIC_DRIVER==TRUE) || (NF_AUTO_DETECT_2KB==TRUE) || (NF_AUTO_DETECT_512B==TRUE) 01901 zone_A = ((U16)g_copy_src>>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01902 zone_B = ((U16)copy_dst >>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01903 #elif ( G_COPY_BACK_DISCONT != 0 ) 01904 zone_A = ((U16)g_copy_src>>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01905 zone_B = ((U16)copy_dst >>G_SHIFT_BLOCK_PAGE) % G_COPY_BACK_DISCONT; 01906 #endif 01907 if( zone_A != zone_B ) 01908 b_copy_fast = 0; // no possible 01909 } 01910 } 01911 } 01912 01913 // Start copy 01914 if( !b_copy_fast ) 01915 { 01916 // copy the page of the old block in buffer 01917 nfc_open_page_read( g_copy_src, 0 ); 01918 nf_upload( // Works by packet of 16 bytes 01919 g_page_buffer 01920 , ((U16)1<<(G_SHIFT_PAGE_BYTE-4)) // Data zone (Page size / 16) 01921 + ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4))); // Spare zone (Page size / 32 / 16) 01922 01923 // Add LBA markers to help recovery function 01924 // Need to explain a bit why LBA are written: 01925 // nf_copy is called from copy_head and copy_tail. 01926 // - copy_head: need to write all the LBA of the pages to help recovery finding 01927 // where the last sector is written. 01928 // Moreover, in case that nf_copy is called from copy_head and source block at page 0 01929 // does not contain LBA. 01930 // - copy_tail: no need to mark the last LBA of the last page to identify the source 01931 // block since we use another method 01932 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3] = NFC_OFST_3_DATA_DST; // 3- [SW] Source block (recovery) (HW capability not used) 01933 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA ] = MSB(g_log_block_id); // 6- LBA 01934 g_page_buffer[NF_SPARE_POS+NFC_SPARE_OFST_6_LBA+1 ] = LSB(g_log_block_id); // 7- LBA 01935 if( Is_nf_2k() ) 01936 { 01937 g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA ] = 01938 g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA ] = 01939 g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA ] = MSB(g_log_block_id); // 6- LBA 01940 g_page_buffer[NF_SPARE_POS +16*1 +NFC_SPARE_OFST_6_LBA+1] = 01941 g_page_buffer[NF_SPARE_POS +16*2 +NFC_SPARE_OFST_6_LBA+1] = 01942 g_page_buffer[NF_SPARE_POS +16*3 +NFC_SPARE_OFST_6_LBA+1] = LSB(g_log_block_id); // 7- LBA 01943 } 01944 01945 // copy the buffer in the page of the new block 01946 nfc_open_page_write( copy_dst, 0 ); 01947 nf_download( // Works by packet of 16 bytes 01948 g_page_buffer 01949 , ((U16)1<<(G_SHIFT_PAGE_BYTE-4)) // Data zone (Page size / 16) 01950 + ((U16)1<<(G_SHIFT_PAGE_BYTE-5-4))); // Spare zone (Page size / 32 / 16) 01951 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01952 } 01953 else 01954 { 01955 nfc_copy_back_init( g_copy_src ); 01956 01957 Nfc_unprotect_all_flash(); // WP may be actif due to block protection 01958 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01959 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)%256 ); 01960 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3)/256 ); 01961 Nfc_set_adr( LSB0(copy_dst) ); 01962 Nfc_set_adr( LSB1(copy_dst) ); 01963 if ( 3==G_N_ROW_CYCLES ) 01964 { 01965 Nfc_set_adr( MSB1(copy_dst) ); 01966 } 01967 01968 // Remove Source block mask 01969 Nfc_wr_data( NFC_OFST_3_DATA_DST ); 01970 01971 // Add LBA markers to help recovery function 01972 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01973 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)%256 ); 01974 Nfc_set_adc( (NF_SPARE_POS+NFC_SPARE_OFST_6_LBA)/256 ); 01975 Nfc_wr_data( MSB(g_log_block_id) ); 01976 Nfc_wr_data( LSB(g_log_block_id) ); 01977 01978 if( Is_nf_2k() ) 01979 { 01980 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01981 Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)%256 ); 01982 Nfc_set_adc( (NF_SPARE_POS + 16*1 +NFC_SPARE_OFST_6_LBA)/256 ); 01983 Nfc_wr_data( MSB(g_log_block_id) ); 01984 Nfc_wr_data( LSB(g_log_block_id) ); 01985 01986 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01987 Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)%256 ); 01988 Nfc_set_adc( (NF_SPARE_POS + 16*2 +NFC_SPARE_OFST_6_LBA)/256 ); 01989 Nfc_wr_data( MSB(g_log_block_id) ); 01990 Nfc_wr_data( LSB(g_log_block_id) ); 01991 01992 Nfc_set_cmd(NF_RANDOM_DATA_INPUT_CMD); 01993 Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)%256 ); 01994 Nfc_set_adc( (NF_SPARE_POS + 16*3 +NFC_SPARE_OFST_6_LBA)/256 ); 01995 Nfc_wr_data( MSB(g_log_block_id) ); 01996 Nfc_wr_data( LSB(g_log_block_id) ); 01997 } 01998 Nfc_set_cmd(NF_PAGE_PROGRAM_CMD); 01999 } 02000 }
Swap 2 blocks from the LUT and the FBB.
This function swaps 2 blocks: one taken into the LUT according to the LBA, and one from the FBB. This is used when modifying a block. The g_block_to_kill[] holds the block address source (LUT) that will be erased after processing.
| dev_id | Device Id of recipient page | |
| u8_ofst_lut | block offset in LUT | |
| u8_ofst_fbb | block offset in FBB |
Definition at line 2018 of file nf_mngt.c.
Referenced by nf_translate().
02019 { 02020 Assert( dev_id < NF_N_DEVICES ); 02021 Assert( u8_ofst_lut < CACHE_LUT_SIZE); 02022 Assert( u8_ofst_fbb < CACHE_FBB_SIZE); 02023 Assert( g_cache_lut.mem[u8_ofst_lut] >=g_nf_first_block ); 02024 Assert( g_cache_lut.mem[u8_ofst_lut] < G_N_BLOCKS ); 02025 Assert( g_cache_fbb.mem[u8_ofst_fbb] >=g_nf_first_block ); 02026 Assert( g_cache_fbb.mem[u8_ofst_fbb] < G_N_BLOCKS ); 02027 g_block_to_kill[dev_id ] = g_cache_lut.mem[u8_ofst_lut] ; 02028 g_cache_lut.mem[u8_ofst_lut] = g_cache_fbb.mem[u8_ofst_fbb] ; 02029 g_cache_fbb.mem[u8_ofst_fbb] = g_block_to_kill[dev_id] ; 02030 trace("g_cache_lut.mem["); trace_u8(u8_ofst_lut); trace("] = "); trace_hex32(g_cache_lut.mem[u8_ofst_lut]); trace_nl(); 02031 trace("g_cache_fbb.mem["); trace_u8(u8_ofst_fbb); trace("] = "); trace_hex32(g_cache_fbb.mem[u8_ofst_fbb]); trace_nl(); 02032 02033 // both FBB and LUT caches becomes invalid 02034 g_cache_lut.ctrl.dirty=TRUE; 02035 g_cache_fbb.ctrl.dirty=TRUE; 02036 }
| void nf_erase_all_blocks | ( | void | ) |
Definition at line 2088 of file nf_mngt.c.
References G_N_BLOCKS, nf_block_2_page(), nfc_erase_block(), and TRUE.
02089 { 02090 U16 i_block; 02091 02092 for (i_block = G_N_BLOCKS ; i_block != 0 ; i_block--) 02093 { 02094 nfc_erase_block( nf_block_2_page(i_block), TRUE ); 02095 } 02096 }
| Ctrl_status nf_ram_2_nf | ( | U32 | addr, | |
| U8 * | ram | |||
| ) |
This fonction initialise the memory for a write operation from ram buffer.
DATA FLOW is: RAM => NF
(sector = 512B)
| addr | Sector address to write | |
| ram | Ram buffer pointer |
Definition at line 2114 of file nf_mngt.c.
02115 { 02116 Ctrl_status tmp_bool; 02117 U16 i; 02118 02119 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02120 nf_XMCR_enable(); 02121 #endif 02122 02123 s_n_sectors = 1; 02124 s_curr_log_sector = addr; 02125 s_save_log_addr = addr + 1; 02126 g_fatal = FALSE; 02127 s_mem = TRUE; 02128 s_start = TRUE; 02129 02130 // First write operation 02131 Nf_access_signal_on(); 02132 if(( s_curr_log_sector==g_last_log_sector ) // New write is just after to the last write 02133 && (!( ( 0==((U16)g_last_log_sector & ( ((U16)1<<(S_SHIFT_LOG_BLOCK_SECTOR)) -1))) // Not on a logical block boundary 02134 && ( g_curr_dev_id==0 )))) 02135 { 02136 nf_translate( NF_TRANS_NORMAL ); 02137 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); // open the current device 02138 nfc_open_page_write( g_next_phys_page_addr, s_curr_n_byte ); 02139 } 02140 else 02141 { 02142 nf_open_write( TRUE ); 02143 } 02144 02145 for(i=0;i<512;i++) 02146 { 02147 Nf_wr_byte(*ram); 02148 ram++; 02149 } 02150 02151 if (Is_nf_2k()) 02152 { 02153 nf_update_spare_zone((U8)(1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-s_nb_sectors_step, s_nb_sectors_step); // update the spare zone once the page has been filled in 02154 } 02155 else 02156 { 02157 nf_update_spare_zone(0, 1); // update the spare zone once the page has been filled in 02158 } 02159 nf_xfer_update_vars(); 02160 02161 tmp_bool = nf_dfc_write_stop(0); // ends write operations with "nf_dfc_write_stop(0)" that save the current environnement 02162 Nf_access_signal_off(); 02163 02164 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02165 nf_XMCR_disable(); 02166 #endif 02167 02168 return tmp_bool; 02169 }
| Ctrl_status nf_nf_2_ram | ( | U32 | addr, | |
| U8 * | ram | |||
| ) |
This fonction read 1 sector from NF to ram buffer.
DATA FLOW is: NF => RAM
(sector = 512B)
| addr | Sector address to read | |
| ram | Ram buffer pointer |
Definition at line 2183 of file nf_mngt.c.
02184 { 02185 U16 i; 02186 02187 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02188 nf_XMCR_enable(); 02189 #endif 02190 02191 s_n_sectors = 1; 02192 s_curr_log_sector = addr; 02193 s_save_log_addr = addr + 1; 02194 g_fatal = FALSE; 02195 s_mem = TRUE; 02196 s_start = TRUE; 02197 02198 // First read operation 02199 Nf_access_signal_on(); 02200 nf_open_read(TRUE); 02201 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id); 02202 nfc_open_page_read( g_phys_page_addr[g_curr_dev_id], s_curr_n_byte ); 02203 s_nb_sectors_step = (U8) // determine number of sectors to be read 02204 (Min( // on this first page 02205 1, 02206 ((1<<(G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE))-(s_curr_n_byte >> 9)) 02207 ) 02208 ); 02209 02210 Disable_interrupt(); 02211 for(i=0;i<512;i++) 02212 { 02213 *ram=Nf_rd_byte(); 02214 ram++; 02215 } 02216 Enable_interrupt(); 02217 nf_xfer_update_vars(); 02218 Nf_access_signal_off(); 02219 02220 #if (NF_XMCR_MODULE_SHARED == ENABLED) 02221 nf_XMCR_disable(); 02222 #endif 02223 02224 return CTRL_GOOD; 02225 }
| _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 |
1.5.3