⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 这是atmel公司的89C51SND1C的mp3源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   As this function is called very often it must be short and optimized
*   in execution time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fputc (Byte d)
{
  /* check if we are at the end of a cluster */
  if ((((Byte*)&fat_file_byte_counter)[3] == 0x00) &&
      ((((Byte*)&fat_file_byte_counter)[2] & fat_cluster_mask) == 0x00))
  {
    /* extract if necessary the next cluster from the allocation list */
    if (clusters.number[fat_chain_index] == fat_chain_cluster)
    { /* new fragment */
      fat_chain_index++;
      fat_chain_cluster = 1;
      Hard_write_open(fat_ptr_data + ((Uint32)(clusters.cluster[fat_chain_index]) * fat_cluster_size));
    }
    else
    { /* no new fragment */
      fat_chain_cluster++;                /* one more cluster read */
    }
  }
  fat_file_byte_counter++;                /* one more byte read */
  Hard_write_byte(d);
}


/*F**************************************************************************
* NAME: fat_feof
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Return the file end flag
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_feof (void)
{
  return (fat_file_byte_counter >= fat_cache.info.size);
}


/*F**************************************************************************
* NAME: fat_dseek
*----------------------------------------------------------------------------
* 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:
*****************************************************************************/ 
bit fat_dseek (Int16 offset)
{
idata Byte     nb_sect;                     /* number of sectors to seek */
idata Uint16   nb_byte;                     /* number of bytes to seek */
idata Uint16   next_cluster;                /* the possible next cluster to load */
idata Uint16   target_cluster;              /* the cluster to reach        */
Uint16   i;

  fat_directory_pos += offset;              /* Calculate the absolute byte pos */
  nb_sect = (Byte)((fat_directory_pos) / SECTOR_SIZE);
  nb_byte = (Uint16)((fat_directory_pos) % SECTOR_SIZE);

  fat_current_sector = fat_directory_base + nb_sect;
  fat_current_byte_counter = nb_byte;
  
  if (dir_is_root == FALSE)                 /* Sub-directory ?   */
  {                                         /* Fin the # cluster */
    target_cluster = (nb_sect / fat_cluster_size);
    fat_current_dir_cluster = 0;
    next_cluster = dir_clusters.cluster[fat_current_dir_cluster];
    fat_current_dir_fragment = 1;
    for (i = 0; i < target_cluster; i++)
    {
      if (dir_clusters.number[fat_current_dir_cluster] <= fat_current_dir_fragment)
        { /* new fragment */
          fat_current_dir_cluster++;
          fat_current_dir_fragment = 1;
          next_cluster = dir_clusters.cluster[fat_current_dir_cluster];
        }
        else
        { /* no new fragment */
          next_cluster = dir_clusters.cluster[fat_current_dir_cluster] + fat_current_dir_fragment;
          fat_current_dir_fragment++;
        }
    }
    fat_current_sector = (((Uint32)(next_cluster) * fat_cluster_size)
                           + fat_ptr_data + (nb_sect % fat_cluster_size));
  }

  if (Hard_read_open(fat_current_sector) == OK)
  {
    for (i = 0;  i < fat_current_byte_counter; i += 2)
    {
      /* dummy reads */
      nb_sect = Hard_read_byte();
      nb_sect = Hard_read_byte();
    }
    return OK;
  }
  else
  {
    return KO;
  }
}


/*F**************************************************************************
* NAME: fat_dgetc
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Return the directory data byte at the current position
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/ 
Byte fat_dgetc (void)
{
idata Uint16 next_cluster;                  /* new cluster in allocation list */

  /* check if we are at the end of a cluster */
  if (((((Byte*)&fat_current_byte_counter)[0] & fat_cluster_mask) == 0x00) &&
      (((Byte*)&fat_current_byte_counter)[1] == 0x00) && (fat_current_byte_counter != 0x00))
  {
    /* extract the next cluster from the clusters allocation list */
    if (dir_clusters.number[fat_current_dir_cluster] == fat_current_dir_fragment)
    /* if there is a new fragment */
    {
      fat_current_dir_cluster++;
      fat_current_dir_fragment = 1;
      next_cluster = dir_clusters.cluster[fat_current_dir_cluster];
    }
    else
    {
      next_cluster = dir_clusters.cluster[fat_current_dir_cluster] + fat_current_dir_fragment;
      fat_current_dir_fragment++;
    }
    /* read the next sectors... */
    fat_current_sector = fat_ptr_data + ((Uint32)(next_cluster) * fat_cluster_size);
    while(Hard_read_open(fat_current_sector) != OK);
    fat_current_byte_counter = 0;
  }
  
  /* increment the global counters */
  fat_current_byte_counter++;

  return Hard_read_byte();
}


/*F**************************************************************************
* NAME: fat_fseek
*----------------------------------------------------------------------------
* PARAMS:   offset: seek offset in file
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Change file read pointer of an openned file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fseek (Uint32 offset)
{
Int16   cluster_offset;               /* offset size in clusters */
Byte    index;

  /* compute cluster number */
  cluster_offset = (offset / (SECTOR_SIZE * fat_cluster_size));
  index = 0;

  while (cluster_offset > clusters.number[index])
  {
    cluster_offset -= clusters.number[index];
    index++;
  }

  /* init file byte counter */
  fat_file_byte_counter = offset;

  /* set the allocation list variable */
  fat_chain_cluster = cluster_offset;
  fat_chain_index = index;

  /* re-open file in read or write mode */
  if (fat_open_mode == READ)
  {
    Hard_read_close();                      /* close  reading */
    Hard_read_open(((Uint32)(clusters.cluster[index] + cluster_offset) * fat_cluster_size)
                   + (offset / SECTOR_SIZE) % fat_cluster_size + fat_ptr_data);
  }
  else
  {
    Hard_write_close();                     /* close writing */
    Hard_write_open(((Uint32)(clusters.cluster[index] + cluster_offset) * fat_cluster_size)
                   + (offset / SECTOR_SIZE) % fat_cluster_size + fat_ptr_data);
  }

  /* seek in sector */
  offset = offset % SECTOR_SIZE;
  if (((Uint16)offset) != 0)
  {
    fat_chain_cluster++;
    do
    {
      Hard_read_byte();                     /* dummy read */
      offset--;
    }
    while (((Uint16)offset) != 0);
  }
}


/*F**************************************************************************
* NAME: fat_check_ext
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Return the type of the file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_check_ext (void)
{
  if ((fat_cache.info.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
  {
    return FILE_DIR;
  }
  else
  {
    if ((ext[0] == 'M') &&
        (ext[1] == 'P') &&
        (ext[2] == '3'))
    {
      return FILE_MP3;
    }
    else
    {
      if ((ext[0] == 'W') &&
          (ext[1] == 'A') &&
          (ext[2] == 'V'))
      {
        return FILE_WAV;
      }
      else
      {
        if ((ext[0] == 'S') &&
            (ext[1] == 'Y') &&
            (ext[2] == 'S'))
        {
          return FILE_SYS;
        }
        else
        {
          return FILE_XXX;
        }
      }
    }
  }
}


/*F**************************************************************************
* NAME: fat_get_name
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Return the address of the file name string
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
char pdata * fat_get_name (void)
{
  return (lfn_name);
}


/*F**************************************************************************
* NAME: fat_format
*----------------------------------------------------------------------------
* PARAMS:
*   voice: - TRUE:  format with voice files
*          - FALSE: format without voice files
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Create single FAT12 or FAT16 partition and format the selected memory 
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   - Single partition
*   - Cluster size is 4 or 8 Kbytes
*   - Sector size is 512 bytes
*   - 2 fats management
*   - 512 entries in the root directory
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_format (bit voice)
{
#define WAV_CLUST_SIZE  (Uint16)((WAV_SECTOR_SIZE) / fat_cluster_size)
#define FORMAT_NB_CYLINDER            (*tab).nb_cylinder
#define FORMAT_NB_HEAD                (*tab).nb_head
#define FORMAT_NB_SECTOR              (*tab).nb_sector
#define FORMAT_NB_HIDDEN_SECTOR       (*tab).nb_hidden_sector
#define FORMAT_NB_SECTOR_PER_CLUSTER  (*tab).nb_sector_per_cluster

Byte i, j;
Uint32 nb_total_sectors;
Uint16 nb_sector_fat;
Uint16  s, t;
s_format  code  *tab;

  tab = Hard_format();

  fat_cluster_size = FORMAT_NB_SECTOR_PER_CLUSTER;
  nb_total_sectors = (Uint32)FORMAT_NB_CYLINDER * FORMAT_NB_HEAD * FORMAT_NB_SECTOR;

  /* FAT type caculation */
  fat_is_fat16 = ((nb_total_sectors  / fat_cluster_size) > MAX_CLUSTERS12);

  /* -- MASTER BOOT RECORD -- */
  Hard_write_open(0x00);
  for (i = 446/2; i != 0; i--)              /* Boot Code */
  {
    Hard_write_byte(0x00);
    Hard_write_byte(0x00);
  }

  /* First Partition entry */
  Hard_write_byte(0x80);                    /* Default Boot Partition */
  Hard_write_byte((Byte)(FORMAT_NB_HIDDEN_SECTOR / FORMAT_NB_SECTOR));       /* Start head */
  Hard_write_byte((Byte)((FORMAT_NB_HIDDEN_SECTOR % FORMAT_NB_SECTOR) + 1)); /* Start Sector */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -