ATMEL: fat.c File Reference

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

# 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 44 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 900 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().

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

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 924 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().

    00925 {
    00926    U8 u8_cluster_offset = fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start % fs_g_nav.u8_BPB_SecPerClus;
    00927    fs_g_cache_clusterlist[fs_g_u8_current_cache].u8_lun       = fs_g_nav.u8_lun;          // valid cache
    00928    fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start   -= u8_cluster_offset;
    00929    fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_addr     = fs_g_seg.u32_addr - u8_cluster_offset;
    00930    fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_size     = fs_g_seg.u32_size_or_pos + u8_cluster_offset;
    00931
    00932    // Update the "level used" of cache
    00933    fat_cache_clusterlist_update_select();
    00934 }

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 964 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().

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

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 939 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().

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

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 91 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().

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

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 154 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().

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

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 175 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().

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

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 195 of file fat.c.

Referenced by fat_check_mount_select_open().

    00196 {
    00197    if( Fat_file_isnot_open() )
    00198    {
    00199       fs_g_status = FS_ERR_FILE_NO_OPEN;
    00200       return FALSE;
    00201    }
    00202    return TRUE;
    00203 }

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 211 of file fat.c.

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

    00212 {
    00213    if (FS_NO_SEL == fs_g_nav_fast.u16_entry_pos_sel_file)
    00214    {
    00215       fs_g_status = FS_ERR_NO_FILE_SEL;
    00216       return FALSE;
    00217    }
    00218    return TRUE;
    00219 }

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 227 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().

    00228 {
    00229    if( !fat_check_mount() )
    00230       return FALSE;
    00231    return fat_check_noopen();
    00232 }

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 240 of file fat.c.

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

    00241 {
    00242    if( !fat_check_mount() )
    00243       return FALSE;
    00244    if( !fat_check_select() )
    00245       return FALSE;
    00246    return fat_check_noopen();
    00247 }

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 255 of file fat.c.

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

    00256 {
    00257    if( !fat_check_mount() )
    00258       return FALSE;
    00259    if( !fat_check_select() )
    00260       return FALSE;
    00261    return fat_check_open();
    00262 }

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 270 of file fat.c.

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

    00271 {
    00272    if( !fat_check_mount() )
    00273       return FALSE;
    00274    return fat_check_select();
    00275 }

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 283 of file fat.c.

Referenced by file_ispresent(), and file_open().

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

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 299 of file fat.c.

Referenced by nav_partition_nb().

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

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 364 of file fat.c.

Referenced by fat_read_dir(), and fat_read_file().

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

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 603 of file fat.c.

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

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

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 798 of file fat.c.

Referenced by fat_cluster_list(), and fat_getfreespace().

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

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 845 of file fat.c.

Referenced by fat_cluster_list().

    00846 {
    00847   if ( !fs_g_cluster.u32_val )
    00848     return FS_CLUS_BAD;
    00849
    00850   // Cluster bad if (FAT12 == 0x0FF7) (FAT16 == 0xFFF7) (FAT32 == 0x0FFFFFF7)
    00851   // Last cluster if (FAT12 > 0x0FF7) (FAT16 > 0xFFF7) (FAT32 > 0x0FFFFFF7)
    00852   if ( Is_fat32 )
    00853   {
    00854     if (fs_g_cluster.u32_val >= 0x0FFFFFF8)
    00855       return FS_CLUS_END;
    00856     else if (fs_g_cluster.u32_val == 0x0FFFFFF7)
    00857       return FS_CLUS_BAD;
    00858   }
    00859   else if ( Is_fat16 )
    00860   {
    00861     if (fs_g_cluster.u32_val >= 0xFFF8)
    00862       return FS_CLUS_END;
    00863     else if (fs_g_cluster.u32_val == 0xFFF7)
    00864       return FS_CLUS_BAD;
    00865   }
    00866   else if ( Is_fat12 )
    00867   {
    00868     if (fs_g_cluster.u32_val >= 0xFF8)
    00869       return FS_CLUS_END;
    00870     else if (fs_g_cluster.u32_val == 0xFF7)
    00871       return FS_CLUS_BAD;
    00872   }
    00873
    00874   return FS_CLUS_OK;
    00875 }

Here is the caller graph for this function:

void fat_cache_clusterlist_reset | ( | void |  | ) |

This function resets the cluster list caches.

Definition at line 882 of file fat.c.

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

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

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 1035 of file fat.c.

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

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

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 1195 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().

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

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 1243 of file fat.c.

Referenced by nav_filelist_set().

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

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 1294 of file fat.c.

Referenced by nav_file_checkext().

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

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 1353 of file fat.c.

Referenced by nav_dir_gotoparent(), and nav_filelist_set().

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

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 1385 of file fat.c.

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

    01386 {
    01387    fs_g_status = FS_ERR_NO_DIR;
    01388    return (FS_ATTR_DIRECTORY & fs_g_nav_entry.u8_attr);
    01389 }

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 1394 of file fat.c.

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

    01395 {
    01396    fs_g_nav_fast.u16_entry_pos_sel_file= FS_NO_SEL;
    01397    fs_g_nav.u16_pos_sel_file           = FS_NO_SEL;
    01398    if( !fs_g_nav.b_mode_nav_single )
    01399    {
    01400       fs_g_nav.b_mode_nav                 = FS_DIR;
    01401    }
    01402    fs_g_nav_entry.u8_attr     = 0;
    01403    fs_g_nav_entry.u32_cluster = 0;
    01404    fs_g_nav_entry.u32_size    = 0;
    01405    Fat_file_close();
    01406 }

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 1476 of file fat.c.

Referenced by nav_file_name().

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

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 1607 of file fat.c.

Referenced by nav_file_name().

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

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 1763 of file fat.c.

Referenced by fat_entry_longname().

    01764 {
    01765    return (('\0'==character)||('\\'==character)||('/'==character));
    01766 }

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 1773 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().

    01774 {
    01775    return &fs_g_sector[(fs_g_nav_fast.u16_entry_pos_sel_file * FS_SIZE_FILE_ENTRY) & FS_512B_MASK];
    01776 }

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 1794 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().

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

Here is the caller graph for this function:

void fat_cache_reset | ( | void |  | ) |

This function resets the sector cache.

Definition at line 1829 of file fat.c.

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

    01830 {
    01831    fs_g_sectorcache.u8_lun                = FS_BUF_SECTOR_EMPTY;
    01832    fs_g_sectorcache.u8_dirty              = FALSE;
    01833    fs_g_sectorcache.u32_clusterlist_start = 0xFFFFFFFF;
    01834 }

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 1860 of file fat.c.

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

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

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 68 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 69 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 581 of file fat.c.

Referenced by fat_cluster_readnext(), and fat_cluster_val().