📄 fat.c
字号:
Uint16 gl_offset;
Uint16 i;
for (i = fat_dir_list_index + 1, gl_offset = 0; i < fat_dir_list_last; fat_dir_list_index++, i++)
gl_offset += fat_dir_entry_list[i];
if (fat_dseek(gl_offset * DIR_SIZE) == OK)
{
fat_get_dir_entry(&fat_cache.current);
return OK;
}
else
return KO; /* low level error */
}
/*F**************************************************************************
* NAME: fat_seek_entry_record
*----------------------------------------------------------------------------
* PARAMS:
* fat_dir_list_index : # of the fetched entry
*
* return:
* OK: file available
* KO: low level error
*----------------------------------------------------------------------------
* PURPOSE:
* Fetch the selected entry
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_seek_entry_record (void)
{
Uint16 gl_offset = 0;
Uint16 i;
if (dir_is_root)
{
fat_dir_current_sect = fat_ptr_rdir;
}
else
{
fat_dir_current_sect = (((Uint32)(dclusters[0].cluster)) * fat_cluster_size)
+ fat_ptr_data;
}
fat_dir_current_offs = 0; /* reset the global offset */
for (i = 0; i <= fat_dir_list_index; i++)
gl_offset += fat_dir_entry_list[i];
return fat_dseek(gl_offset * DIR_SIZE);
}
/*F**************************************************************************
* NAME: fat_seek_first
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - OK: first file found
* - KO: low level error
*----------------------------------------------------------------------------
* PURPOSE:
* Fetch the first directory info in cache
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_seek_first (void)
{
fat_dir_current_offs = 0; /* reset the global offset */
if (dir_is_root)
{ /* root diretory */
fat_dir_list_index = 0; /* point first root entry */
if (fat_dseek((Int16)(fat_dir_entry_list[0] * DIR_SIZE)) == OK)
{
fat_get_dir_entry(&fat_cache.current);/* update first file info */
return OK;
}
else
{
return KO; /* low level error */
}
}
else
{ /* not root dir */
fat_dir_list_index = 1; /* point ".." entry */
if (fat_dseek((Int16)(fat_dir_entry_list[1] * 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 */
}
}
/*F**************************************************************************
* NAME: fat_goto_subdir
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension to select
*
* return:
* - OK: subdir selected
* - KO: current entry not a directory
* - KO: no file in subdir
* - KO: low level error
*----------------------------------------------------------------------------
* PURPOSE:
* Go to the subdir if current is a directory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* Also called by goto_parentdir() with current info from parent info
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_goto_subdir (Byte id)
{
/* check if current file is a directory */
if ((fat_cache.current.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
{
/* computes the sector address (RELATIVE) */
if (fat_cache.current.start_cluster != 0)
{ /* go to not root dir */
dir_is_root = FALSE; /* not the root dir */
/* get directory allocation table */
fat_get_clusters(&dclusters, MAX_DIR_FRAGMENT_NUMBER);
/* Save last index position for chain cluster */
fat_last_dclust_index = fat_last_clust_index;
/* initialize fat pointers */
fat_dchain_nb_clust = 0;
fat_dchain_index = 0;
fat_dclust_byte_count = 0;
/* computes sector address from allocation table */
fat_dir_current_sect = (((Uint32)(dclusters[0].cluster)) * fat_cluster_size)
+ fat_ptr_data;
}
else
{ /* go to root dir */
return fat_get_root_directory(id);
}
fat_get_dir_file_list(id); /* create list of entries */
fat_dir_list_index = 1; /* point ".." entry */
if (fat_dseek((Int16)(fat_dir_entry_list[1] * 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
return KO; /* current entry is not a dir */
}
/*F**************************************************************************
* NAME: fat_goto_parentdir
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension to select
*
* return:
* status: OK: parent_dir selected
* KO: no parent dir (root)
*----------------------------------------------------------------------------
* PURPOSE:
* Go to the parent directory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* File pointed is sub-dir if parent dir is not root or first file if root
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_goto_parentdir (Byte id)
{
Uint16 temp_cluster;
if (dir_is_root)
{ /* already in root dir */
fat_seek_first(); /* point on first file */
return KO;
}
else
{ /* not in root dir */
temp_cluster = dclusters[0].cluster + 2;/* save cluster info */
fat_cache.current = fat_cache.parent; /* goto the parent directory */
/* issue the equivalent to a cd .. DOS command */
if (fat_goto_subdir(id))
{ /* reselect the dir entry in list */
while (temp_cluster != fat_cache.current.start_cluster)
{
if (fat_goto_next() == KO)
break;
}
if (temp_cluster == fat_cache.current.start_cluster)
return OK;
else
return KO;
}
else
{
return KO;
}
}
}
/*F**************************************************************************
* NAME: fat_fopen
*----------------------------------------------------------------------------
* PARAMS:
* mode: READ: open file for read
* WRITE: open file for write
*
* return:
* - OK: file opened
* - KO: file not opened: - file is empty
* - low level read error
*----------------------------------------------------------------------------
* PURPOSE:
* Open the file in read or write mode
*----------------------------------------------------------------------------
* EXAMPLE:
* if (fat_get_root_directory(FILE_WAV) == OK) // Select first WAV file in root
* {
* fat_fopen(WRITE); // Open this file in WRITE mode
* for (j = 0; j < 10; j++)
* fat_fputc(buff[j]);
* fat_fclose();
* }
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
* For write mode, there must be an entry in the root and entry data must be
* updated.
*****************************************************************************/
bit fat_fopen (bit mode)
{
if (mode == READ)
{
if (fat_cache.current.size.l == 0)
{
return KO; /* file empty */
}
else
{
fat_fclust_byte_count = 0; /* byte 0 of cluster */
/* reset the allocation list variable */
fat_fchain_index = 0;
fat_fchain_nb_clust = 0; /* start on first contiguous cl */
/* get file allocation list */
fat_get_clusters(&fclusters, MAX_FILE_FRAGMENT_NUMBER);
/* seek to the beginning of the file */
fat_open_mode = READ;
return Hard_read_open(fat_ptr_data + ((Uint32)(fclusters[0].cluster)*fat_cluster_size));
}
}
}
/*F**************************************************************************
* NAME: fat_fclose
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Close opened file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fclose (void)
{
if (fat_open_mode == READ)
{
Hard_read_close(); /* close reading */
}
}
/*F**************************************************************************
* NAME: fat_refresh_dir_file_info
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*
*----------------------------------------------------------------------------
* PURPOSE:
* Reconstruct the file directory list and seek to the file pointed by
* fat_dir_list_index
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
*
*****************************************************************************/
void fat_refresh_dir_file_info (Byte id)
{
/* update fat_dir_current_sect with directory starting value */
if (dir_is_root)
{
fat_dir_current_sect = fat_ptr_rdir;
}
else
{
fat_dir_current_sect = (((Uint32)(dclusters[0].cluster)) * fat_cluster_size)
+ fat_ptr_data;
}
fat_get_dir_file_list(id); /* Refresh file list */
fat_seek_entry_record(); /* Re-fetch the entry <-> fat_dir_list_index */
fat_get_dir_entry(&fat_cache.current); /* update current file info */
}
/*F**************************************************************************
* NAME: fat_read_cluster12
*----------------------------------------------------------------------------
* PARAMS:
* init : initialize the parity bit or not
* return:
* FAT12 cluster value
*----------------------------------------------------------------------------
* PURPOSE:
* Read in fat12 file system a cluster value
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Uint16 fat_read_cluster (bit init)
{
static bit fat12_parity;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -