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

📄 mmc_spi_fat16.c

📁 fat16 biblioteca spi mmc
💻 C
📖 第 1 页 / 共 3 页
字号:
      lnf_tiles=buff[0] & 0b00111111;
      bytes_read=bytes_read+lnf_tiles*32;
      if(bytes_read>cluster_size_bytes){
         // compute next cluster address next_cluster_ptr must be valid
         // assigns this_cluster_ptr

         dir_addr_ptr=cluster_addr(fnbr,NEXT_CLUSTER);
         if (dir_addr_ptr==0xFFFFFF) return (22);
         bytes_read=bytes_read-cluster_size_bytes;
         dir_addr_ptr=dir_addr_ptr+bytes_read;
      }
      else{
         dir_addr_ptr=dir_addr_ptr+lnf_tiles*32;
      }

      //advance over the lnf tiles
      /// test to see if we need next cluster in chain
      if (read_BLOCK(dir_addr_ptr,buff)==false) return(31);
      /// !!! may read into next sector
   }


   /// check out the standard DOS tile
   #IF MMC_OPEN_TRACE
      printf("\n\r fname[%s] level=%u \n\r",file_name,level);
      for (j=0;j<11;j++)printf("%c",buff[j]);
   #ENDIF
   if(strncmp(buff,file_name, 11)==0){ ///8.3 file name ex "FILE EXT" "FOLDER "
      // we have a file type or a sub directory(folder)
      // so we get the starting cluster number
      attribute=buff[11];

      file[fnbr].root_cluster_ptr=make16(buff[27],buff[26]);/// assign initial cluster ptr
      /// if it is not a directory
      /// it points to the begining of the file
      /// cluster chain



      if ((attribute & 0b00010000)>0)directory=true;
      else directory=false;
      if ((attribute & 0b00100000)>0 || attribute==0){
         archive=true; //// we have our file

         file[fnbr].size=make32(buff[31],buff[30],buff[29],buff[28]);
         file[fnbr].dir_addr_ptr=dir_addr_ptr; ///save address of this files tile
         /// assign global value
      }
      else archive=false;



      goto match_found;
      // goto fill_table; // we have a match
   }
   next_tile:
   bytes_read=bytes_read+32;
   if(bytes_read > cluster_size_bytes){
      /// requires a valid next=next_cluster_ptr
      // compute next cluster address and assign this cluster
      dir_addr_ptr=cluster_addr(fnbr,NEXT_CLUSTER);
      if (dir_addr_ptr==0xFFFFFF) return (23);
      bytes_read=bytes_read-cluster_size_bytes;
      dir_addr_ptr=dir_addr_ptr+bytes_read;
   }
   else{
      dir_addr_ptr=dir_addr_ptr+32;
   }


   dir_addr_ptr=dir_addr_ptr+32;

   if (read_BLOCK(dir_addr_ptr,buff)==false) return(32);
   goto tile_decode;

   match_found:
   ///// if we have a sub directory we need to cycle down a level
   if (directory==true) {
      // compute the sub directory address
      // compute this cluster address this_cluster_ptr must be valid
      dir_addr_ptr=cluster_addr(fnbr,ROOT_CLUSTER); /// set physical addr of starting cluster
      #IF MMC_OPEN_TRACE
         printf("\n\r next_cluster_ptr=%lu \n\r ",file[fnbr].next_cluster_ptr);
      #ENDIF
      //printf("\n\r dir_addr_ptr=%lu",dir_addr_ptr);
      // dir_addr_ptr=((int32)cluster_table[0]-(int32)2)*(int32)cluster_size_bytes+
      // data_area_address;
      level++;
      goto read_directory;
   }


   // note record length must divide into 512 to align properly
   if (rec_length<2) return(12);



   /// get the initial file_addr_ptr

   file[fnbr].addr_ptr=cluster_addr(fnbr,ROOT_CLUSTER);
   file[fnbr].offset=0; //init bytes read from beginning of open file
   file[fnbr].cluster_offset=0; //init bytes read to beginning of the current cluster
   file[fnbr].rec_size=(int32)rec_length; /// assign file record size
   #IF MMC_OPEN_TRACE
      printf("root_cluster=%lu \n\r",file[fnbr].root_cluster_ptr);
   #ENDIF

   //printf("\n\r fopen %u rec size=%lu",fnbr,file[fnbr].rec_size);

   if(set_BLOCKLEN(file[fnbr].rec_size)==false) return(13);

   return(0);
}

//////////////////////////////////////////////////////////////////////////////////
////////////////////////////// FILE READ ///////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
#separate
int file_read(int8 fnbr,char *buff){
   int32 address;
   int32 nxt_cluster;
   //// MMC allows a read to start and stop at any address but this file system
   //// imposes a record size restriction the record size must divide into the
   /// 512 block to allow writing of the records
   /// rec_size must align with cluster boundary 2048 ...must be a divisor of 2048
   /// find the cluster containing the offset
   /// buff must be at least the size of the recordsize requested in the File open

   //printf("foffset=%lu coffset=%lu ",file[fnbr].offset,file[fnbr].cluster_offset);////$$$$

   if ( file[fnbr].offset>=file[fnbr].size) return(10); /// already beyond eof

   if ( file[fnbr].offset + (int32) file[fnbr].rec_size > file[fnbr].cluster_offset + (int32) cluster_size_bytes){
      #IF MMC_READ_TRACE
         printf("adv to next cluster");
      #ENDIF
      /// need to advance to the next cluster
      nxt_cluster=cluster_addr(fnbr,NEXT_CLUSTER);
      if ( nxt_cluster!=0XFFFFFFFF) file[fnbr].addr_ptr=nxt_cluster;
      else return(11); /// last cluster in file reached

      file[fnbr].cluster_offset=file[fnbr].cluster_offset+(int32)cluster_size_bytes; //foffset is the byte offset within the file
      //that file_addr_ptr points to
   }
   address=file[fnbr].addr_ptr+file[fnbr].offset-file[fnbr].cluster_offset;
   #IF MMC_READ_TRACE
      //printf("\n\r offset=%lu",cluster_offset);
      printf("\n\r data_area_address=%lu",address);
      printf("\n\r cluster_size_bytes=%lu",cluster_size_bytes);

      //printf("\n\r file_addr_ptr=%lu",file_addr_ptr);
   #ENDIF

   if (read_BLOCK(address,buff)==false)return(12); /// read block into buff

   if ( file[fnbr].offset+file[fnbr].rec_size< file[fnbr].size ) file[fnbr].offset=file[fnbr].offset+file[fnbr].rec_size;
   else{ /// end of file
      #IF MMC_READ_TRACE
         printf("eof size=%lu",file[fnbr].size);
      #ENDIF
      buff[ file[fnbr].size-file[fnbr].offset]=0; /// short record
      file[fnbr].offset=file[fnbr].size;
      return(255); //eof
   }
   return(0);
}


//////////////////////////////////////////////////////////////////////////////////
////////////////////////////// WRITE FILE /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
#separate
int file_write(int8 fnbr,int *buff){
   //// buff size must be at least the recordsize requested in File open
   //// the record is updated only chars beyond rec_size are ignored
   /// set up for write
   /// A MMC write is restricted it must be for a block and allign on block boundaries
   /// blocklen must be exactly 512 and start address must be the begining of a
   /// sector
   /// the buff could potentially span a sector and or span a block(512) boundary
   /// ex there could be 1byte left in a block and 1 byte lect in a sector
   // if the block is the last block in the sector
   /// worst case we could write to two blocks and need a new sector
   int32 address,nxt_cluster;

   int16 in_cluster_size,out_cluster_size;
   int8 appending_flag;
   appending_flag=0;
   if (file[fnbr].offset + file[fnbr].rec_size>=file[fnbr].size) appending_flag=1;


   /// find the cluster containing the offset
   if ( file[fnbr].offset+file[fnbr].rec_size>=file[fnbr].cluster_offset + cluster_size_bytes){
      #IF MMC_WRITE_TRACE
         printf("spanning cluster \n\r");
      #ENDIF
      /// spans the current cluster so we split the write
      in_cluster_size=file[fnbr].cluster_offset+cluster_size_bytes-file[fnbr].offset;
      /// bytes from start of file to end of this cluste- bytes into the file
      out_cluster_size=file[fnbr].rec_size - in_cluster_size;
      #IF MMC_WRITE_TRACE
         printf("write>> spanning cluster inside=%lu outside=%lu \n\r",in_cluster_size,out_cluster_size);
      #ENDIF
      address=file[fnbr].addr_ptr+file[fnbr].offset - file[fnbr].cluster_offset;
      // physical address=
      // physical address of the cluster +offset from begining of file
      // - offset from the begining of file for the byte at the begining of the cluster
      #IF MMC_WRITE_TRACE
         printf("write file>>cluster=%lu in clstr addr=%lu",file[fnbr].this_cluster_ptr,address);
      #ENDIF
      //// address=physical offset of this cluster +bytes into this cluster
      if(write_BLOCK(address,buff,in_cluster_size)==false)return(81); //// write first chunk



      /// allocate the next cluster
      nxt_cluster=cluster_addr(fnbr,NEXT_CLUSTER); ///physical address of file data that the
      /// specific cluster indexes
      #IF MMC_WRITE_TRACE
         printf("nxt_cluster=%lu",nxt_cluster);
      #ENDIF

      if ( nxt_cluster==0xFFFFFFFF){
         #IF MMC_WRITE_TRACE
            printf("updating FAT");
         #ENDIF
         //// FAT2 is an identical copy of FAT1
         file_new_cluster(fnbr,1); /// a new cluster is allocated in FAT1
         file_new_cluster(fnbr,2); /// a new cluster is allocated in FAT2
         nxt_cluster=cluster_addr(fnbr,NEXT_CLUSTER); ///physical address of file data that the
         #IF MMC_WRITE_TRACE
            printf("\n\r write>>nxt_cluster addr=%lu this clstr=%lu next=%lu",nxt_cluster,file[fnbr].this_cluster_ptr,file[fnbr].next_cluster_ptr); /// specific cluster indexes
         #ENDIF
      }

      file[fnbr].addr_ptr =nxt_cluster;
      file[fnbr].cluster_offset=file[fnbr].cluster_offset + cluster_size_bytes; //foffset is the byte offset within the file
      //that file_addr_ptr points to
      address=file[fnbr].addr_ptr + file[fnbr].offset - file[fnbr].cluster_offset + in_cluster_size;
      #IF MMC_WRITE_TRACE
         printf("out addr=%lu,out size=%lu",address,out_cluster_size);
      #ENDIF
      if(write_BLOCK(address,&buff[in_cluster_size],out_cluster_size)==false)return(82); /// write block pads with 0x00 to end of sector
   }// end of spanned cluster
   else{
      /// within the current cluster
      address=file[fnbr].addr_ptr+file[fnbr].offset - file[fnbr].cluster_offset;



      if(write_BLOCK(address,buff,file[fnbr].rec_size)==false)return(84); /// write block pads with 0x00 to end of sector

   }
   if(appending_flag==1) {
      /// if appended we need to up date the file size
      file[fnbr].size=file[fnbr].size + file[fnbr].rec_size; /// add one record
      address=file[fnbr].dir_addr_ptr+28; /// file size is offset 28 in tiles
      #IF MMC_WRITE_TRACE
         printf("new file size=%lu",file[fnbr].size);
      #ENDIF
      buff[0]=make8(file[fnbr].size,0);
      buff[1]=make8(file[fnbr].size,1);
      buff[2]=make8(file[fnbr].size,2);
      buff[3]=make8(file[fnbr].size,3);
      MMC_dir_protected=false;
      if(write_BLOCK(address,buff,4)==false)return(85);
   }
   if(set_BLOCKLEN(file[fnbr].rec_size)==false) return(86); /// reset to original rec_size
   return(0);
}


#separate
int file_set(int fnbr,int32 offset){
   /// file open sets the offset to the begining offset=0
   /// this sets the offset within the file ...offset of 0 is a reset

   if(offset>=file[fnbr].size) return(71);

   file[fnbr].offset=offset; //// overwrite the existing offset
   file[fnbr].next_cluster_ptr=file[fnbr].root_cluster_ptr; /// set current ptr to beginning
   file[fnbr].cluster_offset=0;
   // move the cluster to the one containing the offset

   while ( offset>cluster_size_bytes ){

      file[fnbr].addr_ptr=cluster_addr(fnbr,NEXT_CLUSTER);
      file[fnbr].cluster_offset+=cluster_size_bytes; //foffset is the byte offset within the file
      if (offset-cluster_size_bytes >0) offset= offset - cluster_size_bytes;

   }
   return(0);
}


#separate
int file_new_cluster(int8 fnbr,int8 mode){ ///////////// this does identical writes to either the FAT1 and FAT2 sectors
   int16 eof_cluster;

   char buff[2],tmp_buff[2];
   int32 address;
   int32 fat_address;
   int16 slot;
   /// an unused cluster has the value 0x0000 as its next cluster ptr
   /// a used cluster has either 0xFFFF meaning last in chain
   /// or a valid cluster displacement in the FAT1 amd FAT2 area
   /// to append a cluster the 0XFFFF needs to be replaced by the appended
   /// cluster location and the appended locations data (next ptr) needs to be set to 0XFFFF



   eof_cluster=file[fnbr].this_cluster_ptr;
   #IF MMC_NEW_CLUSTER
      printf("the cluster with eof (FFFF)=%lu \n\r",eof_cluster);
   #ENDIF

   slot=0;
   if(set_BLOCKLEN((int32)2)==false)return(false); // force blocklen to 2
   /// use global address of FAT1 assigned by INIT
   if (mode==2)fat_address=fat2_address;
   else fat_address=fat1_address;
   address=fat_address;

   #IF MMC_NEW_CLUSTER
      printf("mode=%u FAT addr=%lu \n\r",mode,address);
   #ENDIF

   do{
      if(read_block(address,buff)==false) return(false) ;
      slot=slot+1;
      address=address+2;
      //printf(" slot %lu =%2x %2x",slot,buff[0],buff[1]);
   }
   while (buff[0]!=0 || buff[1]!=0);

   address=address-2; // correct for over step
   slot=slot-1;


   #IF MMC_NEW_CLUSTER
      printf("slot=%lu address=%lu",slot,address);
   #ENDIF

   /// found an unused cluster
   tmp_buff[0]=0xFF;tmp_buff[1]=0xFF; /// stamp it as last
   MMC_dir_protected=false; /// allow writes to the protected areas
   if(write_block(address,tmp_buff,2)==false ) return(false);

   /////////////////////////////////////////////
   /// update prev cluster with 0xFFFF in it
   tmp_buff[1]=make8(slot,1);
   tmp_buff[0]=make8(slot,0);
   if (mode==1){
      //// update the file info
      file[fnbr].next_cluster_ptr=slot;
      #IF MMC_NEW_CLUSTER
         printf("cluster %lu was updated to point to %lu",file[fnbr].this_cluster_ptr,file[fnbr].next_cluster_ptr);
      #ENDIF
   }
   /// compute physical address of the current cluster
   MMC_dir_protected=false; /// allow writes to the protected areas
   if(write_BLOCK(fat_address+(file[fnbr].this_cluster_ptr)*2,tmp_buff,2)==false) return(33);
   if(set_BLOCKLEN((int32)file[fnbr].rec_size)==false)return(false); // reset blocklen

   return(true);
}


/*signed int strncmp(char *s1, char *s2, int n){
   for (; n > 0; s1++, s2++, n--){
      if (*s1 != *s2) return((*s1 <*s2) ? -1: 1);
      else if (*s1 == '\0') return(0);
   }
   return(0);
}*/

⌨️ 快捷键说明

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