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

📄 fat.c

📁 AVR ATMega library for using MMC /SD cart.
💻 C
📖 第 1 页 / 共 2 页
字号:

unsigned short fatLastReadEntryNumber(void)
{
  return lastReadEntryNumber;
}


unsigned long fatLastReadSectorNumber(void)
{
  return lastReadSectorNumber;
}


// return the size of the last directory entry
unsigned long fatGetFilesize(void)
{
  return FileSize;
}


// return the long name of the last directory entry
char* fatGetFilename(void)
{	
  return LongNameBuffer;
}


// return the directory of the last directory entry
char* fatGetDirname(void)
{	
  return DirNameBuffer;
}


// load a clusterfull of data
void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
{
  register unsigned char i;
  // read cluster
  //while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0);
  for(i=0; i<SectorsPerCluster; i++) {
    //		ataReadSectors( DRIVE0, clust2sect(cluster)+i, 1, buffer+(i<<9) );
    // temporary fix for wierd misaligned cluster problem
    // (only when using FAT16?)
    ataReadSectors( DRIVE0, fatClustToSect(cluster+8)+i, 1, buffer+(i<<9) );
  }
}


// find next cluster in the FAT chain
unsigned long fatNextCluster(unsigned long cluster)
{
  unsigned long nextCluster;
  unsigned long fatMask;
  unsigned long fatOffset;
  unsigned long sector;
  unsigned int offset;
	
  // get fat offset in bytes
  if(Fat32Enabled) {
    // four FAT bytes (32 bits) for every cluster
    fatOffset = cluster << 2;
    // set the FAT bit mask
    fatMask = FAT32_MASK;
  }
  else {
    // two FAT bytes (16 bits) for every cluster
    fatOffset = cluster << 1;
    // set the FAT bit mask
    fatMask = FAT16_MASK;
  }
  
  // calculate the FAT sector that we're interested in
  sector = FirstFATSector + (fatOffset / BytesPerSector);
  // calculate offset of the our entry within that FAT sector
  offset = fatOffset % BytesPerSector;
  
  //rprintfProgStrM("sec: ");
  //rprintfu32(sector);


  // if we don't already have this FAT chunk loaded, go get it
  if (sector != FatInCache) {
    // read sector of FAT table
    while (ataReadSectors( DRIVE0, sector, 1, (unsigned char*)FAT_CACHE_ADDR) != 0);
    FatInCache = sector;
  }

  // read the nextCluster value
  nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;
  
  // check to see if we're at the end of the chain
  if (nextCluster == (CLUST_EOFE & fatMask))
    nextCluster = 0;

#if EXTRA_DEBUG
#ifdef DEBUG_FAT
  rprintfProgStrM(">");
  rprintfu32(nextCluster);
  rprintfCRLF();
#endif
#endif
	
  return nextCluster;
}

unsigned long fatFirstFATSector( void )
{
  return FirstFATSector;
}


unsigned long fatFirstFAT2Sector( void )
{
  return FirstFAT2Sector;
}

unsigned short fatFATSectors( void )
{
  return FATSectors;
}

int fatFindFirstDeletedEntry( unsigned long * sect, unsigned short * entryNr )
{
  ulong startSect = FirstDataSector; // first sect with root dir

  for(;;) {
    
    ataReadSectors(DRIVE0, startSect, 1, SectorBuffer);
    
    uchar entry;

    for( entry = 0;entry < 16; entry++ ) {
    }
    

  }
  
}

/*
 *
 */

//ulong tmp;


int fatFindFreeAllocUnit( unsigned long * clusterNo, ulong * sect )
{
#if 0
  unsigned long fatSect;
  unsigned long clust = 0;

  bool isFreeUnit = false;

  ushort i = 0;

  ulong clst = (*clusterNo) + 1;  // next

  fatSect = FirstFATSector;

  fatSect += clst / (512 / 2);


  for( ; fatSect < FirstFATSector + FATSectors; ++fatSect ) {

    if( fatSect != FatInCache ) {

      ataReadSectors( DRIVE0, fatSect, 1, FatCacheBuffer /*SectorBuffer*/ );
      FatInCache = fatSect;
    }


    for( i = clst % (512 / 2); i < (512/2); ++i ) {

      if( *((unsigned short*) &FatCacheBuffer[i*2]) == 0x0000 ) {
        isFreeUnit = true;
        break;
      }
    }

    if( isFreeUnit ) break;

    clust += 512/2;
  }


  *clusterNo = clust + i;
  if( sect ) *sect = fatSect;
#endif

  return 0;
}

/*
 *
 */
// call after GetDirEntry

void fatFileUpadate( void )
{
  ulong fileSize;
  ulong fatSect;

  ulong dirSectNo = fatLastReadSectorNumber();
  ushort entryNo = fatLastReadEntryNumber();

  ataReadSectors( DRIVE0, dirSectNo, 1, SectorBuffer );
  struct direntry * de = (struct direntry*) SectorBuffer;
  unsigned long clusterNo = 0;

  fileSize = de[ entryNo ].deFileSize;
  {
#if EXTRA_DEBUG
    char str[64];
    snprintf_P( str, sizeof( str ) , PSTR("file size: %ld, dirSectNo: [%lx], entryNo: %d\r\n"), 
		(long) fileSize, (long) dirSectNo, (int) entryNo );
    PutTextDBG( str );
#endif
  }

  fileSize = 0;

  if( fileSize == 0 ) {
    fileSize = 10000;
    
    fatFindFreeAllocUnit( & clusterNo, & fatSect );
    ataReadSectors( DRIVE0, dirSectNo, 1, SectorBuffer );
    
    de[ entryNo ].deFileSize = fileSize;
    de[ entryNo ].deHighClust = clusterNo >> 16;
    de[ entryNo ].deStartCluster = clusterNo & 0xFFFF;
    
    ataWriteSectors( DRIVE0, dirSectNo, 1, SectorBuffer );
#if EXTRA_DEBUG
    PutTextDBG("Update dir entry\r\n");
#endif
  }
  else {
    clusterNo = ((ulong) de[ entryNo ].deHighClust << 16) + de[ entryNo ].deStartCluster;

    fatSect = FirstFATSector;
    
    fatSect += clusterNo / (512 / 2);
    
    fileSize = de[ entryNo ].deFileSize;
  }

  if( fileSize == 0 ) return;
  
  // update FAT
  unsigned short cl;
  unsigned long prevFatSect;

#if EXTRA_DEBUG
  char str[64];
  snprintf_P( str, sizeof( str ) , PSTR("File Size: %ld\r\n"), (long) fileSize );
  PutTextDBG( str );
#endif


  for( cl = 0; cl <= ( fileSize / 512 ); ++cl ) {

    unsigned long prevClust = clusterNo;
    prevFatSect = fatSect;

    fatFindFreeAllocUnit( & clusterNo, & fatSect );

#if EXTRA_DEBUG
    char str[64];
    snprintf_P( str, sizeof( str ) , PSTR("clusterNo: %ld, cl: %d, fatSect: %lx\r\n"), 
		(long) clusterNo, (int) cl, (long) fatSect );
    PutTextDBG( str );
#endif
    if( prevFatSect != fatSect ) {
      ataReadSectors( DRIVE0, prevFatSect, 1, SectorBuffer );
#if EXTRA_DEBUG
      PutTextDBG("read sect\r\n");
#endif
    }


    if( cl < ( fileSize / 512 ) ) {

#if EXTRA_DEBUG
      snprintf_P( str, sizeof( str ) , PSTR("prevClust: %ld, clusterNo: %ld \r\n"), 
		  (long) prevClust, (long) clusterNo );
      PutTextDBG( str );
#endif
      * ((ushort*) (&SectorBuffer[ prevClust * 2 ])) = 0x1234 ; //clusterNo & 0x0000FFFFL;
      {
#if EXTRA_DEBUG
        ushort idx = 0;
        uchar i;

	idx += sprintf( &str[ idx ], "%04x: ", (ushort) ((prevClust * 2) / 16) * 16 );

        for( i=0; i<16; i++ ) {
	  idx += sprintf( &str[ idx ], "%02x ", (ushort) SectorBuffer[ ((prevClust * 2) / 16) * 16  + i ] );
        }

        PutTextDBG( str );
        PutTextDBG( "\r\n" );
#endif
      }

      //snprintf_P( str, sizeof( str ) , PSTR("clusterNo: %ld, cl: %d\r\n"), (long) clusterNo, (int) cl  );
      //PutTextDBG( str );

    }
    else {
      * (ushort*) &SectorBuffer[ prevClust * 2 ] = 0xFFFF;
      
      ataWriteSectors( DRIVE0, prevFatSect, 1, SectorBuffer );

#if EXTRA_DEBUG
      unsigned short idx, i, j;

      for( j=0; j<512/16; j++ ) {
	idx = 0;
	
	for( i=0; i<16; i++ ) {
	  idx += sprintf( &str[ idx ], "%02x ", (ushort) SectorBuffer[ j*16 + i ] );
	}

	PutTextDBG( str );
	PutTextDBG( "\r\n" );
      }
#endif

#if EXTRA_DEBUG
      snprintf_P( str, sizeof( str ) , PSTR("prevFatSect: %lx\r\n"), (long) prevFatSect );
      PutTextDBG( str );
      PutTextDBG("[WR last]");
#endif
    }

    if( prevFatSect != fatSect ) {
      ataWriteSectors( DRIVE0, prevFatSect, 1, SectorBuffer );
#if EXTRA_DEBUG
      PutTextDBG("[WR]");
#endif
    }
  }

#if EXTRA_DEBUG
  PutTextDBG("Update FAT\r\n");
#endif
}

⌨️ 快捷键说明

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