Embedded system Fun Blog
























































Find out all the best information, libraries and circuit about the latest Embedded systems.
Showing posts with label drive. Show all posts
Showing posts with label drive. Show all posts

Saturday, 7 January 2012

SD Card Code for AT91SAM7S64

.from: http://read.pudn.com/downloads102/sourcecode/embed/416830/FAT%E6%88%90%E5%8A%9F/fat.c__.htm

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx fat.c XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx


  1. /************************************************************/   
  2. /*       SD Code for   AT91SAM7S64                      */   
  3. /*              By   pasyong                                */   
  4. /*                  2006-5                                  */   
  5. /*              Base IAR 4.30A                      */   
  6. /************************************************************/   
  7. #include <string.h>   
  8. #include "sd.h"   
  9. #include "fat.h"   
  10. #include "uart.h"   
  11. #include "3310.h"   
  12. extern uchar BUFFER[512];   
  13. unsigned char  LONGNAME_BUFFER_ADDR[30];   
  14. unsigned char  DIRNAME_BUFFER_ADDR[30];   
  15.  unsigned char *LongNameBuffer =        (unsigned char *) LONGNAME_BUFFER_ADDR;   
  16. unsigned char *DirNameBuffer =      (unsigned char *) DIRNAME_BUFFER_ADDR;   
  17. struct partrecord *PartInfo;   
  18. unsigned char Fat32Enabled;   
  19. unsigned long FirstDataSector;   
  20. unsigned int  BytesPerSector;   
  21. unsigned int  SectorsPerCluster;   
  22. unsigned long FirstFATSector;   
  23. unsigned long FirstDirSector;   
  24. unsigned long FileSize;   
  25. unsigned long FatInCache = 0;   
  26.    
  27. //********************************************************************************************   
  28. //¶ÁÒ»¸öÉÈÇø   
  29. void ReadBlock(unsigned long LBA)   
  30. //********************************************************************************************   
  31. {   unsigned long temp;   
  32.     temp=LBA<<9;   
  33.     SD_Read_Block(temp);   
  34. }   
  35. /*-----------------------------------------------------------------------   
  36.  ²éѯÊý¾ÝÇøÒ»¸ö´Ø¿ªÊ¼ÉÈÇøºÅ   
  37. -----------------------------------------------------------------------*/   
  38. unsigned long fatClustToSect(unsigned long clust)   
  39. {   
  40.     return ((clust-2) * SectorsPerCluster) + FirstDataSector;   
  41. }   
  42. /*-----------------------------------------------------------------------  
  43.  ²éѯһ¸ö´ØËùÕ¼ÉÈÇøÊý  
  44. -----------------------------------------------------------------------*/   
  45. unsigned int fatClusterSize(void)   
  46. {   
  47.     // return the number of sectors in a disk cluster   
  48.     return SectorsPerCluster;   
  49. }   
  50. /*-----------------------------------------------------------------------  
  51. ²éѯSD¿¨ÎļþϵͳÐÅÏ¢  
  52. -----------------------------------------------------------------------*/   
  53. unsigned char fatInit()   
  54. {       unsigned int data;unsigned char t1,t2;   
  55.         unsigned char PartType;   
  56.         unsigned long StartLBA,FATsecs,Size;   
  57.     //struct bpb710 *bpb;   
  58.     // ¶ÁMBR½á¹¹   
  59.     ReadBlock(0);   
  60.     // ¶ÁÈ¡·ÖÇø±íÐÅÏ¢   
  61.     //PartInfo = ((struct partrecord *) ((struct partsector *)BUFFER)->psPart);   
  62.     // ¶ÁÒýµ¼ÉÈÇø   
  63.     // Òýµ¼ÉÈÇøºÅÔÚPartInfo.prStartLBAÖР  
  64.         PartType=BUFFER[450];   
  65.         Size=BUFFER[458]+(BUFFER[459]<<8)+(BUFFER[460]<<16)+(BUFFER[461]<<24);   
  66.         StartLBA=BUFFER[454]+(BUFFER[455]<<8)+(BUFFER[456]<<16)+(BUFFER[457]<<24);   
  67.         ReadBlock(StartLBA);  //FAT32ʱÊÇ99ºÅÉÈÇø   
  68.    
  69.         //bpb = (struct bpb710 *) ((struct bootsector710 *) BUFFER)->bsBPB;   
  70.    
  71.     FirstDataSector=StartLBA;     //FirstDataSector = PartInfo->prStartLBA;   
  72.        
  73.         FATsecs=BUFFER[22]+(BUFFER[23]<<8);//bpb->bpbFATsecs   
  74.         if(FATsecs)//bpb->bpbFATsecs   
  75.     {   
  76.         // bpbFATsecs·Ç0,ΪFAT16,FAT±íËùÕ¼µÄÉÈÇøÊýÔÚbpbFATsecsÀï   
  77.        FirstDataSector  += BUFFER[14]+(BUFFER[15]<<8)+BUFFER[16]*FATsecs;   
  78.           //FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;   
  79.     }   
  80.     else   
  81.     {   
  82.         // bpbFATsecsÊÇ0,ΪFAT32,FAT±íËùÕ¼µÄÉÈÇøÊýÔÚbpbBigFATsecsÀï   
  83.       FirstDataSector   += BUFFER[14]+(BUFFER[15]<<8)+BUFFER[16]*(BUFFER[36]+(BUFFER[37]<<8)+(BUFFER[38]<<16)+(BUFFER[39]<<24));   
  84.           //FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;   
  85.     }   
  86.        
  87.     SectorsPerCluster   =BUFFER[13]; //bpb->bpbSecPerClust;   
  88.     BytesPerSector      =BUFFER[11]+(BUFFER[12]<<8); //bpb->bpbBytesPerSec;   
  89.     FirstFATSector      =BUFFER[14]+(BUFFER[15]<<8)+StartLBA; //bpb->bpbResSectors + PartInfo->prStartLBA;   
  90. //²éѯSD¿¨Îļþϵͳ·ÖÇøÀàÐÍ   
  91.     switch (PartType)//PartInfo->prPartType   
  92.     {   
  93.         case PART_TYPE_DOSFAT16:   
  94.         case PART_TYPE_FAT16:   
  95.         case PART_TYPE_FAT16LBA:   
  96.             // µÚÒ»¸öĿ¼ÉÈÇøºÅΪ2   
  97.             FirstDirSector  = CLUST_FIRST;   
  98.             //FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;   
  99.             Fat32Enabled = 0;   
  100.                
  101.             break;   
  102.         case PART_TYPE_FAT32LBA:   
  103.         case PART_TYPE_FAT32:   
  104.                
  105.             FirstDirSector =BUFFER[44]+(BUFFER[45]<<8)+(BUFFER[46]<<16)+(BUFFER[47]<<24); //bpb->bpbRootClust;   
  106.             Fat32Enabled = 1;   
  107.             break;   
  108.         default:break;   
  109.             //return 1;   
  110.     }   
  111. //²éѯSD¿¨ÎļþϵͳÐÅÏ¢   
  112.     switch (PartType)   
  113.     {   
  114.         case PART_TYPE_DOSFAT16:   
  115.                 LCD_write_english_string(0,0,"DOSFAT 16");   
  116.                 break;   
  117.         case PART_TYPE_FAT16:   
  118.                 LCD_write_english_string(0,0,"FAT16 ");   
  119.                 break;   
  120.         case PART_TYPE_FAT16LBA:   
  121.                 LCD_write_english_string(0,0,"FAT16 LBA");   
  122.                 break;   
  123.         case PART_TYPE_FAT32LBA:   
  124.                 LCD_write_english_string(0,0,"FAT32 LBA");   
  125.                 break;   
  126.         case PART_TYPE_FAT32:   
  127.                 LCD_write_english_string(0,0,"FAT32");   
  128.                 break;   
  129.         default:   
  130.                 LCD_write_english_string(0,0,"No Partition!");   
  131.                 break;   
  132.     }   
  133.    //ÏÔʾ´ÅÅÌÈÝÁ¿   
  134.   data=Size>>11;   
  135.     LCD_set_XY(56,0);   
  136.     t1=data/100;   
  137.     LCD_write_char(t1+48);   
  138.     data=data%100;   
  139.     t1=data/10;   
  140.     LCD_write_char(t1+48);   
  141.     t2=data%10;   
  142.     LCD_write_char(t2+48);   
  143.     LCD_write_english_string(76,0,"M");   
  144.     LCD_write_english_string(0,1,"RATE");   
  145.        
  146.         return 0;      
  147. }   
  148.    
  149. /*-----------------------------------------------------------------------  
  150. ²éѯһ¸öÎļþµÄ¿ªÊ¼´Ø  
  151. -----------------------------------------------------------------------*/   
  152. unsigned long fatGetDirEntry(unsigned char entry)   
  153. {   
  154.         unsigned char offentry,offsetsector,n;   
  155.         unsigned long temp;   
  156.         offsetsector=entry/16;   
  157.         offentry=entry%16;   
  158.     // read dir data   
  159.         ReadBlock(fatClustToSect(FirstDirSector)+offsetsector);   
  160.         //for( w=0;w<512;w++)   
  161.            //putchar(BUFFER[w]);   
  162.         n=offentry*32;   
  163.     temp=((unsigned long)BUFFER[26+n])+((unsigned long)BUFFER[27+n]<<8) +((unsigned long)BUFFER[20+n] << 16)+((unsigned long)BUFFER[21+n]<<24);   
  164.      //ÎļþµÄÆðʼ´ØµØÖ·   
  165.     if((BUFFER[0+n] == 0x00)||(BUFFER[0+n] == 0xE5))   
  166.     return 0;   
  167.     else   
  168.       return temp;   
  169.        
  170. }   
  171.    
  172.    
  173.    
  174. /*-----------------------------------------------------------------------  
  175.  ÔÚFAT±íÖвéѯÏÂÒ»¸ö´ØËùÔÚÉÈÇøºÅ  
  176. -----------------------------------------------------------------------*/   
  177. unsigned long fatNextCluster(unsigned long cluster)   
  178. {   
  179.     unsigned long nextCluster;   
  180.     unsigned long fatMask;   
  181.     unsigned long fatOffset;   
  182.     unsigned long sector;   
  183.     unsigned int offset;   
  184.        
  185.     if(Fat32Enabled)   
  186.     {   
  187.         // Ò»¸ö±íÏîΪ4bytes(32 bits)   
  188.         fatOffset = cluster << 2;   
  189.         // ÉèÖàFAT32 bit mask   
  190.         fatMask = FAT32_MASK;   
  191.     }   
  192.     else   
  193.     {   
  194.         // Ò»¸ö±íÏîΪ2bytes(16 bits)   
  195.         fatOffset = cluster << 1;   
  196.         // ÉèÖàFAT16 bit mask   
  197.         fatMask = FAT16_MASK;   
  198.     }   
  199.        
  200.     //¼ÆËãFATÉÈÇøºÅ   
  201.     sector = FirstFATSector + (fatOffset / BytesPerSector);   
  202.     //¼ÆËãFATÉÈÇøºÅÖбíÏîµÄÆ«ÒÆµØÖ·   
  203.     offset = fatOffset % BytesPerSector;   
  204.    
  205.     ReadBlock(sector);   
  206.    
  207.     // ¶ÁÈ¡ÏÂÒ»¸ö´ØºÅ   
  208.     nextCluster = (*((unsigned long*) &((char*)BUFFER)[offset])) & fatMask;   
  209.    
  210.     // ÊÇ·ñÎļþµÄ½áÊø´Ø   
  211.     if (nextCluster == (CLUST_EOFE & fatMask))   
  212.         nextCluster = 0;   
  213.            
  214.     return nextCluster;   
  215. }  

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx fat.h XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx


/************************************************************/ 
/*   FAT Code for   AT91SAM7S64      */ 
/*    By   pasyong        */ 
/*     2006-5         */ 
/*    Base IAR 4.30A      */ 
/************************************************************/ 
#ifndef FAT_H 
#define FAT_H 
 
#define CHAR unsigned char 
#define BYTE unsigned char 
#define WORD unsigned int 
#define DWORD unsigned long 
 
//´Ø¶¨Òå 
#define MSDOSFSROOT     0 
#define CLUST_FREE      0 
#define MSDOSFSFREE     CLUST_FREE 
#define CLUST_FIRST     2               // µÚÒ»¸öÊý¾Ý´Ø 
#define CLUST_RSRVD     0xfffffff6      // ϵͳ±£Áô´Ø 
#define CLUST_BAD       0xfffffff7      // »µ´Ø 
#define CLUST_EOFS      0xfffffff8      // µÚÒ»¸ö½áÊø´Ø 
#define CLUST_EOFE      0xffffffff      // ×îºóÒ»¸ö½áÊø´Ø 
 
#define FAT12_MASK      0x00000fff      // FAT12ÑÚÂë 
#define FAT16_MASK      0x0000ffff      // FAT16ÑÚÂë 
#define FAT32_MASK      0x0fffffff      // FAT32ÑÚÂë 
 
 
// ·ÖÇøÀàÐÍ 
#define PART_TYPE_UNKNOWN  0x00 
#define PART_TYPE_FAT12   0x01 
#define PART_TYPE_XENIX   0x02 
#define PART_TYPE_DOSFAT16  0x04 
#define PART_TYPE_EXTDOS  0x05 
#define PART_TYPE_FAT16   0x06 
#define PART_TYPE_NTFS   0x07 
#define PART_TYPE_FAT32   0x0B 
#define PART_TYPE_FAT32LBA  0x0C 
#define PART_TYPE_FAT16LBA  0x0E 
#define PART_TYPE_EXTDOSLBA  0x0F 
#define PART_TYPE_ONTRACK  0x33 
#define PART_TYPE_NOVELL  0x40 
#define PART_TYPE_PCIX   0x4B 
#define PART_TYPE_PHOENIXSAVE 0xA0 
#define PART_TYPE_CPM   0xDB 
#define PART_TYPE_DBFS   0xE0 
#define PART_TYPE_BBT   0xFF 
 
struct partrecord //  16 ×Ö½Ú 
{    
 BYTE prIsActive;     // 0x80´ú±í¸Ã·ÖÇøÎªÈ±Ê¡·ÖÇø 
 BYTE prStartHead;    // ¸Ã·ÖÇøÈë¿ÚµÄ´ÅÍ·µØÖ· 
 WORD prStartCylSect;    // ¸Ã·ÖÇøÈë¿ÚµÄÉÈÇøµØÖ·ºÍÖùÃæµØÖ· 
 BYTE prPartType;     // ¸Ã·ÖÇøÀàÐÍ 
 BYTE prEndHead;     // ¸Ã·ÖÇø½áÊøµÄÉÈÇøµØÖ· 
 WORD prEndCylSect;    // ¸Ã·ÖÇø½áÊøµÄÖùÃæµØÖ· 
 DWORD prStartLBA;     // ¸Ã·ÖÇøÄÚµÚÒ»¸öÉÈÇøµØÖ· 
 DWORD prSize;      // ¸Ã·ÖÇøËù°üº¬µÄÉÈÇø×ÜÊý 
}; 
 
 
struct partsector 
{ 
 CHAR psPartCode[512-64-2];  // Æô¶¯´úÂë (446 bytes) 
 BYTE psPart[64];     // Ëĸö·ÖÇø±í(64 bytes) 
 BYTE psBootSectSig0;    // Á½¸öÇ©Ãû(2 bytes) 
 BYTE psBootSectSig1; 
#define BOOTSIG0        0x55 
#define BOOTSIG1        0xaa 
}; 
 
//ϵͳÒýµ¼ÉÈÇø(DOS BOOT RECORD)DBR½á¹¹ 
 
struct bootsector710 { 
 BYTE bsJump[3];     // Ìø×ªÖ¸Áî 
 CHAR bsOEMName[8];    // ³§É̱êÖ¾ºÍOS°æ±¾ºÅ 
 CHAR bsBPB[53];     // BIOS ²ÎÊý¿é 
 CHAR bsExt[26];     // À©Õ¹BPB 
 CHAR bsBootCode[418];   // Òýµ¼ÉÈÇø´úÂë 
 BYTE bsBootSectSig2;     
 BYTE bsBootSectSig3; 
 BYTE bsBootSectSig0;    // Òýµ¼ÉÈÇøÇ©Ãû0x55 
 BYTE bsBootSectSig1;    // Òýµ¼ÉÈÇøÇ©Ãû0xAA 
#define BOOTSIG0        0x55 
#define BOOTSIG1        0xaa 
#define BOOTSIG2        0 
#define BOOTSIG3        0 
}; 
 
 
// BIOS ²ÎÊý¿é 
struct bpb710 { 
  WORD bpbBytesPerSec; // ÿÉÈÇø×Ö½ÚÊý 
  BYTE bpbSecPerClust; // ÿ´ØÉÈÇøÊý 
  WORD bpbResSectors; // ±£ÁôÇøÓòÖеı£ÁôÉÈÇøÊý 
  BYTE bpbFATs;  // FAT±íµÄ·ÝÊý 
  WORD bpbRootDirEnts; // ¸ùĿ¼ÏîÊý 
  WORD bpbSectors;  // ´ËÓòΪ´æ´¢¾íÉϵÄÉÈÇø×ÜÊý 
  BYTE bpbMedia;  // ¹Ì¶¨´æ´¢½éÖÊÃèÊö 
  WORD bpbFATsecs;  // FAT±íËùÕ¼µÄÉÈÇøÊý 
  WORD bpbSecPerTrack; // ÿµÀÉÈÇøÊý 
  WORD bpbHeads;  // ´ÅÍ·Êý 
  DWORD bpbHiddenSecs; // Òþ²ØÉÈÇøÊý 
  DWORD bpbHugeSectors; // ×ÜÉÈÇøÊý 
  DWORD     bpbBigFATsecs;// ÿ¸öFATÇøËùÕ¼ÉÈÇøÊý 
  WORD      bpbExtFlags; // À©Õ¹±êÖ¾ 
#define FATNUM    0xf    
#define FATMIRROR 0x80    
  WORD      bpbFSVers; // Îļþϵͳ°æ±¾ 
#define FSVERS    0     
  DWORD     bpbRootClust; // ¸ùĿ¼´ØºÅ 
  WORD      bpbFSInfo; // ÎļþϵͳÐÅÏ¢ÉÈÇøºÅ 
  WORD      bpbBackup; // ±¸·ÝÒýµ¼ÉÈÇø 
}; 
 
// Ŀ¼»òÎļþÈë¿ÚµØÖ·½á¹¹ 
struct direntry { 
  BYTE  deName[8];          // ÎļþÃû 
#define SLOT_EMPTY      0x00            // Ŀ¼ÏîΪ¿Õ 
#define SLOT_E5         0x05 
#define SLOT_DELETED    0xe5            // ÎļþÒѱ»É¾³ý 
  BYTE  deExtension[3];     // À©Õ¹Ãû 
  BYTE  deAttributes;       // ÎļþÊôÐÔ 
#define ATTR_NORMAL     0x00            // ¶Áд 
#define ATTR_READONLY   0x01            // Ö»¶Á 
#define ATTR_HIDDEN     0x02            // Òþ²Ø 
#define ATTR_SYSTEM     0x04            // ϵͳÎļþ 
#define ATTR_VOLUME     0x08            // ¾í±êÎļþ 
#define ATTR_LONG_FILENAME 0x0f  // ³¤ÎļþÃûÎļþ    
#define ATTR_DIRECTORY  0x10            // ×ÓĿ¼Îļþ 
#define ATTR_ARCHIVE    0x20            // ¹éµµÎļþ 
  BYTE        deLowerCase;        // ϵͳ±£Áô 
#define LCASE_BASE      0x08 
#define LCASE_EXT       0x10 
  BYTE        deCHundredth;       // Îļþ´´½¨Ê±¼äµÄ10MS 
  BYTE        deCTime[2];         // Îļþ´´½¨Ê±¼ä 
  BYTE        deCDate[2];         // Îļþ´´½¨ÈÕÆÚ 
  BYTE        deADate[2];         // Îļþ×î½ü·ÃÎÊÈÕÆÚ 
  WORD        deHighClust;      // ÎļþÆðʼ´ØºÅµÄ¸ß16λ 
  BYTE        deMTime[2];         // Îļþ×î½üÐÞ¸Äʱ¼ä 
  BYTE        deMDate[2];         // Îļþ×î½üÐÞ¸ÄÈÕÆÚ 
  WORD        deStartCluster;     // ÎļþÆðʼ´ØºÅµÄµÍ16λ 
  DWORD       deFileSize;       // Îļþ³¤¶È 
}; 
 
// Ò»¸öÉÈÇøÖеÄĿ¼ÏîÊý 
#define DIRENTRIES_PER_SECTOR 0x10 
 
// ³¤ÎļþÃûÈë¿ÚµØÖ·½á¹¹ 
struct winentry { 
  BYTE  weCnt; 
#define WIN_LAST        0x40 
#define WIN_CNT         0x3f 
  BYTE  wePart1[10]; 
  BYTE  weAttributes; 
#define ATTR_WIN95      0x0f 
  BYTE  weReserved1; 
  BYTE  weChksum; 
  BYTE  wePart2[12]; 
  WORD        weReserved2; 
  BYTE  wePart3[4]; 
}; 
 
#define WIN_CHARS 13      //³¤ÎļþÃûÈë¿ÚµØÖ·½á¹¹¿É°üº¬13¸ö×Ö·û 
 
//ÔÚFAT32ÖУ¬ÎļþÃû×¿Éµ½255¸ö×Ö·û 
#define WIN_MAXLEN      255 
 
// Ŀ¼»òÎļþÈë¿ÚµØÖ·½á¹¹ÖеÄʱ¼ä½á¹¹ 
 
#define DT_2SECONDS_MASK        0x1F    // Ãë 
#define DT_2SECONDS_SHIFT       0 
#define DT_MINUTES_MASK         0x7E0   // ·Ö 
#define DT_MINUTES_SHIFT        5 
#define DT_HOURS_MASK           0xF800  // ʱ 
#define DT_HOURS_SHIFT          11 
 
// Ŀ¼»òÎļþÈë¿ÚµØÖ·½á¹¹ÖеÄÈÕÆÚ½á¹¹ 
 
#define DD_DAY_MASK             0x1F    // ÈÕ 
#define DD_DAY_SHIFT            0 
#define DD_MONTH_MASK           0x1E0   // ÔÂ 
#define DD_MONTH_SHIFT          5 
#define DD_YEAR_MASK            0xFE00  // Äê - 1980 
#define DD_YEAR_SHIFT           9 
 
// µ÷¿Éº¯Êý 
void ReadBlock(unsigned long LBA); 
unsigned long fatClustToSect(unsigned long clust); 
unsigned char fatInit( void); 
unsigned int fatClusterSize(void); 
unsigned long fatGetDirEntry(unsigned char entry); 
unsigned long fatGetFilesize(void); 
char* fatGetFilename(void); 
char* fatGetDirname(void); 
void fatLoadCluster(unsigned long cluster, unsigned char *buffer); 
unsigned long fatNextCluster(unsigned long cluster); 
 
#endif 

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx