📄 mmc_spi_fat32.c
字号:
MMC_Select(); // if the /CS line of the MMC is low during CMD0,(below), the card enters SPI-mode
MMCOut(0x40); // CMD0
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x95); // CRC
MMC8Clock();
response = MMCIn();
MMC_Deselect();
do
{
delay_us(1000);
//output_low(ChipClk);
MMC_Select();
MMCOut(0x41); // CMD1
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x01);
MMC8Clock();
response = MMCIn();
MMC_Deselect();
MMC8Clock();
errcnt--;
} while (response && errcnt);
if(response == 0)
return MMC_OK;
else
return MMC_TIME_OUT;
}
// "Packed" Date:
// +-------+------------+-------+-----+
// | BITS | 15:9 | 8:5 | 4:0 |
// | VALUE |Year – 1980 | Month | Day |
// +-------+------------+-------+-----+
int16 GetCurrentDOSDate()
{
int16 retval;
retval = Time.Year - 1980;
retval <<= 9;
retval |= ((int16)Time.Month << 5);
retval |= (int16)Time.Day;
return retval;
}
// "Packed" Time:
// +-------+-------+--------+----------+
// | BITS | 15:11 | 10:5 | 4:0 |
// | VALUE | Hour | Minute | Second/2 |
// +-------+-------+--------+----------+
int16 GetCurrentDOSTime()
{
int16 retval;
retval = Time.Hour;
retval <<= 11;
retval |= ((int16)Time.Minute << 5);
retval |= (int16)Time.Second >> 1;
return retval;
}
// Function: Reads a sector from MMC
MMCResponse ReadSector(int32 sector, char *hova)
{
char errs,response;
char cnt2,cnt3;
#byte sectorL = sector
#byte sectorH = sector+1
#byte sectorHL = sector+2
if (!CardInserted())
return MMC_NO_CARD_INSERTED;
Disable_interrupts(GLOBAL);
Restart_wdt();
MMCAddressL = 0;
MMCAddressH = sectorL;
MMCAddressHL = sectorH;
MMCAddressHH = sectorHL;
gFAT32Vars.MMCAddress <<= 1;
MMC_Select();
MMCOut(0x51);
MMCOut(MMCAddressHH);
MMCOut(MMCAddressHL);
MMCOut(MMCAddressH & 0xFE);
MMCOut(0);
MMCOut(0x01);
errs = 8;
do
{
response = MMCIn();
} while (--errs && response==0xFF);
errs = 50;
do
{
response = MMCIn();
if (response == 0xFE)
break;
delay_ms(1);
} while (--errs);
FSR0L = (int16)hova; // *0xFE9
cnt3 = 2;
cnt2 = 0;
do
{
do
{
#ifdef MMC_SPI_SOFTWARE
POSTINC0 = MMC_Xfer(0xFF); // *0xFEE
#else
SSPBUF=0xFF; // Writes 0xFF on SPI
while(!BF); // Wait until Transmitted/Received
POSTINC0 = SSPBUF; // Read the received byte and place it in adress oxFEE
#endif
} while (--cnt2);
} while (--cnt3);
response = MMCIn();
response = MMCIn();
MMC_Deselect();
Enable_interrupts(GLOBAL);
return MMC_OK;
}
// Writes a sector to MMC
MMCResponse WriteSector(int32 sector, char *honnan)
{
char errs,response;
char cnt2,cnt3;
#byte sectorL = sector
#byte sectorH = sector+1
#byte sectorHL = sector+2
if (!CardInserted())
return MMC_NO_CARD_INSERTED;
Disable_interrupts(GLOBAL);
Restart_wdt();
MMCAddressL = 0;
MMCAddressH = sectorL;
MMCAddressHL = sectorH;
MMCAddressHH = sectorHL;
gFAT32Vars.MMCAddress <<= 1;
response = 0;
//output_low(ChipClk);
MMC_Select();
MMCOut(0x58);
MMCOut(MMCAddressHH);
MMCOut(MMCAddressHL);
MMCOut(MMCAddressH & 0xFE);
MMCOut(0);
MMCOut(0x01);
MMC8Clock();
errs = 8;
do
{
response = MMCIn();
} while (--errs && response==0xFF);
if (response)
{
MMC_Deselect();
//output_high(ChipClk);
MMC8Clock();
Enable_interrupts(GLOBAL);
return MMC_INVALID_RESPONSE;
}
MMC8Clock();
MMCOut(0xFE);
FSR0L = (int16)honnan; // *0xFE9
cnt3 = 2;
cnt2 = 0;
do
{
do
{ /*
*/
#ifdef MMC_SPI_SOFTWARE
MMC_Xfer(POSTINC0); // *0xFEE
#else
SSPBUF=POSTINC0; // Write the byte on address oxFEE to SPI
while (!BF);
response = SSPBUF; // thanks to wielen
#endif
} while (--cnt2);
} while (--cnt3);
MMCOut(0x00);
MMCOut(0x01);
response = MMCIn();
response ^= 0xE5; // Bitwise exclusive or assignment operator, x^=y, is the same as x=x^y
if (response)
{
goto endwr3;
}
do
{
response = MMCIn();
} while (response == 0);
response = 0;
endwr3:
MMC_Deselect();
//output_high(ChipClk);
MMC8Clock();
Enable_interrupts(GLOBAL);
return MMC_OK;
}
// Function: Initializes the FAT system
void InitFAT()
{
int32 actsector;
char i;
gFirstEmptyCluster = 0;
gFAT32Vars.gStartSector = 0;
ReadSector(gFAT32Vars.gStartSector,gFiles[MAXFILES-1].IOpuffer);
if (gFiles[MAXFILES-1].IOpuffer[0] != 0xEB)
{
gStartSectorL = gFiles[MAXFILES-1].IOpuffer[0x1C6];
gStartSectorH = gFiles[MAXFILES-1].IOpuffer[0x1C7];
gStartSectorHL = gFiles[MAXFILES-1].IOpuffer[0x1C8];
ReadSector(gFAT32Vars.gStartSector,gFiles[MAXFILES-1].IOpuffer);
}
memcpy(&DiskInfo,gFiles[MAXFILES-1].IOpuffer,sizeof(DiskInfo));
actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1;
ReadSector(actsector,FATTable);
gFAT32Vars.FATstartidx = 0;
gFAT32Vars.gFirstDataSector = gFAT32Vars.gStartSector + DiskInfo.FATCopies*DiskInfo.hSectorsPerFat+DiskInfo.Reserved1 - 2;
for (i=0;i<MAXFILES;i++)
{
gFiles[i].Free = TRUE;
}
#ifdef ENABLE_FILELISTNG
// Code for initializing file-listing
for(i=0;i<MAX_FILE_LIST;i++)
FileList[i].name = NULL;
changeList = TRUE;
#endif
// MMC_Debug("-FATInit ");
}
int32 GetNextCluster(int32 curcluster)
{
int32 actsector;
int32 clpage;
char clpos;
clpage = curcluster >> 7;
clpos = curcluster & 0x7F;
if (clpage != gFAT32Vars.FATstartidx) // read in the requested page
{
actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + clpage;
ReadSector(actsector,FATTable);
gFAT32Vars.FATstartidx = clpage;
}
return (FATTable[clpos]);
}
void SetClusterEntry(int32 curcluster,int32 value)
{
int32 actsector;
int32 clpage;
char clpos;
clpage = curcluster >> 7;
clpos = curcluster & 0x7F;
actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + clpage;
if (clpage != gFAT32Vars.FATstartidx)
{
ReadSector(actsector,FATTable);
gFAT32Vars.FATstartidx = clpage;
}
FATTable[clpos] = value;
WriteSector(actsector,FATTable);
actsector += DiskInfo.hSectorsPerFat;
WriteSector(actsector,FATTable);
}
void ClearClusterEntry(int32 curcluster)
{
int32 actsector;
int32 clpage;
char clpos;
clpage = curcluster >> 7;
clpos = curcluster & 0x7F;
if (clpage != gFAT32Vars.FATstartidx)
{
actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + gFAT32Vars.FATstartidx;
WriteSector(actsector,FATTable);
actsector += DiskInfo.hSectorsPerFat;
WriteSector(actsector,FATTable);
actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + clpage;
ReadSector(actsector,FATTable);
gFAT32Vars.FATstartidx = clpage;
}
FATTable[clpos] = 0;
}
int32 FindFirstFreeCluster()
{
int32 i,st,actsector,retval;
char j;
st = gFirstEmptyCluster;
for (i=st;i<DiskInfo.hSectorsPerFat;i++)
{
if (i != gFAT32Vars.FATstartidx)
{
actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + i;
ReadSector(actsector,FATTable);
gFAT32Vars.FATstartidx = gFirstEmptyCluster = i;
}
for (j=0;j<128;j++)
{
if (FATTable[j] == 0)
{
retval = i;
retval <<= 7;
retval |= j;
return retval;
}
}
}
return 0x0FFFFFFF;
}
// Function: Converts a dir-entry to a 8.3 filename
void ConvertFilename(DIR *beDir,char *name)
{
char i,j,c;
j = 0;
name[0] = 0;
for (i=0;i<8;i++)
{
c = beDir->sName[i];
if (c == ' ')
break;
name[j++] = c;
}
for (i=0;i<3;i++)
{
c = beDir->spam[i];
if (c == ' ' || c == 0)
break;
if (!i)
name[j++] = '.';
name[j++] = c;
}
name[j++] = 0;
}
// Function: Converts a dir-entry to a (part of a) long filename.
// One dir-entry can hold 13 unicode characters
void ConvertLongFilename(DIR *beDir,char *name)
{
char i,j,c;
j = 0;
name[0] = 0;
for (i=1;i<11;i+=2)
{
c = (char)(*(((char*)beDir)+i));
if (c == 0x00 || c == 0xFF)
break;
name[j++] = c;
}
if(c!=0x00 && c!= 0xFF)
{
for (i=14;i<26;i+=2)
{
c = (char)(*(((char*)beDir)+i));;
if (c == 0 || c == 0xFF)
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -