Fat32 error getting next cluster on FatDirEntry

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello!

Im working in one project at master system(Z80), but for debbug easy, I teste the code at avr,...
On fat32, when listing files, the method i got, only show the first cluster files, and stop. The FatEntryList_t was a way i find to do pagination(18 filename on screen) on files list without sort. I know chanfatfs sources, but dont enough space on program memory to use this.

 

Cannot find the problem on code, at avr and z80, dont work. Can someone try help, just ignore the FatEntryList struct?

 

typedef struct FatEntryList_t{
	u16 ptrBufferPos;
	u16 dirEntryPos;
	u32 dirCluster;
    u16 numSector;
	struct FatEntryList_t *next;
    struct FatEntryList_t *back;
} FatEntryList_t;
#define getFirstSector(clusterNum)  (((clusterNum - 2) * sectorPerCluster) + firstDataSector)
#define fatIsEndOfClusterChain(thisCluster) (thisCluster == 0x0FFFFFFF)

u32 getNextCluster(u32 clusterNumber)
{
    u16 FATEntryOffset;
    u32 *FATEntryValue;
    u32 FATEntrySector;
    u32 Cluster = clusterNumber * 4;

    //get sector number of the cluster entry in the FAT
    FATEntrySector = unusedSectors + reservedSectorCount + (Cluster / bytesPerSector) ;

    //get the offset address in that sector number
    FATEntryOffset = (u16) ((clusterNumber * 4) % bytesPerSector);

    if(fatCacheAddress != FATEntrySector){
      fatCacheAddress = FATEntrySector;
      SD_readSingleBlock(fatCacheBytes, FATEntrySector);
    }

    //get the cluster address from the buffer
    FATEntryValue = (u32 *) &fatCacheBytes[FATEntryOffset];

    return ((*FATEntryValue) & 0x0fffffff);
}

extern u8 numberOfPages;
extern u16 numberOfFiles;
/**
 * @brief Essa função apenas percorre todo
 * o fatentry e obtem a quantidade de arquivos
 * possibilitando a paginação futura
 *
 * @param linkedPage
 * @param pageSize
 */
void loadAllPages(FatEntryList_t* linkedPage){
  const u16 bytesPerCluster = (u16)(bytesPerSector * sectorPerCluster);
  const u16 entry_per_cluster = (u16)(bytesPerCluster / FAT_DIRENT_SIZE);
  signed char fileName[262];
  u8 *buffer = ((u8 *)0xB000);
  u8 offset, last, sector_cnt=0, yy = 7, resp;
  const u8 *ptr = buffer;
  u16 fnLen = 0, fileCount = 0, i=0, buffPos=0,x=0;
  u32 dirCluster;    

  dirCluster = getFirstSector(rootCluster);

  linkedPage->dirCluster  = dirCluster;
  linkedPage->dirEntryPos = 0;
  linkedPage->ptrBufferPos= 0;
  linkedPage->back        = NULL;
  linkedPage->next        = NULL;
  linkedPage->numSector   = 0;

  resp = SD_readSingleBlock(buffer, dirCluster);

  for(;;){
    if(*ptr == 0x00){
      break;
    }
    else if(fatIsLongFilename(ptr)){
      offset = *ptr;
      last = offset & 0x40; // chegou ao fim?
      offset &= 0x1F;
      offset--;
      offset *= 13;
      fileName[offset+0] = ptr[1];
      fileName[offset+1] = ptr[3];
      fileName[offset+2] = ptr[5];
      fileName[offset+3] = ptr[7];
      fileName[offset+4] = ptr[9];
      fileName[offset+5] = ptr[14];
      fileName[offset+6] = ptr[16];
      fileName[offset+7] = ptr[18];
      fileName[offset+8] = ptr[20];
      fileName[offset+9] = ptr[22];
      fileName[offset+10] = ptr[24];
      fileName[offset+11] = ptr[28];
      fileName[offset+12] = ptr[30];

      if ( last ) {
          fileName[offset+13] = '\0';
          fileName[offset+14] = '\0';
          offset += 12;
          while ( fileName[offset] == 0 || fileName[offset] == -1 ) {
              fileName[offset] = 0;
              offset--;
          }
          offset++;
          fnLen = offset;
      }

    }else if(!fatIsDeletedFile(ptr) && !fatIsVolumeName(ptr)){

        if(fnLen > 0){
          numberOfFiles++; // contador de arquivos total.
          fileCount++; // incrementa contador de file
          if(fileCount == NUM_FILES_PER_PAGE){
            while(linkedPage->next != NULL)
              linkedPage = linkedPage->next;

            numberOfPages++;
            fileCount = 0;
            linkedPage->next = malloc(sizeof(FatEntryList_t));
            linkedPage->next->back = linkedPage;
            linkedPage->next->next = NULL;
            linkedPage->next->dirCluster  = dirCluster;
            linkedPage->next->dirEntryPos = i;
            linkedPage->next->numSector   = sector_cnt;
            linkedPage->next->ptrBufferPos= buffPos;
          }
        }
        fnLen = 0;
    }
    // incrementa Dir Entry ponteiro do buffer
    ptr += FAT_DIRENT_SIZE;
    buffPos += FAT_DIRENT_SIZE;
    // incrementa contador de dir entry
    i++;
    x += FAT_DIRENT_SIZE;

    if(i == entry_per_cluster){
        dirCluster = getNextCluster(dirCluster);
        // for esse for o ultimo cluster
        if(fatIsEndOfClusterChain(dirCluster)){
            break;
        }
        // ler proximo cluster com as entradas dos diretorios
        resp = SD_readSingleBlock(buffer, getFirstSector(dirCluster));
        // zera contador
        i = 0;
        x = 0;
        sector_cnt = 0;
        buffPos = 0;
        // coloca o ponteiro para o inicio do buffer
        ptr = buffer;
    }
    if(x == bytesPerSector){
      sector_cnt++;
      // ler proximo cluster com as entradas dos diretorios
      SD_readSingleBlock(buffer, dirCluster + sector_cnt);
      // coloca o ponteiro para o inicio do buffer
      ptr = buffer;
      buffPos = 0;
      x = 0;
    }
  }// for
}

 

getNextCluster() work when I read the entirelly file;
I know some var is duplicated. need a clean on code. but first need make this work;

Know a better way to paginate on small device? Ill listen you carefully ^^.