fat_unusual.c File Reference

FAT services. More...

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

Include dependency graph for fat_unusual.c:

Go to the source code of this file.

Functions

Bool fat_select_filesystem (U8 u8_fat_type, Bool b_MBR)
Bool fat_write_MBR (void)
Bool fat_write_PBR (Bool b_MBR)
Bool fat_clean_zone (Bool b_MBR)
Bool fat_initialize_fat (void)
Bool fat_mount (void)
 This function mounts a partition file system (FAT12, FAT16 or FAT32) of selected drive.
void fat_get_date (FS_STRING sz_date, Bool type_date)
 This function reads the information about a date.
U32 fat_getfreespace (void)
 This function returns the space free in the partition.
U8 fat_getfreespace_percent (void)
 This function returns the space free in percent.
Sub routines used by date read-write routines
void fat_translatedate_number_to_ascii (FS_STRING sz_date, PTR_CACHE ptr_date, Bool enable_ms)
 This function translates a date FAT value to ascii string.
void fat_translate_number_to_ascii (FS_STRING sz_ascii_number, U8 u8_size_number_ascii, U8 u8_nb_increment)
 This function translates a digital number to a ASCII number.
void fat_translatedate_ascii_to_number (const FS_STRING sz_date, PTR_CACHE ptr_date, Bool enable_ms)
U16 fat_translate_ascii_to_number (const FS_STRING sz_ascii_number, U8 u8_size_number_ascii)
Sub routine used to create a entry file
void fat_create_long_name_entry (FS_STRING sz_name, U8 u8_crc, U8 u8_id)
U8 fat_create_short_entry_name (FS_STRING sz_name, FS_STRING short_name, U8 nb, Bool mode)
U8 fat_find_short_entry_name (FS_STRING sz_name)
Bool fat_entry_shortname_compare (FS_STRING short_name)
U8 fat_check_name (FS_STRING sz_name)
U8 fat_translate_char_shortname (U8 character)
Bool fat_alloc_entry_free (U8 u8_nb_entry)
Bool fat_garbage_collector_entry (void)


Detailed Description

FAT services.

This file is a set of rarely-used FAT functions.

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

Definition in file fat_unusual.c.


Function Documentation

Bool fat_select_filesystem ( U8  u8_fat_type,
Bool  b_MBR 
)

Bool fat_write_MBR ( void   ) 

Bool fat_write_PBR ( Bool  b_MBR  ) 

Bool fat_clean_zone ( Bool  b_MBR  ) 

Bool fat_initialize_fat ( void   ) 

void fat_translatedate_number_to_ascii ( FS_STRING  sz_date,
PTR_CACHE  ptr_date,
Bool  enable_ms 
)

This function translates a date FAT value to ascii string.

Parameters:
sz_date table to store the date information
storage format (ASCII) = "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde
ptr_date pointer on date in internal cache
enable_ms TRUE, translate the millisecond field

Definition at line 1219 of file fat_unusual.c.

References fat_translate_number_to_ascii().

Referenced by fat_get_date().

01220 {
01221    FS_STRING ptr_string_date;
01222    U8 u8_i;
01223    U8 msb_date, lsb_date, msb_time, lsb_time, u8_ms = 0;
01224 
01225    // Read entry value of date and time
01226    if( enable_ms )
01227    {
01228       u8_ms = *ptr_date;
01229       ptr_date++;
01230    }
01231    lsb_time = *ptr_date;
01232    ptr_date++;
01233    msb_time = *ptr_date;
01234    ptr_date++;
01235    lsb_date = *ptr_date;
01236    ptr_date++;
01237    msb_date = *ptr_date;
01238 
01239    // Initialise the string with "1980000000000000" (Year = 1980 and other at 0)
01240    ptr_string_date = sz_date;
01241    *ptr_string_date = '1';
01242    ptr_string_date++;
01243    *ptr_string_date = '9';
01244    ptr_string_date++;
01245    *ptr_string_date = '8';
01246    ptr_string_date++;
01247    for( u8_i=(15-2) ; u8_i!=0 ; u8_i-- )
01248    {
01249       *ptr_string_date = '0';
01250       ptr_string_date++;
01251    }
01252 
01253    // Get the year
01254    fat_translate_number_to_ascii( sz_date, 4 , msb_date>>1 );
01255 
01256    // Get the month
01257    fat_translate_number_to_ascii( &sz_date[4] , 2 , ((msb_date & 0x01)<<3) + (lsb_date>>5) );
01258 
01259    // Get the day
01260    fat_translate_number_to_ascii( &sz_date[6] , 2 , lsb_date & 0x1F );
01261 
01262    // Get the hour
01263    fat_translate_number_to_ascii( &sz_date[8] , 2 , msb_time >> (11-8) );
01264 
01265    // Get the minute
01266    fat_translate_number_to_ascii( &sz_date[10] , 2 , ((msb_time & 0x07)<<3) + (lsb_time>>5) );
01267 
01268    // Get the seconde
01269    fat_translate_number_to_ascii( &sz_date[12] , 2 , (lsb_time & 0x1F)<<1 );
01270    if( 99 < u8_ms )
01271    {
01272      // Add one seconde
01273      fat_translate_number_to_ascii( &sz_date[12] , 2 , 1 );
01274      u8_ms -= 100;
01275    }
01276 
01277    // Get the miliseconde
01278    fat_translate_number_to_ascii( &sz_date[14] , 2 , u8_ms );
01279 }

Here is the call graph for this function:

Here is the caller graph for this function:

void fat_translate_number_to_ascii ( FS_STRING  sz_ascii_number,
U8  u8_size_number_ascii,
U8  u8_nb_increment 
)

This function translates a digital number to a ASCII number.

Parameters:
sz_ascii_number ascii string to increment (ex:"1907")
u8_size_number_ascii number of digit (ex:4)
u8_nb_increment number to add (ex:"102")
//! OUT, Update sz_ascii_number (ex:"2009")
//! 

Definition at line 1292 of file fat_unusual.c.

Referenced by fat_translatedate_number_to_ascii().

01293 {
01294    FS_STRING ptr_sz_ascii_number;
01295 
01296    u8_size_number_ascii--;
01297 
01298    for( ; u8_nb_increment != 0 ; u8_nb_increment-- )
01299    {
01300       ptr_sz_ascii_number = sz_ascii_number + u8_size_number_ascii;
01301       ptr_sz_ascii_number[0]++;
01302       while( ('9'+1) == *ptr_sz_ascii_number )
01303       {
01304          *ptr_sz_ascii_number = '0';
01305          ptr_sz_ascii_number--;
01306          ptr_sz_ascii_number[0]++;
01307       }
01308    }
01309 }

Here is the caller graph for this function:

void fat_translatedate_ascii_to_number ( const FS_STRING  sz_date,
PTR_CACHE  ptr_date,
Bool  enable_ms 
)

U16 fat_translate_ascii_to_number ( const FS_STRING  sz_ascii_number,
U8  u8_size_number_ascii 
)

void fat_create_long_name_entry ( FS_STRING  sz_name,
U8  u8_crc,
U8  u8_id 
)

U8 fat_create_short_entry_name ( FS_STRING  sz_name,
FS_STRING  short_name,
U8  nb,
Bool  mode 
)

U8 fat_find_short_entry_name ( FS_STRING  sz_name  ) 

Bool fat_entry_shortname_compare ( FS_STRING  short_name  ) 

U8 fat_check_name ( FS_STRING  sz_name  ) 

U8 fat_translate_char_shortname ( U8  character  ) 

Bool fat_alloc_entry_free ( U8  u8_nb_entry  ) 

Bool fat_garbage_collector_entry ( void   ) 

Bool fat_mount ( void   ) 

This function mounts a partition file system (FAT12, FAT16 or FAT32) of selected drive.

This function mounts a partition.

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

TRUE otherwise

//! Global variables used
//! IN :
//!   fs_g_nav.u8_lun            Indicate the drive to mount
//!   fs_g_nav.u8_partition      Indicate the partition to mount (if FS_MULTI_PARTITION =  ENABLED )
//! OUT:
//!   fs_g_nav                   update structure
//! If the FS_MULTI_PARTITION option is disabled
//! then the mount routine selects the first partition supported by file system. <br>
//! 

Definition at line 102 of file fat_unusual.c.

References FALSE, fat_cache_read_sector(), fat_check_device(), fat_clear_entry_info_and_ptr(), FS_512B, FS_BR_SIGNATURE_HIGH, FS_BR_SIGNATURE_LOW, FS_ERR_NO_FORMAT, FS_ERR_NO_PART, FS_ERR_NO_SUPPORT_PART, FS_FAT12_MAX_CLUSTERS, FS_FAT16_MAX_CLUSTERS, fs_g_nav, fs_g_nav_fast, fs_g_sector, fs_g_status, fs_gu32_addrsector, FS_MBR_OFFSET_PART_ENTRY, FS_NB_FAT, FS_PART_BOOTABLE, FS_PART_NO_BOOTABLE, FS_PART_TYPE_FAT12, FS_PART_TYPE_FAT16_INF32M, FS_PART_TYPE_FAT16_SUP32M, FS_PART_TYPE_FAT16_SUP32M_BIS, FS_PART_TYPE_FAT32, FS_PART_TYPE_FAT32_BIS, FS_SIZE_FILE_ENTRY, FS_TYPE_FAT_12, FS_TYPE_FAT_16, FS_TYPE_FAT_32, FS_TYPE_FAT_UNM, HIGH_16_BPB_BytsPerSec, HIGH_16_BPB_FATSz16, HIGH_16_BPB_ResvSecCnt, HIGH_16_BPB_RootEntCnt, HIGH_16_BPB_TotSec16, LOW0_32_BPB_FATSz32, LOW0_32_BPB_RootClus, LOW0_32_BPB_TotSec32, LOW1_32_BPB_FATSz32, LOW1_32_BPB_RootClus, LOW1_32_BPB_TotSec32, LOW2_32_BPB_FATSz32, LOW2_32_BPB_RootClus, LOW2_32_BPB_TotSec32, LOW3_32_BPB_FATSz32, LOW3_32_BPB_RootClus, LOW3_32_BPB_TotSec32, LOW_16_BPB_FATSz16, LOW_16_BPB_FSInfo, LOW_16_BPB_ResvSecCnt, LOW_16_BPB_RootEntCnt, LOW_16_BPB_TotSec16, LSB, LSB0, LSB1, LSB2, LSB3, mem_sector_size(), MSB, Fs_management::rootdir, Fs_rootdir::seg, TRUE, Fs_management::u16_fat_size, Fs_management::u16_offset_FSInfo, Fs_rootdir::u16_pos, Fs_rootdir::u16_size, Fs_rootdir::u32_cluster, Fs_management::u32_cluster_sel_dir, Fs_management::u32_CountofCluster, Fs_management::u32_offset_data, Fs_management::u32_ptr_fat, U8_BPB_SecPerClus, Fs_management::u8_BPB_SecPerClus, Fs_management::u8_lun, Fs_management::u8_partition, and Fs_management_fast::u8_type_fat.

00103 {
00104    U8  u8_sector_size;
00105    U8  u8_tmp;
00106    U16 u16_tmp;
00107    U32 u32_tmp;
00108 
00109    // Select the root directory
00110    fs_g_nav.u32_cluster_sel_dir   = 0;
00111    // No selected file
00112    fat_clear_entry_info_and_ptr();
00113 
00114    fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM;
00115    fs_gu32_addrsector = 0;    // Start read at the beginning of memory
00116 
00117    // Check if the drive is availabled
00118    if( !fat_check_device() )
00119       return FALSE;
00120 
00121    while( 1 )  // Search a valid partition
00122    {
00123       // Read one sector
00124       if( !fat_cache_read_sector( TRUE ))
00125          return FALSE;
00126 
00127       // Check PBR/MBR signature
00128       if ( (fs_g_sector[510] != FS_BR_SIGNATURE_LOW  )
00129       &&   (fs_g_sector[511] != FS_BR_SIGNATURE_HIGH ) )
00130       {
00131          fs_g_status = FS_ERR_NO_FORMAT;
00132          return FALSE;
00133       }
00134 
00135       if ( 0 == fs_gu32_addrsector )
00136       {
00137          //** first sector then check a MBR structure
00138          // Search the first partition supported
00139 #if (FS_MULTI_PARTITION == ENABLED)
00140          u16_tmp=0;  // Init to "no valid partition found"
00141 #endif
00142          for( u8_tmp=0 ; u8_tmp!=4 ; u8_tmp++ )
00143          {
00144             // The first sector must be a MBR, then check the partition entry in the MBR
00145             if ( ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_BOOTABLE             )||
00146                   (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_NO_BOOTABLE          )  )
00147             &&   ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT12           )||
00148                   (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_INF32M    )||
00149                   (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M    )||
00150                   (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M_BIS)||
00151                   (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32           )||
00152                   (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32_BIS       )) )
00153             {
00154                // A valid partition is found
00155 #if (FS_MULTI_PARTITION == ENABLED)
00156                if( u16_tmp == fs_g_nav.u8_partition )
00157                   break;   // The selected partition is valid
00158                u16_tmp++;
00159 #else
00160                break;
00161 #endif
00162             }
00163          }
00164          if( u8_tmp != 4 )
00165          {
00166             // Partition found -> Get partition position (unit sector) at offset 8
00167             LSB0(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+8];
00168             LSB1(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+9];
00169             LSB2(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+10];
00170             LSB3(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+11];
00171             fs_gu32_addrsector *= mem_sector_size( fs_g_nav.u8_lun );
00172             continue;   // Go to check PBR of partition
00173          }
00174 
00175          // No MBR found then check PBR
00176 #if (FS_MULTI_PARTITION == ENABLED)
00177          // The device don't have mutli partition, but only one
00178          if ( 0 != fs_g_nav.u8_partition )
00179          {
00180             fs_g_status = FS_ERR_NO_PART;
00181             return FALSE;
00182          }
00183 #endif
00184       }
00185 
00186       //** Check a PBR structure
00187       if ( (fs_g_sector[0] == 0xEB) &&          // PBR Byte 0
00188            (fs_g_sector[2] == 0x90) &&          // PBR Byte 2
00189            ((fs_g_sector[21] & 0xF0) == 0xF0) ) // PBR Byte 21 : Media byte
00190       {
00191          break;   // valid PBR found
00192       }
00193       // PBR not found
00194       fs_g_status = FS_ERR_NO_PART;
00195       return FALSE;
00196    }
00197 
00198    fs_g_status = FS_ERR_NO_SUPPORT_PART;  // by default partition no supported
00199 
00200    // Get sector size of File System (unit 512B)
00201    // To translate from sector disk unit to sector 512B unit
00202    u8_sector_size = HIGH_16_BPB_BytsPerSec/2;
00203 
00204    // Read BPB_SecPerClus (unit sector)
00205    fs_g_nav.u8_BPB_SecPerClus = U8_BPB_SecPerClus * u8_sector_size;
00206 
00207    //** FAT Type determination (algorithm of "Hardware White Paper FAT")
00208    // Get FAT size (unit sector)
00209    LSB( u16_tmp ) = LOW_16_BPB_FATSz16;
00210    MSB( u16_tmp ) = HIGH_16_BPB_FATSz16;
00211    if ( 0==u16_tmp )
00212    {
00213       LSB( u16_tmp ) = LOW0_32_BPB_FATSz32;
00214       MSB( u16_tmp ) = LOW1_32_BPB_FATSz32;
00215       // a large FAT32 isn't supported by this file system
00216       if( (0 != LOW2_32_BPB_FATSz32 )
00217       ||  (0 != LOW3_32_BPB_FATSz32 ) )
00218       {
00219          return FALSE;
00220       }
00221    }
00222    fs_g_nav.u16_fat_size = u16_tmp * u8_sector_size;
00223 
00224    // Get total count of sectors in partition
00225    if ( (0==LOW_16_BPB_TotSec16) && (0==HIGH_16_BPB_TotSec16) )
00226    {
00227       LSB0( u32_tmp ) = LOW0_32_BPB_TotSec32;
00228       LSB1( u32_tmp ) = LOW1_32_BPB_TotSec32;
00229       LSB2( u32_tmp ) = LOW2_32_BPB_TotSec32;
00230       LSB3( u32_tmp ) = LOW3_32_BPB_TotSec32;
00231    }
00232    else
00233    {
00234       LSB0( u32_tmp ) = LOW_16_BPB_TotSec16;
00235       LSB1( u32_tmp ) = HIGH_16_BPB_TotSec16;
00236       LSB2( u32_tmp ) = 0;
00237       LSB3( u32_tmp ) = 0;
00238    }
00239    u32_tmp *= u8_sector_size;   // Translate from sector disk unit to sector 512B unit
00240 
00241    // Compute the offset (unit 512B) between the end of FAT (beginning of root dir in FAT1x) and the beginning of PBR
00242    fs_g_nav.rootdir.seg.u16_pos = FS_NB_FAT * fs_g_nav.u16_fat_size;
00243 
00244    // Compute the root directory size (unit sector), for FAT32 is always 0
00245    LSB( u16_tmp ) = LOW_16_BPB_RootEntCnt;
00246    MSB( u16_tmp ) = HIGH_16_BPB_RootEntCnt;
00247    fs_g_nav.rootdir.seg.u16_size = ((u16_tmp * FS_SIZE_FILE_ENTRY) + ((FS_512B*u8_sector_size)-1)) / (FS_512B*u8_sector_size);
00248    fs_g_nav.rootdir.seg.u16_size *= u8_sector_size;
00249 
00250    // Get number of reserved sector
00251    LSB( u16_tmp ) = LOW_16_BPB_ResvSecCnt;
00252    MSB( u16_tmp ) = HIGH_16_BPB_ResvSecCnt;
00253    // Get FSInfo position
00254    fs_g_nav.u16_offset_FSInfo = (u16_tmp-LOW_16_BPB_FSInfo)*u8_sector_size;
00255    u16_tmp *= u8_sector_size; // number of reserved sector translated in unit 512B
00256 
00257    // Compute the FAT address (unit 512B)
00258    fs_g_nav.u32_ptr_fat = fs_gu32_addrsector + u16_tmp;
00259 
00260    // Compute the offset (unit 512B) between the first data cluster and the FAT beginning
00261    fs_g_nav.u32_offset_data = (FS_NB_FAT * (U32)fs_g_nav.u16_fat_size) + (U32)fs_g_nav.rootdir.seg.u16_size;
00262 
00263    // Compute the data region (clusters space = Total - Sector used) size (unit 512B)
00264    u32_tmp -= ((U32)u16_tmp + fs_g_nav.u32_offset_data);
00265 
00266    // Compute the count of CLUSTER in the data region
00267    // !!!Optimization -> u32_CountofCluster (unit 512B)/ fs_g_nav.u8_BPB_SecPerClus (unit 512B & power of 2)
00268    for( u8_tmp = fs_g_nav.u8_BPB_SecPerClus; u8_tmp!=1 ; u8_tmp >>= 1 )
00269    {
00270      u32_tmp  >>= 1;   // This computation round down
00271    }
00272    fs_g_nav.u32_CountofCluster = u32_tmp+2; // The total of cluster include the two reserved clusters
00273 
00274    // Determine the FAT type
00275    if (u32_tmp < FS_FAT12_MAX_CLUSTERS)
00276    {
00277       // Is FAT 12
00278 #if (FS_FAT_12 == DISABLED)
00279       return FALSE;
00280 #endif
00281       fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12;
00282    } else {
00283    if (u32_tmp < FS_FAT16_MAX_CLUSTERS)
00284    {
00285       // Is FAT 16
00286 #if (FS_FAT_16 == DISABLED)
00287       return FS_NO_SUPPORT_PART;
00288 #endif
00289       fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16;
00290    } else {
00291       // Is FAT 32
00292 #if (FS_FAT_32 == DISABLED)
00293       return FALSE;
00294 #endif
00295       fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32;
00296       // In FAT32, the root dir is like another directory, this one have a cluster list
00297       // Get the first cluster number of root
00298       LSB0( fs_g_nav.rootdir.u32_cluster ) = LOW0_32_BPB_RootClus;
00299       LSB1( fs_g_nav.rootdir.u32_cluster ) = LOW1_32_BPB_RootClus;
00300       LSB2( fs_g_nav.rootdir.u32_cluster ) = LOW2_32_BPB_RootClus;
00301       LSB3( fs_g_nav.rootdir.u32_cluster ) = LOW3_32_BPB_RootClus;
00302    }
00303    }
00304 
00305    return TRUE;
00306 }

Here is the call graph for this function:

void fat_get_date ( FS_STRING  sz_date,
Bool  type_date 
)

This function reads the information about a date.

Parameters:
type_date choose the date type (FS_DATE_LAST_WRITE or FS_DATE_CREATION)
sz_date table to store the date
storage format (ASCII) = "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde

Definition at line 1196 of file fat_unusual.c.

References FALSE, fat_get_ptr_entry(), fat_translatedate_number_to_ascii(), FS_DATE_LAST_WRITE, and TRUE.

01197 {
01198    PTR_CACHE ptr_entry;
01199 
01200    ptr_entry = fat_get_ptr_entry();
01201    if( FS_DATE_LAST_WRITE == type_date )
01202    {
01203       fat_translatedate_number_to_ascii( sz_date , &ptr_entry[22] , FALSE );
01204    }
01205    else
01206    {
01207       fat_translatedate_number_to_ascii( sz_date , &ptr_entry[13] , TRUE );
01208    }
01209 }

Here is the call graph for this function:

U32 fat_getfreespace ( void   ) 

This function returns the space free in the partition.

Returns:
the number of sector free
if 0, then error or full

Definition at line 2107 of file fat_unusual.c.

References FALSE, fat_cluster_readnext(), fat_cluster_val(), fat_read_fat32_FSInfo(), fat_write_fat32_FSInfo(), FS_CLUST_VAL_READ, fs_g_cluster, fs_g_nav, Is_fat12, Is_fat32, Fs_management::u32_CountofCluster, Fs_cluster::u32_pos, Fs_cluster::u32_val, and Fs_management::u8_BPB_SecPerClus.

02108 {
02109    U32 u32_nb_free_cluster = 0;
02110 
02111    // Read ALL FAT1
02112    fs_g_cluster.u32_pos = 2;
02113 
02114    if( Is_fat12 )
02115    {  // FAT12 only
02116       for(
02117       ;     fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02118       ;     fs_g_cluster.u32_pos++ )
02119       {
02120          // Get the value of the cluster
02121          if ( !fat_cluster_val( FS_CLUST_VAL_READ ) )
02122             return 0;
02123 
02124          if ( 0 == fs_g_cluster.u32_val )
02125             u32_nb_free_cluster++;
02126       }
02127    }
02128    else
02129    {
02130       if( Is_fat32 )
02131       {
02132          u32_nb_free_cluster = fat_read_fat32_FSInfo();
02133          if( 0xFFFFFFFF != u32_nb_free_cluster )
02134             goto endof_fat_getfreespace;
02135          u32_nb_free_cluster = 0;
02136       }
02137       // Speed optimization only for FAT16 and FAT32
02138       // init first value used by fat_cluster_readnext()
02139       if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02140          return FALSE;
02141       for(
02142       ;     fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02143       ;     fs_g_cluster.u32_pos++ )
02144       {
02145          if ( 0 == fs_g_cluster.u32_val )
02146             u32_nb_free_cluster++;
02147          if( !fat_cluster_readnext() )
02148             return FALSE;
02149       }
02150 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) )
02151       if( Is_fat32 )
02152       {
02153          // Save value for the future call
02154          fat_write_fat32_FSInfo( u32_nb_free_cluster );
02155       }
02156 #endif
02157    }
02158 endof_fat_getfreespace:
02159    return (u32_nb_free_cluster * fs_g_nav.u8_BPB_SecPerClus);
02160 }

Here is the call graph for this function:

U8 fat_getfreespace_percent ( void   ) 

This function returns the space free in percent.

Returns:
percent of free space (1 to 100) if 0, then error or full
//! More speed than fat_getfreespace() routine but error delta 1%
//! 

Definition at line 2172 of file fat_unusual.c.

References FALSE, fat_cache_read_sector(), fat_cluster_val(), fat_getfreespace(), fat_read_fat32_FSInfo(), FS_CLUST_VAL_READ, fs_g_cluster, fs_g_nav, fs_g_sector, fs_gu32_addrsector, Is_fat12, Is_fat16, Is_fat32, TRUE, Fs_management::u16_fat_size, Fs_management::u32_CountofCluster, Fs_cluster::u32_pos, and Fs_management::u8_BPB_SecPerClus.

02173 {
02174    U32 u32_nb_free_cluster = 0;
02175    U16 u16_tmp, u16_pos;
02176 
02177    if( Is_fat12 )
02178    {  // No speed optimization necessary on FAT12
02179       return (((fat_getfreespace()/fs_g_nav.u8_BPB_SecPerClus)*100) / fs_g_nav.u32_CountofCluster);
02180    }
02181 
02182 
02183    fs_g_cluster.u32_pos = 2;
02184    // Init first value used by fat_cluster_readnext()
02185    if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02186       return FALSE;
02187 
02188    // The optimization is to
02189    // - read only the LSB byte of cluster
02190    // - read only 1 cluster for 2 clusters
02191    if( Is_fat32 )
02192    {
02193       u32_nb_free_cluster = fat_read_fat32_FSInfo();
02194       if( 0xFFFFFFFF != u32_nb_free_cluster )
02195          goto endof_fat_getfreespace_percent;
02196       u32_nb_free_cluster = 0;
02197 
02198       u16_pos = 2*4;
02199       for(  u16_tmp = fs_g_nav.u16_fat_size
02200       ;     u16_tmp!=0
02201       ;     u16_tmp-- )
02202       {
02203          for( ; u16_pos < 512 ; u16_pos += (2*4) )
02204          {
02205             if( 0 == fs_g_sector[u16_pos] )
02206                u32_nb_free_cluster+=2;
02207          }
02208          // Read next sector in FAT
02209          u16_pos = 0;
02210          fs_gu32_addrsector++;
02211          if( !fat_cache_read_sector( TRUE ))
02212             return 0;
02213       }
02214    }
02215 
02216    if ( Is_fat16 )
02217    {
02218       u16_pos = 2*2;
02219 
02220       for(  u16_tmp = fs_g_nav.u16_fat_size
02221       ;     u16_tmp!=0
02222       ;     u16_tmp-- )
02223       {
02224          for( ; u16_pos < 512 ; u16_pos += (2*2) )
02225          {
02226             if( 0 == fs_g_sector[u16_pos] )
02227                u32_nb_free_cluster+=2;
02228          }
02229          // Read next sector in FAT
02230          u16_pos = 0;
02231          fs_gu32_addrsector++;
02232          if( !fat_cache_read_sector( TRUE ))
02233             return 0;
02234       }
02235    }
02236 
02237    // Compute percent
02238    if( u32_nb_free_cluster > fs_g_nav.u32_CountofCluster )
02239       return 100;
02240    if( u32_nb_free_cluster > ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256) )
02241    {
02242       // Compute and add a delta error
02243       u32_nb_free_cluster -= ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256);
02244    }
02245 endof_fat_getfreespace_percent:
02246    return ((u32_nb_free_cluster * 100) / fs_g_nav.u32_CountofCluster);
02247 }

Here is the call graph for this function:


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