ATMEL: file.c Source File

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

# file.c

Go to the documentation of this file.

    00001 /*This file is prepared for Doxygen automatic documentation generation.*/
    00014 /* Copyright (C) 2006-2008, Atmel Corporation All rights reserved.
    00015  *
    00016  * Redistribution and use in source and binary forms, with or without
    00017  * modification, are permitted provided that the following conditions are met:
    00018  *
    00019  * 1. Redistributions of source code must retain the above copyright notice,
    00020  * this list of conditions and the following disclaimer.
    00021  *
    00022  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00023  * this list of conditions and the following disclaimer in the documentation
    00024  * and/or other materials provided with the distribution.
    00025  *
    00026  * 3. The name of Atmel may not be used to endorse or promote products derived
    00027  * from this software without specific prior written permission.
    00028  *
    00029  * 4. This software may only be redistributed and used in connection with an Atmel
    00030  * AVR product.
    00031  *
    00032  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
    00033  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00034  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
    00035  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00036  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00037  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00038  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00039  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00040  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00041  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00042  */
    00043
    00044
    00045 //_____  I N C L U D E S ___________________________________________________
    00046 #include "conf_explorer.h"
    00047 #include "file.h"
    00048 #include "navigation.h"
    00049 #include LIB_MEM
    00050 #include LIB_CTRLACCESS
    00051
    00052
    00053 //_____ D E C L A R A T I O N S ____________________________________________
    00054
    00056 #if __GNUC__ && __AVR32__
    00057 __attribute__((__aligned__(4)))
    00058 #elif __ICCAVR32__
    00059 #pragma data_alignment = 4
    00060 #endif
    00061 extern   _MEM_TYPE_SLOW_   U8    fs_g_sector[ FS_CACHE_SIZE ];
    00062
    00063 static   void  file_load_segment_value( Fs_file_segment _MEM_TYPE_SLOW_ *segment );
    00064
    00065
    00066
    00072 Bool  file_ispresent( void )
    00073 {
    00074    if( !fat_check_mount_select() )
    00075       return FALSE;
    00076    return fat_check_is_file();
    00077 }
    00078
    00079
    00092 Bool  file_open( U8 fopen_mode )
    00093 {
    00094    if( !fat_check_mount_select_noopen())
    00095       return FALSE;
    00096
    00097    if( !fat_check_is_file())
    00098       return FALSE;
    00099
    00100    if(FOPEN_WRITE_ACCESS & fopen_mode)
    00101    {
    00102       if( !fat_check_nav_access_file( TRUE ) )
    00103          return FALSE;
    00104 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
    00105       if (FS_ATTR_READ_ONLY & fs_g_nav_entry.u8_attr)
    00106       {
    00107          fs_g_status = FS_ERR_READ_ONLY;  // File is read only
    00108          return FALSE;
    00109       }
    00110       if( mem_wr_protect( fs_g_nav.u8_lun  ))
    00111       {
    00112          fs_g_status = FS_LUN_WP;  // Disk read only
    00113          return FALSE;
    00114       }
    00115 #else
    00116       fs_g_status = FS_ERR_MODE_NOAVIALABLE;
    00117       return FALSE;
    00118 #endif  // FS_LEVEL_FEATURES
    00119    }
    00120    else
    00121    {
    00122       if( !fat_check_nav_access_file( FALSE ) )
    00123          return FALSE;
    00124    }
    00125
    00126    if(FOPEN_CLEAR_SIZE & fopen_mode)
    00127    {
    00128       fs_g_nav_entry.u32_size    = 0;     // The size is null
    00129    }
    00130    if(FOPEN_CLEAR_PTR & fopen_mode)
    00131    {
    00132       fs_g_nav_entry.u32_pos_in_file = 0;
    00133    }
    00134    else
    00135    {  // Go to at the end of file
    00136       fs_g_nav_entry.u32_pos_in_file = fs_g_nav_entry.u32_size;
    00137    }
    00138    fs_g_nav_entry.u8_open_mode = fopen_mode;
    00139    return TRUE;
    00140 }
    00141
    00142
    00147 static void file_load_segment_value( Fs_file_segment _MEM_TYPE_SLOW_ *segment )
    00148 {
    00149    segment->u8_lun = fs_g_nav.u8_lun;
    00150    segment->u32_addr = fs_g_seg.u32_addr;
    00151    segment->u16_size = fs_g_seg.u32_size_or_pos;
    00152 }
    00153
    00154
    00172 Bool  file_read( Fs_file_segment _MEM_TYPE_SLOW_ *segment )
    00173 {
    00174    U8 u8_nb_sector_truncated;
    00175
    00176    if( !fat_check_mount_select_open())
    00177       return FALSE;
    00178
    00179    if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode))
    00180    {
    00181       fs_g_status = FS_ERR_WRITE_ONLY;
    00182       return FALSE;
    00183    }
    00184
    00185    if ( file_eof() )
    00186    {
    00187       // End of the file
    00188       fs_g_status = FS_ERR_EOF;
    00189       return FALSE;
    00190    }
    00191
    00192    if( !fat_read_file(FS_CLUST_ACT_SEG))
    00193    {
    00194       if( FS_ERR_OUT_LIST == fs_g_status )
    00195          fs_g_status = FS_ERR_EOF;  // translate the error
    00196       return FALSE;
    00197    }
    00198    // If the segment is too large then truncate it
    00199    if( (segment->u16_size != 0)                          // if no limit then no truncate
    00200    &&  (segment->u16_size < fs_g_seg.u32_size_or_pos) )
    00201    {
    00202       u8_nb_sector_truncated   = fs_g_seg.u32_size_or_pos - segment->u16_size;
    00203       fs_g_seg.u32_size_or_pos = segment->u16_size ;
    00204    }else{
    00205       u8_nb_sector_truncated = 0;
    00206    }
    00207
    00208    // Update file position
    00209    fs_g_nav_entry.u32_pos_in_file += (U32)fs_g_seg.u32_size_or_pos * FS_512B;
    00210    if( fs_g_nav_entry.u32_size < fs_g_nav_entry.u32_pos_in_file )
    00211    {
    00212       // The segment is more larger then file
    00213       // case possible: if the file don't use all cluster space
    00214       // then compute sectors not used in last cluster of file cluster list
    00215       U8 u8_nb_sector_not_used;
    00216
    00217       // Compute the number of sector used in last cluster
    00218       // remark: also the two first bytes of size is used, because the cluster size can't be more larger then 64KB
    00219       u8_nb_sector_not_used = LSB1( fs_g_nav_entry.u32_size ) >> (FS_512B_SHIFT_BIT-8);
    00220       if( 0 != (fs_g_nav_entry.u32_size & FS_512B_MASK) )
    00221       {  // last sector of file isn't full, but it must been read
    00222          u8_nb_sector_not_used++;
    00223       }
    00224
    00225       // Compute the number of sector not used in last cluster
    00226       u8_nb_sector_not_used = fs_g_nav.u8_BPB_SecPerClus - (u8_nb_sector_not_used % fs_g_nav.u8_BPB_SecPerClus);
    00227       // if all space of cluster isn't used, then it is wrong
    00228       if( u8_nb_sector_not_used == fs_g_nav.u8_BPB_SecPerClus )
    00229          u8_nb_sector_not_used = 0; // The file uses all last cluster space
    00230
    00231       // Subtract this value a the file position and segment size
    00232       u8_nb_sector_not_used -= u8_nb_sector_truncated;
    00233       fs_g_seg.u32_size_or_pos -= u8_nb_sector_not_used;                                     // unit sector
    00234       fs_g_nav_entry.u32_pos_in_file -= ((U16)u8_nb_sector_not_used) << FS_512B_SHIFT_BIT;   // unit byte
    00235    }
    00236    file_load_segment_value( segment );
    00237    return TRUE;
    00238 }
    00239
    00240
    00249 U16   file_read_buf( U8 _MEM_TYPE_SLOW_ *buffer , U16 u16_buf_size )
    00250 {
    00251    _MEM_TYPE_FAST_ U16 u16_nb_read_tmp;
    00252    _MEM_TYPE_FAST_ U16 u16_nb_read;
    00253    _MEM_TYPE_FAST_ U16 u16_pos_in_sector;
    00254    _MEM_TYPE_FAST_ U32 u32_byte_remaining;
    00255
    00256    if( !fat_check_mount_select_open())
    00257       return FALSE;
    00258
    00259    if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode))
    00260    {
    00261       fs_g_status = FS_ERR_WRITE_ONLY;
    00262       return FALSE;
    00263    }
    00264
    00265    u16_nb_read = 0;
    00266
    00267    while( 0 != u16_buf_size )
    00268    {
    00269       if ( file_eof() )
    00270       {
    00271          fs_g_status = FS_ERR_EOF;
    00272          return u16_nb_read;     // End of the file
    00273       }
    00274       u32_byte_remaining = fs_g_nav_entry.u32_size-fs_g_nav_entry.u32_pos_in_file;
    00275       u16_pos_in_sector = fs_g_nav_entry.u32_pos_in_file % FS_512B;
    00276
    00277       if( (0== u16_pos_in_sector)
    00278       &&  (FS_512B <= u32_byte_remaining)
    00279       &&  (FS_512B <= u16_buf_size)
    00280 #if __GNUC__ && __AVR32__ || __ICCAVR32__
    00281       &&  (Test_align((U32)buffer, sizeof(U32)))
    00282 #endif
    00283       )
    00284       {
    00285          // The file data sector can been directly transfer from memory to buffer (don't use internal cache)
    00286          if( u16_buf_size <= u32_byte_remaining)
    00287          {
    00288             u16_nb_read_tmp = u16_buf_size;
    00289          }else{
    00290             u16_nb_read_tmp = u32_byte_remaining;
    00291          }
    00292          u16_nb_read_tmp = u16_nb_read_tmp / FS_512B;  // read a modulo sector size
    00293
    00294          // Get following sector segment of file
    00295          if( !fat_read_file(FS_CLUST_ACT_SEG))
    00296          {
    00297             if( FS_ERR_OUT_LIST == fs_g_status )
    00298                fs_g_status = FS_ERR_EOF;  // translate the error
    00299             return u16_nb_read;
    00300          }
    00301          // Truncate the segment size found if more larger than asked size
    00302          if( u16_nb_read_tmp > fs_g_seg.u32_size_or_pos )
    00303          {
    00304             u16_nb_read_tmp = fs_g_seg.u32_size_or_pos;
    00305          }else{
    00306             fs_g_seg.u32_size_or_pos = u16_nb_read_tmp;
    00307          }
    00308
    00309          // Directly data tranfert from memory to buffer
    00310          while( 0 != fs_g_seg.u32_size_or_pos )
    00311          {
    00312             if( CTRL_GOOD != memory_2_ram( fs_g_nav.u8_lun  , fs_g_seg.u32_addr, buffer))
    00313             {
    00314                fs_g_status = FS_ERR_HW;
    00315                return u16_nb_read;
    00316             }
    00317             fs_g_seg.u32_size_or_pos--;
    00318             fs_g_seg.u32_addr++;
    00319             buffer += FS_512B;
    00320          }
    00321          // Translate from sector unit to byte unit
    00322          u16_nb_read_tmp *= FS_512B;
    00323       }
    00324       else
    00325       {
    00326          // The file data can't been directly transfer from memory to buffer, the internal cache must be used
    00327
    00328          // Tranfer data from memory to internal cache
    00329          if( !fat_read_file( FS_CLUST_ACT_ONE ))
    00330          {
    00331             if( FS_ERR_OUT_LIST == fs_g_status )
    00332             {  // Translate the error
    00333                fs_g_status = FS_ERR_EOF;   // End of file
    00334             }
    00335             return u16_nb_read;
    00336          }
    00337
    00338          // Compute the number of data to transfer
    00339          u16_nb_read_tmp = FS_512B - u16_pos_in_sector;  // The number is limited at sector size
    00340          if( u16_nb_read_tmp > u32_byte_remaining )
    00341             u16_nb_read_tmp = u32_byte_remaining;
    00342          if( u16_nb_read_tmp > u16_buf_size )
    00343             u16_nb_read_tmp = u16_buf_size;
    00344
    00345          // Tranfer data from internal cache to buffer
    00346          memcpy_ram2ram( buffer , &fs_g_sector[ u16_pos_in_sector ], u16_nb_read_tmp );
    00347          buffer += u16_nb_read_tmp;
    00348       }
    00349       // Update positions
    00350       fs_g_nav_entry.u32_pos_in_file   += u16_nb_read_tmp;
    00351       u16_nb_read                      += u16_nb_read_tmp;
    00352       u16_buf_size                     -= u16_nb_read_tmp;
    00353    }
    00354    return u16_nb_read;  // Buffer is full
    00355 }
    00356
    00357
    00363 U16   file_getc( void )
    00364 {
    00365    U16   u16_byte;
    00366
    00367    while(1)
    00368    {
    00369       if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode))
    00370       {
    00371          fs_g_status = FS_ERR_WRITE_ONLY;
    00372          break;
    00373       }
    00374       if( fs_g_nav_entry.u32_size <= fs_g_nav_entry.u32_pos_in_file )
    00375       {
    00376          fs_g_status = FS_ERR_EOF;
    00377          break;
    00378       }
    00379
    00380       if( !fat_read_file( FS_CLUST_ACT_ONE ))
    00381       {
    00382          if( FS_ERR_OUT_LIST == fs_g_status )
    00383          {  // Translate the error
    00384             fs_g_status = FS_ERR_EOF;   // End of file
    00385          }
    00386          break;
    00387       }
    00388
    00389       u16_byte = fs_g_sector[ fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK ];
    00390       fs_g_nav_entry.u32_pos_in_file++;
    00391       return u16_byte;
    00392    }
    00393    return FS_EOF;   // No data readed
    00394 }
    00395
    00396
    00397 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
    00415 Bool  file_write( Fs_file_segment _MEM_TYPE_SLOW_ *segment )
    00416 {
    00417    if( !fat_check_mount_select_open())
    00418       return FALSE;
    00419
    00420    if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
    00421    {
    00422       fs_g_status = FS_ERR_READ_ONLY;
    00423       return FALSE;
    00424    }
    00425
    00426    if( !fat_write_file( FS_CLUST_ACT_SEG , segment->u16_size ))
    00427       return FALSE;
    00428
    00429    // If the segment is too large then truncate it
    00430    if( (segment->u16_size != 0)  // if not undefine limit
    00431    &&  (segment->u16_size < fs_g_seg.u32_size_or_pos) )
    00432    {
    00433       fs_g_seg.u32_size_or_pos = segment->u16_size ;
    00434    }
    00435
    00436    // Update file position
    00437    fs_g_nav_entry.u32_pos_in_file += ((U32)fs_g_seg.u32_size_or_pos * FS_512B);
    00438
    00439    // Update size file
    00440    if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size )
    00441    {
    00442       fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
    00443    }
    00444    file_load_segment_value( segment );
    00445    return TRUE;
    00446 }
    00447
    00448
    00460 Bool  file_set_eof( void )
    00461 {
    00462    if( !fat_check_mount_select_open())
    00463       return FALSE;
    00464
    00465    if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
    00466    {
    00467       fs_g_status = FS_ERR_READ_ONLY;
    00468       return FALSE;
    00469    }
    00470
    00471    // Update the file size
    00472    fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
    00473
    00474    if( !fat_read_file( FS_CLUST_ACT_CLR ))
    00475       return FALSE;
    00476
    00477    return fat_cache_flush();
    00478 }
    00479
    00480
    00489 U16   file_write_buf( U8 _MEM_TYPE_SLOW_ *buffer , U16 u16_buf_size )
    00490 {
    00491    _MEM_TYPE_FAST_ U16 u16_nb_write_tmp;
    00492    _MEM_TYPE_FAST_ U16 u16_nb_write;
    00493    _MEM_TYPE_FAST_ U16 u16_pos_in_sector;
    00494
    00495    if( !fat_check_mount_select_open())
    00496       return FALSE;
    00497
    00498    if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
    00499    {
    00500       fs_g_status = FS_ERR_READ_ONLY;
    00501       return FALSE;
    00502    }
    00503
    00504    u16_nb_write = 0;
    00505
    00506    while( 0 != u16_buf_size )
    00507    {
    00508       // The file data sector can been directly transfer from buffer to memory (don't use internal cache)
    00509       u16_pos_in_sector = fs_g_nav_entry.u32_pos_in_file % FS_512B;
    00510       if( (0== u16_pos_in_sector)
    00511       &&  (FS_512B <= u16_buf_size)
    00512 #if __GNUC__ && __AVR32__ || __ICCAVR32__
    00513       &&  (Test_align((U32)buffer, sizeof(U32)))
    00514 #endif
    00515       )
    00516       {
    00517          u16_nb_write_tmp = u16_buf_size / FS_512B;  // read a modulo sector size
    00518
    00519          // Get and eventually alloc the following sector segment of file
    00520          if( !fat_write_file( FS_CLUST_ACT_SEG , u16_nb_write_tmp ))
    00521             return FALSE;
    00522          // Truncate the segment found if more larger than asked size
    00523          if( u16_nb_write_tmp < fs_g_seg.u32_size_or_pos)
    00524          {
    00525             fs_g_seg.u32_size_or_pos = u16_nb_write_tmp;
    00526          }else{
    00527             u16_nb_write_tmp = fs_g_seg.u32_size_or_pos;
    00528          }
    00529
    00530          // Directly data tranfert from buffer to memory
    00531          while( 0 != fs_g_seg.u32_size_or_pos )
    00532          {
    00533             if( CTRL_GOOD != ram_2_memory( fs_g_nav.u8_lun  , fs_g_seg.u32_addr, buffer))
    00534             {
    00535                fs_g_status = FS_ERR_HW;
    00536                return u16_nb_write;
    00537             }
    00538             fs_g_seg.u32_size_or_pos--;
    00539             fs_g_seg.u32_addr++;
    00540             buffer += FS_512B;
    00541          }
    00542          // Translate from sector unit to byte unit
    00543          u16_nb_write_tmp *= FS_512B;
    00544       }
    00545       else
    00546       {
    00547          // The file data can't been directly transfer from buffer to memory, the internal cache must be used
    00548
    00549          // Tranfer and eventually alloc a data sector from internal cache to memory
    00550          if((fs_g_nav_entry.u32_pos_in_file == fs_g_nav_entry.u32_size)
    00551          && (0==u16_pos_in_sector) )
    00552          {
    00553             // Eventually alloc one new sector for the file
    00554             if( !fat_write_file( FS_CLUST_ACT_SEG  , 1 ))
    00555                return FALSE;
    00556             // Update the cache
    00557             fs_gu32_addrsector = fs_g_seg.u32_addr;
    00558             if( !fat_cache_read_sector( FALSE ))         // The memory is not readed because it is a new sector
    00559                return FALSE;
    00560          }else{
    00561             // The sector must existed then alloc no necessary
    00562             if( !fat_write_file( FS_CLUST_ACT_ONE  , 1 ))
    00563                return FALSE;
    00564          }
    00565
    00566          // Flag internal cache modified
    00567          fat_cache_mark_sector_as_dirty();
    00568
    00569          // Compute the number of data to transfer
    00570          u16_nb_write_tmp = FS_512B - u16_pos_in_sector; // The number is limited at sector size
    00571          if( u16_nb_write_tmp > u16_buf_size )
    00572             u16_nb_write_tmp = u16_buf_size;
    00573
    00574          // Tranfer data from buffer to internal cache
    00575          memcpy_ram2ram( &fs_g_sector[ u16_pos_in_sector ], buffer , u16_nb_write_tmp );
    00576          buffer += u16_nb_write_tmp;
    00577       }
    00578       // Update positions
    00579       fs_g_nav_entry.u32_pos_in_file+= u16_nb_write_tmp;
    00580       u16_nb_write                  += u16_nb_write_tmp;
    00581       u16_buf_size                  -= u16_nb_write_tmp;
    00582       // Update file size
    00583       if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size )
    00584       {
    00585          fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
    00586       }
    00587    }
    00588    return u16_nb_write;  // All buffer is writed
    00589 }
    00590
    00591
    00599 Bool  file_putc( U8 u8_byte )
    00600 {
    00601    if( !fat_check_mount_select_open())
    00602       return FALSE;
    00603
    00604    if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
    00605    {
    00606       fs_g_status = FS_ERR_READ_ONLY;
    00607       return FALSE;
    00608    }
    00609
    00610    if( !fat_write_file( FS_CLUST_ACT_ONE  , 1 ))
    00611       return FALSE;
    00612
    00613    // Write the data in the internal cache
    00614    fat_cache_mark_sector_as_dirty();
    00615    fs_g_sector[ fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK ]    = u8_byte;
    00616    fs_g_nav_entry.u32_pos_in_file++;
    00617
    00618    // Update the file size
    00619    if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size )
    00620    {
    00621       fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
    00622    }
    00623    return TRUE;
    00624 }
    00625 #endif  // FS_LEVEL_FEATURES
    00626
    00627
    00632 U32   file_getpos( void )
    00633 {
    00634    if( !fat_check_mount_select_open() )
    00635       return 0;
    00636
    00637    return fs_g_nav_entry.u32_pos_in_file;
    00638 }
    00639
    00640
    00653 Bool  file_seek( U32 u32_pos , U8 u8_whence )
    00654 {
    00655    if( !fat_check_mount_select_open())
    00656       return FALSE;
    00657
    00658    switch(u8_whence)
    00659    {
    00660       case FS_SEEK_CUR_RE:
    00661       if( fs_g_nav_entry.u32_pos_in_file < u32_pos )
    00662       {  // Out of the limit
    00663          fs_g_status = FS_ERR_BAD_POS;
    00664          return FALSE;
    00665       }
    00666       // update the position
    00667       fs_g_nav_entry.u32_pos_in_file -= u32_pos;
    00668       break;
    00669
    00670       case FS_SEEK_SET:
    00671       if( fs_g_nav_entry.u32_size < u32_pos )
    00672       {  // Out of the limit
    00673          fs_g_status = FS_ERR_BAD_POS;
    00674          return FALSE;
    00675       }
    00676       // update the position
    00677       fs_g_nav_entry.u32_pos_in_file = u32_pos;
    00678       break;
    00679
    00680       case FS_SEEK_END:
    00681       if( fs_g_nav_entry.u32_size < u32_pos )
    00682       {  // Out of the limit
    00683          fs_g_status = FS_ERR_BAD_POS;
    00684          return FALSE;
    00685       }
    00686       // update the position
    00687       fs_g_nav_entry.u32_pos_in_file = fs_g_nav_entry.u32_size - u32_pos;
    00688       break;
    00689
    00690       case FS_SEEK_CUR_FW:
    00691       u32_pos += fs_g_nav_entry.u32_pos_in_file;
    00692       if( fs_g_nav_entry.u32_size < u32_pos )
    00693       {  // Out of the limit
    00694          fs_g_status = FS_ERR_BAD_POS;
    00695          return FALSE;
    00696       }
    00697       // update the position
    00698       fs_g_nav_entry.u32_pos_in_file = u32_pos;
    00699       break;
    00700    }
    00701    return TRUE;
    00702 }
    00703
    00704
    00711 U8    file_bof( void )
    00712 {
    00713    if( !fat_check_mount_select_open() )
    00714       return 0xFF;
    00715
    00716    return (0 == fs_g_nav_entry.u32_pos_in_file );
    00717 }
    00718
    00719
    00726 U8    file_eof( void )
    00727 {
    00728    if( !fat_check_mount_select_open() )
    00729       return 0xFF;
    00730    return (fs_g_nav_entry.u32_size <= fs_g_nav_entry.u32_pos_in_file );
    00731 }
    00732
    00733
    00736 void  file_flush( void )
    00737 {
    00738    U8 save_open_mode;
    00739    save_open_mode = fs_g_nav_entry.u8_open_mode;
    00740    file_close();
    00741    fs_g_nav_entry.u8_open_mode = save_open_mode;
    00742 }
    00743
    00744
    00747 void  file_close( void )
    00748 {
    00749    // If a file is opened, then close this one
    00750    if( fat_check_mount_select_open() )
    00751    {
    00752
    00753 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
    00754       if( FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode )
    00755       {
    00756          // Write file information
    00757          if( !fat_read_dir() )
    00758             return;           // error
    00759          fat_write_entry_file();
    00760          fat_cache_flush();   // In case of error during writing data, flush the data before exit function
    00761       }
    00762 #endif  // FS_LEVEL_FEATURES
    00763       Fat_file_close();
    00764    }
    00765 }