00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "conf_explorer.h"
00047 #include "file.h"
00048 #include "navigation.h"
00049 #include LIB_MEM
00050 #include LIB_CTRLACCESS
00051
00052
00053
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;
00108 return FALSE;
00109 }
00110 if( mem_wr_protect( fs_g_nav.u8_lun ))
00111 {
00112 fs_g_status = FS_LUN_WP;
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;
00129 }
00130 if(FOPEN_CLEAR_PTR & fopen_mode)
00131 {
00132 fs_g_nav_entry.u32_pos_in_file = 0;
00133 }
00134 else
00135 {
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
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;
00196 return FALSE;
00197 }
00198
00199 if( (segment->u16_size != 0)
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
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
00213
00214
00215 U8 u8_nb_sector_not_used;
00216
00217
00218
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 {
00222 u8_nb_sector_not_used++;
00223 }
00224
00225
00226 u8_nb_sector_not_used = fs_g_nav.u8_BPB_SecPerClus - (u8_nb_sector_not_used % fs_g_nav.u8_BPB_SecPerClus);
00227
00228 if( u8_nb_sector_not_used == fs_g_nav.u8_BPB_SecPerClus )
00229 u8_nb_sector_not_used = 0;
00230
00231
00232 u8_nb_sector_not_used -= u8_nb_sector_truncated;
00233 fs_g_seg.u32_size_or_pos -= u8_nb_sector_not_used;
00234 fs_g_nav_entry.u32_pos_in_file -= ((U16)u8_nb_sector_not_used) << FS_512B_SHIFT_BIT;
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;
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
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;
00293
00294
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;
00299 return u16_nb_read;
00300 }
00301
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
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
00322 u16_nb_read_tmp *= FS_512B;
00323 }
00324 else
00325 {
00326
00327
00328
00329 if( !fat_read_file( FS_CLUST_ACT_ONE ))
00330 {
00331 if( FS_ERR_OUT_LIST == fs_g_status )
00332 {
00333 fs_g_status = FS_ERR_EOF;
00334 }
00335 return u16_nb_read;
00336 }
00337
00338
00339 u16_nb_read_tmp = FS_512B - u16_pos_in_sector;
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
00346 memcpy_ram2ram( buffer , &fs_g_sector[ u16_pos_in_sector ], u16_nb_read_tmp );
00347 buffer += u16_nb_read_tmp;
00348 }
00349
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;
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 {
00384 fs_g_status = FS_ERR_EOF;
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;
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
00430 if( (segment->u16_size != 0)
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
00437 fs_g_nav_entry.u32_pos_in_file += ((U32)fs_g_seg.u32_size_or_pos * FS_512B);
00438
00439
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
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
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;
00518
00519
00520 if( !fat_write_file( FS_CLUST_ACT_SEG , u16_nb_write_tmp ))
00521 return FALSE;
00522
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
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
00543 u16_nb_write_tmp *= FS_512B;
00544 }
00545 else
00546 {
00547
00548
00549
00550 if((fs_g_nav_entry.u32_pos_in_file == fs_g_nav_entry.u32_size)
00551 && (0==u16_pos_in_sector) )
00552 {
00553
00554 if( !fat_write_file( FS_CLUST_ACT_SEG , 1 ))
00555 return FALSE;
00556
00557 fs_gu32_addrsector = fs_g_seg.u32_addr;
00558 if( !fat_cache_read_sector( FALSE ))
00559 return FALSE;
00560 }else{
00561
00562 if( !fat_write_file( FS_CLUST_ACT_ONE , 1 ))
00563 return FALSE;
00564 }
00565
00566
00567 fat_cache_mark_sector_as_dirty();
00568
00569
00570 u16_nb_write_tmp = FS_512B - u16_pos_in_sector;
00571 if( u16_nb_write_tmp > u16_buf_size )
00572 u16_nb_write_tmp = u16_buf_size;
00573
00574
00575 memcpy_ram2ram( &fs_g_sector[ u16_pos_in_sector ], buffer , u16_nb_write_tmp );
00576 buffer += u16_nb_write_tmp;
00577 }
00578
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
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;
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
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
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 {
00663 fs_g_status = FS_ERR_BAD_POS;
00664 return FALSE;
00665 }
00666
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 {
00673 fs_g_status = FS_ERR_BAD_POS;
00674 return FALSE;
00675 }
00676
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 {
00683 fs_g_status = FS_ERR_BAD_POS;
00684 return FALSE;
00685 }
00686
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 {
00694 fs_g_status = FS_ERR_BAD_POS;
00695 return FALSE;
00696 }
00697
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
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
00757 if( !fat_read_dir() )
00758 return;
00759 fat_write_entry_file();
00760 fat_cache_flush();
00761 }
00762 #endif // FS_LEVEL_FEATURES
00763 Fat_file_close();
00764 }
00765 }