fat.c File Reference

FAT 12/16/32 Services. More...

#include "conf_explorer.h"
#include "fs_com.h"
#include "fat.h"
#include <LIB_MEM>
#include <LIB_CTRLACCESS>

Include dependency graph for fat.c:

Go to the source code of this file.

Position of the current cluster in the FAT <br>

Global variable used to take time with routines fat_cluster_readnext() and fat_cluster_val()

_MEM_TYPE_FAST_ U16 fs_g_u16_pos_fat
Bool fat_cluster_val (Bool b_mode)
 This function returns or modifys a cluster value in FAT.
Bool fat_cluster_readnext (void)
 This function is optimized to read a continue cluster list on FAT16 and FAT32.
U8 fat_checkcluster (void)
 This function checks the cluster value.

Defines

#define _fat_c_
#define u8_data3   (LSB(u16_offset_fat))
#define u8_data4   (MSB(u16_offset_fat))

Functions

Bool fat_check_device (void)
 This function checks device state.
Bool fat_check_mount (void)
 This function checks if the partition is mounted.
Bool fat_check_noopen (void)
 This function checks if a file is not opened on current navigator.
Bool fat_check_open (void)
 This function checks if a file is opened on current navigator.
Bool fat_check_select (void)
 This function checks if a file is selected on current navigator.
Bool fat_check_mount_noopen (void)
 This function checks if the partition is mounted and no file is opened.
Bool fat_check_mount_select_noopen (void)
 This function checks if the partition is mounted and if no file is opened and a file is selected.
Bool fat_check_mount_select_open (void)
 This function checks if the partition is mounted and if a file is opened.
Bool fat_check_mount_select (void)
 This function checks if the partition is mounted and if a file is selected.
Bool fat_check_is_file (void)
 This function checks if the selected file entry is a file and not a directory.
U8 fat_get_nbpartition (void)
 This function returns the number of partition on current drive.
Bool fat_cluster_list (U8 opt_action, Bool b_for_file)
 This function gets or clears a cluster list.
Bool fat_read_file (U8 mode)
 This function gets or clears a cluster list at the current position in the selected file.
Bool fat_read_dir (void)
 This function fill the internal cache with a sector from current directory.
Bool fat_entry_check (Bool b_type)
 This function checks the entry.
Bool fat_entry_checkext (FS_STRING sz_filter)
 This function checks the file extension.
void fat_get_entry_info (void)
 This function reads information about selected file.
Bool fat_entry_is_dir (void)
 This function checks if the entry file is a directory.
void fat_clear_entry_info_and_ptr (void)
 This function resets the selection pointers.
Bool fat_entry_shortname (FS_STRING sz_name, U8 u8_size_max, Bool b_mode)
 This function returns or compares the short name entry.
Bool fat_entry_longname (FS_STRING sz_name, U8 u8_size_max, Bool b_mode, Bool b_match_case)
 This function returns or compares the long name entry.
Bool fat_check_eof_name (U16 character)
 Check end of name.
PTR_CACHE fat_get_ptr_entry (void)
 This function returns a cache pointer on the current entry.
Bool fat_cache_read_sector (Bool b_load)
 This function loads a memory sector in internal cache sector.
void fat_cache_reset (void)
 This function resets the sector cache.
Bool fat_cache_flush (void)
 This function flushs the sector cache on the memory if necessary.
Internal functions to manage cluster list caches
void fat_cache_clusterlist_update_start (Bool b_for_file)
 This function initializes a cache in cluster list caches.
void fat_cache_clusterlist_update_finish (void)
 This function updates a cache of cluster list caches.
Bool fat_cache_clusterlist_update_read (Bool b_for_file)
 This function searchs a cluster list in cluster list caches.
void fat_cache_clusterlist_update_select (void)
 This function signals that a cache is used.
void fat_cache_clusterlist_reset (void)
 This function resets the cluster list caches.

Variables

Variables to manage cluster list caches
_MEM_TYPE_SLOW_
Fs_clusterlist_cache 
fs_g_cache_clusterlist [FS_NB_CACHE_CLUSLIST *2]
_MEM_TYPE_SLOW_ U8 fs_g_u8_current_cache


Detailed Description

FAT 12/16/32 Services.

This file defines a useful set of functions for the FAT accesses on AVR32 devices.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file fat.c.


Define Documentation

#define _fat_c_

Definition at line 41 of file fat.c.

#define u8_data3   (LSB(u16_offset_fat))

Referenced by fat_cluster_val().

#define u8_data4   (MSB(u16_offset_fat))

Referenced by fat_cluster_val().


Function Documentation

void fat_cache_clusterlist_update_start ( Bool  b_for_file  ) 

This function initializes a cache in cluster list caches.

Parameters:
b_for_file If TRUE then it is a file cluster list else a directory cluster list

Definition at line 896 of file fat.c.

References Fs_clusterlist_cache::b_cache_file, fs_g_cache_clusterlist, fs_g_cluster, fs_g_seg, fs_g_u8_current_cache, FS_NB_CACHE_CLUSLIST, Fs_clusterlist_cache::u32_cluster, Fs_cluster::u32_pos, Fs_segment::u32_size_or_pos, Fs_clusterlist_cache::u32_start, Fs_clusterlist_cache::u8_level_use, and Fs_clusterlist_cache::u8_lun.

Referenced by fat_cache_clusterlist_update_read().

00897 {
00898    // Get the OLD cache (=max level used)
00899    U8 u8_i;
00900    for( u8_i=0; u8_i<((FS_NB_CACHE_CLUSLIST*2)-1); u8_i++ ) // (FS_NB_CACHE_CLUSLIST*2)-1, in case of error
00901    {
00902       if( fs_g_cache_clusterlist[u8_i].b_cache_file == b_for_file )
00903       {
00904 #if (FS_NB_CACHE_CLUSLIST>1)
00905          if( (FS_NB_CACHE_CLUSLIST-2) < fs_g_cache_clusterlist[u8_i].u8_level_use )
00906 #endif
00907             break;
00908       }
00909    }
00910    fs_g_u8_current_cache = u8_i;
00911    fs_g_cache_clusterlist[fs_g_u8_current_cache].b_cache_file = b_for_file;
00912    fs_g_cache_clusterlist[fs_g_u8_current_cache].u8_lun       = 0xFF;                     // unvalid cache
00913    fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_cluster  = fs_g_cluster.u32_pos;
00914    fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start    = fs_g_seg.u32_size_or_pos;
00915 }

Here is the caller graph for this function:

void fat_cache_clusterlist_update_finish ( void   ) 

This function updates a cache of cluster list caches.

Definition at line 920 of file fat.c.

References fat_cache_clusterlist_update_select(), fs_g_cache_clusterlist, fs_g_nav, fs_g_seg, fs_g_u8_current_cache, Fs_segment::u32_addr, Fs_clusterlist_cache::u32_addr, Fs_clusterlist_cache::u32_size, Fs_segment::u32_size_or_pos, Fs_clusterlist_cache::u32_start, Fs_management::u8_BPB_SecPerClus, Fs_management::u8_lun, and Fs_clusterlist_cache::u8_lun.

Referenced by fat_cluster_list().

Here is the call graph for this function:

Here is the caller graph for this function:

Bool fat_cache_clusterlist_update_read ( Bool  b_for_file  ) 

This function searchs a cluster list in cluster list caches.

Parameters:
b_for_file If TRUE then it is a file cluster list else a directory cluster list
Returns:
TRUE cluster list found and global variable fs_g_seg updated

FALSE no found in cluster list caches

Definition at line 960 of file fat.c.

References FALSE, fat_cache_clusterlist_update_select(), fat_cache_clusterlist_update_start(), fs_g_cache_clusterlist, fs_g_cluster, fs_g_nav, fs_g_seg, fs_g_u8_current_cache, FS_NB_CACHE_CLUSLIST, TRUE, Fs_clusterlist_cache::u32_addr, Fs_segment::u32_addr, Fs_management::u32_offset_data, Fs_cluster::u32_pos, Fs_management::u32_ptr_fat, Fs_clusterlist_cache::u32_size, Fs_segment::u32_size_or_pos, Fs_clusterlist_cache::u32_start, Fs_management::u8_BPB_SecPerClus, Fs_management::u8_lun, and Fs_clusterlist_cache::u8_lun.

Referenced by fat_cluster_list().

00961 {
00962    U32 u32_tmp;
00963    U8 u8_i;
00964    for( u8_i=0; u8_i<(FS_NB_CACHE_CLUSLIST*2); u8_i++ )
00965    {
00966       if( (fs_g_cache_clusterlist[u8_i].b_cache_file == b_for_file)
00967       &&  (fs_g_cache_clusterlist[u8_i].u8_lun == fs_g_nav.u8_lun ) )
00968       {
00969          if( fs_g_cache_clusterlist[u8_i].u32_cluster == fs_g_cluster.u32_pos )
00970          {
00971             if( fs_g_cache_clusterlist[u8_i].u32_start <= fs_g_seg.u32_size_or_pos )
00972             {
00973                // The segment research is in or after the cache
00974                if( fs_g_cache_clusterlist[u8_i].u32_size  > (fs_g_seg.u32_size_or_pos-fs_g_cache_clusterlist[u8_i].u32_start) )
00975                {
00976                   //** The segment research is in cache, then compute the segment infos
00977                   fs_g_seg.u32_size_or_pos -= fs_g_cache_clusterlist[u8_i].u32_start;
00978                   fs_g_seg.u32_addr = fs_g_cache_clusterlist[u8_i].u32_addr + fs_g_seg.u32_size_or_pos;
00979                   fs_g_seg.u32_size_or_pos = fs_g_cache_clusterlist[u8_i].u32_size - fs_g_seg.u32_size_or_pos;
00980                   fs_g_u8_current_cache = u8_i;
00981                   fat_cache_clusterlist_update_select();
00982                   return TRUE;   // the segment is in cluster list cache
00983                }else{
00984                   //** It is after the cache then get cache information and continue to read the cluster list in FAT
00985                   // Store the resultat in this cache
00986                   fs_g_u8_current_cache = u8_i;
00987                   fs_g_cache_clusterlist[fs_g_u8_current_cache].u8_lun       = 0xFF;   // unvalid cache
00988                   // fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_cluster  = fs_g_cluster.u32_pos;  // It is the same cluster start
00989 
00990                   // Get cache information to take time during the next FAT access
00991                   // Compute the cluster number corresponding at the last cluster of the cluster list cache
00992                   fs_g_cluster.u32_pos     = ((fs_g_cache_clusterlist[u8_i].u32_addr -fs_g_nav.u32_ptr_fat - fs_g_nav.u32_offset_data + fs_g_cache_clusterlist[u8_i].u32_size -1)
00993                                              / fs_g_nav.u8_BPB_SecPerClus) +2;
00994                   u32_tmp  = fs_g_seg.u32_size_or_pos;                                 // save position ask
00995                   // Compute the position of the end of cluster list cache, and decrement the position asked
00996                   fs_g_seg.u32_size_or_pos-= ((fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start + fs_g_cache_clusterlist[u8_i].u32_size -1)
00997                                              / fs_g_nav.u8_BPB_SecPerClus)
00998                                              * fs_g_nav.u8_BPB_SecPerClus;
00999                   fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start = u32_tmp;   // Update cache with the position asked
01000                   return FALSE;                                                        // The segment isn't in cluster list cache
01001                }
01002             }
01003          }
01004       }
01005    }
01006    // No found in cache then read FAT and store the resultat in cache
01007    fat_cache_clusterlist_update_start(b_for_file);
01008    return FALSE;
01009 }

Here is the call graph for this function:

Here is the caller graph for this function:

void fat_cache_clusterlist_update_select ( void   ) 

This function signals that a cache is used.

Definition at line 935 of file fat.c.

References Fs_clusterlist_cache::b_cache_file, fs_g_cache_clusterlist, fs_g_u8_current_cache, FS_NB_CACHE_CLUSLIST, and Fs_clusterlist_cache::u8_level_use.

Referenced by fat_cache_clusterlist_update_finish(), and fat_cache_clusterlist_update_read().

00936 {
00937    U8 u8_i;
00938    U8 u8_level_to_update;
00939    Bool b_file_cache;
00940 
00941    b_file_cache         = fs_g_cache_clusterlist[ fs_g_u8_current_cache ].b_cache_file;
00942    u8_level_to_update   = fs_g_cache_clusterlist[ fs_g_u8_current_cache ].u8_level_use;
00943    for( u8_i=0; u8_i<(FS_NB_CACHE_CLUSLIST*2); u8_i++ )
00944    {
00945       if( fs_g_cache_clusterlist[u8_i].b_cache_file == b_file_cache )
00946          if( u8_level_to_update > fs_g_cache_clusterlist[u8_i].u8_level_use )
00947            fs_g_cache_clusterlist[u8_i].u8_level_use++;
00948    }
00949    fs_g_cache_clusterlist[  fs_g_u8_current_cache  ].u8_level_use = 0;
00950 }

Here is the caller graph for this function:

Bool fat_check_device ( void   ) 

This function checks device state.

Returns:
TRUE device ready

FALSE otherwise

//! This function updates all navigator datas when the device state change.
//! 

Definition at line 88 of file fat.c.

Referenced by fat_check_mount(), fat_check_noopen(), fat_get_nbpartition(), fat_mount(), nav_partition_freespace(), nav_partition_freespace_percent(), nav_partition_space(), and nav_partition_type().

00089 {
00090    U8 retry=0;
00091 #if (FS_NB_NAVIGATOR > 1)
00092    U8 i;
00093 #endif
00094    Ctrl_status status;
00095    
00096    // Possibility to ignore the disk check. Used to take time during multi read/write access
00097    if( g_b_no_check_disk )
00098       return TRUE;
00099 
00100    if( 0xFF == fs_g_nav.u8_lun )
00101    {
00102       fs_g_status = FS_ERR_HW;
00103       return FALSE;                                // No device selected
00104    }
00105 
00106    for( retry=0 ; retry<100 ; retry++ )
00107    {
00108       // Check device
00109       status = mem_test_unit_ready( fs_g_nav.u8_lun );
00110       if( CTRL_GOOD       == status )
00111          return TRUE;                              // drive ready
00112 
00113       //* HERE error or state change
00114       // Clean all navigator datas which use this device
00115       fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM; // By default the fat isn't mounted
00116       Fat_file_close();                            // By default the file is not open
00117 #if (FS_NB_NAVIGATOR > 1)
00118       for( i=0 ; i!=(FS_NB_NAVIGATOR-1) ; i++ )
00119       {
00120          if( fs_g_nav.u8_lun == fs_g_navext[i].u8_lun )
00121          {
00122             fs_g_navext_fast[i].u8_type_fat     = FS_TYPE_FAT_UNM;   // By default the fat isn't mounted
00123             fs_g_navext_entry[i].u8_open_mode   = 0;                 // By default the file is not open
00124          }
00125       }
00126 #endif
00127       // If the internal cache corresponding at device then clean it
00128       if( fs_g_nav.u8_lun == fs_g_sectorcache.u8_lun )
00129       {
00130          fat_cache_reset();
00131       }
00132       fat_cache_clusterlist_reset();
00133 
00134       fs_g_status = FS_ERR_HW;                     // By default HW error
00135       if( CTRL_BUSY == status )
00136          continue;                                 // If device busy then retry
00137 
00138       if( CTRL_NO_PRESENT == status )
00139          fs_g_status = FS_ERR_HW_NO_PRESENT;       // Update error flag
00140       break;                                       // FAIL or NOT PRESENT = fatal error = no retry
00141    }
00142    return FALSE;
00143 }

Here is the caller graph for this function:

Bool fat_check_mount ( void   ) 

This function checks if the partition is mounted.

Returns:
TRUE partition mounted

FALSE otherwise

Definition at line 151 of file fat.c.

Referenced by fat_check_mount_noopen(), fat_check_mount_select(), fat_check_mount_select_noopen(), fat_check_mount_select_open(), and nav_partition_serialnumber().

00152 {
00153    if( !fat_check_device() )
00154       return FALSE;
00155    if (FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat)
00156    {
00157       if( !fat_mount() )
00158       {
00159          fs_g_status = FS_ERR_NO_MOUNT;
00160          return FALSE;
00161       }
00162    }
00163    return TRUE;
00164 }

Here is the caller graph for this function:

Bool fat_check_noopen ( void   ) 

This function checks if a file is not opened on current navigator.

Returns:
TRUE no file opened

FALSE otherwise

Definition at line 172 of file fat.c.

Referenced by fat_check_mount_noopen(), fat_check_mount_select_noopen(), nav_drive_set(), nav_filelist_fileisnotopen(), nav_partition_mount(), nav_partition_set(), and nav_setcwd().

00173 {
00174    if( !fat_check_device() )
00175       return TRUE;
00176    if (FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat)
00177       return TRUE;
00178    if( Fat_file_is_open() )
00179    {
00180       fs_g_status = FS_ERR_TOO_FILE_OPEN;  // The navigation have already open a file
00181       return FALSE;
00182    }
00183    return TRUE;
00184 }

Here is the caller graph for this function:

Bool fat_check_open ( void   ) 

This function checks if a file is opened on current navigator.

Returns:
TRUE a file is opened

FALSE otherwise

Definition at line 192 of file fat.c.

Referenced by fat_check_mount_select_open().

00193 {
00194    if( Fat_file_isnot_open() )
00195    {
00196       fs_g_status = FS_ERR_FILE_NO_OPEN;
00197       return FALSE;
00198    }
00199    return TRUE;
00200 }

Here is the caller graph for this function:

Bool fat_check_select ( void   ) 

This function checks if a file is selected on current navigator.

Returns:
TRUE a file is selected

FALSE otherwise

Definition at line 208 of file fat.c.

Referenced by fat_check_mount_select(), fat_check_mount_select_noopen(), fat_check_mount_select_open(), and nav_getcwd().

00209 {
00210    if (FS_NO_SEL == fs_g_nav_fast.u16_entry_pos_sel_file)
00211    {
00212       fs_g_status = FS_ERR_NO_FILE_SEL;
00213       return FALSE;
00214    }
00215    return TRUE;
00216 }

Here is the caller graph for this function:

Bool fat_check_mount_noopen ( void   ) 

This function checks if the partition is mounted and no file is opened.

Returns:
TRUE partition mounted and no file is opened

FALSE otherwise

Definition at line 224 of file fat.c.

Referenced by nav_dir_gotoparent(), nav_dir_is_root(), nav_dir_name(), nav_filelist_reset(), nav_filelist_set(), and nav_getcwd().

00225 {
00226    if( !fat_check_mount() )
00227       return FALSE;
00228    return fat_check_noopen();
00229 }

Here is the caller graph for this function:

Bool fat_check_mount_select_noopen ( void   ) 

This function checks if the partition is mounted and if no file is opened and a file is selected.

Returns:
TRUE partition mounted and no file is opened and a file is selected

FALSE otherwise

Definition at line 237 of file fat.c.

Referenced by file_open(), nav_dir_cd(), and nav_filelist_validpos().

00238 {
00239    if( !fat_check_mount() )
00240       return FALSE;
00241    if( !fat_check_select() )
00242       return FALSE;
00243    return fat_check_noopen();
00244 }

Here is the caller graph for this function:

Bool fat_check_mount_select_open ( void   ) 

This function checks if the partition is mounted and if a file is opened.

Returns:
TRUE partition mounted and a file is opened

FALSE otherwise

Definition at line 252 of file fat.c.

Referenced by file_bof(), file_close(), file_eof(), file_getpos(), file_read(), file_read_buf(), and file_seek().

00253 {
00254    if( !fat_check_mount() )
00255       return FALSE;
00256    if( !fat_check_select() )
00257       return FALSE;
00258    return fat_check_open();
00259 }

Here is the caller graph for this function:

Bool fat_check_mount_select ( void   ) 

This function checks if the partition is mounted and if a file is selected.

Returns:
TRUE partition mounted and a file is selected

FALSE otherwise

Definition at line 267 of file fat.c.

Referenced by file_ispresent(), nav_file_checkext(), nav_file_dateget(), nav_file_isreadonly(), and nav_file_name().

00268 {
00269    if( !fat_check_mount() )
00270       return FALSE;
00271    return fat_check_select();
00272 }

Here is the caller graph for this function:

Bool fat_check_is_file ( void   ) 

This function checks if the selected file entry is a file and not a directory.

Returns:
TRUE It is a file and not a directory

FALSE otherwise

Definition at line 280 of file fat.c.

Referenced by file_ispresent(), and file_open().

00281 {
00282    if( Fat_is_not_a_file )
00283    {
00284       fs_g_status = FS_ERR_NO_FILE;   // It isn't a file, it is a directory or a volume id
00285       return FALSE;
00286    }
00287    return TRUE;
00288 }

Here is the caller graph for this function:

U8 fat_get_nbpartition ( void   ) 

This function returns the number of partition on current drive.

This function returns the number of partition present on selected drive.

Returns:
u8_number number of partition

Definition at line 296 of file fat.c.

Referenced by nav_partition_nb().

00297 {
00298    if( !fat_check_device() )
00299       return 0;
00300 
00301 #warning this routine contains bug, rework it
00302    // Read the first sector of drive
00303    fs_gu32_addrsector = 0;
00304    if( !fat_cache_read_sector( TRUE ))
00305       return FALSE;
00306 
00307    // Check PBR or MBR signature
00308    if ( (fs_g_sector[510] != FS_BR_SIGNATURE_LOW  )
00309    &&   (fs_g_sector[511] != FS_BR_SIGNATURE_HIGH ) )
00310    {
00311       // No MBR
00312       // The sector, is it a PBR ?
00313       if ( (fs_g_sector[0] == 0xEB) &&          // PBR Byte 0
00314            (fs_g_sector[2] == 0x90) &&          // PBR Byte 2
00315            ((fs_g_sector[21] & 0xF0) == 0xF0) ) // PBR Byte 21 : Media byte
00316       {
00317          return 1;   // No MBR but PBR exist then only one partition
00318       } else {
00319          return 0;   // No MBR and no PBR then no partition found
00320       }
00321    }
00322 
00323    number_part = 0;
00324    while( 1 )
00325    {
00326       // The first sector must be a MBR, then check the partition entry in the MBR
00327       if ( ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(number_part)+0] != FS_PARTITION_ACTIVE) &&
00328             (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(number_part)+0] != 0x00))
00329       ||    (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(number_part)+4] == 0x00) )
00330       {
00331          break;
00332       }
00333       number_part++;
00334    }
00335    return number_part;
00336 }

Here is the caller graph for this function:

Bool fat_cluster_list ( U8  opt_action,
Bool  b_for_file 
)

This function gets or clears a cluster list.

Parameters:
b_for_file If TRUE then it is a file cluster list else a directory cluster list
opt_action Choose action on the cluster list
FS_CLUST_ACT_SEG Get continue memory segment corresponding at cluster list
FS_CLUST_ACT_ONE Get only one memory sector (512B) corresponding at cluster list
FS_CLUST_ACT_CLR Clear the cluster list
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! Global variables used
//! IN :
//!   fs_g_seg.u32_addr          The first cluster of the cluster list
//!   fs_g_seg.u32_size_or_pos   Start position in the cluster list (unit 512B)
//! OUT:
//!   fs_g_seg.u32_addr          The memory segment address corresponding at the beginning of cluster list (only for action FS_CLUST_ACT_SEG & FS_CLUST_ACT_ONE)
//!   fs_g_seg.u32_size_or_pos   The memory segment size corresponding at cluster list readed or cleared (unit 512B)
//! 

Definition at line 361 of file fat.c.

Referenced by fat_read_dir(), and fat_read_file().

00362 {
00363    _MEM_TYPE_FAST_ U32 u32_tmp;
00364    _MEM_TYPE_FAST_ U8 u8_cluster_status;
00365 
00366    fs_g_status = FS_ERR_FS;      // By default system error
00367 
00368    if(  Is_fat32
00369    &&  (FS_CLUST_ACT_CLR == opt_action) )
00370    {
00371 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) )
00372       // Clear free space information storage in FAT32
00373       if( !fat_write_fat32_FSInfo( 0xFFFFFFFF ))
00374          return FALSE;
00375 #else
00376       return FALSE;
00377 #endif
00378    }
00379 
00380    if ( 0 == fs_g_seg.u32_addr )
00381    {
00382       // Cluster list of root directory
00383       if( FS_CLUST_ACT_CLR == opt_action )
00384          return FALSE;           // Impossible to erase ROOT DIR
00385 
00386       if ( Is_fat12 || Is_fat16 )
00387       {
00388          // For a FAT 12 & 16, the root dir isn't a cluster list
00389          // Check the position
00390          if ( fs_g_seg.u32_size_or_pos < fs_g_nav.rootdir.seg.u16_size )
00391          {
00392             // Compute the start address and the size
00393             fs_g_seg.u32_addr = fs_g_nav.u32_ptr_fat + fs_g_nav.rootdir.seg.u16_pos + fs_g_seg.u32_size_or_pos;
00394             fs_g_seg.u32_size_or_pos = fs_g_nav.rootdir.seg.u16_size - fs_g_seg.u32_size_or_pos;
00395             return TRUE;
00396          } else {
00397             fs_g_status = FS_ERR_OUT_LIST;
00398             return FALSE;        // Position outside the root area
00399          }
00400       }
00401       if ( Is_fat32 )
00402       {
00403          // For FAT 32, the root is a cluster list and the first cluster is reading during the mount
00404          fs_g_cluster.u32_pos = fs_g_nav.rootdir.u32_cluster;
00405       }
00406    } else {
00407       // It is the first cluster of a cluster list
00408       fs_g_cluster.u32_pos = fs_g_seg.u32_addr;
00409    }
00410 
00411    // Management of cluster list caches
00412    if( FS_CLUST_ACT_CLR != opt_action )
00413    {
00414       if( fat_cache_clusterlist_update_read( b_for_file ) )
00415          return TRUE;            // Segment found in cache
00416       // Segment not found & cache ready to update
00417    }else{
00418       fat_cache_clusterlist_reset();   // It is a clear action then clear cluster list caches
00419 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
00420       fat_clear_info_fat_mod();        // Init cache on fat modification range
00421 #endif  // FS_LEVEL_FEATURES
00422    }
00423 
00424    // Init loop with a start segment no found
00425    MSB0( fs_g_seg.u32_addr ) = 0xFF;
00426 
00427    //**** Loop to read the cluster list
00428    while ( 1 )
00429    {
00430       if ( fs_g_seg.u32_size_or_pos < fs_g_nav.u8_BPB_SecPerClus )
00431       {
00432          // The segment starts in this cluster
00433          // Compute the sector address of this cluster
00434          fs_g_seg.u32_addr = ((fs_g_cluster.u32_pos - 2) * fs_g_nav.u8_BPB_SecPerClus)
00435                            + fs_g_nav.u32_ptr_fat + fs_g_nav.u32_offset_data + fs_g_seg.u32_size_or_pos;
00436 
00437          if ( FS_CLUST_ACT_ONE == opt_action )
00438          {
00439             // Compute the maximum size
00440             fs_g_seg.u32_size_or_pos = fs_g_nav.u8_BPB_SecPerClus-fs_g_seg.u32_size_or_pos;
00441             fat_cache_clusterlist_update_finish();
00442             // Send a size of one sector
00443             fs_g_seg.u32_size_or_pos = 1;
00444             return TRUE;
00445          }
00446          // Update the segment size
00447          fs_g_seg.u32_size_or_pos = fs_g_nav.u8_BPB_SecPerClus - LSB0( fs_g_seg.u32_size_or_pos );
00448 
00449          // Take time, during read cluster list on FAT 16 & 32
00450          if( (FS_CLUST_ACT_SEG == opt_action)
00451          &&  (!Is_fat12) )
00452          {
00453             // Init loop with the current cluster
00454             u32_tmp = fs_g_cluster.u32_pos;
00455             if( !fat_cluster_val( FS_CLUST_VAL_READ ))
00456                return FALSE;
00457             // Read cluster list, while this one is continue
00458             while(1)
00459             {
00460                if ( (++fs_g_cluster.u32_pos) != fs_g_cluster.u32_val )
00461                {
00462                   fs_g_cluster.u32_pos--;                   // Recompute previous value
00463                   u32_tmp = fs_g_cluster.u32_pos - u32_tmp; // Compute the size of cluster list
00464                   fs_g_seg.u32_size_or_pos += u32_tmp * fs_g_nav.u8_BPB_SecPerClus;
00465                   break;
00466                }
00467                if( !fat_cluster_readnext() )
00468                   return FALSE;
00469             }
00470          }
00471       }
00472       // Get the cluster value
00473       if( !fat_cluster_val( FS_CLUST_VAL_READ ))
00474          return FALSE;
00475 
00476       // Read and check the status of the new cluster
00477       u8_cluster_status = fat_checkcluster();
00478       if (FS_CLUS_BAD == u8_cluster_status)
00479          return FALSE; // error, end of cluster list
00480 
00481       if (0xFF == MSB0(fs_g_seg.u32_addr))
00482       {
00483          // The beginning of the segment isn't found
00484          if (FS_CLUS_END == u8_cluster_status)
00485          {
00486             u32_tmp = fs_g_seg.u32_size_or_pos;       // Save number of sector remaining
00487 
00488             // Compute the sector address of this last cluster to take time during a futur request with the same cluster list
00489             fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start -= fs_g_seg.u32_size_or_pos;
00490             fs_g_seg.u32_addr = ((fs_g_cluster.u32_pos - 2) * fs_g_nav.u8_BPB_SecPerClus)
00491                               + fs_g_nav.u32_ptr_fat + fs_g_nav.u32_offset_data;
00492             fs_g_seg.u32_size_or_pos = fs_g_nav.u8_BPB_SecPerClus;
00493             if (FS_CLUST_ACT_CLR != opt_action)
00494                fat_cache_clusterlist_update_finish();
00495 
00496             // The position is outside the cluster list
00497             fs_g_seg.u32_addr = fs_g_cluster.u32_pos; // Send the last cluster value
00498             fs_g_seg.u32_size_or_pos = u32_tmp;       // Restore number of sector remaining
00499             fs_g_status = FS_ERR_OUT_LIST;
00500             return FALSE;
00501          }
00502          // Good cluster then continue
00503          fs_g_seg.u32_size_or_pos -= fs_g_nav.u8_BPB_SecPerClus;
00504 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
00505          if (FS_CLUST_ACT_CLR == opt_action)
00506          {
00507             if( fs_g_seg.u32_size_or_pos == 0)
00508             {
00509                // At cluster position, set the flag end of cluster list
00510                fs_g_seg.u32_addr = fs_g_cluster.u32_val; // Save the next cluster
00511                fs_g_cluster.u32_val = FS_CLUST_VAL_EOL;
00512                if( !fat_cluster_val( FS_CLUST_VAL_WRITE ))
00513                   return FALSE;
00514                fs_g_cluster.u32_val = fs_g_seg.u32_addr; // Resotre the next cluster
00515                // !!!! It isn't necessary to reinit MSB0( fs_g_seg.u32_addr ) to 0xFF,
00516                // !!!! fs_g_seg.u32_addr will be modified at the beginning of main loop
00517             }
00518          }
00519 #endif  // FS_LEVEL_FEATURES
00520       }
00521       else
00522       {
00523          // The beginning of segment is found
00524          if (FS_CLUST_ACT_SEG == opt_action)
00525          {
00526             if ( (fs_g_cluster.u32_pos+1) != fs_g_cluster.u32_val )
00527             {
00528                // The cluster is not a continue cluster or a invalid cluster
00529                fat_cache_clusterlist_update_finish();
00530                return TRUE;                              // End of segment
00531             }
00532          }
00533 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
00534          if (FS_CLUST_ACT_CLR == opt_action)
00535          {
00536             //** Clear cluster position
00537             fs_g_seg.u32_addr = fs_g_cluster.u32_val;    // Save the next cluster
00538             fs_g_cluster.u32_val = 0;                    // by default free cluster
00539             // If it is the first cluster (fs_g_seg.u32_size_or_pos <= fs_g_nav.u8_BPB_SecPerClus)
00540             // and doesn't start at the beginning of cluster (fs_g_seg.u32_size_or_pos != fs_g_nav.u8_BPB_SecPerClus)
00541             if (fs_g_seg.u32_size_or_pos < fs_g_nav.u8_BPB_SecPerClus)
00542             {
00543                fs_g_cluster.u32_val = FS_CLUST_VAL_EOL;  // End of cluster list allocated
00544             }
00545             if( !fat_cluster_val( FS_CLUST_VAL_WRITE ))
00546                return FALSE;
00547             fs_g_cluster.u32_val = fs_g_seg.u32_addr;    // Resotre the next cluster
00548             // !!!! It isn't necessary to reinit MSB0( fs_g_seg.u32_addr ) at 0xFF,
00549             // !!!! because it isn't possible that MSB0( fs_g_cluster.val ) = 0xFF.
00550          }
00551 #endif  // FS_LEVEL_FEATURES
00552 
00553          // Check the end of cluster list
00554          if (FS_CLUS_END == u8_cluster_status)
00555          {
00556 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
00557             if (FS_CLUST_ACT_CLR == opt_action)
00558             {
00559                return fat_update_fat2();
00560             }
00561 #endif  // FS_LEVEL_FEATURES
00562             fat_cache_clusterlist_update_finish();
00563             return TRUE; // End of segment
00564          }
00565 
00566          // Update the segment size
00567          fs_g_seg.u32_size_or_pos += fs_g_nav.u8_BPB_SecPerClus;
00568       }
00569       // HERE, Continue to read the cluster list
00570       // The next cluster is the value of previous cluster
00571       fs_g_cluster.u32_pos = fs_g_cluster.u32_val;
00572    }  // End of main loop
00573 }

Here is the caller graph for this function:

Bool fat_cluster_val ( Bool  b_mode  ) 

This function returns or modifys a cluster value in FAT.

Parameters:
b_mode FALSE, to read a cluster value
TRUE, to write a cluster value
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! Global variables used
//! IN :
//!   fs_g_cluster.u32_pos    cluster number to read or write
//!   fs_g_cluster.u32_val    value to write
//! OUT:
//!   fs_g_cluster.u32_val    value readed
//!   fs_g_u16_pos_fat        position in FAT of the cluster to read or write
//!                           value init in case of the fat_cluster_readnext() routine is used after
//! 

Definition at line 600 of file fat.c.

Referenced by fat_cluster_list(), fat_getfreespace(), and fat_getfreespace_percent().

00601 {
00602    _MEM_TYPE_FAST_ U16   u16_offset_fat;
00603    _MEM_TYPE_FAST_ U8    u8_data1, u8_data2;
00604 #define  u8_data3    (LSB(u16_offset_fat)) // Manual overlay
00605 #define  u8_data4    (MSB(u16_offset_fat)) // Manual overlay
00606    _MEM_TYPE_FAST_ PTR_CACHE u8_ptr_cluster;
00607 
00608    //**** Compute the cluster position in FAT (sector address & position in sector)
00609    if ( Is_fat32 )
00610    {
00611       // FAT 32
00612       // Optimization of -> u16_offset_fat = fs_g_cluster.pos * 4 / FS_CACHE_SIZE;
00613       // Optimization of -> u16_offset_fat = fs_g_cluster.pos / 128
00614       u16_offset_fat = fs_g_cluster.u32_pos >> (8-1);
00615 
00616       // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos * 4) % FS_CACHE_SIZE;
00617       // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos % 128) * 4
00618       fs_g_u16_pos_fat = ((U16)(LSB0(fs_g_cluster.u32_pos) & 0x7F))<< 2;
00619    }
00620    else if ( Is_fat16 )
00621    {
00622       // FAT 16
00623       // Optimization of -> u16_offset_fat = fs_g_cluster.u32_pos * 2 / FS_CACHE_SIZE = fs_g_cluster.u32_pos / 256;
00624       u16_offset_fat = LSB1(fs_g_cluster.u32_pos);
00625       // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos * 2) % FS_CACHE_SIZE;
00626       // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos % 256) * 2
00627       fs_g_u16_pos_fat = ((U16)LSB0(fs_g_cluster.u32_pos)) <<1;
00628    }
00629    else if ( Is_fat12 )
00630    {
00631       // FAT 12
00632       // Optimization of -> fs_g_u16_pos_fat = fs_g_cluster.u32_pos + (fs_g_cluster.u32_pos/ 2)
00633       fs_g_u16_pos_fat = (U16)fs_g_cluster.u32_pos + ((U16)fs_g_cluster.u32_pos >>1);
00634       // Optimization of -> u16_offset_fat = fs_g_cluster.u32_pos / FS_CACHE_SIZE
00635       u16_offset_fat = MSB(fs_g_u16_pos_fat) >> 1;
00636       // Optimization of -> fs_g_u16_pos_fat = fs_g_u16_pos_fat % FS_CACHE_SIZE
00637       MSB( fs_g_u16_pos_fat ) &= 0x01;
00638    }
00639 
00640 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
00641    if (b_mode)
00642    {
00643       // Update information about FAT modification
00644       if( fs_g_u16_first_mod_fat > u16_offset_fat )
00645       {
00646          fs_g_u16_first_mod_fat = u16_offset_fat;
00647       }
00648       if( fs_g_u16_last_mod_fat < u16_offset_fat )
00649       {
00650          fs_g_u16_last_mod_fat = u16_offset_fat;
00651       }
00652       if ( Is_fat12 )
00653       {  // A cluster may be stored on two sectors
00654          if( fs_g_u16_pos_fat == (FS_CACHE_SIZE-1) )
00655          {  // Count the next FAT sector
00656             if( fs_g_u16_last_mod_fat < (u16_offset_fat+1) )
00657             {
00658                fs_g_u16_last_mod_fat = (u16_offset_fat+1);
00659             }
00660          }
00661       }
00662    }
00663 #endif  // FS_LEVEL_FEATURES
00664 
00665    //**** Read cluster sector in FAT
00666    fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + u16_offset_fat;   // Computed logical sector address
00667    if( !fat_cache_read_sector( TRUE ))
00668       return FALSE;
00669 
00670    // Read cluster information
00671    u8_ptr_cluster = &fs_g_sector[fs_g_u16_pos_fat];
00672    u8_data1 = u8_ptr_cluster[0];
00673    // Remark: if (fs_g_u16_pos_fat+1)=512 then it isn't a mistake, because this value will be erase in next lines
00674    u8_data2 = u8_ptr_cluster[1];
00675    u8_data3 = u8_ptr_cluster[2];
00676    u8_data4 = u8_ptr_cluster[3];
00677 
00678    if ( Is_fat12 )
00679    {   // A cluster may be stored on two sectors
00680       if(  fs_g_u16_pos_fat == (FS_CACHE_SIZE-1) )
00681       {  // Go to next sector
00682          fs_gu32_addrsector++;
00683          if( !fat_cache_read_sector( TRUE ))
00684            return FALSE;
00685          u8_data2 = fs_g_sector[0];
00686       }
00687    }
00688 
00689    if (FALSE == b_mode)
00690    {
00691       //**** Read the cluster value
00692       LSB0( fs_g_cluster.u32_val ) = u8_data1;  // FAT 12,16,32
00693       LSB1( fs_g_cluster.u32_val ) = u8_data2;  // FAT 12,16,32
00694 
00695       if ( Is_fat32 )
00696       {  // FAT 32
00697          LSB2( fs_g_cluster.u32_val ) = u8_data3;
00698          LSB3( fs_g_cluster.u32_val ) = u8_data4 & 0x0F; // The high 4 bits are reserved
00699       }
00700       else
00701       {  // FAT 12 & 16 don't use the high bytes
00702          LSB2( fs_g_cluster.u32_val ) = 0;
00703          LSB3( fs_g_cluster.u32_val ) = 0;
00704 
00705          // FAT 12 translate 16bits value to 12bits
00706          if ( Is_fat12 )
00707          {
00708             if ( 0x01 & LSB0(fs_g_cluster.u32_pos) )
00709             {  // Readed cluster is ODD
00710                LSB0( fs_g_cluster.u32_val ) = (LSB1( fs_g_cluster.u32_val ) <<4 ) + (LSB0( fs_g_cluster.u32_val ) >>4 );
00711                LSB1( fs_g_cluster.u32_val ) =  LSB1( fs_g_cluster.u32_val ) >>4 ;
00712             }
00713             else
00714             {  // Readed cluster is EVEN
00715                LSB1( fs_g_cluster.u32_val ) &= 0x0F;
00716             }
00717          }
00718       }
00719    } else {
00720 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
00721       //**** Write the cluster value
00722       if ( Is_fat12 )
00723       {
00724          // FAT 12, translate cluster value
00725          if ( 0x01 & LSB0(fs_g_cluster.u32_pos) )
00726          {  // Cluster writing is ODD
00727             u8_data1 = (u8_data1 & 0x0F) + (LSB0( fs_g_cluster.u32_val )<<4);
00728             u8_data2 = (LSB1( fs_g_cluster.u32_val )<<4) + (LSB0( fs_g_cluster.u32_val )>>4) ;
00729          } else {
00730             // Cluster writing is EVEN
00731             u8_data1 = LSB0( fs_g_cluster.u32_val );
00732             u8_data2 = (u8_data2 & 0xF0) + (LSB1( fs_g_cluster.u32_val ) & 0x0F) ;
00733          }
00734 
00735          // A cluster may be stored on two sectors
00736          if( fs_g_u16_pos_fat == (FS_CACHE_SIZE-1) )
00737          {
00738             fs_g_sector[0] = u8_data2;
00739             fat_cache_mark_sector_as_dirty();
00740             // Go to previous sector
00741             fs_gu32_addrsector--;
00742             if( !fat_cache_read_sector( TRUE ))
00743               return FALSE;
00744             // Modify the previous sector
00745             fs_g_sector[ FS_CACHE_SIZE-1 ] = u8_data1;
00746             fat_cache_mark_sector_as_dirty();
00747             return TRUE;
00748          }
00749       }
00750       else
00751       {
00752          // FAT 16 & 32
00753          u8_data1 = LSB0( fs_g_cluster.u32_val );
00754          u8_data2 = LSB1( fs_g_cluster.u32_val );
00755          if ( Is_fat32 )
00756          {  // FAT 32
00757             u8_ptr_cluster[2] = LSB2( fs_g_cluster.u32_val );
00758             u8_ptr_cluster[3] = LSB3( fs_g_cluster.u32_val ) + (u8_data4 & 0xF0); // The high 4 bits are reserved
00759          }
00760       }
00761       // Here for FAT 32, 16 & 12 (only if the cluster values are in the same sector)
00762       u8_ptr_cluster[0] = u8_data1;
00763       u8_ptr_cluster[1] = u8_data2;
00764       fat_cache_mark_sector_as_dirty();
00765 #else
00766       fs_g_status = FS_ERR_COMMAND;
00767       return FALSE;
00768 #endif  // FS_LEVEL_FEATURES
00769    }
00770 
00771    return TRUE;
00772 #undef  u8_data3    // end of Manual overlay
00773 #undef  u8_data4    // end of Manual overlay
00774 }

Here is the caller graph for this function:

Bool fat_cluster_readnext ( void   ) 

This function is optimized to read a continue cluster list on FAT16 and FAT32.

Read global value "fs_g_status" in case of error : FS_ERR_HW Hardware driver error FS_LUN_WP Drive is read only

Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! Global variables used
//! IN :
//!   fs_g_u16_pos_fat        previous cluster position in FAT
//! OUT:
//!   fs_g_u16_pos_fat        readed cluster position in FAT
//!   fs_g_cluster.u32_val    value of cluster readed
//! 

Definition at line 795 of file fat.c.

Referenced by fat_cluster_list(), and fat_getfreespace().

00796 {
00797    // Compute the next cluster position in FAT
00798    if ( Is_fat32 )
00799    {
00800       fs_g_u16_pos_fat += 4;
00801    }else{
00802       // Is_fat16
00803       fs_g_u16_pos_fat += 2;
00804    }
00805 
00806    // Check if next cluster is in internal cache
00807    if( FS_CACHE_SIZE == fs_g_u16_pos_fat )
00808    {
00809       // Update cache
00810       fs_g_u16_pos_fat = 0;
00811       fs_gu32_addrsector++;
00812       if( !fat_cache_read_sector( TRUE ))
00813          return FALSE;
00814    }
00815 
00816    //**** Read the cluster value
00817    LSB0( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+0];  // FAT 16,32
00818    LSB1( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+1];  // FAT 16,32
00819 
00820    if ( Is_fat32 )
00821    {  // FAT 32
00822       LSB2( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+2];
00823       LSB3( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+3];
00824    }
00825    return TRUE;
00826 }

Here is the caller graph for this function:

U8 fat_checkcluster ( void   ) 

This function checks the cluster value.

Returns:
value status
FS_CLUS_OK Value correct
FS_CLUS_BAD Value bad
FS_CLUS_END It is a end of list
//! Global variable used
//! IN :
//!   fs_g_cluster.u32_val       value to check
//! 

Definition at line 842 of file fat.c.

Referenced by fat_cluster_list().

00843 {
00844   if ( !fs_g_cluster.u32_val )
00845     return FS_CLUS_BAD;
00846 
00847   // Cluster bad if (FAT12 > 0x0FF6) (FAT16 > 0xFFF6) (FAT32 > 0x0FFFFFF6) or cluster null
00848   if ( Is_fat32 )
00849   {
00850     if (fs_g_cluster.u32_val <= 0x0FFFFFF6)
00851       return FS_CLUS_OK;
00852     else if (fs_g_cluster.u32_val == 0x0FFFFFFF)
00853       return FS_CLUS_END;
00854   }
00855   else if ( Is_fat16 )
00856   {
00857     if (fs_g_cluster.u32_val <= 0xFFF6)
00858       return FS_CLUS_OK;
00859     else if (fs_g_cluster.u32_val == 0xFFFF)
00860       return FS_CLUS_END;
00861   }
00862   else if ( Is_fat12 )
00863   {
00864     if (fs_g_cluster.u32_val <= 0x0FF6)
00865       return FS_CLUS_OK;
00866     else if (fs_g_cluster.u32_val == 0x0FFF)
00867       return FS_CLUS_END;
00868   }
00869 
00870   return FS_CLUS_BAD;
00871 }

Here is the caller graph for this function:

void fat_cache_clusterlist_reset ( void   ) 

This function resets the cluster list caches.

Definition at line 878 of file fat.c.

Referenced by fat_check_device(), fat_cluster_list(), and nav_reset().

00879 {
00880    U8 u8_i;
00881    fs_g_u8_current_cache=0;
00882    for( u8_i=0; u8_i<(FS_NB_CACHE_CLUSLIST*2); u8_i++ )
00883    {
00884       // The cache list is splited in two cache (file cluster list and directory cluster list)
00885       fs_g_cache_clusterlist[u8_i].b_cache_file = (u8_i<FS_NB_CACHE_CLUSLIST)?TRUE:FALSE;
00886       fs_g_cache_clusterlist[u8_i].u8_lun = 0xFF;
00887       fs_g_cache_clusterlist[u8_i].u8_level_use = 0xFF;
00888    }
00889 }

Here is the caller graph for this function:

Bool fat_read_file ( U8  mode  ) 

This function gets or clears a cluster list at the current position in the selected file.

Parameters:
mode Choose action
FS_CLUST_ACT_SEG Get memory segment corresponding at the position in selected file
FS_CLUST_ACT_ONE Store in internal cache the sector corresponding at the position in selected file
FS_CLUST_ACT_CLR Clear the cluster list corresponding at the position in selected file
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! Global variable used
//! IN :
//!   fs_g_nav_entry.u32_cluster       First cluster of selected file
//!   fs_g_nav_entry.u32_pos_in_file   Position in file (unit byte)
//! 

Definition at line 1031 of file fat.c.

Referenced by file_getc(), file_read(), and file_read_buf().

01032 {
01033    U32   u32_sector_pos;
01034 
01035    // Compute sector position
01036    u32_sector_pos = fs_g_nav_entry.u32_pos_in_file >> FS_512B_SHIFT_BIT;
01037 
01038    if(FS_CLUST_ACT_ONE  == mode)
01039    {
01040       if( (fs_g_sectorcache.u8_lun                 == fs_g_nav.u8_lun )
01041       &&  (fs_g_sectorcache.u32_clusterlist_start  == fs_g_nav_entry.u32_cluster )
01042       &&  (fs_g_sectorcache.u32_clusterlist_pos    == u32_sector_pos ) )
01043       {
01044          return TRUE;      // The internal cache contains the sector ascked
01045       }
01046    }
01047    else
01048    {
01049       if( FS_CLUST_ACT_CLR == mode )
01050       {
01051          // Clear cluster list
01052          if( 0 == fs_g_nav_entry.u32_cluster )
01053             return TRUE;   // No cluster list is linked with the file, then no clear is necessary
01054 
01055          if(0 != (fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK) )
01056          {
01057             // The actual sector is used, then start clear on the next sector
01058             u32_sector_pos++;
01059          }
01060       }
01061    }
01062 
01063    // Get the segment which start at the current position
01064    fs_g_seg.u32_addr = fs_g_nav_entry.u32_cluster;
01065    fs_g_seg.u32_size_or_pos = u32_sector_pos;
01066    if( FS_CLUST_ACT_ONE != mode )
01067    {
01068       if( fat_cluster_list( mode, TRUE ) )
01069          return TRUE;      // Get or clear segment OK
01070    }
01071    else
01072    {
01073       if( fat_cluster_list( FS_CLUST_ACT_SEG, TRUE ) )   // Read all segment
01074       {
01075          // Read the sector corresponding at the position file (= first sector of segment)
01076          fs_gu32_addrsector = fs_g_seg.u32_addr ;
01077          if( fat_cache_read_sector( TRUE ) )
01078          {
01079             fs_g_sectorcache.u32_clusterlist_start  = fs_g_nav_entry.u32_cluster;
01080             fs_g_sectorcache.u32_clusterlist_pos    = u32_sector_pos;
01081             return TRUE;
01082          }
01083       }
01084    }
01085    if( (FS_CLUST_ACT_CLR == mode       )
01086    &&  (FS_ERR_OUT_LIST  == fs_g_status) )
01087    {
01088       // It is possible to clear nothing
01089       return TRUE;
01090    }
01091    return FALSE;
01092 }

Here is the caller graph for this function:

Bool fat_read_dir ( void   ) 

This function fill the internal cache with a sector from current directory.

Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! Global variable used
//! IN :
//!   fs_g_nav.u32_cluster_sel_dir           First cluster of current directory
//!   fs_g_nav_fast.u16_entry_pos_sel_file   Position in directory (unit entry)
//! 

Definition at line 1191 of file fat.c.

Referenced by file_close(), nav_dir_gotoparent(), nav_file_checkext(), nav_file_dateget(), nav_file_name(), nav_filelist_set(), and nav_partition_label().

01192 {
01193    U32 u32_cluster_pos;
01194 
01195    // Compute the cluster list position corresponding of the current entry
01196    u32_cluster_pos = fs_g_nav_fast.u16_entry_pos_sel_file >> (FS_512B_SHIFT_BIT - FS_SHIFT_B_TO_FILE_ENTRY);
01197 
01198    if( (fs_g_sectorcache.u8_lun                 == fs_g_nav.u8_lun )
01199    &&  (fs_g_sectorcache.u32_clusterlist_start  == fs_g_nav.u32_cluster_sel_dir )
01200    &&  (fs_g_sectorcache.u32_clusterlist_pos    == u32_cluster_pos ) )
01201    {
01202          return TRUE;      // The internal cache contains the sector ascked
01203    }
01204 
01205    // Get sector address corresponding at cluster list position
01206    fs_g_seg.u32_addr = fs_g_nav.u32_cluster_sel_dir;
01207    fs_g_seg.u32_size_or_pos = u32_cluster_pos;
01208    if( fat_cluster_list( FS_CLUST_ACT_ONE, FALSE ) )
01209    {
01210       // Read the sector
01211       fs_gu32_addrsector = fs_g_seg.u32_addr;
01212       if( fat_cache_read_sector( TRUE ) )
01213       {
01214          // Update information about internal sector cache
01215          fs_g_sectorcache.u32_clusterlist_start  = fs_g_nav.u32_cluster_sel_dir;
01216          fs_g_sectorcache.u32_clusterlist_pos    = u32_cluster_pos;
01217          return TRUE;
01218       }
01219    }
01220    return FALSE;
01221 }

Here is the caller graph for this function:

Bool fat_entry_check ( Bool  b_type  ) 

This function checks the entry.

Parameters:
b_type entry type to compare (FS_FILE or FS_DIR)
Returns:
TRUE, the entry is a short entry and correspond to b_type

FALSE, otherwise

//! Global variable used
//! IN :
//!   fs_g_sector       The directory sector corresponding at the current position
//!   fs_g_nav_fast.u16_entry_pos_sel_file    Position in directory of the entry file (unit entry)
//! 

Definition at line 1239 of file fat.c.

Referenced by nav_filelist_set().

01240 {
01241    PTR_CACHE u8_ptr_entry;
01242    U8 u8_first_byte, u8_seconde_byte;
01243    U8 u8_attribut;
01244 
01245    u8_ptr_entry = fat_get_ptr_entry();
01246 
01247    u8_first_byte = u8_ptr_entry[0];
01248    if ( FS_ENTRY_END == u8_first_byte )
01249    {
01250       fs_g_status = FS_ERR_ENTRY_EMPTY;   // end of directory
01251       return FALSE;
01252    }
01253    fs_g_status = FS_ERR_ENTRY_BAD;        // by default BAD ENTRY
01254    if ( FS_ENTRY_DEL == u8_first_byte )      { return FALSE;   } // entry deleted
01255    if (   '.'  == u8_first_byte )            { return FALSE;   } // current dir "."
01256    u8_seconde_byte = u8_ptr_entry[1];
01257    if ( ('.'  == u8_first_byte)
01258    &&   ('.'  == u8_seconde_byte) )          { return FALSE;   } // current dir ".."
01259 
01260    // Check attribut
01261    u8_attribut = u8_ptr_entry[11];
01262    if ( FS_ATTR_VOLUME_ID & u8_attribut )    { return FALSE;   } // volume id
01263    // Optimization, this line isn't necessary because the next test control this case
01264    // if ( FS_ATTR_LFN_ENTRY == *u8_ptr_entry) { return FALSE;   } // long file name
01265 
01266    // Check entry type
01267    if( FS_ATTR_DIRECTORY & u8_attribut )
01268    {
01269       return (FS_DIR == b_type);
01270    }else{
01271       return (FS_FILE == b_type);
01272    }
01273 }

Here is the caller graph for this function:

Bool fat_entry_checkext ( FS_STRING  sz_filter  ) 

This function checks the file extension.

Parameters:
sz_filter extension filter is a ASCII string (ex: "mp3,w*" )
Returns:
TRUE, the file name have a good extension

FALSE, otherwise

//! Global variable used
//! IN :
//!   fs_g_sector       The directory sector corresponding at the current position
//!   fs_g_nav_fast.u16_entry_pos_sel_file    Position in directory of the entry file (unit entry)
//! 

Definition at line 1290 of file fat.c.

Referenced by nav_file_checkext().

01291 {
01292    PTR_CACHE u8_ptr_entry;
01293    U8 u8_i, u8_filter_char, u8_entry_char;
01294 
01295    u8_ptr_entry = fat_get_ptr_entry();
01296 
01297    // Compare the extension with filter
01298    for( u8_i=0 ; u8_i<3 ; u8_i++)
01299    {
01300       u8_filter_char = *sz_filter;
01301       if ('*' == u8_filter_char)
01302          break; // All extension is good
01303 
01304       u8_entry_char = u8_ptr_entry[8+u8_i];
01305 
01306       // Compare the extension filter to extension file (this one ignore the case)
01307       if( (u8_filter_char!=  u8_entry_char     )
01308       &&  (u8_filter_char!= (u8_entry_char+('a'-'A'))) )
01309       {
01310          if ( (',' == u8_filter_char)
01311          ||   ( 0  == u8_filter_char) )
01312          {
01313            // It is the end of filter
01314            if (' ' == u8_entry_char)
01315               break; // it is the end of extension file -> extension good
01316          }
01317          // here, bad extension
01318 
01319          // Search the next filter
01320          while( ',' != u8_filter_char )
01321          {
01322             if (0  == u8_filter_char)
01323             {
01324                return FALSE;   // it is the last filter
01325             }
01326             sz_filter++;
01327             u8_filter_char = *sz_filter;
01328          }
01329          u8_i = 0xFF;          // restart loop compare
01330       }
01331       sz_filter++; // go to next char of filter
01332    }
01333 
01334    return TRUE; // It is a good extension
01335 }

Here is the caller graph for this function:

void fat_get_entry_info ( void   ) 

This function reads information about selected file.

//! Global variable used
//! IN :
//!   fs_g_sector       The directory sector corresponding at the current position
//!   fs_g_nav_fast.u16_entry_pos_sel_file    Position in directory of the entry file (unit entry)
//! OUT:
//!   fs_g_nav_entry. u32_cluster, u8_attr, u32_size
//! 

Definition at line 1349 of file fat.c.

Referenced by nav_dir_gotoparent(), and nav_filelist_set().

01350 {
01351    PTR_CACHE ptr_entry;
01352 
01353    ptr_entry = fat_get_ptr_entry();
01354 
01355    // Get attribut
01356    ptr_entry+= 11;
01357    fs_g_nav_entry.u8_attr = ptr_entry[0];
01358 
01359    // Get the first cluster of the file cluster list
01360    ptr_entry += (20-11);
01361    LSB2(fs_g_nav_entry.u32_cluster) = ptr_entry[0];
01362    LSB3(fs_g_nav_entry.u32_cluster) = ptr_entry[1];
01363    ptr_entry += (26-20);
01364    LSB0(fs_g_nav_entry.u32_cluster) = ptr_entry[0];
01365    LSB1(fs_g_nav_entry.u32_cluster) = ptr_entry[1];
01366 
01367    // Get the size of file
01368    ptr_entry += (28-26);
01369    LSB0(fs_g_nav_entry.u32_size) = ptr_entry[0];
01370    LSB1(fs_g_nav_entry.u32_size) = ptr_entry[1];
01371    LSB2(fs_g_nav_entry.u32_size) = ptr_entry[2];
01372    LSB3(fs_g_nav_entry.u32_size) = ptr_entry[3];
01373 }

Here is the caller graph for this function:

Bool fat_entry_is_dir ( void   ) 

This function checks if the entry file is a directory.

Returns:
TRUE, this entry is a directory

FALSE, otherwise

Definition at line 1381 of file fat.c.

Referenced by nav_dir_cd(), nav_file_isdir(), and nav_setcwd().

01382 {
01383    fs_g_status = FS_ERR_NO_DIR;
01384    return (FS_ATTR_DIRECTORY & fs_g_nav_entry.u8_attr);
01385 }

Here is the caller graph for this function:

void fat_clear_entry_info_and_ptr ( void   ) 

This function resets the selection pointers.

Definition at line 1390 of file fat.c.

Referenced by fat_mount(), nav_filelist_reset(), and nav_partition_mount().

Here is the caller graph for this function:

Bool fat_entry_shortname ( FS_STRING  sz_name,
U8  u8_size_max,
Bool  b_mode 
)

This function returns or compares the short name entry.

Parameters:
b_mode action mode:
FS_NAME_GET to get the short name of selected file
FS_NAME_CHECK to compare the short name of selected file
sz_name if FS_NAME_GET then buffer to store the short name file (ASCII or UNICODE )
if FS_NAME_CHECK then name to compare with short name (ASCII or UNICODE), it must be terminate by NULL or '*' value
u8_size_max buffer size (unit ASCII or UNICODE ) (ignored in "FS_NAME_CHECK" mode)
Returns:
FALSE, in case of error, see global value "fs_g_status" for more detail

TRUE, the name is correct or read OK

//! Global variable used
//! IN :
//!   fs_g_sector       The directory sector corresponding at the current position
//!   fs_g_nav_fast.u16_entry_pos_sel_file    Position in directory of the entry file (unit entry)
//! 

Definition at line 1472 of file fat.c.

Referenced by nav_file_name().

01473 {
01474    Bool b_extension_nostart = TRUE;
01475    U8 u8_pos_name;
01476    U8 u8_entry_char, u8_szname_char;
01477    PTR_CACHE ptr_entry;
01478    U8 u8_pos_entry;
01479 
01480    fs_g_status = FS_ERR_NAME_INCORRECT;  // by default the name don't corresponding at filter name
01481 
01482    u8_pos_name = 0;
01483    u8_pos_entry = 0;
01484    ptr_entry = fat_get_ptr_entry();
01485 
01486    // for each characters of short name
01487    while( 1 )
01488    {
01489       if( FS_SIZE_SFNAME == u8_pos_entry )
01490       {
01491          u8_entry_char = 0;   // end of name
01492       }
01493       else
01494       {
01495          u8_entry_char = ptr_entry[ u8_pos_entry ];
01496          if( ((FS_SIZE_SFNAME_WITHOUT_EXT == u8_pos_entry) && b_extension_nostart)  // end of name and '.' character no writed
01497          ||  ( ' ' == u8_entry_char) )
01498          {
01499             // end of name or extension
01500             if( (FS_SIZE_SFNAME_WITHOUT_EXT >= u8_pos_entry)         // End of name without extension
01501             &&  (' ' != ptr_entry[ FS_SIZE_SFNAME_WITHOUT_EXT ]) )   // extension exists
01502             {
01503                // go to extension position
01504                b_extension_nostart = FALSE;
01505                u8_pos_entry = FS_SIZE_SFNAME_WITHOUT_EXT-1;
01506                u8_entry_char = '.';
01507             }
01508             else
01509             {
01510                u8_entry_char = 0;                                    // end of name
01511             }
01512          }
01513       }
01514 
01515       if( FS_NAME_GET == b_mode )
01516       {
01517          if( !g_b_string_length )
01518          {
01519             if(u8_pos_name >= (u8_size_max-1))
01520                u8_entry_char = 0;                                    // buffer full then force end of string
01521 
01522             if( ('A'<=u8_entry_char) && (u8_entry_char<='Z'))
01523                u8_entry_char += ('a'-'A');                           // display short name in down case
01524 
01525             if( Is_unicode )
01526             {
01527                ((FS_STR_UNICODE)sz_name)[0] = u8_entry_char;
01528             }else{
01529                sz_name[0] = u8_entry_char;
01530             }
01531          }
01532       }
01533       else
01534       {
01535          // Compare the name
01536          if( Is_unicode
01537          && (0 != MSB(((FS_STR_UNICODE)sz_name)[0])) )
01538          {
01539             // The UNICODE is not possibled in short name
01540             return FALSE;
01541          }
01542 
01543          if( Is_unicode )
01544          {
01545             u8_szname_char = ((FS_STR_UNICODE)sz_name)[0];
01546          }else{
01547             u8_szname_char = sz_name[0];
01548          }
01549          if ('*' == u8_szname_char)
01550          {  // end of filter name which autorise all next character
01551             return TRUE;   //*** The name is correct ***
01552          }
01553 
01554          if( (0 != u8_entry_char) || (('\\' != u8_szname_char) && ('/' != u8_szname_char)) )
01555          {
01556             if((u8_szname_char != u8_entry_char)
01557             && (u8_szname_char != (u8_entry_char+('a'-'A'))) )  // no case sensitive
01558                return FALSE;  // short name not equal
01559          }
01560       }
01561 
01562       // For each characters
01563       if (0 == u8_entry_char)
01564       {
01565          if( g_b_string_length )
01566          {
01567             ((FS_STR_UNICODE)sz_name)[0] = u8_pos_name+1;      // Get length name
01568          }
01569          return TRUE;   // End of test correct or end of get name
01570       }
01571       if( !g_b_string_length )
01572       {
01573          sz_name += (Is_unicode? 2 : 1 );
01574       }
01575       u8_pos_name++;
01576       u8_pos_entry++;
01577    }
01578 }

Here is the caller graph for this function:

Bool fat_entry_longname ( FS_STRING  sz_name,
U8  u8_size_max,
Bool  b_mode,
Bool  b_match_case 
)

This function returns or compares the long name entry.

Parameters:
b_mode action mode:
FS_NAME_GET to get the long name of selected file
FS_NAME_CHECK to compare the long name of selected file
sz_name if FS_NAME_GET then buffer to store the long name file (ASCII or UNICODE )
if FS_NAME_CHECK then name to compare with long name (ASCII or UNICODE), it must be terminate by NULL or '*' value
b_match_case FALSE, ignore the case (only used in "FS_NAME_CHECK" action mode)
u8_size_max buffer size (unit ASCII or UNICODE ) (ignored in "FS_NAME_CHECK" mode)
Returns:
FALSE is not the end of long name, or in case of error, see global value "fs_g_status" for more detail

TRUE, the name is correct or read is finish

//! Global variable used
//! IN :
//!   fs_g_sector       The directory sector corresponding at the current position
//!   fs_g_nav_fast.u16_entry_pos_sel_file    Position in directory of the entry file (unit entry)
//! 

Definition at line 1603 of file fat.c.

Referenced by nav_file_name().

01604 {
01605    U8 u8_pos_name;
01606    PTR_CACHE ptr_entry;
01607    U16 u16_unicode_entry;
01608    U16 u16_unicode_szname;
01609 
01610    ptr_entry = fat_get_ptr_entry();
01611 
01612    if( (FS_ENTRY_END == *ptr_entry )            // end of directory
01613    ||  (FS_ENTRY_DEL == *ptr_entry )            // entry deleted
01614    ||  (FS_ATTR_LFN_ENTRY != ptr_entry[11]) )   // no long name
01615    {
01616       fs_g_status = FS_ERR_ENTRY_BAD;
01617       return FALSE;
01618    }
01619 
01620    if( g_b_string_length )
01621    {
01622       if ( 0 == (FS_ENTRY_LFN_LAST & *ptr_entry))
01623       {
01624          // no necessary -> ((FS_STR_UNICODE)sz_name)[0] = FS_SIZE_LFN_ENTRY;
01625          fs_g_status = FS_NO_LAST_LFN_ENTRY;
01626          return FALSE;                          // Other entry long name
01627       }
01628    }
01629 
01630    ptr_entry++;                                 // The long name start at offset 1 of the entry file
01631 
01632    u8_pos_name=0;
01633    while( 1 )
01634    {
01635       LSB(u16_unicode_entry) = ptr_entry[0];
01636       MSB(u16_unicode_entry) = ptr_entry[1];
01637       if( FS_NAME_GET == b_mode )
01638       {
01639          if( !g_b_string_length )
01640          {
01641             // Check the end of buffer
01642             if( u8_pos_name>=(u8_size_max-1) )
01643             {
01644                // Write end of string
01645                if( Is_unicode )
01646                {
01647                   ((FS_STR_UNICODE)sz_name)[0] = 0;
01648                }else{
01649                   sz_name[0] = 0;
01650                }
01651                return TRUE;                     // the buffer is full
01652             }
01653             // Read and store the long name
01654             if( Is_unicode )
01655             {
01656                ((FS_STR_UNICODE)sz_name)[0] = u16_unicode_entry;
01657             }else{
01658                sz_name[0] = (U8)u16_unicode_entry;
01659             }
01660          }
01661       }
01662       else
01663       {
01664          if( Is_unicode )
01665          {
01666             u16_unicode_szname = ((FS_STR_UNICODE)sz_name)[0];
01667          }else{
01668             u16_unicode_szname = sz_name[0];
01669          }
01670          // Check the name
01671          if( '*' == u16_unicode_szname )
01672          {  // end of filter name which autorise all next character
01673             return TRUE;   //*** The name is correct ***
01674          }
01675 
01676          if( ((0 != u16_unicode_entry ) || (( '\\' != u16_unicode_szname) && ( '/' != u16_unicode_szname)) )
01677          &&  ((u16_unicode_szname != (u16_unicode_entry+('a'-'A'))) || b_match_case)
01678          &&  ((u16_unicode_szname != (u16_unicode_entry-('a'-'A'))) || b_match_case)
01679          &&  (u16_unicode_szname != u16_unicode_entry) )
01680          {
01681            fs_g_status = FS_ERR_NAME_INCORRECT; //  The name don't corresponding at filter name
01682            return FALSE;
01683          }
01684       }
01685 
01686       if( 0 == u16_unicode_entry)
01687       {
01688          if( g_b_string_length )
01689          {
01690             ((FS_STR_UNICODE)sz_name)[0] = u8_pos_name+1;
01691          }
01692          return TRUE;                           // Last long name entry
01693       }
01694       if( 4 == u8_pos_name )
01695          ptr_entry += 3;                        // Go to second character
01696 
01697       if( 10 == u8_pos_name )
01698          ptr_entry += 2;                        // Go to third character
01699 
01700       if( 12 == u8_pos_name )
01701       {  // End of entry long name
01702          ptr_entry -= (FS_SIZE_FILE_ENTRY-2);   // Go to the first byte of the file entry
01703          if ( 0 == (FS_ENTRY_LFN_LAST & ptr_entry[0]))
01704          {
01705             fs_g_status = FS_NO_LAST_LFN_ENTRY;
01706             return FALSE;                       // Other long name entry is present
01707          }
01708          else
01709          {  // It is the last long name entry
01710             // then it is the end of name
01711             if( (FS_NAME_GET == b_mode) && g_b_string_length )
01712             {
01713                ((FS_STR_UNICODE)sz_name)[0] = 14;
01714                return TRUE;
01715             }
01716             sz_name += (Is_unicode? 2 : 1 );
01717             if( FS_NAME_GET == b_mode )
01718             {
01719                // Write end of string UNICODE
01720                if( Is_unicode )
01721                {
01722                   ((FS_STR_UNICODE)sz_name)[0] = 0;
01723                }else{
01724                   sz_name[0] = 0;
01725                }
01726                return TRUE;
01727             }
01728             else
01729             {
01730                // if it is the end of filter
01731                if( Is_unicode )
01732                {
01733                   u16_unicode_szname = ((FS_STR_UNICODE)sz_name)[0];
01734                }else{
01735                   u16_unicode_szname = sz_name[0];
01736                }
01737                return fat_check_eof_name(u16_unicode_szname);
01738             }
01739          }
01740       }
01741 
01742       if( !g_b_string_length )
01743       {
01744          sz_name += (Is_unicode? 2 : 1 );
01745       }
01746       u8_pos_name++;
01747       ptr_entry+=2;
01748    }
01749 }

Here is the caller graph for this function:

Bool fat_check_eof_name ( U16  character  ) 

Check end of name.

Parameters:
character value of character to check
Returns:
TRUE, it is a character to signal a end of name (0,'\','/')

FALSE, otherwise

Definition at line 1759 of file fat.c.

Referenced by fat_entry_longname().

01760 {
01761    return (('\0'==character)||('\\'==character)||('/'==character));
01762 }

Here is the caller graph for this function:

PTR_CACHE fat_get_ptr_entry ( void   ) 

This function returns a cache pointer on the current entry.

Returns:
a pointer on the internal cache

Definition at line 1769 of file fat.c.

Referenced by fat_entry_check(), fat_entry_checkext(), fat_entry_longname(), fat_entry_shortname(), fat_get_date(), and fat_get_entry_info().

Here is the caller graph for this function:

Bool fat_cache_read_sector ( Bool  b_load  ) 

This function loads a memory sector in internal cache sector.

Parameters:
b_load TRUE, load the cache with the memory sector corresponding
FALSE, Don't change the sector cache but change the memory address of cache
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! Global variable used
//! IN :
//!   fs_g_nav.u8_lun      drive number to read
//!   fs_gu32_addrsector   address to read (unit sector)
//! 

Definition at line 1790 of file fat.c.

Referenced by fat_cluster_readnext(), fat_cluster_val(), fat_get_nbpartition(), fat_getfreespace_percent(), fat_mount(), fat_read_dir(), and fat_read_file().

01791 {
01792    // Check if the sector asked is the same in cache
01793    if( (fs_g_sectorcache.u8_lun     == fs_g_nav.u8_lun )
01794    &&  (fs_g_sectorcache.u32_addr   == fs_gu32_addrsector ) )
01795    {
01796       return TRUE;
01797    }
01798 
01799    // Write previous cache before fill cache with a new sector
01800    if( !fat_cache_flush())
01801       return FALSE;
01802 
01803    // Delete informations about the caches
01804    fat_cache_reset();
01805 
01806    // Init sector cache
01807    fs_g_sectorcache.u32_addr = fs_gu32_addrsector;
01808    if( b_load )
01809    {
01810       // Load the sector from memory
01811       if( CTRL_GOOD != memory_2_ram( fs_g_nav.u8_lun  , fs_g_sectorcache.u32_addr, fs_g_sector))
01812       {
01813          fs_g_status = FS_ERR_HW;
01814          return FALSE;
01815       }
01816    }
01817    // Valid sector cache
01818    fs_g_sectorcache.u8_lun = fs_g_nav.u8_lun;
01819    return TRUE;
01820 }

Here is the caller graph for this function:

void fat_cache_reset ( void   ) 

This function resets the sector cache.

Definition at line 1825 of file fat.c.

Referenced by fat_cache_read_sector(), fat_check_device(), nav_reset(), stream_mem_to_mem(), and ushell_cmd_perform_access().

Here is the caller graph for this function:

Bool fat_cache_flush ( void   ) 

This function flushs the sector cache on the memory if necessary.

Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

Definition at line 1856 of file fat.c.

Referenced by fat_cache_read_sector(), file_close(), nav_exit(), stream_mem_to_mem(), and ushell_cmd_perform_access().

01857 {
01858    // If the cache is modified, then write the sector cache on the device
01859    if ( TRUE == fs_g_sectorcache.u8_dirty )
01860    {
01861       fs_g_sectorcache.u8_dirty = FALSE; // Always clear, although an error occur
01862       if( mem_wr_protect( fs_g_sectorcache.u8_lun  ))
01863       {
01864          fs_g_status = FS_LUN_WP;
01865          return FALSE;
01866       }
01867       if (CTRL_GOOD != ram_2_memory( fs_g_sectorcache.u8_lun , fs_g_sectorcache.u32_addr , fs_g_sector ))
01868       {
01869          fs_g_status = FS_ERR_HW;
01870          return FALSE;
01871       }
01872    }
01873    return TRUE;
01874 }

Here is the caller graph for this function:


Variable Documentation

_MEM_TYPE_SLOW_ Fs_clusterlist_cache fs_g_cache_clusterlist[FS_NB_CACHE_CLUSLIST *2]

Definition at line 65 of file fat.c.

Referenced by fat_cache_clusterlist_reset(), fat_cache_clusterlist_update_finish(), fat_cache_clusterlist_update_read(), fat_cache_clusterlist_update_select(), fat_cache_clusterlist_update_start(), and fat_cluster_list().

_MEM_TYPE_SLOW_ U8 fs_g_u8_current_cache

Definition at line 66 of file fat.c.

Referenced by fat_cache_clusterlist_reset(), fat_cache_clusterlist_update_finish(), fat_cache_clusterlist_update_read(), fat_cache_clusterlist_update_select(), fat_cache_clusterlist_update_start(), and fat_cluster_list().

_MEM_TYPE_FAST_ U16 fs_g_u16_pos_fat

Definition at line 578 of file fat.c.

Referenced by fat_cluster_readnext(), and fat_cluster_val().


Generated on Fri May 15 15:41:39 2009 for ATMEL by  doxygen 1.5.3