Phát hiện thẻ SD thất bại

Một phần của tài liệu khảo sát và thực hiện một số ứng dụng với board altera fpga de3 (Trang 89)

CHƢƠNG 6: KẾT LUẬN VÀ ĐỊNH HƢỚNG PHÁT TRIỂN ĐỀ TÀI 6.1 KẾT LUẬN 6.1 KẾT LUẬN

Trong thời gian 4 tháng tìm hiểu đề tài, nhóm đã hoàn thành việc nghiên cứu board DE3 và xây dựng ứng dụng đọc dữ liệu từ SD Card. Qua đề tài này, nhóm có thêm kiến thức về FPGA, Altera DE3, cách xây dựng hệ thống SOPC từ Quartus II và cách sử dụng Nios II để lập trình cho hệ thống phần cứng được thiết kế. Bên cạnh việc có thêm kiến thức mới, chúng tôi cũng học được cách làm việc nhóm hiệu quả. Tuy hoàn thành được việc đọc dữ liệu từ SD Card nhưng do thời gian hạn chế nên nhóm chưa thực được những ứng dụng khác trên Altera DE3 như: nhận dữ liệu qua cổng USB.

6.2 ĐỊNH HƢỚNG PHÁT TRIỂN ĐỀ TÀI

Nghiên cứu board DE3 và xây dựng ứng dụng mà nhóm thực hiện chỉ hoàn thành ở mức cơ bản đọc dữ liệu từ SD Card. Trong thời gian tới, ứng dụng cần được cải tiến và có nhiều tính năng hơn.

Định hướng phát triển cho đề tài:

Xây dựng thêm ứng dụng nhận dữ liệu qua cổng USB có trên board và kết nối được với các thiết bị như máy nghe nhạc, điện thoại... .

TÀI LIỆU THAM KHẢO

[1] DE3 User Manual.

URL: https://www.altera.com/support/training/university/de3.html

[2] Aseem Vasudev and Jayanti Addepalli. Interfacing SD Cards with Blackfin® Processors. 2010.

[3] Getting Started with the Graphical User Interface.

URL:https://www.altera.com/en_US/pdfs/literature/hb/nios2/n2sw_nii52017.pdf

PHỤ LỤC A

SỰ GIAO TIẾP GIỮA BOARD VÀ THÀNH PHẦN TRÊN BOARD

Button và LED đơn:

http://www.mediafire.com/watch/txd4h7er4gtfdyj/WP_20150510_172(1).mp4

Button và LED 7 đoạn:

PHỤ LỤC B

HƢỚNG DẪN XÂY DỰNG SD CARD

 Khi tạo xong project ứng dụng, ta nhấp chuột phải vào DE3_SDCARD chọn New/Source Folder để tạo thư mục chứa các thư viện xây dựng thẻ SD.

Hình B.1: Tạo project ứng dụng

 Chúng ta sẽ tạo 3 thư mục đó là terasic_fat, terasic_lib và terasic_sdcard. Ta nhấp chuột phải vào DE3_SDCARD chọn New/Source Folder để tạo một thư mục.

Hình B.2: Tạo thư mục chứa các thư viện

 Khi thư mục terasic_fat được tạo ra, ta nhấp chuột phải vào nó và chọn New, sau đó chọn Source File và Header File để tạo thư viện .c và .h, ta đặt tên là

Hình B.3: Tạo thư viện .c

Hình B.4: Tạo thư viện .h Thư viện FatFileSystem.c:

#include <string.h> // memcpy

#include "..\terasic_lib\terasic_includes.h" #include "FatFileSystem.h"

#include "FatInternal.h" #ifdef DEBUG_FAT

#define FAT_DEBUG(x) DEBUG(x) #else

#define FAT_DEBUG(x) #endif

void fatComposeShortFilename(FAT_DIRECTORY *pDir, char *szFilename); bool fatSameLongFilename(alt_u16 *p1, alt_u16 *p2);

FAT_HANDLE Fat_Mount(FAT_DEVICE FatDevice, DEVICE_HANDLE hDevice){ //Fat_Unmount(); FAT_HANDLE hFat = 0; if (FatDevice == FAT_SD_CARD){ #ifdef SUPPORT_SD_CARD hFat = fatMountSdcard(); #endif //SUPPORT_SD_CARD

}else if (FatDevice == FAT_USB_DISK){ #ifdef SUPPORT_USB_DISK

hFat = fatMountUsbDisk(hDevice); #endif }

return hFat; }

void Fat_Unmount(FAT_HANDLE Fat){

VOLUME_INFO *pVol = (VOLUME_INFO *)Fat; if (!pVol) return;

#ifdef FAT_READONLY if (pVol->szFatTable){ free(pVol->szFatTable);

pVol->szFatTable = 0; } #endif //#ifdef FAT_READONLY

pVol->bMount = FALSE; free(pVol); }

bool Fat_FileBrowseBegin(FAT_HANDLE hFat, FAT_BROWSE_HANDLE

*pFatBrowseHandle){

VOLUME_INFO *pVol = (VOLUME_INFO *)hFat; if (!pVol) return FALSE;

if (!pVol->bMount) return FALSE; pFatBrowseHandle->DirectoryIndex = 0; pFatBrowseHandle->hFat = hFat;

return TRUE;}

bool Fat_FileBrowseNext(FAT_BROWSE_HANDLE *pFatBrowseHandle, FILE_CONTEXT *pFileContext){

bool bFind = FALSE, bVlaid, bError=FALSE, bLongFilename = FALSE; int OrderValue = 0;

FAT_DIRECTORY *pDir;

unsigned int nSecter, nOffset; char szBlock[512];

VOLUME_INFO *pVol = (VOLUME_INFO *)pFatBrowseHandle->hFat; if (!pVol) return FALSE;

if (!pVol->bMount) return FALSE;

do{nOffset=(sizeof(FAT_DIRECTORY)*pFatBrowseHandle->DirectoryIndex)/pVol- > BPB_BytsPerSec;

nSecter = pVol->RootDirectoryEntrySecter + nOffset; if (!pVol->ReadBlock512(pVol->DiskHandle, nSecter, szBlock)){ bError = TRUE;}

else{

nOffset=(sizeof(FAT_DIRECTORY)*pFatBrowseHandle>DirectoryIndex)%pVol- >BPB_BytsPerSec;

pDir = (FAT_DIRECTORY *)(szBlock + nOffset); pFatBrowseHandle->DirectoryIndex++;

bVlaid = fatIsValid(pDir);

if (bVlaid){ if ((pDir->Attribute & ATTR_LONG_NAME) == ATTR_LONG_NAME) { FAT_LONG_DIRECTORY *pLDIR = (FAT_LONG_DIRECTORY *)pDir;

// check attribute

if ((pLDIR->LDIR_Attr & ATTR_LONG_NAME) != ATTR_LONG_NAME){ bError = TRUE; }else{ // check order if (OrderValue == 0){ if (bLongFilename) bError = TRUE; else

OrderValue = pLDIR->LDIR_Ord & 0x3F;

memset(pFileContext->szName, 0, sizeof(pFileContext->szName)); }else{

if ((pLDIR->LDIR_Ord & 0x3F) != OrderValue) bError = TRUE;}} // if (!bError){ int BaseOffset; bLongFilename = TRUE; OrderValue--; BaseOffset = OrderValue * 26; // cast filename memcpy(pFileContext->szName+BaseOffset, pLDIR->LDIR_Name1, 10); memcpy(pFileContext->szName+BaseOffset+10, pLDIR->LDIR_Name2, 12); memcpy(pFileContext->szName+BaseOffset+22, pLDIR->LDIR_Name3, 4);}

}else{

if (bLongFilename){ pFileContext->Attribute = ATTR_LONG_NAME; if ((pDir->Attribute & (ATTR_ARCHIVE | ATTR_DIRECTORY)) == 0) bError = TRUE;

else

bFind = TRUE;}

else{ fatComposeShortFilename(pDir, pFileContext->szName); bFind = TRUE;}

if (bFind){ // my ext

pFileContext->bLongFilename = bLongFilename;

pFileContext->bFile = (pDir->Attribute & ATTR_ARCHIVE)?TRUE:FALSE; pFileContext->bDirectory = (pDir->Attribute & ATTR_DIRECTORY)?TRUE:FALSE; pFileContext->bVolume = (pDir->Attribute & ATTR_VOLUME_ID)?TRUE:FALSE; // pFileContext->Attribute = pDir->Attribute; pFileContext->CreateTime = pDir->CreateTime; pFileContext->LastAccessDate = pDir->LastAccessDate; pFileContext->FirstLogicalClusterHi = pDir->FirstLogicalClusterHi; pFileContext->LastWriteTime = pDir->LastWriteTime; pFileContext->LastWriteDate = pDir->LastWriteDate; pFileContext->FirstLogicalCluster = pDir->FirstLogicalCluster; pFileContext->FileSize = pDir->FileSize;}}}} }while (!bFind && !fatIsLast(pDir) && !bError);

return bFind;} /*

bool Fat_FileBrowseNext(FAT_BROWSE_HANDLE *pFatBrowseHandle, FAT_DIRECTORY *pDirectory){

bool bFind = FALSE, bError=FALSE; FAT_DIRECTORY *pDir;

unsigned int nSecter, nOffset; char szBlock[512];

VOLUME_INFO *pVol = (VOLUME_INFO *)pFatBrowseHandle->hFat; if (!pVol) return FALSE;

if (!pVol->bMount) return FALSE; do{

nOffset = (sizeof(FAT_DIRECTORY)*pFatBrowseHandle->DirectoryIndex)/pVol- >BPB_BytsPerSec;

// if (!SD_read_block(nSecter, szBlock)){

if (!pVol->ReadBlock512(pVol->DiskHandle, nSecter, szBlock)){ bError = TRUE;

}else{

nOffset = (sizeof(FAT_DIRECTORY)*pFatBrowseHandle->DirectoryIndex)%pVol- >BPB_BytsPerSec;

pDir = (FAT_DIRECTORY *)(szBlock + nOffset);

printf("[%d]=%02Xh\n", pFatBrowseHandle->DirectoryIndex, pDir->Name[0]); pFatBrowseHandle->DirectoryIndex++;

bFind = fatIsValid(pDir); if (bFind){

*pDirectory = *pDir;

printf("find....\n");}} }while (!bFind && !fatIsLast(pDir) && !bError); return bFind;}

*/

unsigned int Fat_FileCount(FAT_HANDLE Fat){ unsigned int nCount = 0;

FAT_BROWSE_HANDLE hBrowse; FILE_CONTEXT FileContext; if (Fat_FileBrowseBegin(Fat, &hBrowse)){ while(Fat_FileBrowseNext(&hBrowse, &FileContext)) nCount++;} return nCount;}

bool fatSameLongFilename(alt_u16 *p1, alt_u16 *p2){ bool bSame = TRUE;

while(bSame && ((*p1 != 0) || (*p2 != 0))){ if (*p1 != *p2){ bSame = FALSE;} p1++; p2++;} return bSame;}

void fatComposeShortFilename(FAT_DIRECTORY *pDir, char *szFilename){ int i,nPos=0;

i=0;

while(i < 8 && pDir->Name[i] != 0 && pDir->Name[i] != ' ') szFilename[nPos++] = pDir->Name[i++];

if (pDir->Attribute & (ATTR_ARCHIVE | ATTR_DIRECTORY)){

szFilename[nPos++] = '.'; i=0;

while(i < 3 && pDir->Extension[i] != 0 && pDir->Extension[i] != ' ') szFilename[nPos++] = pDir->Extension[i++];}

szFilename[nPos++] = 0;} // File Access

FAT_FILE_HANDLE Fat_FileOpen(FAT_HANDLE Fat, const char *pFilename){ bool bFind = FALSE;

FAT_BROWSE_HANDLE hBrowse; FILE_CONTEXT FileContext;

FAT_FILE_INFO *pFile = 0;

if (Fat_FileBrowseBegin(Fat, &hBrowse)){

while (!bFind && Fat_FileBrowseNext(&hBrowse, &FileContext)){ if (FileContext.bLongFilename){

bFind = fatSameLongFilename((alt_u16 *)FileContext.szName, (alt_u16

*)pFilename); }else{

if (strcmpi(FileContext.szName, pFilename) == 0)bFind = TRUE;} if (bFind){ pFile = malloc(sizeof(FAT_FILE_INFO)); if (pFile){ pFile->SeekPos = 0; pFile->Directory = FileContext; pFile->IsOpened = TRUE; pFile->Cluster = FileContext.FirstLogicalCluster; pFile->ClusterSeq = 0; pFile->Fat = Fat;}}}} return (FAT_FILE_HANDLE)pFile;}

unsigned int Fat_FileSize(FAT_FILE_HANDLE hFileHandle){ FAT_FILE_INFO *f = (FAT_FILE_INFO *)hFileHandle; if (f->IsOpened)

return f->Directory.FileSize; return 0;}

bool Fat_FileRead(FAT_FILE_HANDLE hFileHandle, void *pBuffer, const int nBufferSize){

FAT_FILE_INFO *f = (FAT_FILE_INFO *)hFileHandle; VOLUME_INFO *pVol;

unsigned int Pos, PhysicalSecter, NextCluster, Cluster; unsigned int BytesPerCluster, nReadCount=0, nClusterSeq;

int s;

bool bSuccess= TRUE; char szBlock[512];

if (!f || !f->Fat) return FALSE; pVol = (VOLUME_INFO *)f->Fat; if (!f->IsOpened){

FAT_DEBUG(("[FAT] Fat_FileRead, file not opened\r\n")); return bSuccess;}

BytesPerCluster = pVol->nBytesPerCluster; //gVolumeInfo.BPB_BytsPerSec * gVolumeInfo.BPB_SecPerCluster;

Pos = f->SeekPos;

if (BytesPerCluster == 32768){ nClusterSeq = Pos >> 15; Pos -= (f->ClusterSeq << 15);}

else if (BytesPerCluster == 16384){ nClusterSeq = Pos >> 14; Pos -= (f->ClusterSeq << 14);}

else if (BytesPerCluster == 2048){ nClusterSeq = Pos >> 11; Pos -= (f->ClusterSeq << 11);}

else{ nClusterSeq = Pos/BytesPerCluster;

Pos -= f->ClusterSeq*BytesPerCluster;} Cluster = f->Cluster;

if (nClusterSeq != f->ClusterSeq){ Cluster = f->Cluster; // move to first clustor for reading

while (Pos >= BytesPerCluster && bSuccess){ // go to next cluster

NextCluster = fatNextCluster(pVol, Cluster);

if (NextCluster == 0){ bSuccess = FALSE; FAT_DEBUG(("[FAT] Fat_FileRead, not next Cluster, current Cluster=%d\r\n", Cluster)); } else{ Cluster = NextCluster; }

Pos -= BytesPerCluster; f->Cluster = Cluster;

f->ClusterSeq++; }} // reading

while(nReadCount < nBufferSize && bSuccess){ if (pVol->BPB_SecPerCluster == 32)

PhysicalSecter = ((Cluster-2) << 5) + pVol->DataEntrySecter; // -2: FAT0 & FAT1 are reserved

else if (pVol->BPB_SecPerCluster == 64)

PhysicalSecter = ((Cluster-2) << 6) + pVol->DataEntrySecter; // -2: FAT0 & FAT1 are reserved

PhysicalSecter = (Cluster-2)*pVol->BPB_SecPerCluster + pVol- >DataEntrySecter; // -2: FAT0 & FAT1 are reserved

for(s=0;s<pVol->BPB_SecPerCluster && nReadCount < nBufferSize;s++){ if (Pos >= pVol->BPB_BytsPerSec){Pos -= pVol->BPB_BytsPerSec;}

else{

int nCopyCount;

nCopyCount = pVol->BPB_BytsPerSec; if (Pos) nCopyCount -= Pos;

if (nCopyCount > (nBufferSize-nReadCount)) nCopyCount = nBufferSize- nReadCount;

if (nCopyCount == 512){

//if (PhysicalSecter == 262749)

// FAT_DEBUG(("[FAT] here, 262749"));

if (!pVol->ReadBlock512(pVol->DiskHandle, PhysicalSecter, (char

*)pBuffer+nReadCount)){

bSuccess = FALSE; // fail

FAT_DEBUG(("[FAT] Fat_FileRead, SD_read_block fail, PhysicalSecter=%d (512)\r\n", PhysicalSecter)); }

else{

//FAT_DEBUG(("[FAT] Fat_FileRead Success, PhysicalSecter=%d (512)\r\n", PhysicalSecter));

nReadCount += nCopyCount; if (Pos > 0) Pos = 0;}} else{

if (!pVol->ReadBlock512(pVol->DiskHandle, PhysicalSecter, szBlock)){ bSuccess = FALSE; // fail

FAT_DEBUG(("[FAT] Fat_FileRead, SD_read_block fail\r\n"));

else{memcpy((void *)((char *)pBuffer+nReadCount), szBlock+Pos,nCopyCount);

nReadCount += nCopyCount;

if (Pos > 0) Pos = 0;}}} PhysicalSecter++; } // next cluster

if (nReadCount < nBufferSize){NextCluster = fatNextCluster(pVol, Cluster); if (NextCluster == 0){ bSuccess = FALSE;

FAT_DEBUG(("[FAT] Fat_FileRead, no next cluster\r\n")); } else{ Cluster = NextCluster;}

//

f->ClusterSeq++;

f->Cluster = Cluster; } }

return bSuccess; }

bool Fat_FileSeek(FAT_FILE_HANDLE hFileHandle, const FAT_SEEK_POS SeekPos, const int nOffset){

FAT_FILE_INFO *f = (FAT_FILE_INFO *)hFileHandle; VOLUME_INFO *pVol;

bool bSuccess= TRUE;

if (!f || !f->Fat) return FALSE; pVol = (VOLUME_INFO *)f->Fat; if (!f->IsOpened) return FALSE; switch(SeekPos){

case FILE_SEEK_BEGIN: f->SeekPos = nOffset; break; case FILE_SEEK_CURRENT: f->SeekPos += nOffset; break;

case FILE_SEEK_END: f->SeekPos = f->Directory.FileSize+nOffset; break; default: bSuccess = FALSE; break; }

f->Cluster = f->Directory.FirstLogicalCluster; f->ClusterSeq = 0; return bSuccess; }

void Fat_FileClose(FAT_FILE_HANDLE hFileHandle){ FAT_FILE_INFO *f = (FAT_FILE_INFO *)hFileHandle; if (!f) return; free(f);}

bool Fat_FileIsOpened(FAT_FILE_HANDLE hFileHandle){ FAT_FILE_INFO *f = (FAT_FILE_INFO *)hFileHandle; if (!f) return FALSE; return f->IsOpened; }

float Fat_SpeedTest(FAT_HANDLE hFat, alt_u32 TestDurInMs){ bool bSuccess = TRUE;

alt_u32 time_start, time_finish, time_elapsed, TotalReadBytes=0; int nSecter = 0;

float fMegaBytePerSec = 0; char szBlock[512];

VOLUME_INFO *pVol = (VOLUME_INFO *)hFat;

if (!pVol) return 0; time_start = alt_nticks();

time_finish = alt_nticks() + TestDurInMs * 1000 / alt_ticks_per_second(); while(alt_nticks() < time_finish && bSuccess){

bSuccess = pVol->ReadBlock512(pVol->DiskHandle, nSecter, szBlock); nSecter++;

TotalReadBytes += sizeof(szBlock); } if (bSuccess){ time_elapsed = alt_nticks() - time_start;

fMegaBytePerSec = (float)TotalReadBytes * (float)alt_ticks_per_second() / (float)time_elapsed / 1024.0 / 1024.0; }

Thư viện FatInternal.c: #include "..\terasic_lib\terasic_includes.h" #include "FatFileSystem.h" #include "FatInternal.h" #include "FatConfig.h" #ifdef SUPPORT_SD_CARD #include "..\terasic_sdcard\SDCardDriver.h" #endif //SUPPORT_USB_DISK #ifdef SUPPORT_USB_DISK #include "..\terasic_usb_isp1761\class\usb_disk\usb_disk.h" #include "..\terasic_usb_isp1761\usb_host\usb_hub.h" #endif //SUPPORT_USB_DISK #ifdef DEBUG_FAT

#define FAT_DEBUG(x) {DEBUG(("[FAT]")); DEBUG(x);} #else

#define FAT_DEBUG(x) #endif

//extern VOLUME_INFO gVolumeInfo; // For FAT16 only

CLUSTER_TYPE fatClusterType(unsigned short Fat){ CLUSTER_TYPE Type;

if (Fat > 0 && Fat < 0xFFF0) Type = CLUSTER_NEXT_INFILE; else if (Fat >= 0xFFF8) // && Fat <= (unsigned short)0xFFFF) Type = CLUSTER_LAST_INFILE;

else if (Fat == (unsigned short)0x00) Type = CLUSTER_UNUSED; else if (Fat >= 0xFFF0 && Fat <= 0xFFF6) Type = CLUSTER_RESERVED; else if (Fat == 0xFFF7) Type = CLUSTER_BAD;

return Type;}

unsigned int fatNextCluster(VOLUME_INFO *pVol, unsigned short

ThisCluster){

CLUSTER_TYPE ClusterType; unsigned int NextCluster; #ifdef FAT_READONLY

// const int nFatEntrySize = 2; // 2 byte for FAT16

// NextCluster = *(unsigned short *)(gVolumeInfo.szFatTable + ThisCluster*nFatEntrySize);

NextCluster = *(unsigned short *)(pVol->szFatTable + (ThisCluster << 1)); ClusterType = fatClusterType(NextCluster);

if (ClusterType != CLUSTER_NEXT_INFILE && ClusterType != CLUSTER_LAST_INFILE){

NextCluster = 0; // invalid cluster } #else

int nFatEntryPerSecter;

const int nFatEntrySize = 2; // 2 byte for FAT16 unsigned int Secter;

char szBlock[512];

nFatEntryPerSecter = pVol->BPB_BytsPerSec/nFatEntrySize;

Secter = pVol->FatEntrySecter + (ThisCluster*nFatEntrySize)/pVol- >BPB_BytsPerSec;

if (pVol->ReadBlock512(pVol->DiskHandle, Secter,szBlock)){

NextCluster = *(unsigned short *)(szBlock +

(ThisCluster%nFatEntryPerSecter)*nFatEntrySize); ClusterType = fatClusterType(NextCluster);

if (ClusterType != CLUSTER_NEXT_INFILE && ClusterType !=

CLUSTER_LAST_INFILE)

NextCluster = 0; // invalid cluster } return NextCluster;

#endif

return NextCluster;}

void fatDumpDate(unsigned short Date){ int Year, Month, Day;

Year = ((Date >> 9) & 0x1F) + 1980; Month = ((Date >> 5) & 0xF);

Day = ((Date >> 0) & 0x1F);

FAT_DEBUG(("%d,%d,%d", Year, Month, Day)); } void fatDumpTime(unsigned short Date){

int H,M,S;

H = ((Date >> 9) & 0x1F); M = ((Date >> 5) & 0x3F); S = ((Date >> 0) & 0x1F)*2;

FAT_DEBUG(("%d:%d:%d", H, M, S)); } bool fatIsLast(FAT_DIRECTORY *pDir){

if (pDir->Name[0] == 0x00) return TRUE;

return FALSE; }

char szTest[] = {0x00, 0xE5, 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C}; int i; for(i=0;i<sizeof(szTest)/sizeof(szTest[0]);i++){ if (pDir->Name[0] == szTest[i]){ return FALSE;}} return TRUE;} // debug

void fatDump(FAT_DIRECTORY *pDir){

char szInvalidName[] = {0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C};

int i;

if (pDir->Name[0] == (char)0xE5){

FAT_DEBUG(("the directory entry is free.\n")); return;}

if (pDir->Name[0] == 0x00){

FAT_DEBUG(("the directory entry is free, and there are no allocated directory entries after tis one.\n"));

return;}

if (pDir->Name[0] <= 0x20 && pDir->Name[0] != 0x05){ FAT_DEBUG(("Invalid file name.\n"));

return;}

for(i=0;i<sizeof(szInvalidName)/sizeof(szInvalidName[0]);i++){

if(pDir->Name[0] == szInvalidName[i]) {FAT_DEBUG(("Invalid file

name.\n")); return;}} //printf("sizeof(FAT_TABLE):%d\n", (int)sizeof(FAT_TABLE)); if (pDir->Name[0] == 0x05){ FAT_DEBUG(("Name:%c%c%c%c%c%c%c%c\n", 0xE5,pDir->Name[1],pDir- >Name[2],pDir->Name[3],pDir->Name[4],pDir->Name[5],pDir->Name[6],pDir- >Name[6])); }else{ FAT_DEBUG(("Name:%c%c%c%c%c%c%c%c\n", pDir->Name[0],pDir->Name[1],pDir- >Name[2],pDir->Name[3],pDir->Name[4],pDir->Name[5],pDir->Name[6],pDir- >Name[6]));} FAT_DEBUG(("Extention:%c%c%c\n",pDir->Extension[0],pDir>Extension[1],pDir- >Extension[2])); FAT_DEBUG(("Attribute:%02Xh\n", pDir->Attribute));

if (pDir->Attribute & ATTR_READ_ONLY) FAT_DEBUG((" Read-Only\n")); if (pDir->Attribute & ATTR_HIDDEN) FAT_DEBUG((" Hidden\n"));

if (pDir->Attribute & ATTR_VOLUME_ID) FAT_DEBUG((" Volume\n")); if (pDir->Attribute & ATTR_DIRECTORY) FAT_DEBUG((" Directory\n")); if (pDir->Attribute & ATTR_ARCHIVE) FAT_DEBUG((" Archive\n")); if (pDir->Attribute & ATTR_LONG_NAME) FAT_DEBUG((" Long Name\n"));

FAT_DEBUG(("CreateTime:"));fatDumpTime(pDir>CreateTime);FAT_DEBUG(("\n")); FAT_DEBUG(("CreateDate:"));fatDumpDate(pDir>LastAccessDate);FAT_DEBUG(("\n ")); FAT_DEBUG(("ClusterHi:%04Xh\n",pDir->FirstLogicalClusterHi)); FAT_DEBUG(("LastWriteTime:"));fatDumpTime(pDir>LastWriteTime);FAT_DEBUG((" \n")); FAT_DEBUG(("LastWriteDate:"));fatDumpDate(pDir>LastWriteDate);FAT_DEBUG((" \n")); FAT_DEBUG(("Cluster:%04Xh(%d)\n", pDir->FirstLogicalCluster,pDir-

>FirstLogicalCluster)); FAT_DEBUG(("File Size:%08Xh(%ld)\n", pDir-

>FileSize, (long)pDir->FileSize));}

unsigned int fatArray2Value(unsigned char *pValue, unsigned int nNum){ unsigned char *pMSB = (pValue + nNum - 1);

unsigned int nValue; int i; for(i=0;i<nNum;i++){ nValue <<= 8; nValue |= *pMSB--; } return nValue;} //

bool fatMount(VOLUME_INFO *pVol){ bool bSuccess = TRUE;

int FirstPartitionEntry,PartitionType,FirstSectionInVolume1; int nFatTableSize,nFatTableSecterNum;//, i;

unsigned char szBlock[512]; // parsing Boot Sector system

// Read the Master Boot Record(MBR) of FAT file system (Locate the section 0)

// Offset:

// 000h(446 bytes): Executable Code (Boots Computer) // 1BEh( 16 bytes): 1st Partition Entry

// 1CEh( 16 bytes): 2nd Partition Entry // 1DEh( 16 bytes): 3nd Partition Entry // 1EEh( 16 bytes): 4nd Partition Entry

// 1FEh( 2 bytes): Executable Maker (55h AAh)

// read first block (secotor 0), BPB(BIOS Parameter Block) or called as boot sector or reserved sector

if (!pVol->ReadBlock512(pVol->DiskHandle, 0, szBlock)){ FAT_DEBUG(("Read section 0 error.\n"));

return FALSE; } /*

if (szBlock[510] != 0x55 || szBlock[511] != 0x55){ FAT_DEBUG(("Invalid 0xAA55 signature\n"));

return FALSE; } */

// check file system

FirstPartitionEntry = 0x1BE;

PartitionType = szBlock[FirstPartitionEntry + 4];

if (PartitionType == PARTITION_FAT16){ FAT_DEBUG(("FAT16\n")); }else if (PartitionType == PARTITION_FAT32){

FAT_DEBUG(("FAT32\n")); }else{

FAT_DEBUG(("the partition type(%d) is not supported.\n", PartitionType)); return FALSE; // only support FAT16 in this example }

pVol->Partition_Type = PartitionType;

// 2.2 Find the first section of partition 1

FirstSectionInVolume1 = fatArray2Value(&szBlock[FirstPartitionEntry + 8],4); //szBlock[FirstPartitionEntry + 8 + 3]*256*256*256 + //szBlock[FirstPartitionEntry + 8 + 2]*256*256 + //szBlock[FirstPartitionEntry + 8 + 1]*256 + //szBlock[FirstPartitionEntry + 8]; //3 Parsing the Volume Boot Record(BR)

//3.1 Read the Volume Boot Record(BR)

if (!pVol->ReadBlock512(pVol->DiskHandle, FirstSectionInVolume1,

szBlock)){

FAT_DEBUG(("Read first sector in volume one fail.\n")); return FALSE;}

pVol->PartitionStartSecter = FirstSectionInVolume1; pVol->BPB_BytsPerSec = szBlock[0x0B+1]*256 + szBlock[0x0B]; pVol->BPB_SecPerCluster = szBlock[0x0D];

pVol->BPB_RsvdSecCnt = szBlock[0x0E + 1]*256 + szBlock[0x0E]; pVol->BPB_NumFATs = szBlock[0x10];

pVol->BPB_RootEntCnt = szBlock[0x11+1]*256 + szBlock[0x11]; pVol->BPB_FATSz = szBlock[0x16+1]*256 + szBlock[0x16];

pVol->BPB_FATSz = fatArray2Value(&szBlock[0x24], 4); // BPB_FATSz32

//pVol->BPB_RootEntCnt = fatArray2Value(&szBlock[0x2C], 4); // BPB_RootClus }

if (pVol->BPB_BytsPerSec != 512){

FAT_DEBUG(("This program only supports FAT BPB_BytsPerSec == 512\n")); return FALSE; // only support FAT16 in this example}

#ifdef DUMP_DEBUG

FAT_DEBUG(("First section in partition 1: %04Xh(%d)\n",

gVolumeInfo.PartitionStartSecter, gVolumeInfo.PartitionStartSecter)); FAT_DEBUG(("Byte Per Sector: %04Xh(%d)\n", gVolumeInfo.BPB_BytsPerSec, gVolumeInfo.BPB_BytsPerSec));

FAT_DEBUG(("Sector Per Clusoter: %02Xh(%d)\n",

gVolumeInfo.BPB_SecPerCluster, gVolumeInfo.BPB_SecPerCluster));

FAT_DEBUG(("Reserved Sectors: %04Xh(%d)\n",

gVolumeInfo.BPB_RsvdSecCnt, gVolumeInfo.BPB_RsvdSecCnt));

FAT_DEBUG(("Number of Copyies of FAT: %02Xh(%d)\n",

gVolumeInfo.BPB_NumFATs, gVolumeInfo.BPB_NumFATs));

FAT_DEBUG(("Maxmun Root Directory Entries: %04Xh(%d)\n",

gVolumeInfo.BPB_RootEntCnt, gVolumeInfo.BPB_RootEntCnt));

FAT_DEBUG(("Sectors Per FAT: %04Xh(%d)\n", gVolumeInfo.BPB_FATSz, gVolumeInfo.BPB_FATSz));

#endif //

pVol->FatEntrySecter = pVol->PartitionStartSecter + pVol->BPB_RsvdSecCnt; pVol->RootDirectoryEntrySecter = pVol->FatEntrySecter + pVol->BPB_NumFATs * pVol->BPB_FATSz;

pVol->DataEntrySecter = pVol->RootDirectoryEntrySecter + ((pVol- >BPB_RootEntCnt*32)+(pVol->BPB_BytsPerSec-1))/pVol->BPB_BytsPerSec;

// read FAT table into memory

pVol->nBytesPerCluster = pVol->BPB_BytsPerSec * pVol-

>BPB_SecPerCluster;

nFatTableSecterNum = pVol->BPB_NumFATs * pVol->BPB_FATSz; nFatTableSize = nFatTableSecterNum * pVol->BPB_BytsPerSec; #ifdef FAT_READONLY

pVol->szFatTable = malloc(nFatTableSize); if (!pVol->szFatTable){

FAT_DEBUG(("fat malloc(%d) fail!", nFatTableSize)); return FALSE;}

if (!pVol->ReadBlock512(pVol->DiskHandle, pVol->FatEntrySecter+i, pVol- >szFatTable + i*pVol->BPB_BytsPerSec)){

FAT_DEBUG(("Read first sector in volume one fail.\n")); bSuccess = FALSE;}}

if (!bSuccess && pVol->szFatTable){ free(pVol->szFatTable); pVol->szFatTable = 0;} #endif if (bSuccess){ FAT_DEBUG(("Fat_Mount success\n")); }else{ FAT_DEBUG(("Fat_Mount fail\n"));} pVol->bMount = bSuccess; return bSuccess;} //===================== SUPPORT_SD_CARD #ifdef SUPPORT_SD_CARD

bool SD_ReadBlock512(DISK_HANDLE DiskHandle, alt_u32 PysicalSelector, alt_u8 szBuf[512]){

return SD_read_block(PysicalSelector, szBuf);} FAT_HANDLE fatMountSdcard(void){

FAT_HANDLE hFat = 0; VOLUME_INFO *pVol; const int nMaxTry=10; bool bFind = FALSE; int nTry=0;

bool bSuccess = TRUE;

//1. chek whether SD Card existed. Init SD card if it is present. while(!bFind && nTry++ < nMaxTry){

bFind = SD_card_init();

if (!bFind) usleep(100*1000); } if (!bFind){

FAT_DEBUG(("Cannot find SD card.\n")); return hFat;}

hFat = malloc(sizeof(VOLUME_INFO)); pVol = (VOLUME_INFO *)hFat;

pVol->ReadBlock512 = SD_ReadBlock512; bSuccess = fatMount(pVol);

if (bSuccess){

pVol->bMount = TRUE; }else{ FAT_DEBUG(("Fat_Mount fail\n")); free((void *)hFat); hFat = 0;} return hFat;} #endif ////===================== SUPPORT_SD_CARD //===================== SUPPORT_USB_DISK #ifdef SUPPORT_USB_DISK

FAT_HANDLE fatMountUsbDisk(DEVICE_HANDLE hDevice){ FAT_HANDLE hFat = 0;

bool bSuccess = FALSE; USBDISK_HANDLE hUsbDisk; alt_u8 Port, PortStart=1;

USB_DEVICE *pHub = (USB_DEVICE *)hDevice; //int i; if (!pHub) return 0; #ifdef PORT1_CONFIG_AS_DEVICE PortStart = 2; #endif // PORT1_CONFIG_AS_DEVICE // check whether usb driver is ready

for(Port=PortStart;Port<=3 && !bSuccess;Port++){ if (Hub_IsDeviceAttached(pHub, Port)){

FAT_DEBUG(("Port %d is attached\n", Port)); hUsbDisk = USBDISK_Open(pHub, Port);

if (hUsbDisk) bSuccess = TRUE;}} if (bSuccess){

VOLUME_INFO *pVol;

hFat = malloc(sizeof(VOLUME_INFO)); pVol = (VOLUME_INFO *)hFat;

pVol->DiskHandle = hUsbDisk; pVol->ReadBlock512 = USBDISK_ReadBlock512; if (!fatMount(pVol)){ free((void *)hFat); hFat = 0;}} return hFat;} #endif ////===================== SUPPORT_USB_DISK

Thư viện FatInternal.c: #include "..\terasic_lib\terasic_includes.h" #include "FatFileSystem.h" #include "FatInternal.h" #include "FatConfig.h" #ifdef SUPPORT_SD_CARD #include "..\terasic_sdcard\SDCardDriver.h" #endif //SUPPORT_USB_DISK #ifdef SUPPORT_USB_DISK #include "..\terasic_usb_isp1761\class\usb_disk\usb_disk.h" #include "..\terasic_usb_isp1761\usb_host\usb_hub.h" #endif //SUPPORT_USB_DISK #ifdef DEBUG_FAT

#define FAT_DEBUG(x) {DEBUG(("[FAT]")); DEBUG(x);} #else

#define FAT_DEBUG(x) #endif

//extern VOLUME_INFO gVolumeInfo; // For FAT16 only

CLUSTER_TYPE fatClusterType(unsigned short Fat){ CLUSTER_TYPE Type; if (Fat > 0 && Fat < 0xFFF0) Type = CLUSTER_NEXT_INFILE;

else if (Fat >= 0xFFF8) // && Fat <= (unsigned short)0xFFFF) Type = CLUSTER_LAST_INFILE;

else if (Fat == (unsigned short)0x00) Type = CLUSTER_UNUSED; else if (Fat >= 0xFFF0 && Fat <= 0xFFF6) Type = CLUSTER_RESERVED; else if (Fat == 0xFFF7) Type = CLUSTER_BAD;

return Type;}

unsigned int fatNextCluster(VOLUME_INFO *pVol, unsigned short

ThisCluster){

CLUSTER_TYPE ClusterType; unsigned int NextCluster; #ifdef FAT_READONLY

// const int nFatEntrySize = 2; // 2 byte for FAT16

// NextCluster = *(unsigned short *)(gVolumeInfo.szFatTable + ThisCluster*nFatEntrySize);

NextCluster = *(unsigned short *)(pVol->szFatTable + (ThisCluster << 1));

ClusterType = fatClusterType(NextCluster);

if (ClusterType != CLUSTER_NEXT_INFILE && ClusterType !=

CLUSTER_LAST_INFILE){

NextCluster = 0; // invalid cluster } #else

int nFatEntryPerSecter;

unsigned int Secter; char szBlock[512];

nFatEntryPerSecter = pVol->BPB_BytsPerSec/nFatEntrySize;

Secter = pVol->FatEntrySecter + (ThisCluster*nFatEntrySize)/pVol- >BPB_BytsPerSec;

if (pVol->ReadBlock512(pVol->DiskHandle, Secter,szBlock)){

NextCluster = *(unsigned short *)(szBlock +

(ThisCluster%nFatEntryPerSecter)*nFatEntrySize); ClusterType = fatClusterType(NextCluster);

if (ClusterType != CLUSTER_NEXT_INFILE && ClusterType !=

CLUSTER_LAST_INFILE)

NextCluster = 0; // invalid cluster } return NextCluster;

#endif

return NextCluster;}

void fatDumpDate(unsigned short Date){ int Year, Month, Day;

Year = ((Date >> 9) & 0x1F) + 1980; Month = ((Date >> 5) & 0xF);

Day = ((Date >> 0) & 0x1F);

FAT_DEBUG(("%d,%d,%d", Year, Month, Day)); } void fatDumpTime(unsigned short Date){

int H,M,S;

H = ((Date >> 9) & 0x1F); M = ((Date >> 5) & 0x3F); S = ((Date >> 0) & 0x1F)*2;

FAT_DEBUG(("%d:%d:%d", H, M, S)); } bool fatIsLast(FAT_DIRECTORY *pDir){

if (pDir->Name[0] == 0x00) return TRUE; return FALSE; }

bool fatIsValid(FAT_DIRECTORY *pDir){

char szTest[] = {0x00, 0xE5, 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C}; int i; for(i=0;i<sizeof(szTest)/sizeof(szTest[0]);i++){ if (pDir->Name[0] == szTest[i]){ return FALSE;}} return TRUE;} // debug

void fatDump(FAT_DIRECTORY *pDir){

char szInvalidName[] = {0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C};

int i;

if (pDir->Name[0] == (char)0xE5){ FAT_DEBUG(("the directory entry is free.\n"));

if (pDir->Name[0] == 0x00){

FAT_DEBUG(("the directory entry is free, and there are no allocated directory entries after tis one.\n"));

return;}

if (pDir->Name[0] <= 0x20 && pDir->Name[0] != 0x05){ FAT_DEBUG(("Invalid file name.\n"));

return;}

for(i=0;i<sizeof(szInvalidName)/sizeof(szInvalidName[0]);i++){ if (pDir->Name[0] == szInvalidName[i]){

FAT_DEBUG(("Invalid file name.\n")); return; }} //printf("sizeof(FAT_TABLE):%d\n", (int)sizeof(FAT_TABLE)); if (pDir->Name[0] == 0x05){ FAT_DEBUG(("Name:%c%c%c%c%c%c%c%c\n", 0xE5,pDir->Name[1],pDir- >Name[2],pDir->Name[3],pDir->Name[4],pDir->Name[5],pDir->Name[6],pDir- >Name[6])); } else{ FAT_DEBUG(("Name:%c%c%c%c%c%c%c%c\n", pDir->Name[0],pDir->Name[1],pDir- >Name[2],pDir->Name[3],pDir->Name[4],pDir->Name[5],pDir->Name[6],pDir- >Name[6])); } FAT_DEBUG(("Extention:%c%c%c\n",pDir->Extension[0],pDir- >Extension[1],pDir->Extension[2])); FAT_DEBUG(("Attribute:%02Xh\n", pDir->Attribute));

if (pDir->Attribute & ATTR_READ_ONLY) FAT_DEBUG((" Read-Only\n")); if (pDir->Attribute & ATTR_HIDDEN) FAT_DEBUG((" Hidden\n"));

if (pDir->Attribute & ATTR_SYSTEM) FAT_DEBUG((" System\n")); if (pDir->Attribute & ATTR_VOLUME_ID) FAT_DEBUG((" Volume\n")); if (pDir->Attribute & ATTR_DIRECTORY) FAT_DEBUG((" Directory\n")); if (pDir->Attribute & ATTR_ARCHIVE) FAT_DEBUG((" Archive\n")); if (pDir->Attribute & ATTR_LONG_NAME) FAT_DEBUG((" Long Name\n")); FAT_DEBUG(("CreateTime:"));fatDumpTime(pDir- >CreateTime);FAT_DEBUG(("\n")); FAT_DEBUG(("CreateDate:"));fatDumpDate(pDir- >LastAccessDate);FAT_DEBUG(("\n")); FAT_DEBUG(("ClusterHi:%04Xh\n", pDir->FirstLogicalClusterHi)); FAT_DEBUG(("LastWriteTime:"));fatDumpTime(pDir- >LastWriteTime);FAT_DEBUG(("\n")); FAT_DEBUG(("LastWriteDate:"));fatDumpDate(pDir- >LastWriteDate);FAT_DEBUG(("\n")); FAT_DEBUG(("Cluster:%04Xh(%d)\n",pDir->FirstLogicalCluster,pDir- >FirstLogicalCluster));

FAT_DEBUG(("File Size:%08Xh(%ld)\n", pDir->FileSize, (long)pDir-

>FileSize));}

unsigned int fatArray2Value(unsigned char *pValue, unsigned int nNum){ unsigned char *pMSB = (pValue + nNum - 1);

unsigned int nValue;

Một phần của tài liệu khảo sát và thực hiện một số ứng dụng với board altera fpga de3 (Trang 89)

Tải bản đầy đủ (PDF)

(133 trang)