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

📄 fat.c

📁 看到最近大家都关心 usbhost 的实现, 论坛上能找到的代码仅是一些简单的 demo , 完整的源码级的协议层是找不到的 我就贡献一把, 将我前一段时间移植成功的 USBHost 代码奉上 注
💻 C
📖 第 1 页 / 共 5 页
字号:
    case FS_UNKNOWN:
      return false;

    case FS_FAT12:
      sector = filesysFAT + (((cluster * 3) / 2) / BYTE_PER_READ);
      offset = ((cluster * 3) / 2) % BYTE_PER_READ;

      // If FAT buffer contains wrong sector
      if (sector != fatBufferCurSector)
      {
        // Load correct sector to buffer
        fatBufferCurSector = sector;
        disc_ReadSector(fatBufferCurSector, fatBuffer);
      }

      if (cluster & 0x01) {

        ((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0x0F) | ((value & 0x0F) << 4);

        offset++;
        if (offset >= BYTE_PER_READ) {
          offset = 0;
          // write the buffer back to disc
          disc_WriteSector(fatBufferCurSector, fatBuffer);
          // read the next sector  
          fatBufferCurSector++;
          disc_ReadSector(fatBufferCurSector, fatBuffer);
        }
        
        ((unsigned char*)fatBuffer)[offset] =  (value & 0x0FF0) >> 4;

      } else {
      
        ((unsigned char*)fatBuffer)[offset] = value & 0xFF;
    
        offset++;
        if (offset >= BYTE_PER_READ) {
          offset = 0;
          // write the buffer back to disc
          disc_WriteSector(fatBufferCurSector, fatBuffer);
          // read the next sector  
          fatBufferCurSector++;
          disc_ReadSector(fatBufferCurSector, fatBuffer);
        }
        
        ((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0xF0) | ((value >> 8) & 0x0F);
      }

      break;
      
    case FS_FAT16:
      sector = filesysFAT + ((cluster << 1) / BYTE_PER_READ);
      offset = cluster % (BYTE_PER_READ >> 1);

      // If FAT buffer contains wrong sector
      if (sector != fatBufferCurSector)
      {
        // Load correct sector to buffer
        fatBufferCurSector = sector;
        disc_ReadSector(fatBufferCurSector, fatBuffer);
      }

      // write the value to the FAT buffer
      ((unsigned short*)fatBuffer)[offset] = (value & 0xFFFF);

      break;
      
    case FS_FAT32:
      sector = filesysFAT + ((cluster << 2) / BYTE_PER_READ);
      offset = cluster % (BYTE_PER_READ >> 2);
      
      // If FAT buffer contains wrong sector
      if (sector != fatBufferCurSector)
      {
        // Load correct sector to buffer
        fatBufferCurSector = sector;
        disc_ReadSector(fatBufferCurSector, fatBuffer);
      }

      // write the value to the FAT buffer
      (((unsigned int*)fatBuffer)[offset]) =  value;

      break;
      
    default:
      return false;
  }
  
  // write the buffer back to disc
  disc_WriteSector(fatBufferCurSector, fatBuffer);
      
  return true;
}
#endif

#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_ReadWriteFatEntryBuffered
Internal function - writes FAT information about a cluster to a 
 buffer that should then be flushed to disc using 
 FAT_WriteFatEntryFlushBuffer()
 Call FAT_WriteFatEntry first so as not to ruin the disc.
 Also returns the entry being replaced
-----------------------------------------------------------------*/
unsigned int FAT_ReadWriteFatEntryBuffered (unsigned int cluster, unsigned int value)
{
  unsigned int sector;
  int offset;
  unsigned int oldValue;

  if ((cluster < 0x0002) || (cluster > fatLastCluster))
    return CLUSTER_FREE;

  
  switch (filesysType) 
  {
    case FS_UNKNOWN:
      oldValue = CLUSTER_FREE;
      break;
      
    case FS_FAT12:
      sector = filesysFAT + (((cluster * 3) / 2) / BYTE_PER_READ);
      offset = ((cluster * 3) / 2) % BYTE_PER_READ;

      // If FAT buffer contains wrong sector
      if (sector != fatBufferCurSector)
      {
        // write the old buffer to disc
        if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
          disc_WriteSector(fatBufferCurSector, fatBuffer);
        // Load correct sector to buffer
        fatBufferCurSector = sector;
        disc_ReadSector(fatBufferCurSector, fatBuffer);
      }

      if (cluster & 0x01) {

        oldValue = (((unsigned char*)fatBuffer)[offset] & 0xF0) >> 4;
        ((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0x0F) | ((value & 0x0F) << 4);

        offset++;
        if (offset >= BYTE_PER_READ) {
          offset = 0;
          // write the buffer back to disc
          disc_WriteSector(fatBufferCurSector, fatBuffer);
          // read the next sector  
          fatBufferCurSector++;
          disc_ReadSector(fatBufferCurSector, fatBuffer);
        }
        
        oldValue |= ((((unsigned char*)fatBuffer)[offset]) << 4) & 0x0FF0;
        ((unsigned char*)fatBuffer)[offset] =  (value & 0x0FF0) >> 4;

      } else {
      
        oldValue = ((unsigned char*)fatBuffer)[offset] & 0xFF;
        ((unsigned char*)fatBuffer)[offset] = value & 0xFF;
    
        offset++;
        if (offset >= BYTE_PER_READ) {
          offset = 0;
          // write the buffer back to disc
          disc_WriteSector(fatBufferCurSector, fatBuffer);
          // read the next sector  
          fatBufferCurSector++;
          disc_ReadSector(fatBufferCurSector, fatBuffer);
        }
        
        oldValue |= (((unsigned char*)fatBuffer)[offset] & 0x0F) << 8;
        ((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0xF0) | ((value >> 8) & 0x0F);
      }

      if (oldValue >= 0x0FF7) 
      {
        oldValue = CLUSTER_EOF;
      }

      break;
      
    case FS_FAT16:
      sector = filesysFAT + ((cluster << 1) / BYTE_PER_READ);
      offset = cluster % (BYTE_PER_READ >> 1);

      // If FAT buffer contains wrong sector
      if (sector != fatBufferCurSector)
      {
        // write the old buffer to disc
        if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
          disc_WriteSector(fatBufferCurSector, fatBuffer);
        // Load correct sector to buffer
        fatBufferCurSector = sector;
        disc_ReadSector(fatBufferCurSector, fatBuffer);
      } 

      // write the value to the FAT buffer
      oldValue = ((unsigned short*)fatBuffer)[offset];
      ((unsigned short*)fatBuffer)[offset] = value;

      if (oldValue >= 0xFFF7) 
      {
        oldValue = CLUSTER_EOF;
      }

      break;
      
    case FS_FAT32:
      sector = filesysFAT + ((cluster << 2) / BYTE_PER_READ);
      offset = cluster % (BYTE_PER_READ >> 2);
      
      // If FAT buffer contains wrong sector
      if (sector != fatBufferCurSector)
      {
        // write the old buffer to disc
        if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
          disc_WriteSector(fatBufferCurSector, fatBuffer);
        // Load correct sector to buffer
        fatBufferCurSector = sector;
        disc_ReadSector(fatBufferCurSector, fatBuffer);
      }

      // write the value to the FAT buffer
      oldValue = ((unsigned int*)fatBuffer)[offset];
      ((unsigned int*)fatBuffer)[offset] =  value;

      if (oldValue >= 0x0FFFFFF7) 
      {
        oldValue = CLUSTER_EOF;
      }

      break;
      
    default:
      oldValue = CLUSTER_FREE;
      break;
  }
  
  return oldValue;
}
#endif

#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_WriteFatEntryFlushBuffer
Flush the FAT buffer back to the disc
-----------------------------------------------------------------*/
char FAT_WriteFatEntryFlushBuffer (void)
{
  // write the buffer disc
  if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
  {
    disc_WriteSector(fatBufferCurSector, fatBuffer);
    return true;
  } else {
    return false;
  }
}
#endif

#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_FirstFreeCluster
Internal function - gets the first available free cluster
-----------------------------------------------------------------*/
unsigned int FAT_FirstFreeCluster(void)
{
  // Start at first valid cluster
  if (fatFirstFree < CLUSTER_FIRST)
    fatFirstFree = CLUSTER_FIRST;

  while ((FAT_NextCluster(fatFirstFree) != CLUSTER_FREE) && (fatFirstFree <= fatLastCluster))
  {
    fatFirstFree++;
  }
  if (fatFirstFree > fatLastCluster)
  {
    return CLUSTER_EOF;
  }
  return fatFirstFree;
}
#endif

#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_LinkFreeCluster
Internal function - gets the first available free cluster, sets it
to end of file, links the input cluster to it then returns the 
cluster number
-----------------------------------------------------------------*/
unsigned int FAT_LinkFreeCluster(unsigned int cluster)
{
  unsigned int firstFree;
  unsigned int curLink;

  if (cluster > fatLastCluster)
  {
    return CLUSTER_FREE;
  }

  // Check if the cluster already has a link, and return it if so
  curLink = FAT_NextCluster (cluster);
  if ((curLink >= CLUSTER_FIRST) && (curLink < fatLastCluster))
  {
    return curLink;  // Return the current link - don't allocate a new one
  }
  
  // Get a free cluster
  firstFree = FAT_FirstFreeCluster();

  // If couldn't get a free cluster then return
  if (firstFree == CLUSTER_EOF)
  {
    return CLUSTER_FREE;
  }

  if ((cluster >= CLUSTER_FIRST) && (cluster < fatLastCluster))
  {
    // Update the linked from FAT entry
    FAT_WriteFatEntry (cluster, firstFree);
  }
  // Create the linked to FAT entry
  FAT_WriteFatEntry (firstFree, CLUSTER_EOF);

  return firstFree;
}
#endif


#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_ClearLinks
Internal function - frees any cluster used by a file
-----------------------------------------------------------------*/
char FAT_ClearLinks (unsigned int cluster)
{
  unsigned int nextCluster;
  
  if ((cluster < 0x0002) || (cluster > fatLastCluster))
    return false;

  // Store next cluster before erasing the link
  nextCluster = FAT_NextCluster (cluster);

  // Erase the link
  FAT_WriteFatEntry (cluster, CLUSTER_FREE);

  // Move onto next cluster
  cluster = nextCluster;

  while ((cluster != CLUSTER_EOF) && (cluster != CLUSTER_FREE))
  {
    cluster = FAT_ReadWriteFatEntryBuffered (cluster, CLUSTER_FREE);
  } 

  // Flush fat write buffer
  FAT_WriteFatEntryFlushBuffer ();

  return true;
}
#endif


/*-----------------------------------------------------------------
FAT_InitFiles
Reads the FAT information from the CF card.
You need to call this before reading any files.
char return OUT: true if successful.
-----------------------------------------------------------------*/
char FAT_InitFiles (void)
{
int i;
int bootSector;
BOOT_SEC* bootSec;
  
    if (!disc_Init())
    { return (false);
    }
    
    // Read first sector of CF card
    if( !disc_ReadSector(0, globalBuffer)) return false;
  
    // Make sure it is a valid MBR or boot sector
    if((globalBuffer[0x1FE] != 0x55) || (globalBuffer[0x1FF] != 0xAA)) 
    { return false;
    }
  
    // Check if there is a FAT string, which indicates this is a boot sector
    if((globalBuffer[0x36] == 'F') && (globalBuffer[0x37] == 'A') && (globalBuffer[0x38] == 'T'))
    { bootSector = 0;
    }
    // Check for FAT32
    else if ((globalBuffer[0x52] == 'F') && (globalBuffer[0x53] == 'A') && (globalBuffer[0x54] == 'T'))
    { bootSector = 0;
    }
    else  // This is an MBR
    {
      // Find first valid partition from MBR
      // First check for an active partition
      for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i] != 0x80); i+= 0x10) ;
      // If it didn't find an active partition, search for any valid partition
      if (i == 0x1FE) 
      { for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i+0x04] == 0x00); i+= 0x10); }
      
      // Go to first valid partition
      if ( i != 0x1FE)  // Make sure it found a partition
      { bootSector = globalBuffer[0x8 + i] + (globalBuffer[0x9 + i] << 8) + (globalBuffer[0xA + i] << 16) + ((globalBuffer[0xB + i] << 24) & 0x0F);
      } 
      else 
      { bootSector = 0;  // No partition found, assume this is a MBR free disk
      }
    }
  
    // Read in boot sector
    bootSec = (BOOT_SEC*) globalBuffer;
    if (!disc_ReadSector (bootSector,  bootSec)) 
    { return false;
    }
    
    // Store required information about the file system
    if (bootSec->sectorsPerFAT != 0)
    { filesysSecPerFAT = bootSec->sectorsPerFAT;
    }
    else
    { filesysSecPerFAT = bootSec->extBlock.fat32.sectorsPerFAT32;
    }
    
    if(bootSec->numSectorsSmall != 0)
    { filesysNumSec = bootSec->numSectorsSmall;
    }
    else
    { filesysNumSec = bootSec->numSectors;
    }
  

⌨️ 快捷键说明

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