fat_unusual.c File Reference


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.

#include "conf_explorer.h"
#include "fs_com.h"
#include "fat.h"
#include <string.h>
#include "ctrl_access.h"

Go to the source code of this file.

Data Structures

struct  st_fs_format_table

Global variable to optimize the footprint of format routines

_MEM_TYPE_SLOW_ U32 fs_s_u32_size_partition
Bool fat_format (U8 u8_fat_type)
 This function formats the current drive.

Struture for the tables format

_CONST_TYPE_ Fs_format_table TableFAT12 []
 Table format for FAT12.
_CONST_TYPE_ Fs_format_table TableFAT16 []
 Table format for FAT16.
_CONST_TYPE_ Fs_format_table TableFAT32 []
 Table format for FAT32.
typedef struct st_fs_format_table Fs_format_table
 Table format for FAT12.

Functions

Bool fat_allocfreespace (void)
 This function allocs a cluster list.
Bool fat_clean_zone (Bool b_MBR)
 This function cleans the reserved zone, FAT zone, and root dir zone.
Bool fat_clear_cluster (void)
 This function clears one cluster.
void fat_clear_info_fat_mod (void)
 This function clears the cache information about FAT modifications.
Bool fat_create_entry_file_name (FS_STRING sz_name)
 This function creates the short and the long name of a new entry.
Bool fat_delete_file (Bool b_cluster_list)
 This function deletes the file entries and cluster list.
Bool fat_entry_label (Bool b_action, FS_STRING sz_label)
 This function reads or writes a label in the partition.
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.
Bool fat_initialize_dir (void)
 This function writes the directory information.
Bool fat_initialize_fat (void)
 This function initializes the fat one and two.
Bool fat_mount (void)
 This function mounts a partition file system (FAT12, FAT16 or FAT32) of selected drive.
U32 fat_read_fat32_FSInfo (void)
 This function returns the space free in the selected FAT32 partition.
Bool fat_serialnumber (Bool b_action, U8 _MEM_TYPE_SLOW_ *a_u8_sn)
 This function reads or writes a serial number in the drive.
void fat_set_date (const FS_STRING sz_date, Bool type_date)
 This function changes the date information.
Bool fat_update_fat2 (void)
 This function copys the modifications of the first FAT to the second FAT.
Bool fat_write_fat32_FSInfo (U32 u32_nb_free_cluster)
 This function writes the space free number in selected FAT32 partition.
Bool fat_write_PBR (Bool b_MBR)
 This function writes the PBR.
Sub routine used to create a entry file
Bool fat_alloc_entry_free (U8 u8_nb_entry)
 This function allocs a number of entry in a current directory.
U8 fat_check_name (FS_STRING sz_name)
 This function checks the character in name AND computes the number of entry file to store the name.
void fat_create_long_name_entry (FS_STRING sz_name, U8 u8_crc, U8 u8_id)
 This function creates a long name entry.
U8 fat_create_short_entry_name (FS_STRING sz_name, FS_STRING short_name, U8 nb, Bool mode)
 This function creates a short name in the internal cache sector OR in a string.
Bool fat_entry_shortname_compare (FS_STRING short_name)
 This function compares a short name with the current entry.
U8 fat_find_short_entry_name (FS_STRING sz_name)
 This function searchs an unique short name.
Bool fat_garbage_collector_entry (void)
 This function remove the entry delected in the directory to clean it.
U8 fat_translate_char_shortname (U8 character)
 This function translates the character to autorized short name character.
Sub routines used by format routine
Bool fat_select_filesystem (U8 u8_fat_type, Bool b_MBR)
 This function computes the FAT type to use.
Bool fat_write_MBR (void)
 This function writes the MBR.
Sub routines used by date read-write routines
U16 fat_translate_ascii_to_number (const FS_STRING sz_ascii_number, U8 u8_size_number_ascii)
 This function translates a ASCII number to a digital number.
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)
 This function translates a date ascii string to date FAT value.
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.

Variables

_CONST_TYPE_ U8 fs_s_execption_char [] = {'+',',','.',';','=','[',']'}
 Characters table no supported in a short name.
_CONST_TYPE_ U8 fs_s_tab_incorrect_char [] = {':','*','?','"','<','>','|'}
 Characters table no supported in a file name.
Constante of "FAT32 FSInfo Sector"
_CONST_TYPE_ U8 const_FSI_LeadSig []
_CONST_TYPE_ U8 const_FSI_StrucSig []
Constante for fat_initialize_fat() function
_CONST_TYPE_ U8 const_header_fat12 []
_CONST_TYPE_ U8 const_header_fat16 []
_CONST_TYPE_ U8 const_header_fat32 []
Constante for fat_write_PBR() routine
_CONST_TYPE_ U8 const_header_pbr []
_CONST_TYPE_ U8 const_tail_pbr []


Typedef Documentation

Table format for FAT12.


Function Documentation

Bool fat_alloc_entry_free ( U8  u8_nb_entry  ) 

This function allocs a number of entry in a current directory.

Parameters:
u8_nb_entry number of entry to alloc
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! OUT: Initialise the system on the last alloced free entry
//! 

Definition at line 1921 of file fat_unusual.c.

References fat_allocfreespace(), fat_clear_cluster(), fat_garbage_collector_entry(), fat_get_ptr_entry(), fat_read_dir(), FS_ENTRY_END, FS_ERR_NO_FREE_SPACE, FS_ERR_OUT_LIST, fs_g_nav_fast, fs_g_seg, fs_g_status, Fs_management_fast::u16_entry_pos_sel_file, and Fs_segment::u32_size_or_pos.

Referenced by fat_create_entry_file_name().

01921 {
01922    PTR_CACHE ptr_entry;
01923    Bool b_garbage_collector_used = FALSE;
01924    U8 u8_nb_entry_save;
01925 
01926    u8_nb_entry_save = u8_nb_entry;
01927 
01928    // Start at the beginning of dir
01929    fs_g_nav_fast.u16_entry_pos_sel_file=0;
01930    // Loop in directory
01931    while( 1 )
01932    {
01933       // Fill internal cache with a sector from directory
01934       if( !fat_read_dir() )
01935       {
01936          if( FS_ERR_OUT_LIST != fs_g_status )
01937             return FALSE;
01938 
01939          // The position is outside the cluster list
01940          // then alloc a new sector (= new cluster)
01941          // Remark: The fs_g_seg.u32_addr contains the last cluster value of a directory list to link with the new list
01942          fs_g_seg.u32_size_or_pos = 1;
01943          if( !fat_allocfreespace())
01944          {
01945             // Garbage collector on entry file
01946             if( b_garbage_collector_used )
01947                return FALSE;
01948             if( !fat_garbage_collector_entry())
01949                return FALSE;
01950             b_garbage_collector_used = TRUE;
01951             fs_g_nav_fast.u16_entry_pos_sel_file=0;
01952             u8_nb_entry = u8_nb_entry_save;
01953             continue;
01954          }
01955 
01956          // Clean this new cluster
01957          // Remark: The fs_g_seg.u32_addr contains the new cluster value
01958          if( !fat_clear_cluster())
01959             return FALSE;
01960 
01961          continue;  // Rescan the directory list to find the new allocated sector
01962       }
01963 
01964       // Check entry
01965       ptr_entry = fat_get_ptr_entry();
01966       if ( FS_ENTRY_END == *ptr_entry )
01967       {  // The entry is free
01968          u8_nb_entry--;
01969          if( 0 == u8_nb_entry )
01970          {
01971             return TRUE;  // All free entry is found
01972          }
01973       }
01974 
01975       // go to next entry
01976       fs_g_nav_fast.u16_entry_pos_sel_file++;
01977       if( 0 == fs_g_nav_fast.u16_entry_pos_sel_file )
01978       {
01979          // Here, the directory have the maximum size
01980          // Garbage collector on entry file
01981          if( b_garbage_collector_used )
01982          {
01983             // Directory full (FAT Norm limit directory to 65535 entrys)
01984             fs_g_status = FS_ERR_NO_FREE_SPACE;
01985             return FALSE;
01986          }
01987          if( !fat_garbage_collector_entry())
01988             return FALSE;
01989          b_garbage_collector_used = TRUE;
01990          fs_g_nav_fast.u16_entry_pos_sel_file=0;
01991          u8_nb_entry = u8_nb_entry_save;
01992          continue;
01993       }
01994    }  // end of while(1)
01995 }
01996 

Bool fat_allocfreespace ( void   ) 

This function allocs a 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          Last cluster value of a cluster list to link with the new cluster list
//!                              If no cluster list to link then set MSB0(fs_g_seg.u32_addr) to 0xFF
//!   fs_g_seg.u32_size_or_pos   Maximum size of cluster list to alloc (unit sector)
//! OUT:
//!   fs_g_seg.u32_addr          Return the first cluster value of the new cluster list
//!   fs_g_seg.u32_size_or_pos   The number of sector remainning (no allocated sectors, because disk fragmented or disk full)
//! 

Definition at line 2294 of file fat_unusual.c.

References fat_clear_info_fat_mod(), fat_cluster_val(), fat_update_fat2(), fat_write_fat32_FSInfo(), FS_CLUST_VAL_EOL, FS_CLUST_VAL_READ, FS_CLUST_VAL_WRITE, FS_ERR_NO_FREE_SPACE, fs_g_cluster, fs_g_nav, fs_g_nav_fast, fs_g_seg, fs_g_status, FS_TYPE_FAT_32, Is_fat32, Fs_management::rootdir, Fs_segment::u32_addr, Fs_rootdir::u32_cluster, Fs_management::u32_CountofCluster, st_fs_cluster::u32_pos, Fs_segment::u32_size_or_pos, st_fs_cluster::u32_val, Fs_management::u8_BPB_SecPerClus, and Fs_management_fast::u8_type_fat.

Referenced by fat_alloc_entry_free(), fat_write_file(), and nav_dir_make().

02294 {
02295    // Flag to signal the first step which search the first free cluster of the new list
02296    Bool first_cluster_free_is_found = FALSE;
02297    // If TRUE then use a quick procedure but don't scan all FAT else use a slow proceudre but scan all FAT
02298    Bool b_quick_find = TRUE;
02299 
02300    if( Is_fat32 )
02301    {
02302       // Clear info about free space
02303       if( !fat_write_fat32_FSInfo( 0xFFFFFFFF ))
02304          return FALSE;
02305    }
02306 
02307    if( 0xFF == MSB0(fs_g_seg.u32_addr) )
02308    {
02309 fat_allocfreespace_start:
02310       // New cluster list, then research at the beginning of FAT
02311       fs_g_cluster.u32_pos = 2;
02312    }else{
02313       // Continue the cluster list then start after the end of the cluster list
02314       fs_g_cluster.u32_pos = fs_g_seg.u32_addr+1;
02315    }
02316 
02317    fat_clear_info_fat_mod();
02318 
02319    // Read ALL FAT1
02320    for(
02321    ;     fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02322    ;     fs_g_cluster.u32_pos++ )
02323    {
02324       // Get the value of the cluster
02325       if ( !fat_cluster_val( FS_CLUST_VAL_READ ) )
02326          return FALSE;
02327 
02328       if ( 0 == fs_g_cluster.u32_val )
02329       {
02330          // A free cluster is found
02331          fs_g_cluster.u32_val = fs_g_cluster.u32_pos;    // value of the cluster is the new free cluster
02332          if( TRUE == first_cluster_free_is_found )
02333          {
02334             // Link the new cluster with previous cluster
02335             fs_g_cluster.u32_pos--;                      // select the previous cluster
02336             if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02337                return FALSE;
02338          }
02339          else
02340          {
02341             // It is the first cluster of the new list
02342             first_cluster_free_is_found = TRUE;
02343 
02344             if( 0xFF != MSB0(fs_g_seg.u32_addr) )
02345             {
02346                // Link this new cluster with the current cluster list
02347                // Select the last cluster of the current list
02348                if( 0 == fs_g_seg.u32_addr )
02349                {  // The current cluster list is the cluster list of root directory
02350                   if( FS_TYPE_FAT_32 != fs_g_nav_fast.u8_type_fat )
02351                   {
02352                      // Impossible to increment ROOT DIR size of FAT12 or FAT16
02353                      fs_g_status = FS_ERR_NO_FREE_SPACE;
02354                      return FALSE;
02355                   }
02356                   fs_g_cluster.u32_pos = fs_g_nav.rootdir.u32_cluster;
02357                }
02358                else
02359                {
02360                   fs_g_cluster.u32_pos = fs_g_seg.u32_addr;
02361                }
02362                if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02363                   return FALSE;
02364             }  // else no writing the first cluster value in FAT because no current cluster list
02365             fs_g_seg.u32_addr = fs_g_cluster.u32_val;    // save the first cluster value
02366          }
02367 
02368          // At the new cluster position, set the flag end of list
02369          fs_g_cluster.u32_pos = fs_g_cluster.u32_val;    // Select the new cluster
02370          fs_g_cluster.u32_val = FS_CLUST_VAL_EOL;        // Cluster value is the flag end of list
02371          if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02372             return FALSE;
02373 
02374          // Compute the remaining sectors
02375          if ( fs_g_seg.u32_size_or_pos <= fs_g_nav.u8_BPB_SecPerClus )
02376          {
02377             fs_g_seg.u32_size_or_pos = 0; // All space found
02378             break;                        // Stop loop
02379          }
02380          fs_g_seg.u32_size_or_pos -= fs_g_nav.u8_BPB_SecPerClus;
02381       }
02382       else
02383       {
02384          // The next cluster is not free
02385          if( TRUE == first_cluster_free_is_found )
02386          {
02387             // To have a segment memory continue, the cluster list must be continue
02388             // then stop allocation
02389             break;
02390          }
02391          else
02392          {
02393             // It is the first step to search the first free cluster
02394             // then ignore this cluster no free and continue search
02395             if( b_quick_find )
02396             {
02397                fs_g_cluster.u32_pos += 500;
02398             }
02399          }
02400       }
02401    }
02402 
02403    // End of alloc
02404    if( FALSE == first_cluster_free_is_found )
02405    {
02406       if( b_quick_find )
02407       {
02408          // Retry in normal mode to scann all FAT (= no quick mode)
02409          b_quick_find = FALSE;
02410          goto fat_allocfreespace_start;
02411       }
02412       fs_g_status = FS_ERR_NO_FREE_SPACE; // NO FREE CLUSTER FIND
02413       return FALSE;
02414    }
02415 
02416    return fat_update_fat2();
02417 }
02418 #endif  // FS_LEVEL_FEATURES

U8 fat_check_name ( FS_STRING  sz_name  ) 

This function checks the character in name AND computes the number of entry file to store the name.

Parameters:
sz_name original name to create
Returns:
number of entry file to strore the name (short + long name)
if name incorrect then 0 is returned.

Definition at line 1838 of file fat_unusual.c.

References fat_check_eof_name(), FS_ERR_INCORRECT_NAME, FS_ERR_NAME_TOO_LARGE, fs_g_status, fs_s_tab_incorrect_char, FS_SIZE_LFN_ENTRY, and Is_unicode.

Referenced by fat_create_entry_file_name().

01838 {
01839    U8 u8_nb_entry, u8_i, u8_j;
01840    U16 u16_character;
01841 
01842    u8_nb_entry = 2;        // a short entry + one long name entry minimum
01843    u8_i = FS_SIZE_LFN_ENTRY;
01844    while( 1 )
01845    {
01846       if( Is_unicode )
01847       {
01848          u16_character = ((FS_STR_UNICODE)sz_name)[0];
01849       }else{
01850          u16_character = sz_name[0];
01851       }
01852       if( fat_check_eof_name( u16_character ) )
01853          break;
01854 
01855       for( u8_j = 0 ; u8_j < sizeof(fs_s_tab_incorrect_char) ; u8_j++ )
01856       {
01857          if( u16_character == fs_s_tab_incorrect_char[u8_j] )
01858          {
01859             fs_g_status = FS_ERR_INCORRECT_NAME;
01860             return 0;      // incorrect character
01861          }
01862       }
01863       if( 0 == u8_i )
01864       {
01865          u8_nb_entry++;
01866          u8_i = FS_SIZE_LFN_ENTRY;
01867       }
01868       u8_i--;
01869       sz_name += (Is_unicode? 2 : 1 );
01870    }
01871    if( 0x14 < u8_nb_entry )
01872    {
01873       fs_g_status = FS_ERR_NAME_TOO_LARGE;
01874       return 0;            // Name too large
01875    }
01876    return u8_nb_entry;
01877 }
01878 

Bool fat_clean_zone ( Bool  b_MBR  ) 

This function cleans the reserved zone, FAT zone, and root dir zone.

Parameters:
b_MBR TRUE, include a MBR on disk
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

Definition at line 929 of file fat_unusual.c.

References fat_cache_clear(), fat_cache_flush(), fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), FS_CACHE_SIZE, fs_g_nav, fs_g_sector, fs_gu32_addrsector, Is_fat32, Fs_management::u16_fat_size, and Fs_management::u8_BPB_SecPerClus.

Referenced by fat_format().

00929 {
00930    U16 u16_nb_sector_clean, u16_i;
00931    _MEM_TYPE_SLOW_   U8 *ptr;
00932 
00933    // Flush the internal cache before clear the cache
00934    if( !fat_cache_flush())
00935       return FALSE;
00936    fat_cache_clear();
00937 
00938    // remark: these zones are stored after the PBR and are continues
00939    // Start after PBR
00940    if( b_MBR )
00941    {
00942       fs_gu32_addrsector = 2; // Jump MBR and PBR
00943    }else{
00944       fs_gu32_addrsector = 1; // Jump only a PBR (no MBR create)
00945    }
00946 
00947    // Compute reserved zone size and root size
00948    if( Is_fat32 )
00949    {  // FAT 32
00950       fs_gu32_addrsector++;   // Jump FAT32 FSInfo Sector
00951       // root size = cluster size AND reserved zone = 32 - 2 (2 = PBR + FSInfo)
00952       u16_nb_sector_clean = fs_g_nav.u8_BPB_SecPerClus + 30;
00953    }
00954    else
00955    {  // FAT 12 or 16
00956       // root size = 512 entrys = 32 sectors AND reserved zone = 1 - 1(PBR)
00957       u16_nb_sector_clean = 32;
00958    }
00959    u16_nb_sector_clean += (fs_g_nav.u16_fat_size*2);  // Add FAT size
00960 
00961    // loop to clean
00962    for( ; u16_nb_sector_clean!=0; u16_nb_sector_clean-- )
00963    {
00964       // To improve the format time
00965       // We check if the sector is clean (0x00) instead of write a clean sector.
00966       if( !fat_cache_read_sector( TRUE ))
00967          return FALSE;
00968       ptr = fs_g_sector;
00969       for( u16_i=0; u16_i<FS_CACHE_SIZE; u16_i++,ptr++ )
00970       {
00971          if( 0x00 != *ptr )
00972          {
00973             // Sector not clean then erase it
00974             fat_cache_clear();
00975             fat_cache_mark_sector_as_dirty();
00976             break;
00977          }
00978       }         
00979       fs_gu32_addrsector++;
00980    }
00981    return TRUE;
00982 }
00983 

Bool fat_clear_cluster ( void   ) 

This function clears one cluster.

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          Cluster value to clear
//! 

Definition at line 2474 of file fat_unusual.c.

References fat_cache_clear(), fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), fat_cluster_list(), FS_CLUST_ACT_ONE, fs_g_nav, fs_g_seg, fs_gu32_addrsector, Fs_segment::u32_addr, Fs_segment::u32_size_or_pos, and Fs_management::u8_BPB_SecPerClus.

Referenced by fat_alloc_entry_free(), and fat_initialize_dir().

02474 {
02475    U8 u8_loop;
02476 
02477    // Compute the cluster sector address
02478    fs_g_seg.u32_size_or_pos  = 0;   // Select the beginning of cluster
02479    if( !fat_cluster_list( FS_CLUST_ACT_ONE, FALSE ))
02480       return FALSE;
02481 
02482    // Loop in the cluster (start at the end of cluster)
02483    fs_gu32_addrsector = fs_g_seg.u32_addr + (fs_g_nav.u8_BPB_SecPerClus -1);
02484    for(  u8_loop = 0
02485    ;     fs_g_nav.u8_BPB_SecPerClus != u8_loop
02486    ;     u8_loop++ )
02487    {
02488       // Update internal cache with cluster sector inforamtion but don't read data from memory
02489       if( !fat_cache_read_sector( FALSE ))
02490          return FALSE;
02491 
02492       if(0 == u8_loop)
02493       {  // Clean internal cache (just for the sector)
02494          fat_cache_clear();
02495       }
02496       fat_cache_mark_sector_as_dirty();
02497       fs_gu32_addrsector--;         // go to previous sector
02498    }
02499    return TRUE;
02500 }
02501 #endif  // FS_LEVEL_FEATURES

void fat_clear_info_fat_mod ( void   ) 

This function clears the cache information about FAT modifications.

Definition at line 2425 of file fat_unusual.c.

References fs_g_u16_first_mod_fat, and fs_g_u16_last_mod_fat.

Referenced by fat_allocfreespace(), and fat_cluster_list().

02425 {
02426    fs_g_u16_first_mod_fat = 0xFFFF;
02427    fs_g_u16_last_mod_fat = 0;
02428 }
02429 #endif  // FS_LEVEL_FEATURES

Bool fat_create_entry_file_name ( FS_STRING  sz_name  ) 

This function creates the short and the long name of a new entry.

Parameters:
sz_name name to create (ASCII or UNICODE)
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! IN:
//! b_unicode is a global flag to select UNICODE or ASCII
//! The name must be terminated by NULL and it can't have two dot characters.
//! 

Definition at line 1500 of file fat_unusual.c.

References fat_alloc_entry_free(), fat_check_name(), fat_create_long_name_entry(), fat_create_short_entry_name(), fat_find_short_entry_name(), fat_read_dir(), FS_ENTRY_LFN_LAST, FS_ERR_FILE_EXIST, fs_g_nav_fast, fs_g_status, FS_SIZE_LFN_ENTRY, Is_unicode, and Fs_management_fast::u16_entry_pos_sel_file.

Referenced by nav_file_create().

01500 {
01501    U8 u8_i, u8_nb;
01502    U8 u8_crc, u8_nb_entry;
01503 
01504    // Compute the number of entry for this name
01505    u8_nb_entry = fat_check_name( sz_name  );
01506    if( 0 == u8_nb_entry )
01507       return FALSE;
01508 
01509    // Search a unik short entry
01510    u8_nb = fat_find_short_entry_name( sz_name  );
01511    if( 0 == u8_nb )
01512    {
01513       fs_g_status = FS_ERR_FILE_EXIST;
01514       return FALSE;  // All short name exist
01515    }
01516    
01517    // Alloc a space for entrys
01518    if( !fat_alloc_entry_free( u8_nb_entry ))
01519       return FALSE;
01520    // Remark: here the pointer of entry is on the last free entry of new space allocated
01521 
01522    // Add short name entry
01523    u8_crc = fat_create_short_entry_name( sz_name , 0 , u8_nb, FALSE  );
01524    u8_nb_entry--;
01525 
01526    // For each long name entry
01527    for( u8_i=1 ; u8_i<=u8_nb_entry ; u8_i++ )
01528    {
01529       // Go to previous entry
01530       fs_g_nav_fast.u16_entry_pos_sel_file--;
01531       if( !fat_read_dir())
01532          return FALSE;
01533       // Write a long name entry
01534       if( u8_i == u8_nb_entry )
01535       {
01536          u8_i += FS_ENTRY_LFN_LAST;
01537       }
01538       fat_create_long_name_entry( sz_name , u8_crc , u8_i );
01539       sz_name += FS_SIZE_LFN_ENTRY*(Is_unicode? 2 : 1 );
01540   }
01541   // Go back to the short name entry
01542   fs_g_nav_fast.u16_entry_pos_sel_file += u8_nb_entry;
01543   return TRUE;
01544 }
01545 

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

This function creates a long name entry.

Parameters:
sz_name name to create (ASCII or UNICODE)
u8_crc crc corresponding at short name
u8_id long entry number (1 to n + FS_ENTRY_LFN_LAST)
//! OUT: Update the entry in internal cache sector with a new long name entry
//! 

Definition at line 1558 of file fat_unusual.c.

References fat_cache_mark_sector_as_dirty(), fat_get_ptr_entry(), FS_ATTR_LFN_ENTRY, FS_SIZE_FILE_ENTRY, and Is_unicode.

Referenced by fat_create_entry_file_name().

01558 {
01559    PTR_CACHE ptr_entry;
01560    Bool b_end_of_name = FALSE;
01561 
01562    fat_cache_mark_sector_as_dirty();
01563    ptr_entry = fat_get_ptr_entry();
01564    *ptr_entry = u8_id;
01565    ptr_entry++;   // The long name start at offset 1 of the entry file
01566 
01567    for( u8_id=1; u8_id<FS_SIZE_FILE_ENTRY ; u8_id++ , ptr_entry++ )
01568    {
01569       // fields with no character
01570       if( 11 == u8_id)
01571       {
01572          *ptr_entry = FS_ATTR_LFN_ENTRY;  // attribut field
01573          continue;
01574       }
01575       if( (12 == u8_id)
01576       ||  (26 == u8_id)
01577       ||  (27 == u8_id) )
01578       {
01579          // Reserved field
01580          // *ptr_entry = 0x00;            // No necessary because the cache must be clean
01581          continue;
01582       }
01583       if( 13 == u8_id)
01584       {
01585          *ptr_entry = u8_crc;             // CRC field
01586          continue;
01587       }
01588 
01589       // fields with a character
01590       if( !b_end_of_name )
01591       {
01592          U16 u16_tmp;
01593          if( Is_unicode )
01594          {
01595             u16_tmp = ((FS_STR_UNICODE)sz_name)[0];
01596          }else{
01597             u16_tmp = sz_name[0];
01598          }
01599          if(('\\' == u16_tmp )
01600          || ('/'  == u16_tmp ) )
01601          {  // end of name
01602             u16_tmp = 0;                  // Set a end of name flag
01603          }
01604          if( 0 == u16_tmp )
01605          {
01606             b_end_of_name = TRUE;
01607          }
01608          *ptr_entry = LSB(u16_tmp);
01609          ptr_entry++;
01610          *ptr_entry = MSB(u16_tmp);
01611          u8_id++;
01612          sz_name += (Is_unicode? 2 : 1 );
01613       }
01614       else
01615       {  // end of name
01616          *ptr_entry = 0xFF;               // Padding mandatory
01617       }
01618    } // end of loop
01619 }
01620 

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

This function creates a short name in the internal cache sector OR in a string.

Parameters:
sz_name name to create (ASCII or UNICODE)
short_name short name in 8.3 format ( = 8+3 Bytes) (used only if mode = TRUE)
nb number to add at short name (ex: name~nb)
mode TRUE to write in a string
FALSE to write in internal cache
Returns:
short name CRC

Definition at line 1633 of file fat_unusual.c.

References fat_cache_mark_sector_as_dirty(), fat_check_eof_name(), fat_get_ptr_entry(), fat_translate_char_shortname(), FS_SIZE_SFNAME, FS_SIZE_SFNAME_WITHOUT_EXT, and Is_unicode.

Referenced by fat_create_entry_file_name(), and fat_find_short_entry_name().

01633 {
01634    PTR_CACHE ptr_entry = 0;
01635    U8 u8_i, u8_step, character;
01636    U8 crc;
01637    U8 nb_digit;
01638 
01639    if( !mode )
01640    {
01641       // Modify internal cache to create short name entry in the current entry
01642       fat_cache_mark_sector_as_dirty();
01643       // Get pointer on current entry
01644       ptr_entry = fat_get_ptr_entry();
01645    }
01646 
01647    // Compute the digit number
01648    if( nb < 10 )        nb_digit = 1;
01649    else if( nb < 100 )  nb_digit = 2;
01650    else                 nb_digit = 3;
01651    
01652    crc = u8_i = 0;
01653    u8_step = 1;
01654    while( 1 )
01655    {
01656       if( Is_unicode )
01657       {
01658          character = ((FS_STR_UNICODE)sz_name)[0];
01659       }else{
01660          character = sz_name[0];
01661       }
01662 
01663       if( 1 == u8_step )
01664       {  // step 1 = translate the name
01665          if( ((FS_SIZE_SFNAME_WITHOUT_EXT-(1+nb_digit)) == u8_i)    // name field is full (-2 for "~1")
01666          ||  ('.'    == character)                       // is the end of name without extension
01667          ||  fat_check_eof_name(character)            )  // is the end of name
01668          {
01669             u8_step++;                                   // go to next step
01670             continue;
01671          }
01672       }
01673       if( 8 == u8_step )
01674       {  // step 8 = translate the extension
01675          if( (u8_i == FS_SIZE_SFNAME)                    // name field is full
01676          ||  fat_check_eof_name(character)            )  // is the end of name
01677          {
01678             u8_step++;                                   // go to next step
01679             continue;
01680          }
01681       }
01682       if( (1==u8_step) || (8==u8_step) )
01683       {  // steps to translate name
01684          character = fat_translate_char_shortname( character );
01685          sz_name += (Is_unicode? 2 : 1 );
01686          if( 0 == character )
01687          {
01688             continue;                                    // Bad character, ignore this one
01689          }
01690       }
01691       if( 7 == u8_step )
01692       {  // step 5 = find character '.'
01693          if( ('.'    == character)                       // is the end of name without extension
01694          ||  fat_check_eof_name(character)            )  // is the end of name
01695          {
01696             u8_step++;                                   // go to next step
01697          } else {
01698             sz_name += (Is_unicode? 2 : 1 );
01699          }
01700          continue;                                       // this step don't add a character in the short name
01701       }
01702       if( 6 == u8_step )
01703       {  // step 4 = add padding
01704          if( u8_i == FS_SIZE_SFNAME_WITHOUT_EXT )        // end of field name without extension
01705          {
01706             u8_step++;                                   // go to next step
01707             continue;
01708          }
01709          character = ' ';
01710       }
01711       if( 9 == u8_step )
01712       {  // step 7 = add padding in extension name
01713          if( u8_i == FS_SIZE_SFNAME )                    // end of field name with extension
01714          {
01715             break;                                       // end of loop while(1)
01716          }
01717          character = ' ';
01718       }
01719       if( 5 == u8_step )
01720       {  // step 4 = add unit 1 of number
01721          character = '0'+(nb%10);
01722          u8_step++;                                      // go to next step
01723       }
01724       if( 4 == u8_step )
01725       {  // step 3 = add unit 10 of number
01726          character = '0'+((nb%100)/10);
01727          u8_step++;                                      // go to next step
01728       }
01729       if( 3 == u8_step )
01730       {  // step 2 = add unit 100 of number
01731          character = '0'+(nb/100);
01732          u8_step++;                                      // go to next step
01733       }
01734       if( 2 == u8_step )
01735       {  // step 2 = add character '~'
01736          character = '~';
01737          u8_step+=(4-nb_digit);                          // go to next step
01738       }
01739 
01740       if( mode )
01741       {
01742          // Record the short name in buffer
01743          *short_name = character;
01744          short_name++;
01745       }else{
01746          // Record the character in short entry file
01747          *ptr_entry = character;
01748          ptr_entry++;
01749       }
01750       u8_i++;
01751 
01752       // Compute the CRC of the short name
01753       crc = (crc >> 1) + ((crc & 1) << 7);               // rotate
01754       crc += character;                                  // add next char
01755    } // End of loop while
01756    return crc;
01757 }
01758 

Bool fat_delete_file ( Bool  b_cluster_list  ) 

This function deletes the file entries and cluster list.

Parameters:
b_cluster_list TRUE, delete file entries and cluster list FALSE, delete only file entries
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

Definition at line 2074 of file fat_unusual.c.

References fat_cache_mark_sector_as_dirty(), fat_get_ptr_entry(), fat_read_dir(), fat_read_file(), FS_ATTR_LFN_ENTRY, FS_CLUST_ACT_CLR, FS_ENTRY_DEL, FS_ENTRY_LFN_LAST, fs_g_nav_entry, fs_g_nav_fast, Fs_management_fast::u16_entry_pos_sel_file, and Fs_management_entry::u32_pos_in_file.

Referenced by nav_dir_make(), nav_file_del(), and nav_file_rename().

02074 {
02075    PTR_CACHE ptr_entry;
02076    U8 u8_tmp;
02077    Bool b_short_del = FALSE;
02078 
02079    // loop in directory
02080    while( 1 )
02081    {
02082       // Fill internal cache with a sector from directory
02083       if( !fat_read_dir() )
02084          return FALSE;
02085 
02086       // Get pointer on the current entry
02087       ptr_entry = fat_get_ptr_entry();
02088       u8_tmp = ptr_entry[0];
02089 
02090       if( (FS_ATTR_LFN_ENTRY != ptr_entry[11])
02091       &&  (b_short_del) )
02092       {
02093          // no long entry exist, then only a short entry to delete
02094          break;   // Go to delete cluster list
02095       }
02096 
02097       // Delete entry
02098       b_short_del = TRUE;
02099       ptr_entry[0] = FS_ENTRY_DEL;
02100       fat_cache_mark_sector_as_dirty();
02101 
02102       if( (FS_ATTR_LFN_ENTRY == ptr_entry[11])
02103       &&  ( 0 != (FS_ENTRY_LFN_LAST & u8_tmp)) )
02104       {
02105          // It is the last entry of long name
02106          break;   // Go to delete cluster list
02107       }
02108 
02109       // Go to previous entry
02110       fs_g_nav_fast.u16_entry_pos_sel_file--;
02111    }  // end of while(1)
02112 
02113    if( b_cluster_list )
02114    {
02115       // Delete cluster list
02116       fs_g_nav_entry.u32_pos_in_file=0;      // Delete ALL list (start at begining)
02117       if( !fat_read_file( FS_CLUST_ACT_CLR ))
02118          return FALSE;
02119    }
02120 
02121    return TRUE;
02122 }
02123 #endif  // FS_LEVEL_FEATURES

Bool fat_entry_label ( Bool  b_action,
FS_STRING  sz_label 
)

This function reads or writes a label in the partition.

Parameters:
b_action choose action (FS_LABEL_READ or FS_LABEL_WRITE)
sz_label string ASCII to store label (11B min) or to get new label (11B max)
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

Definition at line 1088 of file fat_unusual.c.

References fat_cache_flush(), fat_cache_mark_sector_as_dirty(), fat_get_ptr_entry(), FS_ATTR_VOLUME_ID, FS_ENTRY_END, FS_ERR_ENTRY_BAD, FS_ERR_ENTRY_EMPTY, FS_ERR_NAME_INCORRECT, fs_g_status, FS_LABEL_READ, and FS_LABEL_WRITE.

Referenced by nav_partition_label().

01088 {
01089    PTR_CACHE ptr_entry;
01090    U8 u8_pos_name;
01091    U8 u8_char;
01092 
01093    ptr_entry = fat_get_ptr_entry();
01094 
01095    if( FS_LABEL_READ == b_action)
01096    {
01097       if( FS_ENTRY_END == ptr_entry[0] )           // end of directory
01098       {
01099          fs_g_status = FS_ERR_ENTRY_EMPTY;
01100          return FALSE;
01101       }
01102       if( FS_ATTR_VOLUME_ID != ptr_entry[11])      // no system label
01103       {
01104          fs_g_status = FS_ERR_ENTRY_BAD;
01105          return FALSE;
01106       }
01107       if( NULL == sz_label )
01108          return TRUE;
01109       for( u8_pos_name=0; u8_pos_name<11; u8_pos_name++ )
01110       {
01111          u8_char = *ptr_entry;
01112          if( 0x20 == u8_char )
01113             u8_char = 0;
01114          *sz_label = u8_char;
01115          if( 0 == u8_char )
01116             return TRUE;                           // Label readed
01117          ptr_entry++;
01118          sz_label++;
01119       }
01120       *sz_label = 0;
01121       return TRUE;
01122    }
01123 
01124    if( FS_LABEL_WRITE == b_action)
01125    {
01126       // Autorize to write the label only on an empty entry or the system label entry
01127       if( FS_ENTRY_END != ptr_entry[0] )           // end of directory
01128       {
01129          if( FS_ATTR_VOLUME_ID != ptr_entry[11])   // no system label
01130          {
01131             fs_g_status = FS_ERR_ENTRY_BAD;
01132             return FALSE;
01133          }
01134       }
01135       if( 0 == *sz_label )
01136       {
01137          fs_g_status = FS_ERR_NAME_INCORRECT;
01138          return FALSE;
01139       }
01140       ptr_entry[11] = FS_ATTR_VOLUME_ID;
01141       for( u8_pos_name=0; u8_pos_name<11; u8_pos_name++ )
01142       {
01143          u8_char = *sz_label;
01144          if( ('a'<=u8_char) && (u8_char<='z') )
01145          {
01146             u8_char -= ('a'-'A');                  // Change to upper case
01147          }
01148          if( 0 == u8_char )
01149          {
01150             u8_char = 0x20;
01151          }
01152          *ptr_entry = u8_char;
01153          ptr_entry++;
01154          if( 0x20 == u8_char )
01155             continue;
01156          sz_label++;
01157       }
01158       fat_cache_mark_sector_as_dirty();
01159       return fat_cache_flush();
01160    }
01161    return FALSE;                                   // To delete the compilation warning
01162 }
01163 #endif  // FS_LEVEL_FEATURES

Bool fat_entry_shortname_compare ( FS_STRING  short_name  ) 

This function compares a short name with the current entry.

Parameters:
short_name short name to compare (format entry = 8+3 Bytes)
Returns:
TRUE it is the same

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

Definition at line 1808 of file fat_unusual.c.

References fat_get_ptr_entry(), FS_ATTR_LFN_ENTRY, FS_ENTRY_DEL, FS_ENTRY_END, FS_ERR_ENTRY_BAD, FS_ERR_ENTRY_EMPTY, and fs_g_status.

Referenced by fat_find_short_entry_name().

01808 {
01809    PTR_CACHE ptr_entry;
01810 
01811    ptr_entry = fat_get_ptr_entry();
01812    if( FS_ENTRY_END == *ptr_entry )             // end of directory
01813    {
01814       fs_g_status = FS_ERR_ENTRY_EMPTY;
01815       return FALSE;
01816    }
01817    if( (FS_ENTRY_DEL == *ptr_entry )            // deleted entry
01818    ||  (FS_ATTR_LFN_ENTRY == ptr_entry[11]) )   // long file name
01819    {
01820       fs_g_status = FS_ERR_ENTRY_BAD;
01821       return FALSE;
01822    }
01823    fs_g_status = FS_ERR_ENTRY_BAD;              // by default this entry is different then bad
01824    return (0==memcmp_ram2ram(ptr_entry , short_name , 8+3 ));
01825 }
01826 

U8 fat_find_short_entry_name ( FS_STRING  sz_name  ) 

This function searchs an unique short name.

Parameters:
sz_name original name
Returns:
the number used to create the short name

0 in case of error

Definition at line 1768 of file fat_unusual.c.

References fat_create_short_entry_name(), fat_entry_shortname_compare(), fat_read_dir(), FS_ERR_ENTRY_EMPTY, FS_ERR_OUT_LIST, fs_g_nav_fast, fs_g_status, and Fs_management_fast::u16_entry_pos_sel_file.

Referenced by fat_create_entry_file_name().

01768 {
01769    char _MEM_TYPE_SLOW_ short_name[11];
01770    U8 u8_nb;
01771 
01772    u8_nb = 0;
01773    while(1)
01774    {
01775       if( 0xFF == u8_nb )
01776          return 0;                                       // All short name exist
01777          
01778       u8_nb++;                                           // Try next short name
01779       fat_create_short_entry_name( sz_name , short_name , u8_nb , TRUE  ); // Compute the short name
01780       fs_g_nav_fast.u16_entry_pos_sel_file = 0;          // Go to beginning of directory
01781       // Scan directory to find a short entry
01782       while(1)
01783       {
01784          if ( !fat_read_dir())                           // Read directory
01785          {
01786             if( FS_ERR_OUT_LIST == fs_g_status )
01787                return u8_nb;                             // short name don't exist, then good number
01788             return 0;                                    // System or Disk Error
01789          }
01790          if( fat_entry_shortname_compare( short_name ) ) // Check entry
01791             break;                                       // Short name exist
01792          if( FS_ERR_ENTRY_EMPTY == fs_g_status )
01793             return u8_nb;                                // Short name don't exist, then good number
01794          fs_g_nav_fast.u16_entry_pos_sel_file++;         // Go to next entry
01795       }
01796    }
01797 }
01798 

Bool fat_format ( U8  u8_fat_type  ) 

This function formats the current drive.

This function formats the drive.

Parameters:
u8_fat_type Select the type of format
FS_FORMAT_DEFAULT, The file system module choose the better FAT format for the drive space
FS_FORMAT_FAT, The FAT12 or FAT16 is used to format the drive, if possible (disk space <2GB)
FS_FORMAT_FAT32, The FAT32 is used to format the drive, if possible (disk space >32MB)
FS_FORMAT_NOMBR_FLAG if you don't want a MRB in disk then add this flag (e.g. FAT format on a CD support)
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 format
//!
//! This routine can't format a multi-partiton, if the disk contains a multi-partition area
//! then the multi-partition will be erased and replaced by a single partition on all disk space.
//! 

Definition at line 341 of file fat_unusual.c.

References fat_cache_flush(), fat_clean_zone(), fat_initialize_fat(), fat_select_filesystem(), fat_write_MBR(), fat_write_PBR(), FS_FORMAT_NOMBR_FLAG, fs_g_nav, fs_s_u32_size_partition, mem_read_capacity(), Fs_management::u8_lun, and Fs_management::u8_partition.

Referenced by nav_drive_format().

00341 {
00342    Bool b_MBR;
00343 #if (FS_MULTI_PARTITION == ENABLED)
00344 #error NOT SUPPORTED
00345    fs_g_nav.u8_partition = 0;
00346 #endif
00347 
00348 
00349    // Get drive capacity (= last LBA)
00350    mem_read_capacity( fs_g_nav.u8_lun , &fs_s_u32_size_partition );
00351 
00352    if( u8_fat_type & FS_FORMAT_NOMBR_FLAG )
00353    {
00354       b_MBR = FALSE;
00355       u8_fat_type &= ~FS_FORMAT_NOMBR_FLAG;
00356       // partition size = disk size = last LBA + 1
00357       fs_s_u32_size_partition++;
00358    }else{
00359       b_MBR = TRUE;
00360       // partition size = size disk -1 = last LBA
00361    }
00362 
00363    // Compute the FAT type for the device
00364    if( !fat_select_filesystem( u8_fat_type , b_MBR ))
00365       return FALSE;
00366 
00367    // Write the MBR sector (first sector)
00368    if( b_MBR )
00369       if( !fat_write_MBR())
00370          return FALSE;
00371 
00372    // Write the PBR sector
00373    if( !fat_write_PBR( b_MBR ))
00374       return FALSE;
00375 
00376    // Clear reserved zone, FAT zone, and Root dir zone
00377    // Remark: the reserved zone of FAT32 isn't initialized, because BPB_FSInfo is equal to 0
00378    if( !fat_clean_zone( b_MBR ))
00379       return FALSE;
00380 
00381    // Initialization of the FAT 1 and 2
00382    if( !fat_initialize_fat())
00383       return FALSE;
00384 
00385    return fat_cache_flush();
00386 }
00387 

Bool fat_garbage_collector_entry ( void   ) 

This function remove the entry delected in the directory to clean it.

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

TRUE otherwise

Definition at line 2004 of file fat_unusual.c.

References fat_cache_mark_sector_as_dirty(), fat_get_ptr_entry(), fat_read_dir(), FS_ENTRY_DEL, FS_ENTRY_END, FS_ERR_OUT_LIST, fs_g_nav_fast, fs_g_status, FS_SIZE_FILE_ENTRY, and Fs_management_fast::u16_entry_pos_sel_file.

Referenced by fat_alloc_entry_free().

02004 {
02005    _MEM_TYPE_SLOW_   U8 entry[ FS_SIZE_FILE_ENTRY ];
02006    PTR_CACHE ptr_entry;
02007    U16 u16_pos_old = 0;
02008    U16 u16_pos_new = 0;
02009 
02010    // Loop in directory
02011    while( 1 )
02012    {
02013       // Go to old entry list
02014       fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_old;
02015       // Fill internal cache with a sector from directory
02016       if( !fat_read_dir() )
02017       {
02018          if( FS_ERR_OUT_LIST != fs_g_status )
02019             return FALSE;
02020          goto fat_garbage_collector_entry_endofdir;
02021       }
02022 
02023       // Check entry
02024       ptr_entry = fat_get_ptr_entry();
02025 
02026       if ( FS_ENTRY_END == *ptr_entry )
02027       {
02028          // The entry is free, then it is the end of entry list
02029 fat_garbage_collector_entry_endofdir:
02030          // Fill empty entry in old list
02031          fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_new;
02032          while( fs_g_nav_fast.u16_entry_pos_sel_file != u16_pos_old )
02033          {
02034             // Fill internal cache with a sector from directory
02035             if( !fat_read_dir() )
02036                return FALSE;
02037             memset( fat_get_ptr_entry() , 0 , 32 );
02038             fat_cache_mark_sector_as_dirty();
02039             fs_g_nav_fast.u16_entry_pos_sel_file++;
02040          }
02041          return TRUE;  // End of garbage
02042       }
02043 
02044       if ( FS_ENTRY_DEL != *ptr_entry )
02045       {
02046          // entry valid
02047          if( u16_pos_old != u16_pos_new )
02048          {
02049             // A free space exist then move entry
02050             memcpy_ram2ram( entry, ptr_entry, FS_SIZE_FILE_ENTRY );
02051             fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_new;
02052             // Fill internal cache with a sector from directory
02053             if( !fat_read_dir() )
02054                return FALSE;
02055             memcpy_ram2ram( fat_get_ptr_entry(), entry, FS_SIZE_FILE_ENTRY );
02056             fat_cache_mark_sector_as_dirty();
02057          }
02058          u16_pos_new++;
02059       }
02060       u16_pos_old++;
02061    }  // end of while(1)
02062 }
02063 

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 1222 of file fat_unusual.c.

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

Referenced by nav_file_dateget().

01222 {
01223    PTR_CACHE ptr_entry;
01224 
01225    ptr_entry = fat_get_ptr_entry();
01226    if( FS_DATE_LAST_WRITE == type_date )
01227    {
01228       fat_translatedate_number_to_ascii( sz_date , &ptr_entry[22] , FALSE );
01229    }
01230    else
01231    {
01232       fat_translatedate_number_to_ascii( sz_date , &ptr_entry[13] , TRUE );
01233    }
01234 }
01235 

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 2133 of file fat_unusual.c.

References 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, st_fs_cluster::u32_pos, st_fs_cluster::u32_val, and Fs_management::u8_BPB_SecPerClus.

Referenced by fat_getfreespace_percent(), and nav_partition_freespace().

02133 {
02134    U32 u32_nb_free_cluster = 0;
02135 
02136    // Read ALL FAT1
02137    fs_g_cluster.u32_pos = 2;
02138 
02139    if( Is_fat12 )
02140    {  // FAT12 only
02141       for(
02142       ;     fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02143       ;     fs_g_cluster.u32_pos++ )
02144       {
02145          // Get the value of the cluster
02146          if ( !fat_cluster_val( FS_CLUST_VAL_READ ) )
02147             return 0;
02148 
02149          if ( 0 == fs_g_cluster.u32_val )
02150             u32_nb_free_cluster++;
02151       }
02152    }
02153    else
02154    {
02155       if( Is_fat32 )
02156       {
02157          u32_nb_free_cluster = fat_read_fat32_FSInfo();
02158          if( 0xFFFFFFFF != u32_nb_free_cluster )
02159             goto endof_fat_getfreespace;
02160          u32_nb_free_cluster = 0;
02161       }
02162       // Speed optimization only for FAT16 and FAT32
02163       // init first value used by fat_cluster_readnext()
02164       if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02165          return FALSE;
02166       for(
02167       ;     fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02168       ;     fs_g_cluster.u32_pos++ )
02169       {
02170          if ( 0 == fs_g_cluster.u32_val )
02171             u32_nb_free_cluster++;
02172          if( !fat_cluster_readnext() )
02173             return FALSE;
02174       }
02175 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) )
02176       if( Is_fat32 )
02177       {
02178          // Save value for the future call
02179          fat_write_fat32_FSInfo( u32_nb_free_cluster );
02180       }
02181 #endif
02182    }
02183 endof_fat_getfreespace:
02184    return (u32_nb_free_cluster * fs_g_nav.u8_BPB_SecPerClus);
02185 }
02186 

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 2198 of file fat_unusual.c.

References 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, Fs_management::u16_fat_size, Fs_management::u32_CountofCluster, st_fs_cluster::u32_pos, and Fs_management::u8_BPB_SecPerClus.

Referenced by nav_partition_freespace_percent().

02198 {
02199    U32 u32_nb_free_cluster = 0;
02200    U16 u16_tmp, u16_pos;
02201 
02202    if( Is_fat12 )
02203    {  // No speed optimization necessary on FAT12
02204       return (((fat_getfreespace()/fs_g_nav.u8_BPB_SecPerClus)*100) / fs_g_nav.u32_CountofCluster);
02205    }
02206 
02207 
02208    fs_g_cluster.u32_pos = 2;
02209    // Init first value used by fat_cluster_readnext()
02210    if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02211       return FALSE;
02212 
02213    // The optimization is to
02214    // - read only the LSB byte of cluster
02215    // - read only 1 cluster for 2 clusters
02216    if( Is_fat32 )
02217    {
02218       u32_nb_free_cluster = fat_read_fat32_FSInfo();
02219       if( 0xFFFFFFFF != u32_nb_free_cluster )
02220          goto endof_fat_getfreespace_percent;
02221       u32_nb_free_cluster = 0;
02222 
02223       u16_pos = 2*4;
02224       for(  u16_tmp = fs_g_nav.u16_fat_size
02225       ;     u16_tmp!=0
02226       ;     u16_tmp-- )
02227       {
02228          for( ; u16_pos < 512 ; u16_pos += (2*4) )
02229          {
02230             if( 0 == fs_g_sector[u16_pos] )
02231                u32_nb_free_cluster+=2;
02232          }
02233          // Read next sector in FAT
02234          u16_pos = 0;
02235          fs_gu32_addrsector++;
02236          if( !fat_cache_read_sector( TRUE ))
02237             return 0;
02238       }
02239    }
02240 
02241    if ( Is_fat16 )
02242    {
02243       u16_pos = 2*2;
02244 
02245       for(  u16_tmp = fs_g_nav.u16_fat_size
02246       ;     u16_tmp!=0
02247       ;     u16_tmp-- )
02248       {
02249          for( ; u16_pos < 512 ; u16_pos += (2*2) )
02250          {
02251             if( 0 == fs_g_sector[u16_pos] )
02252                u32_nb_free_cluster+=2;
02253          }
02254          // Read next sector in FAT
02255          u16_pos = 0;
02256          fs_gu32_addrsector++;
02257          if( !fat_cache_read_sector( TRUE ))
02258             return 0;
02259       }
02260    }
02261 
02262    // Compute percent
02263    if( u32_nb_free_cluster > fs_g_nav.u32_CountofCluster )
02264       return 100;
02265    if( u32_nb_free_cluster > ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256) )
02266    {
02267       // Compute and add a delta error
02268       u32_nb_free_cluster -= ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256);
02269    }
02270 endof_fat_getfreespace_percent:
02271    return ((u32_nb_free_cluster * 100) / fs_g_nav.u32_CountofCluster);
02272 }
02273 

Bool fat_initialize_dir ( void   ) 

This function writes the directory information.

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          cluster value of a directory
//! OUT:
//!   update the sector cache with init directory datas
//! 

Definition at line 1181 of file fat_unusual.c.

References fat_cache_mark_sector_as_dirty(), fat_clear_cluster(), FS_ATTR_DIRECTORY, fs_g_nav, fs_g_nav_entry, fs_g_sector, FS_SIZE_FILE_ENTRY, Fs_management_entry::u32_cluster, and Fs_management::u32_cluster_sel_dir.

Referenced by nav_dir_make().

01181 {
01182    U8 u8_i;
01183 
01184    // Clear the cluster corresponding at directory
01185    if( !fat_clear_cluster())
01186       return FALSE;
01187    fat_cache_mark_sector_as_dirty();
01188    // here, the internal cache is the first sector of the cluster
01189 
01190    // Create the dot "." entry, this one is a directory that points to itself
01191    fs_g_sector[0]='.';
01192    for( u8_i=1 ; u8_i<11 ; u8_i++ )
01193       fs_g_sector[u8_i]=' ';
01194    fs_g_sector[11]=FS_ATTR_DIRECTORY;
01195    fs_g_sector[26]= LSB0( fs_g_nav_entry.u32_cluster );
01196    fs_g_sector[27]= LSB1( fs_g_nav_entry.u32_cluster );
01197    fs_g_sector[20]= LSB2( fs_g_nav_entry.u32_cluster );
01198    fs_g_sector[21]= LSB3( fs_g_nav_entry.u32_cluster );
01199    // Create the dotdot ".." entry, this one points to the starting cluster of the parent directory
01200    fs_g_sector[FS_SIZE_FILE_ENTRY+0]='.';
01201    fs_g_sector[FS_SIZE_FILE_ENTRY+1]='.';
01202    for( u8_i=2 ; u8_i<11 ; u8_i++ )
01203       fs_g_sector[FS_SIZE_FILE_ENTRY+u8_i]=' ';
01204    fs_g_sector[FS_SIZE_FILE_ENTRY+11]=FS_ATTR_DIRECTORY;
01205    fs_g_sector[FS_SIZE_FILE_ENTRY+26]= LSB0( fs_g_nav.u32_cluster_sel_dir );
01206    fs_g_sector[FS_SIZE_FILE_ENTRY+27]= LSB1( fs_g_nav.u32_cluster_sel_dir );
01207    fs_g_sector[FS_SIZE_FILE_ENTRY+20]= LSB2( fs_g_nav.u32_cluster_sel_dir );
01208    fs_g_sector[FS_SIZE_FILE_ENTRY+21]= LSB3( fs_g_nav.u32_cluster_sel_dir );
01209 
01210    return TRUE;
01211 }
01212 #endif  // FS_LEVEL_FEATURES

Bool fat_initialize_fat ( void   ) 

This function initializes the fat one and two.

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

TRUE otherwise

Definition at line 1006 of file fat_unusual.c.

References const_header_fat12, const_header_fat16, const_header_fat32, fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), fs_g_nav, fs_g_sector, fs_gu32_addrsector, Is_fat12, Is_fat16, Is_fat32, Fs_management::u16_fat_size, and Fs_management::u32_ptr_fat.

Referenced by fat_format().

01006 {
01007    // Init and reset the internal cache at the memory beginning
01008    fs_gu32_addrsector = fs_g_nav.u32_ptr_fat;
01009    if( !fat_cache_read_sector( FALSE ))
01010       return FALSE;
01011    fat_cache_mark_sector_as_dirty();
01012 
01013    if( Is_fat32 )
01014    {
01015       memcpy_code2ram( fs_g_sector, const_header_fat32, sizeof(const_header_fat32) );
01016    }
01017    if( Is_fat16 )
01018    {
01019       memcpy_code2ram( fs_g_sector, const_header_fat16, sizeof(const_header_fat16) );
01020    }
01021    if( Is_fat12 )
01022    {
01023       memcpy_code2ram( fs_g_sector, const_header_fat12, sizeof(const_header_fat12) );
01024    }
01025 
01026    // Copy the first sector of FAT 1 in the first sector of FAT 2
01027    fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + fs_g_nav.u16_fat_size;
01028    if( !fat_cache_read_sector( FALSE ))
01029       return FALSE;
01030    fat_cache_mark_sector_as_dirty();
01031    return TRUE;
01032 }
01033 

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 105 of file fat_unusual.c.

References 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, mem_sector_size(), Fs_management::rootdir, Fs_rootdir::seg, 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.

Referenced by fat_check_mount(), nav_drive_format(), and nav_partition_mount().

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

U32 fat_read_fat32_FSInfo ( void   ) 

This function returns the space free in the selected FAT32 partition.

Returns:
the number of sector free (if 0xFFFFFFFF, then no value available in FSInfo Sector)

Definition at line 888 of file fat_unusual.c.

References const_FSI_LeadSig, const_FSI_StrucSig, fat_cache_read_sector(), FS_BR_SIGNATURE_HIGH, FS_BR_SIGNATURE_LOW, fs_g_nav, fs_g_sector, fs_gu32_addrsector, Fs_management::u16_offset_FSInfo, and Fs_management::u32_ptr_fat.

Referenced by fat_getfreespace(), and fat_getfreespace_percent().

00888 {
00889    U32 u32_nb_free_cluster;
00890 
00891    // Read FAT32 FSInfo Sector
00892    fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo;
00893    if( !fat_cache_read_sector( TRUE ))
00894       return 0xFFFFFFFF;
00895 
00896    //* Check signature
00897    // offset 510-511, Signature
00898    if( fs_g_sector[510] != FS_BR_SIGNATURE_LOW )
00899       return 0xFFFFFFFF;
00900    if( fs_g_sector[511] != FS_BR_SIGNATURE_HIGH)
00901       return 0xFFFFFFFF;
00902    // offset 00-04, This lead signature
00903    if( 0 != memcmp_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) ))
00904       return 0xFFFFFFFF;
00905    // offset 004-483, reserved (fill with 0)
00906    // offset 484-487, signature
00907    if( 0 != memcmp_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig)) )
00908       return 0xFFFFFFFF;
00909 
00910    //* Read value
00911    // offset 488-491, free cluster count
00912    LSB0(u32_nb_free_cluster) = fs_g_sector[488];
00913    LSB1(u32_nb_free_cluster) = fs_g_sector[489];
00914    LSB2(u32_nb_free_cluster) = fs_g_sector[490];
00915    LSB3(u32_nb_free_cluster) = fs_g_sector[491];
00916    return u32_nb_free_cluster;
00917 }
00918 #endif  // FS_FAT_32

Bool fat_select_filesystem ( U8  u8_fat_type,
Bool  b_MBR 
)

This function computes the FAT type to use.

Parameters:
u8_fat_type Select the type of format
FS_FORMAT_DEFAULT, The file system module chooses the better FAT format for the drive space
FS_FORMAT_FAT, The FAT12 or FAT16 is used to format the drive, if possible (disk space <2GB)
FS_FORMAT_FAT32, The FAT32 is used to format the drive, if possible (disk space >32MB)
b_MBR TRUE, include a MBR on disk
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

//! Compute the fat type, fat position and fat size.
//! 

Definition at line 484 of file fat_unusual.c.

References FS_512B, FS_ERR_BAD_SIZE_FAT, FS_ERR_DEVICE_TOO_SMALL, FS_FORMAT_FAT, FS_FORMAT_FAT32, fs_g_nav, fs_g_nav_fast, fs_g_status, fs_s_u32_size_partition, FS_TYPE_FAT_12, FS_TYPE_FAT_16, FS_TYPE_FAT_32, Is_fat12, Is_fat16, Is_fat32, TableFAT12, TableFAT16, TableFAT32, Fs_management::u16_fat_size, Fs_management::u32_ptr_fat, Fs_management::u8_BPB_SecPerClus, and Fs_management_fast::u8_type_fat.

Referenced by fat_format().

00484 {
00485    U8 u8_i;
00486    U8 u8_tmp = 0;
00487    U16  u16_tmp, u16_tmp2;
00488    Fs_format_table _CONST_TYPE_ *ptr_table;
00489 
00490    if( (FS_FORMAT_FAT   != u8_fat_type )
00491    &&  (FS_FORMAT_FAT32 != u8_fat_type ) )
00492    {
00493       // Default format then select the better FAT type
00494       if( (((U32)512*1024*1024)/FS_512B) >= fs_s_u32_size_partition  )
00495       {
00496          u8_fat_type = FS_FORMAT_FAT;
00497       } else {
00498          u8_fat_type = FS_FORMAT_FAT32;
00499       }
00500    }
00501 
00502    //** Verify the FAT type choosed
00503    if(FS_FORMAT_FAT == u8_fat_type )
00504    {
00505       if( (((U32)2*1024*1024)/FS_512B) >= fs_s_u32_size_partition  )
00506       {
00507          fs_g_status = FS_ERR_DEVICE_TOO_SMALL;    // The disk size is not supported
00508          return FALSE;
00509       }
00510       if( (((U32)15*1024*1024)/FS_512B) >= fs_s_u32_size_partition  )
00511       {
00512          // FAT 12 format
00513          fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12;
00514          u8_i = sizeof(TableFAT12);
00515          ptr_table = TableFAT12;
00516       }else{
00517          // FAT 16 format
00518          fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16;
00519          u8_i = sizeof(TableFAT16);
00520          ptr_table = TableFAT16;
00521       }
00522    }
00523    else
00524    {  // FAT 32 format
00525       fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32;
00526       u8_i = sizeof(TableFAT32);
00527       ptr_table = TableFAT32;
00528    }
00529    for(  ; u8_i!=0 ; u8_i-- )
00530    {
00531       if( fs_s_u32_size_partition <= ptr_table->u32_disk_size )
00532       {
00533          // Get cluster size (unit sector)
00534          fs_g_nav.u8_BPB_SecPerClus = ptr_table->u8_SecPerClusVal;
00535          break;
00536       }
00537       ptr_table++;
00538    }
00539    if(0 == fs_g_nav.u8_BPB_SecPerClus)
00540    {
00541       fs_g_status = FS_ERR_BAD_SIZE_FAT;    // The disk size is not supported by selected FAT type
00542       return FALSE;
00543    }
00544 
00545    //** Compute fat size
00546    // Compute PBR address
00547    if( b_MBR )
00548       fs_g_nav.u32_ptr_fat = 1;  // MBR exist
00549    else
00550       fs_g_nav.u32_ptr_fat = 0;  // no MBR
00551 
00552    if( Is_fat12 )
00553    {  // FAT 12
00554       fs_g_nav.u32_ptr_fat += 1;  // FAT address = PBR address + 1
00555       // Try all possibility of FAT12 size
00556       fs_g_nav.u16_fat_size=1;
00557       while(1)
00558       {
00559          if( 12 < fs_g_nav.u16_fat_size)        // Max FAT size in FAT12 mode (unit sector) (=0xFFE*1.5/FS_512B)
00560          {
00561             fs_g_status = FS_ERR_BAD_SIZE_FAT;  // The disk size is not supported by file system selected
00562             return FALSE;
00563          }
00564          // Check if the number of cluster corresponding at data zone size
00565          // Note: -1 to not compute PBR sector
00566          u16_tmp  = ((fs_s_u32_size_partition -1 - (fs_g_nav.u16_fat_size *2)) / fs_g_nav.u8_BPB_SecPerClus)+2;
00567          u16_tmp2 = (fs_g_nav.u16_fat_size *FS_512B *2) / 3;
00568          if( u16_tmp <= u16_tmp2 )
00569             break;   // FAT size OK
00570 
00571          fs_g_nav.u16_fat_size++;
00572       }
00573    }
00574    else
00575    {
00576       if( Is_fat32 )
00577       {  // FAT 32
00578          fs_g_nav.u32_ptr_fat += 32;  // FAT address = PBR address + BPB_ResvSecCnt
00579          // RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;
00580          //                = (FS_512B-1) / FS_512B = 0
00581          // TmpVal1        = DskSize – (BPB_ResvdSecCnt + RootDirSectors);
00582          //                = fs_s_u32_size_partition - (32 + 0)
00583          //                = fs_s_u32_size_partition - u8_tmp
00584          u8_tmp = 32;
00585          // TmpVal2        = ((256 * BPB_SecPerClus) + BPB_NumFATs )/2;
00586          //                = ((((U16)fs_g_nav.u8_BPB_SecPerClus)<<8) + 2) >> 1;
00587          //                = (((U16)fs_g_nav.u8_BPB_SecPerClus)<<7) + 1;
00588          //                = u16_tmp
00589          u16_tmp = (((U16)fs_g_nav.u8_BPB_SecPerClus)<<7) + 1;
00590          // BPB_FATSz16    = 0;
00591          // BPB_FATSz32    = FATSz;
00592       }
00593       if( Is_fat16 )
00594       {  // FAT 16
00595          fs_g_nav.u32_ptr_fat += 1;  // FAT address = PBR address + BPB_ResvSecCnt
00596          // RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1))  / BPB_BytsPerSec
00597          //                = ((512            * 32) + (FS_512B-1)) / FS_512B
00598          //                = 32
00599          // TmpVal1        = DskSize – (BPB_ResvdSecCnt + RootDirSectors);
00600          //                = fs_s_u32_size_partition - (1 + 32)
00601          //                = fs_s_u32_size_partition - u8_tmp
00602          u8_tmp = 33;
00603          // TmpVal2        = ((256 * BPB_SecPerClus) + BPB_NumFATs )/2;
00604          //                = (((U16)fs_g_nav.u8_BPB_SecPerClus)<<8) + 2;
00605          //                = u16_tmp
00606          MSB(u16_tmp) = fs_g_nav.u8_BPB_SecPerClus;
00607          LSB(u16_tmp) = 2;
00608       }
00609       // FATSz          = (TMPVal1 + TmpVal2 – 1) / TmpVal2;
00610       fs_g_nav.u16_fat_size = (fs_s_u32_size_partition -u8_tmp +u16_tmp -1) / u16_tmp;
00611    }
00612 
00613    return TRUE;
00614 }
00615 

Bool fat_serialnumber ( Bool  b_action,
U8 _MEM_TYPE_SLOW_ *  a_u8_sn 
)

This function reads or writes a serial number in the drive.

This function reads or writes a serial number.

Parameters:
b_action choose action (FS_SN_READ or FS_SN_WRITE)
a_u8_sn array to store or get the serial number (U8[4])
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

Definition at line 1044 of file fat_unusual.c.

References fat_cache_flush(), fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), fs_g_nav, fs_g_sector, fs_gu32_addrsector, FS_SN_READ, Is_fat12, Is_fat16, and Fs_management::u32_ptr_fat.

Referenced by nav_partition_serialnumber().

01044 {
01045    // Compute PBR address
01046    if ( Is_fat12 || Is_fat16 )
01047    {  // FAT 12 & 16 (BPB_ResvSecCnt must be ega to 1)
01048       fs_gu32_addrsector = fs_g_nav.u32_ptr_fat-1;
01049    }
01050    else
01051    {  // FAT 32 (BPB_ResvSecCnt must be ega to 32)
01052       fs_gu32_addrsector = fs_g_nav.u32_ptr_fat-32;
01053    }
01054    // Read PBR
01055    if( !fat_cache_read_sector( TRUE ))
01056       return FALSE;
01057 
01058    // The serial is storaged at invert
01059    if( b_action == FS_SN_READ )
01060    {
01061       // Read serial number
01062       a_u8_sn[0] = fs_g_sector[42];
01063       a_u8_sn[1] = fs_g_sector[41];
01064       a_u8_sn[2] = fs_g_sector[40];
01065       a_u8_sn[3] = fs_g_sector[39];
01066       return TRUE;
01067    }else{
01068       // Write serial number
01069       fs_g_sector[42] = a_u8_sn[0];
01070       fs_g_sector[41] = a_u8_sn[1];
01071       fs_g_sector[40] = a_u8_sn[2];
01072       fs_g_sector[39] = a_u8_sn[3];
01073       fat_cache_mark_sector_as_dirty();
01074       return fat_cache_flush();
01075    }
01076 }
01077 

void fat_set_date ( const FS_STRING  sz_date,
Bool  type_date 
)

This function changes the date information.

Parameters:
type_date choose date field (FS_DATE_LAST_WRITE or FS_DATE_CREATION)
sz_date table with date information
storage format (ASCII) = "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde
//! OUT, update cache sector with the new date
//! 

Definition at line 1349 of file fat_unusual.c.

References fat_cache_mark_sector_as_dirty(), fat_get_ptr_entry(), fat_translatedate_ascii_to_number(), and FS_DATE_LAST_WRITE.

Referenced by nav_file_dateset().

01349 {
01350    PTR_CACHE ptr_entry;
01351 
01352    fat_cache_mark_sector_as_dirty();
01353    ptr_entry = fat_get_ptr_entry();
01354 
01355    if( FS_DATE_LAST_WRITE == type_date )
01356    {
01357       fat_translatedate_ascii_to_number( sz_date , &ptr_entry[22] , FALSE );
01358    }
01359    else
01360    {
01361       fat_translatedate_ascii_to_number( sz_date , &ptr_entry[13] , TRUE );
01362    }
01363 }
01364 

U16 fat_translate_ascii_to_number ( const FS_STRING  sz_ascii_number,
U8  u8_size_number_ascii 
)

This function translates a ASCII number to a digital number.

Parameters:
sz_ascii_number ascii number (ex:"1907")
u8_size_number_ascii number of digit (ex:4)
Returns:
the digital number
//! OUT, update sz_ascii_number
//! 

Definition at line 1441 of file fat_unusual.c.

Referenced by fat_translatedate_ascii_to_number().

01441 {
01442    U8 sz_ascii_number_copy[4];
01443    U8 _MEM_TYPE_FAST_ *ptr_sz_ascii_number;
01444    U8 u8_i;
01445    U16 u16_number;
01446 
01447    for( u8_i=0; u8_i < u8_size_number_ascii; u8_i++ )
01448    {
01449       sz_ascii_number_copy[u8_i] = sz_ascii_number[u8_i];
01450    }
01451 
01452    u16_number=0;
01453 
01454    while( 1 )
01455    {
01456       // Check if it is the end of ascii number (= "0...0")
01457       ptr_sz_ascii_number = sz_ascii_number_copy;
01458       for( u8_i = u8_size_number_ascii; u8_i !=0; u8_i-- )
01459       {
01460          if( '0' != *ptr_sz_ascii_number )
01461          {
01462             break;
01463          }
01464          ptr_sz_ascii_number++;
01465       }
01466       if( 0 == u8_i)
01467          return u16_number;
01468 
01469       // Decrement the number
01470       ptr_sz_ascii_number = sz_ascii_number_copy + u8_size_number_ascii -1;
01471       u16_number++;
01472       ptr_sz_ascii_number[0]--;
01473       while( ('0'-1) == ptr_sz_ascii_number[0] )
01474       {
01475          *ptr_sz_ascii_number = '9';
01476          ptr_sz_ascii_number--;
01477          ptr_sz_ascii_number[0]--;
01478       }
01479    }
01480 }
01481 #endif  // FS_LEVEL_FEATURES

U8 fat_translate_char_shortname ( U8  character  ) 

This function translates the character to autorized short name character.

Parameters:
character character to translate
Returns:
character translated
if no supported then 0

Definition at line 1891 of file fat_unusual.c.

References fs_s_execption_char.

Referenced by fat_create_short_entry_name().

01891 {
01892    U8 u8_j;
01893 
01894    if( (character<=' ') || ('~'<character) )
01895       return 0;
01896    if( ('a'<=character) && (character<='z') )
01897    {
01898       return (character - ('a'-'A'));  // Change to upper case
01899    }
01900    for( u8_j = 0 ; u8_j < sizeof(fs_s_execption_char) ; u8_j++ )
01901    {
01902       if( character == fs_s_execption_char[u8_j] )
01903          return 0;
01904    }
01905    return character;
01906 }
01907 

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 1318 of file fat_unusual.c.

Referenced by fat_translatedate_number_to_ascii().

01318 {
01319    FS_STRING ptr_sz_ascii_number;
01320 
01321    u8_size_number_ascii--;
01322 
01323    for( ; u8_nb_increment != 0 ; u8_nb_increment-- )
01324    {
01325       ptr_sz_ascii_number = sz_ascii_number + u8_size_number_ascii;
01326       ptr_sz_ascii_number[0]++;
01327       while( ('9'+1) == *ptr_sz_ascii_number )
01328       {
01329          *ptr_sz_ascii_number = '0';
01330          ptr_sz_ascii_number--;
01331          ptr_sz_ascii_number[0]++;
01332       }
01333    }
01334 }
01335 

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

This function translates a date ascii string to date FAT value.

Parameters:
sz_date table with 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
//! OUT, write the date field at ptr_date
//! 

Definition at line 1378 of file fat_unusual.c.

References fat_translate_ascii_to_number().

Referenced by fat_set_date().

01378 {
01379    U8 u8_tmp;
01380    U8 msb_date, lsb_date, msb_time, lsb_time;
01381 
01382    // Set the year
01383    msb_date  = ((U8)(fat_translate_ascii_to_number( sz_date , 4 )-1980))<<1;
01384 
01385    // Set the month
01386    u8_tmp    = (U8)fat_translate_ascii_to_number( &sz_date[4] , 2 );
01387    msb_date |= (u8_tmp >> 3);
01388    lsb_date  = (u8_tmp << 5);
01389 
01390    // Set the day
01391    lsb_date |= (U8)fat_translate_ascii_to_number( &sz_date[6] , 2 );
01392 
01393    // Set the hour
01394    msb_time  = ((U8)fat_translate_ascii_to_number( &sz_date[8] , 2 )) << (11-8);
01395 
01396    // Set the minute
01397    u8_tmp    = (U8)fat_translate_ascii_to_number( &sz_date[10] , 2 );
01398    msb_time |= (u8_tmp >> 3);
01399    lsb_time  = (u8_tmp << 5);
01400 
01401    // Set the seconde
01402    u8_tmp    = (U8)fat_translate_ascii_to_number( &sz_date[12] , 2 );
01403    lsb_time |= (u8_tmp >> 1);
01404 
01405    // Set the miliseconde
01406    if( enable_ms )
01407    {
01408       // check if the seconde time is %2
01409       if( u8_tmp & 0x01 )
01410       {  // it isn't %2
01411          u8_tmp = 100;  // add one seconde
01412       }
01413       else
01414       {
01415          u8_tmp = 0;    // no more seconde
01416       }
01417       *ptr_date = u8_tmp + (U8)fat_translate_ascii_to_number( &sz_date[14] , 2 );
01418       ptr_date++;
01419    }
01420 
01421    // Record value
01422    ptr_date[0] = lsb_time;
01423    ptr_date[1] = msb_time;
01424    ptr_date[2] = lsb_date;
01425    ptr_date[3] = msb_date;
01426 }
01427 

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 1245 of file fat_unusual.c.

References fat_translate_number_to_ascii().

Referenced by fat_get_date().

01245 {
01246    FS_STRING ptr_string_date;
01247    U8 u8_i;
01248    U8 msb_date, lsb_date, msb_time, lsb_time, u8_ms = 0;
01249 
01250    // Read entry value of date and time
01251    if( enable_ms )
01252    {
01253       u8_ms = *ptr_date;
01254       ptr_date++;
01255    }
01256    lsb_time = *ptr_date;
01257    ptr_date++;
01258    msb_time = *ptr_date;
01259    ptr_date++;
01260    lsb_date = *ptr_date;
01261    ptr_date++;
01262    msb_date = *ptr_date;
01263 
01264    // Initialise the string with "1980000000000000" (Year = 1980 and other at 0)
01265    ptr_string_date = sz_date;
01266    *ptr_string_date = '1';
01267    ptr_string_date++;
01268    *ptr_string_date = '9';
01269    ptr_string_date++;
01270    *ptr_string_date = '8';
01271    ptr_string_date++;
01272    for( u8_i=(15-2) ; u8_i!=0 ; u8_i-- )
01273    {
01274       *ptr_string_date = '0';
01275       ptr_string_date++;
01276    }
01277 
01278    // Get the year
01279    fat_translate_number_to_ascii( sz_date, 4 , msb_date>>1 );
01280 
01281    // Get the month
01282    fat_translate_number_to_ascii( &sz_date[4] , 2 , ((msb_date & 0x01)<<3) + (lsb_date>>5) );
01283 
01284    // Get the day
01285    fat_translate_number_to_ascii( &sz_date[6] , 2 , lsb_date & 0x1F );
01286 
01287    // Get the hour
01288    fat_translate_number_to_ascii( &sz_date[8] , 2 , msb_time >> (11-8) );
01289 
01290    // Get the minute
01291    fat_translate_number_to_ascii( &sz_date[10] , 2 , ((msb_time & 0x07)<<3) + (lsb_time>>5) );
01292 
01293    // Get the seconde
01294    fat_translate_number_to_ascii( &sz_date[12] , 2 , (lsb_time & 0x1F)<<1 );
01295    if( 99 < u8_ms )
01296    {
01297      // Add one seconde
01298      fat_translate_number_to_ascii( &sz_date[12] , 2 , 1 );
01299      u8_ms -= 100;
01300    }
01301 
01302    // Get the miliseconde
01303    fat_translate_number_to_ascii( &sz_date[14] , 2 , u8_ms );
01304 }
01305 

Bool fat_update_fat2 ( void   ) 

This function copys the modifications of the first FAT to the second FAT.

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

TRUE otherwise

Definition at line 2439 of file fat_unusual.c.

References fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), fs_g_nav, fs_g_u16_first_mod_fat, fs_g_u16_last_mod_fat, fs_gu32_addrsector, Fs_management::u16_fat_size, and Fs_management::u32_ptr_fat.

Referenced by fat_allocfreespace(), and fat_cluster_list().

02439 {
02440   while( fs_g_u16_first_mod_fat <= fs_g_u16_last_mod_fat )
02441   {
02442      // Compute the modification position of FAT 1
02443      fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + fs_g_u16_first_mod_fat;
02444      // Read FAT1
02445       if( !fat_cache_read_sector( TRUE ))
02446          return FALSE;
02447      // Compute the modification position of FAT 2
02448      fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + ((U32)fs_g_u16_first_mod_fat + fs_g_nav.u16_fat_size);
02449      // Init the sector FAT2 with the previous sector of the FAT1
02450      if( !fat_cache_read_sector( FALSE ))
02451          return FALSE;
02452      // Flag the sector FAT2 like modify
02453      fat_cache_mark_sector_as_dirty();
02454      fs_g_u16_first_mod_fat++;
02455   }
02456   return TRUE;
02457 }
02458 #endif  // FS_LEVEL_FEATURES

Bool fat_write_fat32_FSInfo ( U32  u32_nb_free_cluster  ) 

This function writes the space free number in selected FAT32 partition.

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

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

TRUE otherwise

Definition at line 853 of file fat_unusual.c.

References const_FSI_LeadSig, const_FSI_StrucSig, fat_cache_clear(), fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), FS_BR_SIGNATURE_HIGH, FS_BR_SIGNATURE_LOW, fs_g_nav, fs_g_sector, fs_gu32_addrsector, Fs_management::u16_offset_FSInfo, and Fs_management::u32_ptr_fat.

Referenced by fat_allocfreespace(), fat_cluster_list(), fat_getfreespace(), and fat_write_PBR().

00853 {
00854    // Init sector
00855    fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo;
00856 
00857    if( !fat_cache_read_sector( FALSE ))
00858       return FALSE;
00859    fat_cache_mark_sector_as_dirty();
00860    fat_cache_clear();
00861 
00862    // Fill sector
00863    // offset 00-04, This lead signature
00864    memcpy_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) );
00865    // offset 004-483, reserved (fill with 0)
00866    // offset 484-487, signature
00867    memcpy_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig) );
00868    // offset 488-491, free cluster count (by default NO value)
00869    fs_g_sector[488] = LSB0(u32_nb_free_cluster);
00870    fs_g_sector[489] = LSB1(u32_nb_free_cluster);
00871    fs_g_sector[490] = LSB2(u32_nb_free_cluster);
00872    fs_g_sector[491] = LSB3(u32_nb_free_cluster);
00873    // offset 492-495, indicates the cluster number at which the driver should start looking for free clusters (by default NO value)
00874    memset( &fs_g_sector[492] , 0xFF , 4 );
00875    // offset 496-509, reserved (fill with 0)
00876    // offset 510-511, Signature
00877    fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00878    fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00879    return TRUE;
00880 }
00881 

Bool fat_write_MBR ( void   ) 

This function writes the MBR.

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

TRUE otherwise

Definition at line 623 of file fat_unusual.c.

References fat_cache_clear(), fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), FS_512B, FS_BR_SIGNATURE_HIGH, FS_BR_SIGNATURE_LOW, fs_g_sector, fs_gu32_addrsector, FS_MBR_OFFSET_PART_ENTRY, FS_PART_NO_BOOTABLE, FS_PART_TYPE_FAT12, FS_PART_TYPE_FAT16_INF32M, FS_PART_TYPE_FAT16_SUP32M, FS_PART_TYPE_FAT32, fs_s_u32_size_partition, Is_fat12, Is_fat16, and Is_fat32.

Referenced by fat_format().

00623 {
00624    U8 u8_i = 0;
00625 
00626    // Init and reset the internal cache at the beginning of memory
00627    fs_gu32_addrsector = 0;
00628    if( !fat_cache_read_sector( FALSE ))
00629       return FALSE;
00630    fat_cache_mark_sector_as_dirty();
00631    fat_cache_clear();
00632 
00633    // MBR signature
00634    fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00635    fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00636 
00637    // Write the partition entry in the MBR
00638    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +0] = FS_PART_NO_BOOTABLE;   // Active partition
00639    // Remark: cylinder and header start to 0, and sector value start to 1
00640    //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +1] = 0;                   // The head (0) where the partition starts
00641    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +2] = 2;                     // The sector (2=next to MBR) and the cylinder (0) where the partition starts
00642    //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +3] = 0;
00643 
00644    // Write patition type
00645    if( Is_fat32 )
00646    {  // FAT 32
00647       u8_i = FS_PART_TYPE_FAT32;
00648    }
00649    if( Is_fat16 )
00650    {  // FAT 16
00651       if( fs_s_u32_size_partition < (32L*1024*(1024/FS_512B)) )
00652       {  // Disk < 32MB
00653          u8_i = FS_PART_TYPE_FAT16_INF32M;
00654       }else{
00655          u8_i = FS_PART_TYPE_FAT16_SUP32M;
00656       }
00657    }
00658    if( Is_fat12 )
00659    {  // FAT 12
00660       u8_i = FS_PART_TYPE_FAT12;
00661    }
00662 
00663    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +4] = u8_i;
00664 
00665    // The head where the partitions ends
00666    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +5] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6);
00667    // The sector and the cylinder where the partition ends
00668    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +6] = (LSB1(fs_s_u32_size_partition)&0xC0) + (LSB0(fs_s_u32_size_partition)&0x3F);
00669    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +7] = LSB2(fs_s_u32_size_partition);
00670 
00671    // Write partition position (in sectors) at offset 8
00672    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+ 8] = 0x01;
00673    //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+ 9] = 0x00;
00674    //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+10] = 0x00;
00675    //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+11] = 0x00;
00676    // Write the number of sector in partition (= size - one sector MBR = last LBA, return by read_capacity)
00677    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+12] = LSB0(fs_s_u32_size_partition);
00678    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+13] = LSB1(fs_s_u32_size_partition);
00679    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+14] = LSB2(fs_s_u32_size_partition);
00680    fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+15] = LSB3(fs_s_u32_size_partition);
00681 
00682    return TRUE;
00683 }
00684 

Bool fat_write_PBR ( Bool  b_MBR  ) 

This function writes the PBR.

Parameters:
b_MBR TRUE, include a MBR on disk
Returns:
FALSE in case of error, see global value "fs_g_status" for more detail

TRUE otherwise

Definition at line 730 of file fat_unusual.c.

References const_header_pbr, const_tail_pbr, fat_cache_clear(), fat_cache_mark_sector_as_dirty(), fat_cache_read_sector(), fat_write_fat32_FSInfo(), FS_BR_SIGNATURE_HIGH, FS_BR_SIGNATURE_LOW, fs_g_nav, fs_g_sector, fs_gu32_addrsector, fs_s_u32_size_partition, HIGH_16_BPB_FATSz16, Is_fat12, Is_fat32, LOW0_32_BPB_FATSz32, LOW1_32_BPB_FATSz32, LOW_16_BPB_FATSz16, Fs_management::u16_fat_size, Fs_management::u16_offset_FSInfo, and Fs_management::u8_BPB_SecPerClus.

Referenced by fat_format().

00730 {
00731    U16 u16_tmp;
00732 
00733    //** Init the cache sector with PBR
00734    if( b_MBR )
00735       fs_gu32_addrsector = 1;
00736    else
00737       fs_gu32_addrsector = 0;
00738 
00739    if( !fat_cache_read_sector( FALSE ))
00740       return FALSE;
00741    fat_cache_mark_sector_as_dirty();
00742    fat_cache_clear();
00743 
00744    //** WRITE CONSTANTE & VARIABLE FOR FAT and FAT32
00745    memcpy_code2ram( fs_g_sector, const_header_pbr , sizeof(const_header_pbr) );
00746    // PBR signature
00747    fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00748    fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00749 
00750    // offset 13-13, Add sector by cluster
00751    fs_g_sector[13] = fs_g_nav.u8_BPB_SecPerClus;
00752    // offset 26-27, Number of header
00753    fs_g_sector[26] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6);
00754 
00755    //** WRITE CONSTANTE & VARIABLE DEPENDING OF FAT16 and FAT32
00756    // Since offset 36, there are a different structure space for FAT16 and FAT32
00757    // offset 39-42 or 67-70, Volume ID not used
00758    // offset 43-53 or 71-81, Volume Label
00759    // offset 54-61 or 82-89, File system type
00760    if( Is_fat32 )
00761    {
00762       memcpy_code2ram( &fs_g_sector[64], const_tail_pbr, sizeof(const_tail_pbr) );
00763    }else{
00764       memcpy_code2ram( &fs_g_sector[36], const_tail_pbr, sizeof(const_tail_pbr) );
00765    }
00766 
00767    u16_tmp = fs_g_nav.u16_fat_size;    // save value in fast data space to optimize code
00768    if( Is_fat32 )
00769    {
00770       // offset 14-15, Add Number of reserved sector, FAT32 = 32 sectors
00771       fs_g_sector[14] = 32;
00772       // offset 17-18, Add Number of root entry, FAT32 = 0 entry
00773       // offset 36-39, Fat size 32bits
00774       LOW0_32_BPB_FATSz32 = LSB(u16_tmp);
00775       LOW1_32_BPB_FATSz32 = MSB(u16_tmp);
00776       // offset 40-41, Ext flags (all FAT are enabled = 0)
00777       // offset 42-43, Fs version (version0:0 = 0)
00778       // offset 44-47, Root Cluster (first free cluster = 2)
00779       fs_g_sector[44]= 2;
00780       // offset 48-49, Fs Info (usualy 1)
00781       fs_g_sector[48]= 1;
00782       // offset 50-51, Backup Boot Sector (usualy 6)
00783       // fs_g_sector[50]= 0;
00784       // offset 52-63, reserved space
00785       // offset 54-61, File system type
00786       fs_g_sector[85]='3';
00787       fs_g_sector[86]='2';
00788       // Update FSInfo position
00789       fs_g_nav.u16_offset_FSInfo = (32-1);
00790    }
00791    else
00792    {
00793       // FAT 12 or 16
00794       // offset 14-15, Add Number of reserved sector, FAT = 1 sector
00795       fs_g_sector[14] = 1;
00796       // offset 17-18, Add Number of root entry, FAT = 512 entrys
00797       //fs_g_sector[17] = 512&0xFF;
00798       fs_g_sector[18] = 512>>8;
00799 
00800       // offset 22-23, Fat size 16bits
00801       LOW_16_BPB_FATSz16  = LSB(u16_tmp);
00802       HIGH_16_BPB_FATSz16 = MSB(u16_tmp);
00803       // offset 54-61, File system type
00804       fs_g_sector[57]='1';
00805       if( Is_fat12 )
00806       {
00807          fs_g_sector[58]='2';
00808       }else{
00809          fs_g_sector[58]='6';
00810       }
00811    }
00812 
00813    // Write the number of sector in partition (= size - one sector MBR = last LBA, return by read_capacity)
00814    if( ( Is_fat32 )
00815    ||  ((0x10000-1) <= fs_s_u32_size_partition) )
00816    {
00817       // FAT32 or disk > 32MB
00818       // offset 32-35, Number of sector in partition (value 32 bits)
00819       fs_g_sector[32] = LSB0(fs_s_u32_size_partition);
00820       fs_g_sector[33] = LSB1(fs_s_u32_size_partition);
00821       fs_g_sector[34] = LSB2(fs_s_u32_size_partition);
00822       fs_g_sector[35] = LSB3(fs_s_u32_size_partition);
00823    }
00824    else
00825    {
00826       // offset 19-20, Number of sector in partition (value 16 bits)
00827       fs_g_sector[19] = LSB0(fs_s_u32_size_partition);
00828       fs_g_sector[20] = LSB1(fs_s_u32_size_partition);
00829    }
00830 
00831    if( Is_fat32 )
00832    {
00833       // Init the FAT32 FSInfo Sector
00834       if( !fat_write_fat32_FSInfo( 0xFFFFFFFF ))
00835          return FALSE;
00836    }
00837    return TRUE;
00838 }


Variable Documentation

_CONST_TYPE_ U8 const_FSI_LeadSig[]

Initial value:

 {
   0x52,0x52,0x61,0x41                                
}

Definition at line 714 of file fat_unusual.c.

Referenced by fat_read_fat32_FSInfo(), and fat_write_fat32_FSInfo().

_CONST_TYPE_ U8 const_FSI_StrucSig[]

Initial value:

 {
   0x72,0x72,0x41,0x61                                
}

Definition at line 717 of file fat_unusual.c.

Referenced by fat_read_fat32_FSInfo(), and fat_write_fat32_FSInfo().

_CONST_TYPE_ U8 const_header_fat12[]

Initial value:

 {
   0xF8,0xFF,0xFF                            
   }

Definition at line 988 of file fat_unusual.c.

Referenced by fat_initialize_fat().

_CONST_TYPE_ U8 const_header_fat16[]

Initial value:

 {
   0xF8,0xFF,0xFF,0xFF                       
   }

Definition at line 991 of file fat_unusual.c.

Referenced by fat_initialize_fat().

_CONST_TYPE_ U8 const_header_fat32[]

Initial value:

 {
   0xF8,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x0F   
  ,0xFF,0xFF,0xFF,0x0F                       
   }

Definition at line 994 of file fat_unusual.c.

Referenced by fat_initialize_fat().

_CONST_TYPE_ U8 const_header_pbr[]

Initial value:

 {
   0xEB,0,0x90,                                       
   'M','S','W','I','N','4','.','1',                   
   FS_512B & 0xFF, FS_512B >>8,                       
   0,                                                 
   0,0,                                               
   2,                                                 
   0,0,                                               
   0,0,
   FS_PART_NO_REMOVE_MEDIA,                           
   0,0,
   0x3F,0,                                            
   0,0,                                               
   1                                                  
   }

Definition at line 687 of file fat_unusual.c.

Referenced by fat_write_PBR().

_CONST_TYPE_ U8 const_tail_pbr[]

Initial value:

 {           
   FS_PART_HARD_DISK,                                 
   0,                                                 
   FS_BOOT_SIGN,                                      
   0,0,0,0,                                           
   'N','O',' ','N','A','M','E',' ',' ',' ',' ',       
   'F','A','T',' ',' ',' ',' ',' ',                   
   }

Definition at line 702 of file fat_unusual.c.

Referenced by fat_write_PBR().

_CONST_TYPE_ U8 fs_s_execption_char[] = {'+',',','.',';','=','[',']'}

Characters table no supported in a short name.

Definition at line 1882 of file fat_unusual.c.

Referenced by fat_translate_char_shortname().

_CONST_TYPE_ U8 fs_s_tab_incorrect_char[] = {':','*','?','"','<','>','|'}

Characters table no supported in a file name.

Definition at line 1829 of file fat_unusual.c.

Referenced by fat_check_name().

_MEM_TYPE_SLOW_ U32 fs_s_u32_size_partition

Definition at line 319 of file fat_unusual.c.

Referenced by fat_format(), fat_select_filesystem(), fat_write_MBR(), and fat_write_PBR().

_CONST_TYPE_ Fs_format_table TableFAT12[]

Initial value:

 {
   {  4096, 1},      
   {  8192, 2},      
   { 16384, 4},      
   { 32680, 8},      
}
Table format for FAT12.

Definition at line 399 of file fat_unusual.c.

Referenced by fat_select_filesystem().

_CONST_TYPE_ Fs_format_table TableFAT16[]

Initial value:

 {
   { 8400, 0},       
   { 32680, 2},      
   { 262144, 4},     
   { 524288, 8},     
   { 1048576, 16},   
   
   { 2097152, 32},   
   { 4194304, 64},   
   { 0xFFFFFFFF, 0}  
}
Table format for FAT16.

Definition at line 418 of file fat_unusual.c.

Referenced by fat_select_filesystem().

_CONST_TYPE_ Fs_format_table TableFAT32[]

Initial value:

 {
   { 66600, 0},      
   { 532480, 1},     
   { 16777216, 8},   
   { 33554432, 16},  
   { 67108864, 32},  
   { 0xFFFFFFFF, 64} 
}
Table format for FAT32.

Definition at line 444 of file fat_unusual.c.

Referenced by fat_select_filesystem().


Generated on Fri Feb 19 02:29:44 2010 for AVR32 UC3 - FSACCESS Services by  doxygen 1.5.5