📄 fat_file.c
字号:
fat_dchain_nb_clust++; /* one more cluster read */
}
//fat_dir_current_sect = fat_ptr_data + ((Uint32)(next_cluster) * fat_cluster_size);
//phy_read_open(fat_dir_current_sect);
}
fat_dclust_byte_count += fat_sector_size; /* one more byte read */
phy_read_sector();
}
/*F**************************************************************************
* NAME: fat_dir_seek
*----------------------------------------------------------------------------
* PARAMS:
* offset: offset to current position in signed word value
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Seek from the current position to a new offset computing relative
* poisition +/- scan size limited to a 16 bit offset
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* We consider here that the seek size is minor to the cluster size !!!
* if you want to do a more than a cluster seek, issue two successive
* dseek commands
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_dir_seek (Uint32 offset)
{
Uint16 nb_sect; /* number of sectors to seek */
Uint32 next_cluster; /* the possible next cluster to load */
Uint16 target_cluster; /* the cluster to reach */
Uint16 i;
// fat_dir_current_offs = 0;
fat_dir_current_offs = offset; /* Calculate the absolute byte pos */
nb_sect = (Uint16)((fat_dir_current_offs) / fat_sector_size);
if(fat_type_id != FAT_IS_32)
fat_dir_current_sect = fat_ptr_rdir + nb_sect;
fat_dir_sector_offset = fat_dir_current_offs % (((Uint32)fat_sector_size) * fat_cluster_size);
fat_dclust_byte_count = fat_dir_sector_offset; //offset in a cluster
fat_dir_sector_offset %= fat_sector_size;
if ((dir_is_root == FALSE) || (fat_type_id == FAT_IS_32)) // Sub-directory /
{
// Find the # cluster
target_cluster = (nb_sect / fat_cluster_size);
fat_dchain_index = 0;
if(fat_type_id == FAT_IS_32)
next_cluster = dclusters[fat_dchain_index].cluster.l;
else
next_cluster = dclusters[fat_dchain_index].cluster.w[0]; ///////w[1]//////////////////////
fat_dchain_nb_clust = 1;
for (i = 0; i < target_cluster; i++)
{
if (dclusters[fat_dchain_index].number <= fat_dchain_nb_clust)
{ // new fragment
fat_dchain_index++;
fat_dchain_nb_clust = 1;
if(fat_type_id == FAT_IS_32)
next_cluster = dclusters[fat_dchain_index].cluster.l;
else
next_cluster = dclusters[fat_dchain_index].cluster.w[0];///////w[1]//////////////////////
}
else
{ // not new fragment
//next_cluster = dclusters[fat_dchain_index].cluster + fat_dchain_nb_clust;
if(fat_type_id == FAT_IS_32)
next_cluster = dclusters[fat_dchain_index].cluster.l;
else
next_cluster = dclusters[fat_dchain_index].cluster.w[0];///////w[1]//////////////////////
next_cluster += fat_dchain_nb_clust;
fat_dchain_nb_clust++;
}
}
fat_dir_current_sect = (((Uint32)(next_cluster) * fat_cluster_size)
+ fat_ptr_data + (nb_sect % fat_cluster_size));
}
phy_read_open(fat_dir_current_sect);
return OK;
}
/*F**************************************************************************
* NAME: fat_get_dir
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension or directory to select
*
* return:
* - OK: file available
* - KO: no requested file found
* - KO: low_level memory error
*----------------------------------------------------------------------------
* PURPOSE:
* Select first available file/dir in current diretory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* Fill all the cache information for the first time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_get_dir(Uint32 id)
{
/* select first dir entry */
fat_dclust_byte_count = 0;
fat_dir_sector_offset = 0;
fat_global_id = id;
fat_scan_dir(TRUE);
if(((id & FILE_DIR) == FILE_DIR)&&(dir_is_root == FALSE))
{
if(fat_dir_list_last <= 2)
return KO;
fat_dir_list_index = 1; /* point ".." entry */
if (fat_dir_seek(DIR_SIZE) == OK)
{
fat_get_dir_entry(&fat_cache.parent); /* update parent dir info */
return fat_goto_next(); /* update first file info */
}
else
{
return KO;/* low level error */
}
}
else
{
if(fat_dir_list_last == 0)
return KO;
fat_dir_list_index = 0; /* point on first root entry */
fat_scan_dir(FALSE);
/* extract info from table */
if (fat_dir_seek(((Uint32)fat_dir_all_count) * DIR_SIZE) == OK)
{
fat_get_dir_entry(&fat_cache.current); /* update current file info */
if(dir_is_root == TRUE)
{
/* parent dir is also root */
fat_cache.parent.start_cluster.l = 0;
fat_cache.parent.attributes = ATTR_ROOT_DIR; /* mark as root dir */
}
return OK;
}
}
return KO; /* low level error */
}
/*F**************************************************************************
* NAME: fat_scan_dir
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension to select
* return: none
*----------------------------------------------------------------------------
* PURPOSE:
* Construct the file directory list
*----------------------------------------------------------------------------
* NOTE:
* The value are relative position with the previous file.
* Call to this function assume that the dir fragment chain has been created
*----------------------------------------------------------------------------
* REQUIREMENTS:
* Maximum of 256 entries between 2 authorized file (id extension)
* because the relative position is stored on one byte.
* To allow more than 256 entries (-> 32768), change type of
* fat_dir_entry_list[] from Byte to Uint16 (no overflow management)
* and change MAX_DIRECTORY_GAP_FILE from 255 to 32767
*****************************************************************************/
void fat_scan_dir(Byte flag)
{
Uint16 counter_entry; /* entry counter: 0..MAX_DIRECTORY_FILE */
//data Uint16 entry_pos; /* relative entry position */
//data Uint16 entry_pos_saved; /* used when the file is not the id extension */
Byte i;
Uint16 num=0;
Uint16 nb_cluster;
Uint16 counter_dir;
Byte ready;
// bit del_exist;
Uint16 j;
Uint16 dir_count;
Uint16 dir_offset;
// del_exist = 0;
// index = 0;
ready = 0;
counter_entry = 0;
dir_count = 0;
if((dir_is_root == TRUE) && (fat_type_id != FAT_IS_32))
{
phy_read_open(fat_ptr_rdir);
counter_dir = fat_root_entries;
}
else
{
nb_cluster = 0;
fat_dclust_byte_count = 0;
fat_dchain_nb_clust = 0;
fat_dchain_index = 0;
for(i=0;i<MAX_DIR_FRAGMENT_NUMBER;i++)
{
if(dclusters[i].number == 0)
{
nb_cluster++;
break;
}
else
{
nb_cluster = nb_cluster + dclusters[i].number;
}
}
counter_dir = ((Uint32)nb_cluster * fat_cluster_size * fat_sector_size) / 32;
}
do /* scan all entries */
{
if ((dir_is_root == TRUE) && (fat_type_id != FAT_IS_32))
{
if(num%fat_sector_size==0)
{
phy_read_sector();
num=0;
}
}
else
{ /* subdir can be fragmented -> dgetc() */
if(num % fat_sector_size == 0 )
{
fat_dgetsector();
num=0;
}
}
j = num;
num += DIR_SIZE;
if((gl_buffer[0+j] != FILE_DELETED) && (gl_buffer[0+j] != FILE_NOT_EXIST))
{
dir_count++;
// index++;
dir_offset = counter_entry;
while (gl_buffer[11+j] == ATTR_LFN_ENTRY) /* LFN entry ? */
{ /* then read all the LFN entry */
if (dir_is_root == TRUE)
{ /* root dir is linear */
if(num%fat_sector_size==0)
{
phy_read_sector();
num = 0;
}
}
else
{ /* subdir can be fragmented -> dgetc() */
if(num % fat_sector_size == 0 )
{
fat_dgetsector();
num=0;
}
}
j=num;
num += DIR_SIZE;
counter_entry++;
}
/* filter on the file type */
fat_cache.current.attributes = gl_buffer[11+j];
ext[0] = gl_buffer[8+j];
ext[1] = gl_buffer[9+j];
ext[2] = gl_buffer[10+j];
if ((fat_check_ext() & fat_global_id) == FILE_XXX)
{ /* Don't valid the entry */
dir_count--;
}
if((flag == 0)&&(ready == 0))
{
if(dir_count == (fat_dir_list_index + 1))
{
fat_dir_all_count = dir_offset;//counter_entry;
ready = 1;
}
}
}
counter_entry++;
if ((gl_buffer[0+j] == FILE_NOT_EXIST) || (counter_dir == counter_entry))
break;
}while(1);
fat_dir_list_last = dir_count;
if(flag == 1)
{
fat_dir_all_count = counter_entry;
if(gl_buffer[0+j] == FILE_NOT_EXIST)
fat_dir_all_count--;
if(fat_dir_list_last == 0)
fat_no_file = 1;
else
fat_no_file = 0;
}
phy_read_close();
}
/*F**************************************************************************
* NAME: fat_check_ext
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Return the type of the file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Uint32 fat_check_ext (void)
{
// char ext_bak[3];
if ((fat_cache.current.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
{
return FILE_DIR;
}
if ((ext[0] == 'M') &&
(ext[1] == 'P') &&
(ext[2] == '3'))
{
return FILE_MP3;
}
if(((ext[0] == 'W')&&
(ext[1] == 'M')&&
(ext[2] == 'A'))||
((ext[0] == 'A')&&
(ext[1] == 'S')&&
(ext[2] == 'F'))||
((ext[0] == 'W')&&
(ext[1] == 'M')&&
(ext[2] == 'V')))
{
return FILE_WMA;
}
if((ext[0] == 'W')&&
(ext[1] == 'A')&&
(ext[2] == 'V'))
{
return FILE_WAV;
}
if ((ext[0] == 'M') &&
(ext[1] == 'I') &&
(ext[2] == 'D'))
{
return FILE_MID;
}
if ((ext[0] == 'A') &&
(ext[1] == 'A') &&
(ext[2] == 'C'))
{
return FILE_AAC;
}
if ((ext[0] == 'O') &&
(ext[1] == 'G') &&
(ext[2] == 'G'))
{
return FILE_OGG;
}
return FILE_XXX;
}
void fat_count_sector(void)
{
if(fat_buf_count == fat_sector_size)
{
fat_buf_count=0;
phy_read_sector();
}
}
/*F**************************************************************************
* NAME: fat_get_clusters
*----------------------------------------------------------------------------
* PARAMS:
* chain: allocation list address
* nb_frag: maximum number of fragment
*
* return:
* - OK: allocation done
* - KO: allocation done but truncated: file too much fragmented
*----------------------------------------------------------------------------
* PURPOSE:
* Prepare a list of the file clusters:
* chain[n].cluster contains the starting cluster number of a fragment
* chain[n].number contains the number of contiguous clusters in fragment
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* File cluster list is limited by the nb_frag parameter.
* If memory is too much fragmented, file may not be fully played.
* Last list item always has single cluster
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
#if COMPILE_FAT_16 == TRUE
byte fat16_get_clusters (fat_st_clust_chain *chain, Byte nb_frag)
{
Byte index;
/* index in chain */
Uint16 new_cluster;
Uint16 old_cluster;
nb_frag = nb_frag - 1; /* set limit (index start at 0) */
/* build the first entry of the allocation list */
chain[0].number = 1;
chain[0].cluster.l = fat_cache.current.start_cluster.l - 2; /* 2 = 1st cluster */
old_cluster = fat_cache.current.start_cluster.l;
index = 0;
fat_buf_count = (old_cluster % (fat_sector_size >> 1)) << 1;
phy_read_open(fat_ptr_fats + (old_cluster / (fat_sector_size >> 1)));
/* read first entry */
phy_read_sector();
//((Byte*)&new_cluster)[1] = gl_buffer[fat_buf_count];
//((Byte*)&new_cluster)[0] = gl_buffer[fat_buf_count + 1];
new_cluster = fat_U8_to_U16_LH(gl_buffer[fat_buf_count], gl_buffer[fat_buf_count + 1]);
while (new_cluster != LAST_CLUSTER16) /* loop until last cluster found */
{
if ((new_cluster == (old_cluster + 1)) && (chain[index].number != MAX_CL_PER_FRAG))
{ /* contiguous cluster up to 255 */
chain[index].number++;
fat_buf_count = fat_buf_count + 2;
fat_count_sector();
}
else
{ /* compute fragmentation */
index++;
chain[index].number = 1;
chain[index].cluster.w[0] = new_cluster - 2; /* 2 = 1st cluster */ ///////w[1]//////////////////////
fat_buf_count=(new_cluster % (fat_sector_size >> 1)) << 1;
phy_read_close();
phy_read_open(fat_ptr_fats + (new_cluster / (fat_sector_size >> 1)));
phy_read_sector();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -