📄 fat.c
字号:
////////////////////////////////////////////////////////////////
//
// FAT16 Functions
// Undergraduate Student Project
// Instrumentation, Robotics, and Control Laboratory
//
//Group: MotesArt 2
//Author: Bernard James U. Tan
//modified, simplified and expanded from:
//Group: Axel Activity Monitor Phase 2
//Author: Stephen Alfred K. Quedi
//
////////////////////////////////////////////////////////////////
#include <ez8.h>
#include <stdio.h>
#include <stdlib.h>
#include <sio.h>
#include <string.h>
#include "mmc.h"
#include "spi.h"
#include "fat.h"
unsigned char FATentries[512];
unsigned short FATcounter;
unsigned long int FATaddressincrement; //the increment is used so it can be used for both FAT1 and FAT2
unsigned char FAThigh;
unsigned char FATlow; //these two are used if a file is larger than one cluster
unsigned char CSV_file[512];
unsigned short CSVcounter;
unsigned long int CSVaddress;
unsigned char DATAarray[512];
unsigned short DATAcounter;
unsigned long int DATAaddress;
unsigned long int DATAsectorcount; //incremented every 512 bytes, bec 512bytes/sector, also used for to know cluster count: 16sectors/cluster
unsigned long int DATAsectorcountflag=0;
void format_to_fat16 (void) //format function
{ // this is for 512mb
unsigned char buffer[512]={ //BPB_FAT16
0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x10,0x08,0x00,
0x02,0x00,0x02,0x00,0x00,0xF8,0xF0,0x00,0x3F,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,
0x00,0xF6,0x0E,0x00,0x00,0x00,0x29,0xEB,0x02,0x9D,0x3C,0x4E,0x4F,0x20,0x4E,0x41,
0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20,0x33,0xC9,
0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C,
0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A,
0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,
0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7,
0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11,
0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,
0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6,
0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6,
0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0,
0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E,
0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB,
0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8,
0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0,
0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6,
0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8,
0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8,
0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB,
0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33,
0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8,
0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42,
0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03,
0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB,
0xB0,0x4E,0x54,0x4C,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65,
0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74,
0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73,
0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20,
0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61,
0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA};
unsigned long i,j;
unsigned int err=0;
unsigned long int temporary;
char errorprinted=0;
PDOUT |= 0x01; //symbolyzes error, LED1 on
PBOUT |= 0x80;
do{
err=InitMMC(); //Initialize SPI ports to be used for MMC
if (err==0){
err=WriteMMC(start_address,buffer); //From Experiment, if connection is not okay, it waits here
ReadMMC(start_address,buffer);
if (buffer[0]!=0xEB) err++;
if (buffer[1]!=0x3C) err++;
if (buffer[2]!=0x90) err++;
if (buffer[3]!=0x4D) err++;
if (buffer[510]!=0x55) err++;
if (buffer[511]!=0xAA) err++;
if ((err>0)&&(errorprinted==0)){
printf("Format1: Error writting or No MMC/SD inserted\n");
PDOUT |= 0x01; //LED to show it can't write
PBOUT |= 0x80;
errorprinted=1;
}
}
}while (err>0);
err=0;
errorprinted=0;
PDOUT &= ~0x01; //LED1 off, shows it passed through the first write
PBOUT &= ~0x80;
for(i=0;i<512;i++) buffer[i]=0;
for(i=512;i<data_region_addr;i+=512){
err=WriteMMC(i,buffer); //clean all address after BPB&before dataregion
if (i%5120==0){
printf(".");
PDOUT ^= 0x01;
PBOUT ^= 0x80;
}
}
FATentries[0]=0xF8; //initialize FATentries 0xF8 0xFF 0xFF 0xFF then 0 up to the end
for (i=1;i<4;i++) FATentries[i]=0xFF;
for (;i<512;i++) FATentries[i]=0;
do{
err=0;
err=InitMMC(); //Initialize SPI ports to be used for MMC
if (err==0){
err=WriteMMC(FAT1_entries_start,FATentries); //write FAT1 and FAT2, they are identical
ReadMMC(FAT1_entries_start,buffer);
for (i=0;i<4;i++){
if (buffer[i]!=FATentries[i]){
err=1;
if (errorprinted==0){
printf("Format2: Error writting or No MMC/SD inserted\n");
PDOUT |= 0x01; //LED to show it can't write
PBOUT |= 0x80;
errorprinted=1;
}
}
}
}
}while (err==1);
errorprinted=0;
PDOUT &= ~0x01; //LED1 off, shows it passed through the write
PBOUT &= ~0x80;
for (i=0;i<4;i++) buffer[i]=0; //clear buffer
do{
err=InitMMC(); //Initialize SPI ports to be used for MMC
if (err==0){
err=WriteMMC(FAT2_entries_start,FATentries);
ReadMMC(FAT2_entries_start,buffer);
for (i=0,err=0;i<4;i++){
if (buffer[i]!=FATentries[i]){
err=1;
if (errorprinted==0){
printf("Format3: Error writting or No MMC/SD inserted\n");
PDOUT |= 0x01; //LED to show it can't write
PBOUT |= 0x80;
errorprinted=1;
}
}
}
}
}while (err==1);
errorprinted=0;
PDOUT &= ~0x01; //LED1 off, shows it passed through the write
PBOUT &= ~0x80;
for (i=0;i<512;i++) CSV_file[i]=0; //clear array where root directory, thus CSVfiles are to be written
i=0;
CSV_file[i++]='C'; //put volume label of length of 11 or less
CSV_file[i++]='o';
CSV_file[i++]='R';
CSV_file[i++]='e'; //4th char
for (;i<11;i++) CSV_file[i]=32; //32 is space; put other data for it to be a volume label
CSV_file[11]=8;
do{
err=InitMMC(); //Initialize SPI ports to be used for MMC
if (err==0){
err=WriteMMC(root_directory_addr,CSV_file); //From Experiment, if connection is not okay, it waits here
ReadMMC(root_directory_addr,buffer);
for (i=0,err=0;i<25;i++){
if (buffer[i]!=CSV_file[i]){
err=1;
if (errorprinted==0){
printf("Format4: Error writting or No MMC/SD inserted\n");
PDOUT |= 0x01; //LED to show it can't write
PBOUT |= 0x80;
errorprinted=1;
}
}
}
}
}while (err==1);
errorprinted=0;
PDOUT &= ~0x01; //LED1 off, shows it passed through the write
PBOUT &= ~0x80;
DATAaddress=data_region_addr;
return;
}
//root_directory_addr is the location of the folders and //foldercontents is where CSV filename written
unsigned long int foldercontentsaddress=0;
unsigned char previousfolderhighbyte=0;
unsigned char previousfolderlowbyte=0;
unsigned char findlastfolder(void)
//return 0 if last folder found!
//return 1 if none
{
unsigned short FstClusLO; //used to compute the location of the data of the file in the data region
unsigned char err=0;
PDOUT |= 0x01; //symbolyzes error, LED1 on
PBOUT |= 0x80;
do{
err=InitMMC(); //Initialize SPI ports to be used for MMC
}while (err>0);
for (CSVaddress=root_directory_addr,CSVcounter=0;CSVcounter==0;CSVaddress+=512){ //updates global variable CSVaddress
err=ReadMMC(CSVaddress,CSV_file); //updates global variable CSV_file
for (CSVcounter=0;CSVcounter<512;CSVcounter+=32){ //finds the first empty slot in every 32bits
if (CSV_file[CSVcounter]==0) break; //updates global variable CSVcounter
}
if (CSVcounter==512){
CSVcounter=0;
}
if (CSV_file[CSVcounter]==0) break;
}
if (CSVcounter==0){
CSVaddress-=512;
if (CSVaddress<root_directory_addr) return 1;
err=ReadMMC(CSVaddress,CSV_file); //updates global variable CSV_file
CSVcounter=512;
}
for (CSVcounter-=32;!((CSVaddress==root_directory_addr)&&(CSVcounter==0));CSVcounter-=32){
if (CSV_file[CSVcounter+11]==16){ //found the last folder
previousfolderhighbyte=CSV_file[CSVcounter+27];
previousfolderlowbyte=CSV_file[CSVcounter+26];
FstClusLO=previousfolderhighbyte*256+previousfolderlowbyte;
foldercontentsaddress=(FstClusLO-2)*8192+data_region_addr; //8192=0x2000 (bytes in a cluster for 512mb mmc), because the first file have 2 as FstClusLO and dataregion 0x41000
return 0;
}else{
if (CSVcounter==0) CSVaddress-=512;
}
}
PDOUT &= ~0x01; //LED1 off, shows it passed through the write
PBOUT &= ~0x80;
return 1;
}
char filename[9]; //global so it can be used later in writetommc in MMDDYY
void create_folder_file(char * rawfilename, char inrootdir, char isfolder)
{
char prevfilename[9];
unsigned short FATgreaterthanonecluster; //if the file is greater than one cluster, it will write this in the FAT entry
unsigned short FstClusLO; //used to compute the location of the data of the file in the data region
unsigned int i=0,j=0,intdate;
unsigned char err=0, nextblock=0;
char tempdate[3]=0; // string to be made to int
char errorprinted=0;
do{
err=InitMMC();
ReadMMC(FAT1_entries_start,FATentries); //read FATentries just for checking
if ((FATentries[0]==0)&&(errorprinted==0)){ //by experiment, readmmc returns 0 if no card,and we're sure that the first byte at start address is not 0
printf("No MMC/SD inserted\n");
PDOUT |= 0x01; //LED to show it can't write
PBOUT |= 0x80;
errorprinted=1;
}
}while (FATentries[0]==0);
errorprinted=0;
PDOUT &= ~0x01; //turn off the LED
PBOUT &= ~0x80;
for (i=0;i<8;i++) filename[i]=rawfilename[i];
if ((inrootdir==1)||(foldercontentsaddress==0)){ CSVaddress=root_directory_addr;}
else {CSVaddress=foldercontentsaddress;}
for (CSVcounter=0;CSVcounter==0;CSVaddress+=512){ //updates global variable CSVaddress
if ((inrootdir==1)&&(CSVaddress>=data_region_addr)){
printf("FULL MMC/SD Filenames, maximum number of filenames reached.\n");
while (1){
PDOUT ^= 0x02; //blink a LED and stay here
PAOUT ^= 0x10;
for(i=0;i<0xF000;i++);
}
}
if ((inrootdir==0)&&(nextblock==16)){
printf("Folder Full, creating another Folder in rootdir\n");
create_folder_file(rawfilename,1,1);
create_folder_file(rawfilename,inrootdir,isfolder);
return;
}
err=ReadMMC(CSVaddress,CSV_file); //updates global variable CSV_file
for (CSVcounter=0;CSVcounter<512;CSVcounter+=32){ //finds the first empty slot in every 32bits
if (CSV_file[CSVcounter]==0) break; //updates global variable CSVcounter
}
if (CSVcounter==512){
CSVcounter=0;
nextblock++;
}
if (CSV_file[CSVcounter]==0) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -