📄 mmc_spi_fat32.c
字号:
name[j++] = c;
}
if(c!=0x00 && c != 0xFF)
{
for (i=28;i<31;i+=2)
{
c = (char)(*(((char*)beDir)+i));
if (c == 0 || c == 0xFF)
break;
name[j++] = c;
}
}
}
name[j++] = 0;
}
void GetDOSName(DIR *pDir, char *fname)
{
char i,j,leng,c,toext;
toext = FALSE;
j = 0;
leng = strlen(fname);
for (i=0;i<8;i++)
pDir->sName[i] = ' ';
for (i=0;i<3;i++)
pDir->spam[i] = ' ';
for (i=0;i<leng;i++)
{
c = fname[i];
c = toupper(c);
if (c == '.')
{
toext = TRUE;
continue;
}
if (toext)
pDir->spam[j++] = c;
else
pDir->sName[i] = c;
}
}
// Function: Sets the file f to root dir
MMCResponse ReadRootDirectory(char fil)
{
int32 actsector;
if (fil > (MAXFILES-1))
return MMC_INVALID_FILE;
actsector = gFAT32Vars.gStartSector + DiskInfo.FATCopies*DiskInfo.hSectorsPerFat+DiskInfo.Reserved1;
ReadSector(actsector,gFiles[fil].IOpuffer);
gFAT32Vars.gDirEntrySector = actsector;
gFiles[fil].dirSector = actsector;
gFiles[fil].dirIdx = 0;
memcpy(&(gFiles[fil].DirEntry),gFiles[fil].IOpuffer,32);
gFiles[fil].CurrentCluster = DiskInfo.hRootStartCluster;
return MMC_OK;
}
// Funciton: Finds a file
char FindDirEntry(char *fname,char f)
{
DIR *pDir;
int16 i;
char filename[16];
int32 nextcluster,actsector;
if (f > (MAXFILES-1))
{
return FALSE;
}
gFAT32Vars.gFirstEmptyDirEntry = 0xFF;
gFAT32Vars.gFirstDirEntryCluster = 0x0FFFFFFF;
do
{
pDir = (DIR*)(gFiles[f].IOpuffer);
for (i=0;i<DIRENTRYS_PER_SECTOR;i++)
{
if ((pDir->sName[0] == 0xE5 || pDir->sName[0] == 0) && gFAT32Vars.gFirstEmptyDirEntry == 0xFF) // store first free
{
gFAT32Vars.gFirstEmptyDirEntry = i;
gFAT32Vars.gFirstDirEntryCluster = gFiles[f].CurrentCluster;
}
if (pDir->sName[0] == 0)
{
return FALSE;
}
ConvertFilename(pDir,filename);
if (!strcmp(filename,fname))
{
memcpy(&(gFiles[f].DirEntry),pDir,32);
gFiles[f].dirIdx = i;
gFAT32Vars.gDirEntryIdx = i;
return TRUE;
}
pDir++;
}
nextcluster = GetNextCluster(gFiles[f].CurrentCluster);
if (nextcluster != 0x0FFFFFFF && nextcluster != 0)
{
actsector = nextcluster + gFAT32Vars.gFirstDataSector;
ReadSector(actsector,gFiles[f].IOpuffer);
gFAT32Vars.gDirEntrySector = actsector;
gFiles[f].dirSector = actsector;
gFiles[f].CurrentCluster = nextcluster;
}
} while (nextcluster != 0x0FFFFFFF && nextcluster != 0);
return FALSE;
}
// Function: Assign a filenumber(f) and open the directory
// where the file are and return the filename.
char* TryFile(char *fname, char *f)
{
char i,leng;
char *filename;
*f = 0xFF;
for (i=0;i<MAXFILES;i++)
{
if (gFiles[i].Free)
{
*f = i;
break;
}
}
if (*f == 0xFF)
{
return 0;
}
ReadRootDirectory(*f);
filename = fname;
leng = strlen(fname);
for (i=0;i<leng;i++)
{
if (fname[i] == '/')
{
fname[i] = 0;
if (!cwd(filename,*f))
{
gFiles[*f].Free = TRUE;
return 0;
}
filename = fname+i+1;
}
}
return filename;
}
void strfill(char *dest,char *source,int position)
{
char *d;
for(d=dest+position; *source!=0; d++, source++)
{
*d = *source;
}
}
// Parameters: path, the path to the directory you
// want to view
// Function : Initializes file/dir listing
// Examples:
// strcpy(path,""); // the "path" to the root directory
// f = InitList(path);
// ...
// strcpy(path,"DIR3/DIR32/");
// f = InitList(path);
// if(InitList == MMC_OK)
// {
// res = Listfiles(f);
// CloseList(f);
// }
#ifdef ENABLE_FILELISTNG
MMCResponse InitList(char *path)
{
char f;
if(TryFile(path,&f) == 0)
{
return MMC_NOT_FOUND;
}
gFiles[f].Free = FALSE;
StartList.dirSector = gFiles[f].dirSector;
StartList.CurrentCluster = gFiles[f].CurrentCluster;
StartList.dirIdx = 0;
CurrentList.dirSector = gFiles[f].dirSector;
CurrentList.CurrentCluster = gFiles[f].CurrentCluster;
CurrentList.dirIdx = 0;
return f;
}
// Function: Lists a part (aka page) of the files in the directory
// specified by InitList()
// Returns : The number of files/dirs that were listed
int8 ListFiles(char f)
{
DIR *pDir;
char filename[(CHARACTERS_IN_LONG_FILENAMES+1)]; // should be enough with 13+1
char i,u,fni,len;
BOOLEAN isLongFileName = FALSE;
int32 nextcluster,actsector;
if (f > (MAXFILES-1))
return 0;
if(changeList)
{
FreeList();
}
if((gFiles[f].CurrentCluster != CurrentList.CurrentCluster) || (gFiles[f].dirSector != CurrentList.dirSector))
{
gFiles[f].dirSector = CurrentList.dirSector;
gFiles[f].CurrentCluster = CurrentList.CurrentCluster;
ReadSector(gFiles[f].dirSector,gFiles[f].IOpuffer);
}
gFiles[f].dirIdx = CurrentList.dirIdx;
u=0;
do
{
pDir = (DIR*)(&(gFiles[f].IOpuffer[32*(int16)gFiles[f].dirIdx]));
for (i=gFiles[f].dirIdx;i<DIRENTRYS_PER_SECTOR;i++) // loop throu all direntrys in the sector
{
if ((pDir->sName[0] != 0xE5 && pDir->sName[0] != 0)) // if file/dir isn't deleted and isn't the end of the directory
{
if(pDir->bAttr != 0x0F) // Normal filename (8.3)
{
if(isLongFilename) // If this is the short version of the long filename, just save the number
{
if(changeList)
{
FileList[u].shortName = malloc(13); // 8.3 = 8chars + '.' + 3chars + 0x00
FileList[u].isLong = TRUE;
ConvertFilename(pDir,filename);
strcpy(FileList[u].shortName,filename); // copy the 8.3 name of the file
}
u++;
isLongFilename = FALSE;
if(u == MAX_FILE_LIST)
{
gFiles[f].dirIdx = i+1;
return u;
}
}
else // normal 8.3 filename
{
if(changeList)
{
ConvertFilename(pDir,filename);
FileList[u].name = malloc(strlen(filename)+1); // +1 for char 0x00
strcpy(FileList[u].name,filename);
FileList[u].shortName = FileList[u].name; // point to same string
FileList[u].isLong = FALSE;
if(pDir->bAttr & 0x10) // is directory
FileList[u].isDir = TRUE;
else
FileList[u].isDir = FALSE;
}
u++;
if(u == MAX_FILE_LIST)
{
gFiles[f].dirIdx = i+1;
return u;
}
}
}
else if((pDir->bAttr & 0x0F) == 0x0F) // If it is a long filename entry
{
fni = (pDir->sName[0] & 0x3F); // Filename Index
if((pDir->sName[0] & 0x40)) // First LongFilename entry, the last characters of a long filename
{
if(changeList)
{
ConvertLongFilename(pDir,filename);
len = strlen(filename)+CHARACTERS_IN_LONG_FILENAMES*(fni-1); // Length of the long filename
FileList[u].name = malloc(len+1);// number of chars in this strinng + 13 in each other long filname entry
FileList[u].name[len] = 0x00; // set last char to 0
strfill(FileList[u].name,filename,(fni-1)*CHARACTERS_IN_LONG_FILENAMES); //Fills the name from position (fni-1)*13
if(pDir->bAttr & 0x10) // is directory
FileList[u].isDir = TRUE;
else
FileList[u].isDir = FALSE;
}
isLongFilename = TRUE;
}
else if((pDir->sName[0] & 0x80) == 0) // If it is a long filname, but not deleted
{
if(isLongfilename && changeList)
{
ConvertLongFilename(pDir,filename);
strfill(FileList[u].name,filename,(fni-1)*CHARACTERS_IN_LONG_FILENAMES); //Fills the name from position (fni-1)*13
}
else
printf(glcd_putc,"NoLongFileName!");
}
}
}
if (pDir->sName[0] == 0)
{
gFiles[f].dirIdx = END_OF_DIR;
return u;
}
pDir++;
}
nextcluster = GetNextCluster(gFiles[f].CurrentCluster);
if (nextcluster != 0x0FFFFFFF && nextcluster != 0)
{
actsector = nextcluster + gFAT32Vars.gFirstDataSector;
ReadSector(actsector,gFiles[f].IOpuffer);
gFiles[f].dirSector = actsector;
gFiles[f].CurrentCluster = nextcluster;
gFiles[f].dirIdx = 0;
}
} while (nextcluster != 0x0FFFFFFF && nextcluster != 0);
gFiles[f].dirIdx = END_OF_DIR;
return u;
}
// Function: Go to next page in the file/dir list
// Returns : MMCResponse
MMCResponse NextPage(char f)
{
int32 nextcluster,actsector;
if (f > (MAXFILES-1))
return MMC_INVALID_FILE;
CurrentList.dirSector = gFiles[f].dirSector;
CurrentList.CurrentCluster = gFiles[f].CurrentCluster;
if(gFiles[f].dirIdx == DIRENTRYS_PER_SECTOR)
{
nextcluster = GetNextCluster(gFiles[f].CurrentCluster);
if (nextcluster != 0x0FFFFFFF && nextcluster != 0)
{
actsector = nextcluster + gFAT32Vars.gFirstDataSector;
ReadSector(actsector,gFiles[f].IOpuffer);
CurrentList.dirSector = actsector;
CurrentList.CurrentCluster = nextcluster;
CurrentList.dirIdx = 0;
return MMC_OK;
}
return MMC_INVALID_CLUSTER;
}
else if(gFiles[f].dirIdx == END_OF_DIR)
{
return MMC_END_OF_DIR; // Last file/dir have already been listed by ListFiles
}
else
{
CurrentList.dirIdx = gFiles[f].dirIdx;
}
return MMC_OK;
}
// Note: 0 = first page
MMCResponse SetPage(char f, int32 page)
{
int32 i;
MMCResponse res;
if (f > (MAXFILES-1))
return MMC_INVALID_FILE;
CurrentList.dirSector = StartList.dirSector;
CurrentList.CurrentCluster = StartList.CurrentCluster;
CurrentList.dirIdx = StartList.dirIdx; // should always be 0
changeList = FALSE; // this tells the ListFiles function to not change the list, just loop through files
for(i=0;i<page;i++)
{
ListFiles(f);
res = NextPage(f);
if(res != MMC_OK)
{
changeList = TRUE;
return res;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -