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 #include "conf_explorer.h"
00044 #include "file.h"
00045 #include "navigation.h"
00046 #include LIB_MEM
00047 #include LIB_CTRLACCESS
00048
00049
00050
00051
00053 #if __GNUC__ && __AVR32__
00054 __attribute__((__aligned__(4)))
00055 #elif __ICCAVR32__
00056 #pragma data_alignment = 4
00057 #endif
00058 extern _MEM_TYPE_SLOW_ U8 fs_g_sector[ FS_CACHE_SIZE ];
00059
00060 static void file_load_segment_value( Fs_file_segment _MEM_TYPE_SLOW_ *segment );
00061
00062
00063
00069 Bool file_ispresent( void )
00070 {
00071 if( !fat_check_mount_select() )
00072 return FALSE;
00073 return fat_check_is_file();
00074 }
00075
00076
00089 Bool file_open( U8 fopen_mode )
00090 {
00091 if( !fat_check_mount_select_noopen())
00092 return FALSE;
00093
00094 if( !fat_check_is_file())
00095 return FALSE;
00096
00097 if(FOPEN_WRITE_ACCESS & fopen_mode)
00098 {
00099 if( !fat_check_nav_access_file( TRUE ) )
00100 return FALSE;
00101 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
00102 if (FS_ATTR_READ_ONLY & fs_g_nav_entry.u8_attr)
00103 {
00104 fs_g_status = FS_ERR_READ_ONLY;
00105 return FALSE;
00106 }
00107 if( mem_wr_protect( fs_g_nav.u8_lun ))
00108 {
00109 fs_g_status = FS_LUN_WP;
00110 return FALSE;
00111 }
00112 #else
00113 fs_g_status = FS_ERR_MODE_NOAVIALABLE;
00114 return FALSE;
00115 #endif // FS_LEVEL_FEATURES
00116 }
00117 else
00118 {
00119 if( !fat_check_nav_access_file( FALSE ) )
00120 return FALSE;
00121 }
00122
00123 if(FOPEN_CLEAR_SIZE & fopen_mode)
00124 {
00125 fs_g_nav_entry.u32_size = 0;
00126 }
00127 if(FOPEN_CLEAR_PTR & fopen_mode)
00128 {
00129 fs_g_nav_entry.u32_pos_in_file = 0;
00130 }
00131 else
00132 {
00133 fs_g_nav_entry.u32_pos_in_file = fs_g_nav_entry.u32_size;
00134 }
00135 fs_g_nav_entry.u8_open_mode = fopen_mode;
00136 return TRUE;
00137 }
00138
00139
00144 static void file_load_segment_value( Fs_file_segment _MEM_TYPE_SLOW_ *segment )
00145 {
00146 segment->u8_lun = fs_g_nav.u8_lun;
00147 segment->u32_addr = fs_g_seg.u32_addr;
00148 segment->u16_size = fs_g_seg.u32_size_or_pos;
00149 }
00150
00151
00169 Bool file_read( Fs_file_segment _MEM_TYPE_SLOW_ *segment )
00170 {
00171 U8 u8_nb_sector_truncated;
00172
00173 if( !fat_check_mount_select_open())
00174 return FALSE;
00175
00176 if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode))
00177 {
00178 fs_g_status = FS_ERR_WRITE_ONLY;
00179 return FALSE;
00180 }
00181
00182 if ( file_eof() )
00183 {
00184
00185 fs_g_status = FS_ERR_EOF;
00186 return FALSE;
00187 }
00188
00189 if( !fat_read_file(FS_CLUST_ACT_SEG))
00190 {
00191 if( FS_ERR_OUT_LIST == fs_g_status )
00192 fs_g_status = FS_ERR_EOF;
00193 return FALSE;
00194 }
00195
00196 if( (segment->u16_size != 0)
00197 && (segment->u16_size < fs_g_seg.u32_size_or_pos) )
00198 {
00199 u8_nb_sector_truncated = fs_g_seg.u32_size_or_pos - segment->u16_size;
00200 fs_g_seg.u32_size_or_pos = segment->u16_size ;
00201 }else{
00202 u8_nb_sector_truncated = 0;
00203 }
00204
00205
00206 fs_g_nav_entry.u32_pos_in_file += (U32)fs_g_seg.u32_size_or_pos * FS_512B;
00207 if( fs_g_nav_entry.u32_size < fs_g_nav_entry.u32_pos_in_file )
00208 {
00209
00210
00211
00212 U8 u8_nb_sector_not_used;
00213
00214
00215
00216 u8_nb_sector_not_used = LSB1( fs_g_nav_entry.u32_size ) >> (FS_512B_SHIFT_BIT-8);
00217 if( 0 != (fs_g_nav_entry.u32_size & FS_512B_MASK) )
00218 {
00219 u8_nb_sector_not_used++;
00220 }
00221
00222
00223 u8_nb_sector_not_used = fs_g_nav.u8_BPB_SecPerClus - (u8_nb_sector_not_used % fs_g_nav.u8_BPB_SecPerClus);
00224
00225 if( u8_nb_sector_not_used == fs_g_nav.u8_BPB_SecPerClus )
00226 u8_nb_sector_not_used = 0;
00227
00228
00229 u8_nb_sector_not_used -= u8_nb_sector_truncated;
00230 fs_g_seg.u32_size_or_pos -= u8_nb_sector_not_used;
00231 fs_g_nav_entry.u32_pos_in_file -= ((U16)u8_nb_sector_not_used) << FS_512B_SHIFT_BIT;
00232 }
00233 file_load_segment_value( segment );
00234 return TRUE;
00235 }
00236
00237
00246 U16 file_read_buf( U8 _MEM_TYPE_SLOW_ *buffer , U16 u16_buf_size )
00247 {
00248 _MEM_TYPE_FAST_ U16 u16_nb_read_tmp;
00249 _MEM_TYPE_FAST_ U16 u16_nb_read;
00250 _MEM_TYPE_FAST_ U16 u16_pos_in_sector;
00251 _MEM_TYPE_FAST_ U32 u32_byte_remaining;
00252
00253 if( !fat_check_mount_select_open())
00254 return FALSE;
00255
00256 if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode))
00257 {
00258 fs_g_status = FS_ERR_WRITE_ONLY;
00259 return FALSE;
00260 }
00261
00262 u16_nb_read = 0;
00263
00264 while( 0 != u16_buf_size )
00265 {
00266 if ( file_eof() )
00267 {
00268 fs_g_status = FS_ERR_EOF;
00269 return u16_nb_read;
00270 }
00271 u32_byte_remaining = fs_g_nav_entry.u32_size-fs_g_nav_entry.u32_pos_in_file;
00272 u16_pos_in_sector = fs_g_nav_entry.u32_pos_in_file % FS_512B;
00273
00274 if( (0== u16_pos_in_sector)
00275 && (FS_512B <= u32_byte_remaining)
00276 && (FS_512B <= u16_buf_size)
00277 #if __GNUC__ && __AVR32__ || __ICCAVR32__
00278 && (Test_align((U32)buffer, sizeof(U32)))
00279 #endif
00280 )
00281 {
00282
00283 if( u16_buf_size <= u32_byte_remaining)
00284 {
00285 u16_nb_read_tmp = u16_buf_size;
00286 }else{
00287 u16_nb_read_tmp = u32_byte_remaining;
00288 }
00289 u16_nb_read_tmp = u16_nb_read_tmp / FS_512B;
00290
00291
00292 if( !fat_read_file(FS_CLUST_ACT_SEG))
00293 {
00294 if( FS_ERR_OUT_LIST == fs_g_status )
00295 fs_g_status = FS_ERR_EOF;
00296 return u16_nb_read;
00297 }
00298
00299 if( u16_nb_read_tmp > fs_g_seg.u32_size_or_pos )
00300 {
00301 u16_nb_read_tmp = fs_g_seg.u32_size_or_pos;
00302 }else{
00303 fs_g_seg.u32_size_or_pos = u16_nb_read_tmp;
00304 }
00305
00306
00307 while( 0 != fs_g_seg.u32_size_or_pos )
00308 {
00309 if( CTRL_GOOD != memory_2_ram( fs_g_nav.u8_lun , fs_g_seg.u32_addr, buffer))
00310 {
00311 fs_g_status = FS_ERR_HW;
00312 return u16_nb_read;
00313 }
00314 fs_g_seg.u32_size_or_pos--;
00315 fs_g_seg.u32_addr++;
00316 buffer += FS_512B;
00317 }
00318
00319 u16_nb_read_tmp *= FS_512B;
00320 }
00321 else
00322 {
00323
00324
00325
00326 if( !fat_read_file( FS_CLUST_ACT_ONE ))
00327 {
00328 if( FS_ERR_OUT_LIST == fs_g_status )
00329 {
00330 fs_g_status = FS_ERR_EOF;
00331 }
00332 return u16_nb_read;
00333 }
00334
00335
00336 u16_nb_read_tmp = FS_512B - u16_pos_in_sector;
00337 if( u16_nb_read_tmp > u32_byte_remaining )
00338 u16_nb_read_tmp = u32_byte_remaining;
00339 if( u16_nb_read_tmp > u16_buf_size )
00340 u16_nb_read_tmp = u16_buf_size;
00341
00342
00343 memcpy_ram2ram( buffer , &fs_g_sector[ u16_pos_in_sector ], u16_nb_read_tmp );
00344 buffer += u16_nb_read_tmp;
00345 }
00346
00347 fs_g_nav_entry.u32_pos_in_file += u16_nb_read_tmp;
00348 u16_nb_read += u16_nb_read_tmp;
00349 u16_buf_size -= u16_nb_read_tmp;
00350 }
00351 return u16_nb_read;
00352 }
00353
00354
00360 U16 file_getc( void )
00361 {
00362 U16 u16_byte;
00363
00364 while(1)
00365 {
00366 if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode))
00367 {
00368 fs_g_status = FS_ERR_WRITE_ONLY;
00369 break;
00370 }
00371 if( fs_g_nav_entry.u32_size <= fs_g_nav_entry.u32_pos_in_file )
00372 {
00373 fs_g_status = FS_ERR_EOF;
00374 break;
00375 }
00376
00377 if( !fat_read_file( FS_CLUST_ACT_ONE ))
00378 {
00379 if( FS_ERR_OUT_LIST == fs_g_status )
00380 {
00381 fs_g_status = FS_ERR_EOF;
00382 }
00383 break;
00384 }
00385
00386 u16_byte = fs_g_sector[ fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK ];
00387 fs_g_nav_entry.u32_pos_in_file++;
00388 return u16_byte;
00389 }
00390 return FS_EOF;
00391 }
00392
00393
00394 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
00412 Bool file_write( Fs_file_segment _MEM_TYPE_SLOW_ *segment )
00413 {
00414 if( !fat_check_mount_select_open())
00415 return FALSE;
00416
00417 if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
00418 {
00419 fs_g_status = FS_ERR_READ_ONLY;
00420 return FALSE;
00421 }
00422
00423 if( !fat_write_file( FS_CLUST_ACT_SEG , segment->u16_size ))
00424 return FALSE;
00425
00426
00427 if( (segment->u16_size != 0)
00428 && (segment->u16_size < fs_g_seg.u32_size_or_pos) )
00429 {
00430 fs_g_seg.u32_size_or_pos = segment->u16_size ;
00431 }
00432
00433
00434 fs_g_nav_entry.u32_pos_in_file += ((U32)fs_g_seg.u32_size_or_pos * FS_512B);
00435
00436
00437 if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size )
00438 {
00439 fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
00440 }
00441 file_load_segment_value( segment );
00442 return TRUE;
00443 }
00444
00445
00457 Bool file_set_eof( void )
00458 {
00459 if( !fat_check_mount_select_open())
00460 return FALSE;
00461
00462 if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
00463 {
00464 fs_g_status = FS_ERR_READ_ONLY;
00465 return FALSE;
00466 }
00467
00468
00469 fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
00470
00471 if( !fat_read_file( FS_CLUST_ACT_CLR ))
00472 return FALSE;
00473
00474 return fat_cache_flush();
00475 }
00476
00477
00486 U16 file_write_buf( U8 _MEM_TYPE_SLOW_ *buffer , U16 u16_buf_size )
00487 {
00488 _MEM_TYPE_FAST_ U16 u16_nb_write_tmp;
00489 _MEM_TYPE_FAST_ U16 u16_nb_write;
00490 _MEM_TYPE_FAST_ U16 u16_pos_in_sector;
00491
00492 if( !fat_check_mount_select_open())
00493 return FALSE;
00494
00495 if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
00496 {
00497 fs_g_status = FS_ERR_READ_ONLY;
00498 return FALSE;
00499 }
00500
00501 u16_nb_write = 0;
00502
00503 while( 0 != u16_buf_size )
00504 {
00505
00506 u16_pos_in_sector = fs_g_nav_entry.u32_pos_in_file % FS_512B;
00507 if( (0== u16_pos_in_sector)
00508 && (FS_512B <= u16_buf_size)
00509 #if __GNUC__ && __AVR32__ || __ICCAVR32__
00510 && (Test_align((U32)buffer, sizeof(U32)))
00511 #endif
00512 )
00513 {
00514 u16_nb_write_tmp = u16_buf_size / FS_512B;
00515
00516
00517 if( !fat_write_file( FS_CLUST_ACT_SEG , u16_nb_write_tmp ))
00518 return FALSE;
00519
00520 if( u16_nb_write_tmp < fs_g_seg.u32_size_or_pos)
00521 {
00522 fs_g_seg.u32_size_or_pos = u16_nb_write_tmp;
00523 }else{
00524 u16_nb_write_tmp = fs_g_seg.u32_size_or_pos;
00525 }
00526
00527
00528 while( 0 != fs_g_seg.u32_size_or_pos )
00529 {
00530 if( CTRL_GOOD != ram_2_memory( fs_g_nav.u8_lun , fs_g_seg.u32_addr, buffer))
00531 {
00532 fs_g_status = FS_ERR_HW;
00533 return u16_nb_write;
00534 }
00535 fs_g_seg.u32_size_or_pos--;
00536 fs_g_seg.u32_addr++;
00537 buffer += FS_512B;
00538 }
00539
00540 u16_nb_write_tmp *= FS_512B;
00541 }
00542 else
00543 {
00544
00545
00546
00547 if((fs_g_nav_entry.u32_pos_in_file == fs_g_nav_entry.u32_size)
00548 && (0==u16_pos_in_sector) )
00549 {
00550
00551 if( !fat_write_file( FS_CLUST_ACT_SEG , 1 ))
00552 return FALSE;
00553
00554 fs_gu32_addrsector = fs_g_seg.u32_addr;
00555 if( !fat_cache_read_sector( FALSE ))
00556 return FALSE;
00557 }else{
00558
00559 if( !fat_write_file( FS_CLUST_ACT_ONE , 1 ))
00560 return FALSE;
00561 }
00562
00563
00564 fat_cache_mark_sector_as_dirty();
00565
00566
00567 u16_nb_write_tmp = FS_512B - u16_pos_in_sector;
00568 if( u16_nb_write_tmp > u16_buf_size )
00569 u16_nb_write_tmp = u16_buf_size;
00570
00571
00572 memcpy_ram2ram( &fs_g_sector[ u16_pos_in_sector ], buffer , u16_nb_write_tmp );
00573 buffer += u16_nb_write_tmp;
00574 }
00575
00576 fs_g_nav_entry.u32_pos_in_file+= u16_nb_write_tmp;
00577 u16_nb_write += u16_nb_write_tmp;
00578 u16_buf_size -= u16_nb_write_tmp;
00579
00580 if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size )
00581 {
00582 fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
00583 }
00584 }
00585 return u16_nb_write;
00586 }
00587
00588
00596 Bool file_putc( U8 u8_byte )
00597 {
00598 if( !fat_check_mount_select_open())
00599 return FALSE;
00600
00601 if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
00602 {
00603 fs_g_status = FS_ERR_READ_ONLY;
00604 return FALSE;
00605 }
00606
00607 if( !fat_write_file( FS_CLUST_ACT_ONE , 1 ))
00608 return FALSE;
00609
00610
00611 fat_cache_mark_sector_as_dirty();
00612 fs_g_sector[ fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK ] = u8_byte;
00613 fs_g_nav_entry.u32_pos_in_file++;
00614
00615
00616 if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size )
00617 {
00618 fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
00619 }
00620 return TRUE;
00621 }
00622 #endif // FS_LEVEL_FEATURES
00623
00624
00629 U32 file_getpos( void )
00630 {
00631 if( !fat_check_mount_select_open() )
00632 return 0;
00633
00634 return fs_g_nav_entry.u32_pos_in_file;
00635 }
00636
00637
00650 Bool file_seek( U32 u32_pos , U8 u8_whence )
00651 {
00652 if( !fat_check_mount_select_open())
00653 return FALSE;
00654
00655 switch(u8_whence)
00656 {
00657 case FS_SEEK_CUR_RE:
00658 if( fs_g_nav_entry.u32_pos_in_file < u32_pos )
00659 {
00660 fs_g_status = FS_ERR_BAD_POS;
00661 return FALSE;
00662 }
00663
00664 fs_g_nav_entry.u32_pos_in_file -= u32_pos;
00665 break;
00666
00667 case FS_SEEK_SET:
00668 if( fs_g_nav_entry.u32_size < u32_pos )
00669 {
00670 fs_g_status = FS_ERR_BAD_POS;
00671 return FALSE;
00672 }
00673
00674 fs_g_nav_entry.u32_pos_in_file = u32_pos;
00675 break;
00676
00677 case FS_SEEK_END:
00678 if( fs_g_nav_entry.u32_size < u32_pos )
00679 {
00680 fs_g_status = FS_ERR_BAD_POS;
00681 return FALSE;
00682 }
00683
00684 fs_g_nav_entry.u32_pos_in_file = fs_g_nav_entry.u32_size - u32_pos;
00685 break;
00686
00687 case FS_SEEK_CUR_FW:
00688 u32_pos += fs_g_nav_entry.u32_pos_in_file;
00689 if( fs_g_nav_entry.u32_size < u32_pos )
00690 {
00691 fs_g_status = FS_ERR_BAD_POS;
00692 return FALSE;
00693 }
00694
00695 fs_g_nav_entry.u32_pos_in_file = u32_pos;
00696 break;
00697 }
00698 return TRUE;
00699 }
00700
00701
00708 U8 file_bof( void )
00709 {
00710 if( !fat_check_mount_select_open() )
00711 return 0xFF;
00712
00713 return (0 == fs_g_nav_entry.u32_pos_in_file );
00714 }
00715
00716
00723 U8 file_eof( void )
00724 {
00725 if( !fat_check_mount_select_open() )
00726 return 0xFF;
00727 return (fs_g_nav_entry.u32_size <= fs_g_nav_entry.u32_pos_in_file );
00728 }
00729
00730
00733 void file_flush( void )
00734 {
00735 U8 save_open_mode;
00736 save_open_mode = fs_g_nav_entry.u8_open_mode;
00737 file_close();
00738 fs_g_nav_entry.u8_open_mode = save_open_mode;
00739 }
00740
00741
00744 void file_close( void )
00745 {
00746
00747 if( fat_check_mount_select_open() )
00748 {
00749
00750 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
00751 if( FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode )
00752 {
00753
00754 if( !fat_read_dir() )
00755 return;
00756 fat_write_entry_file();
00757 fat_cache_flush();
00758 }
00759 #endif // FS_LEVEL_FEATURES
00760 Fat_file_close();
00761 }
00762 }