Embedded system Fun Blog
























































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

Saturday, 7 January 2012

Memory Card: SDCard Pinout 1

 .from: http://www.frank-zhao.com/cache/fat_sd.php
 

Pin on SD card Function Connect to Pin on AVR
MOSI (Master Out Slave In) The master refers to the device that generates the clock (the microcontroller), the SD card is the slave. Data on this pin travels from the microcontroller to the SD card. Also known as "DI". MOSI
MISO (Master In Slave Out) Data on this pin travels from the SD card to the microcontroller. Also known as "DO". MISO
SCK Serial clock pin, also known as "CLK" SCK
CS Chip select, the SD card pays attention to the data traveling on the SPI bus when this pin is low, and ignores the data on the bus when this pin is high Port B 3, but it can really be any pin since this one is software definable. You should use a pull-up resistor (I use a 10k and it works fine) on this pin.
GND Vss, ground, 0V Ground
3.3V+ Vcc, power supply pin, supply 3.3V to this pin to power the card. Only connect to a 3.3V power supply
  

MBED Example: How to use SDCard libraries

.from: https://github.com/leroilion/mbed/blob/master/SDCard/SDFileSystem/SDFileSystem.cpp

--

#include "mbed.h"
#include "SDFileSystem.h"

SDFileSystem sd(p5, p6, p7, p12, "sd");

int main() {
 FILE *fp = fopen("/sd/myfile.txt", "w");
 fprintf(fp, "Hello World!\n");
 fclose(fp);
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXx SDFileSystem.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx

/* mbed Microcontroller Library - SDFileSystem
 * Copyright (c) 2008-2009, sford
 *
 * Introduction
 * ------------
 * SD and MMC cards support a number of interfaces, but common to them all
 * is one based on SPI. This is the one I'm implmenting because it means
 * it is much more portable even though not so performant, and we already 
 * have the mbed SPI Interface!
 *
 * The main reference I'm using is Chapter 7, "SPI Mode" of: 
 *  http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
 *
 * SPI Startup
 * -----------
 * The SD card powers up in SD mode. The SPI interface mode is selected by
 * asserting CS low and sending the reset command (CMD0). The card will 
 * respond with a (R1) response.
 *
 * CMD8 is optionally sent to determine the voltage range supported, and 
 * indirectly determine whether it is a version 1.x SD/non-SD card or 
 * version 2.x. I'll just ignore this for now.
 *
 * ACMD41 is repeatedly issued to initialise the card, until "in idle"
 * (bit 0) of the R1 response goes to '0', indicating it is initialised.
 *
 * You should also indicate whether the host supports High Capicity cards,
 * and check whether the card is high capacity - i'll also ignore this
 *
 * SPI Protocol
 * ------------
 * The SD SPI protocol is based on transactions made up of 8-bit words, with
 * the host starting every bus transaction by asserting the CS signal low. The
 * card always responds to commands, data blocks and errors.
 * 
 * The protocol supports a CRC, but by default it is off (except for the 
 * first reset CMD0, where the CRC can just be pre-calculated, and CMD8)
 * I'll leave the CRC off I think! 
 * 
 * Standard capacity cards have variable data block sizes, whereas High 
 * Capacity cards fix the size of data block to 512 bytes. I'll therefore
 * just always use the Standard Capacity cards with a block size of 512 bytes.
 * This is set with CMD16.
 *
 * You can read and write single blocks (CMD17, CMD25) or multiple blocks 
 * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When
 * the card gets a read command, it responds with a response token, and then 
 * a data token or an error.
 * 
 * SPI Command Format
 * ------------------
 * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC.
 *
 * +---------------+------------+------------+-----------+----------+--------------+
 * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 |
 * +---------------+------------+------------+-----------+----------+--------------+
 *
 * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95)
 *
 * All Application Specific commands shall be preceded with APP_CMD (CMD55).
 *
 * SPI Response Format
 * -------------------
 * The main response format (R1) is a status byte (normally zero). Key flags:
 *  idle - 1 if the card is in an idle state/initialising 
 *  cmd  - 1 if an illegal command code was detected
 *
 *    +-------------------------------------------------+
 * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle |
 *    +-------------------------------------------------+
 *
 * R1b is the same, except it is followed by a busy signal (zeros) until
 * the first non-zero byte when it is ready again.
 *
 * Data Response Token
 * -------------------
 * Every data block written to the card is acknowledged by a byte 
 * response token
 *
 * +----------------------+
 * | xxx | 0 | status | 1 |
 * +----------------------+
 *              010 - OK!
 *              101 - CRC Error
 *              110 - Write Error
 *
 * Single Block Read and Write
 * ---------------------------
 *
 * Block transfers have a byte header, followed by the data, followed
 * by a 16-bit CRC. In our case, the data will always be 512 bytes.
 *  
 * +------+---------+---------+- -  - -+---------+-----------+----------+
 * | 0xFE | data[0] | data[1] |        | data[n] | crc[15:8] | crc[7:0] | 
 * +------+---------+---------+- -  - -+---------+-----------+----------+
 */
 
#include "SDFileSystem.h"

#define SD_COMMAND_TIMEOUT 5000

SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) :
  FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) {
  	_cs = 1; 
}

int SDFileSystem::disk_initialize() {

	_spi.frequency(100000); // Set to 100kHz for initialisation
	
	// Initialise the card by clocking it a bit (cs = 1)
	for(int i=0; i<16; i++) {   
		_spi.write(0xFF);
	}

	// send CMD0, should return with all zeros except IDLE STATE set (bit 0)
	if(_cmd(0, 0) != 0x01) { 
		fprintf(stderr, "Not in idle state\n");
		return 1;
	}
	
	// ACMD41 to give host capacity support (repeat until not busy)
	// ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand
	for(int i=0;; i++) {
		_cmd(55, 0); 
		int response = _cmd(41, 0);
		if(response == 0) { 
			break;
		} else if(i > SD_COMMAND_TIMEOUT) {
			fprintf(stderr, "Timeout waiting for card\n");
			return 1;
		}	
	}

	_sectors = _sd_sectors();

	// Set block length to 512 (CMD16)
	if(_cmd(16, 512) != 0) {
		fprintf(stderr, "Set block timeout\n");
		return 1;
	}
		
	_spi.frequency(1000000); // Set to 1MHz for data transfer
	return 0;
}

int SDFileSystem::disk_write(const char *buffer, int block_number) {
	// set write address for single block (CMD24)
	if(_cmd(24, block_number * 512) != 0) {
		return 1;
	}

	// send the data block
	_write(buffer, 512);	
	return 0;	
}

int SDFileSystem::disk_read(char *buffer, int block_number) {		
	// set read address for single block (CMD17)
	if(_cmd(17, block_number * 512) != 0) {
		return 1;
	}
	
	// receive the data
	_read(buffer, 512);
	return 0;
}

int SDFileSystem::disk_status() { return 0; }
int SDFileSystem::disk_sync() { return 0; }
int SDFileSystem::disk_sectors() { return _sectors; }

// PRIVATE FUNCTIONS

int SDFileSystem::_cmd(int cmd, int arg) {
	_cs = 0; 

	// send a command
	_spi.write(0x40 | cmd);
	_spi.write(arg >> 24);
	_spi.write(arg >> 16);
	_spi.write(arg >> 8);
	_spi.write(arg >> 0);
	_spi.write(0x95);

	// wait for the repsonse (response[7] == 0)
	for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
		int response = _spi.write(0xFF);
		if(!(response & 0x80)) {
			_cs = 1;
			return response;
		}
	}
	_cs = 1;
	return -1; // timeout
}

int SDFileSystem::_read(char *buffer, int length) {
	_cs = 0;

	// read until start byte (0xFF)
	while(_spi.write(0xFF) != 0xFE);

	// read data
	for(int i=0; i<length; i++) {
		buffer[i] = _spi.write(0xFF);
	}
	_spi.write(0xFF); // checksum
	_spi.write(0xFF);

	_cs = 1;	
	return 0;
}

int SDFileSystem::_write(const char *buffer, int length) {
	_cs = 0;
	
	// indicate start of block
	_spi.write(0xFE);
	
	// write the data
	for(int i=0; i<length; i++) {
		_spi.write(buffer[i]);
	}
	
	// write the checksum
	_spi.write(0xFF); 
	_spi.write(0xFF);

	// check the repsonse token
	if((_spi.write(0xFF) & 0x1F) != 0x05) {
		_cs = 1; 
		return 1;
	}

	// wait for write to finish
	while(_spi.write(0xFF) == 0);

	_cs = 1; 
	return 0;
}

static int ext_bits(char *data, int msb, int lsb) {
	int bits = 0;
	int size = 1 + msb - lsb; 
	for(int i=0; i<size; i++) {
		int position = lsb + i;
		int byte = 15 - (position >> 3);
		int bit = position & 0x7;
		int value = (data[byte] >> bit) & 1;
		bits |= value << i;
	}
	return bits;
}

int SDFileSystem::_sd_sectors() {

	// CMD9, Response R2 (R1 byte + 16-byte block read)
	if(_cmd(9, 0) != 0) {
		fprintf(stderr, "Didn't get a response from the disk\n");
		return 0;
	}
	
	char csd[16];	
	if(_read(csd, 16) != 0) {
		fprintf(stderr, "Couldn't read csd response from disk\n");
		return 0;
	}

	// csd_structure : csd[127:126]
	// c_size        : csd[73:62]
	// c_size_mult   : csd[49:47]
	// read_bl_len   : csd[83:80] 

	int csd_structure = ext_bits(csd, 127, 126);
	int c_size = ext_bits(csd, 73, 62);
	int c_size_mult = ext_bits(csd, 49, 47);
	int read_bl_len = ext_bits(csd, 83, 80);
	
	if(csd_structure != 0) {
		fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures");
		return 0;
	}
			                
	int blocks = (c_size + 1) * (1 << (c_size_mult + 2));
	int block_size = 1 << read_bl_len;

	if(block_size != 512) {
		fprintf(stderr, "This disk tastes funny! I only like 512-byte blocks");
		return 0;
	}
	
	return blocks;
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXx SDFileSystem.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx

/* mbed Microcontroller Library - SDFileSystem
 * Copyright (c) 2008-2009, sford
 */

#ifndef SDFILESYSTEM_H
#define SDFILESYSTEM_H

#include "mbed.h"
#include "FATFileSystem.h"

/* Class: SDFileSystem
 *  Access the filesystem on an SD Card using SPI
 *
 * Example:
 * > SDFileSystem sd(p5, p6, p7, p12, "sd");
 * > 
 * > int main() {
 * >     FILE *fp = fopen("/sd/myfile.txt", "w");
 * >     fprintf(fp, "Hello World!\n");
 * >     fclose(fp);
 * > }
 */
class SDFileSystem : public FATFileSystem {
public:

	/* Constructor: SDFileSystem
	 *  Create the File System for accessing an SD Card using SPI
	 *
	 * Variables:
	 *  mosi - SPI mosi pin connected to SD Card
	 *  miso - SPI miso pin conencted to SD Card
	 *  sclk - SPI sclk pin connected to SD Card
	 *  cs   - DigitalOut pin used as SD Card chip select
   *  name - The name used to access the filesystem
	 */
	SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name);
	virtual int disk_initialize();
	virtual int disk_write(const char *buffer, int block_number);
	virtual int disk_read(char *buffer, int block_number);	
	virtual int disk_status();
	virtual int disk_sync();
	virtual int disk_sectors();

protected:

	int _cmd(int cmd, int arg);
	int _read(char *buffer, int length);
	int _write(const char *buffer, int length);
	int _sd_sectors();
	int _sectors;
	
	SPI _spi;
	DigitalOut _cs;	 
};

#endif

XxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXx


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

SD CARD: SD Code for AT91SAM7S64 using SPI

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

  1. /************************************************************/   
  2. /*       SD Code for   AT91SAM7S64                      */   
  3. /*              By   pasyong                                */   
  4. /*                  2006-5                                  */   
  5. /*              Base IAR 4.30A                      */   
  6. /************************************************************/   
  7. /*-----------------------------------------------------------------------  
  8. Ó²¼þÁ¬½Ó      SD_CS-----------PA25  
  9. -----------------------------------------------------------------------*/   
  10. #include "ioat91sam7s64.h"   
  11. #include "uart.h"   
  12. #include "vs1011.h"   
  13. #define uchar unsigned char   
  14. #define uint unsigned int   
  15. #define SD_CS     ((unsigned int) 1 <<25)   
  16.    
  17.  extern uchar BUFFER[512];   
  18. uchar reading;   
  19. //Ò»¸öÉÈÇø»º³åÇø   
  20. void delay_Nus(unsigned int n)   
  21.     {   
  22.     unsigned char  b;   
  23.         for (b = 1; b<n; b++)   
  24.             ;   
  25.     }   
  26.    
  27. /*-----------------------------------------------------------------------  
  28. PORT_INITº¯Êý  
  29. -----------------------------------------------------------------------*/   
  30. void SD_port_init(void)   
  31. {   
  32. SPI_init();   
  33. *AT91C_PIOA_PER|=SD_CS;   
  34.    //×÷ΪI/OʹÓà  
  35. *AT91C_PIOA_OER|=SD_CS;   
  36.   //Êä³ö   
  37. *AT91C_PIOA_SODR|=SD_CS;   
  38.   //Êä³ö¸ßµçƽ   
  39. }   
  40.    
  41. //****************************************************************************   
  42. //Send a Command to SD-Card   
  43. //Return: the second byte of response register of SD-Card   
  44. //****************************************************************************   
  45. uchar SD_Write_Command(uchar cmd,unsigned long arg)   
  46. {   
  47.    uchar tmp;   
  48.    uchar retry=0;   
  49.    
  50.    //MMC_PORT|=MMC_CS_PIN;       //SD¿¨¹Ø±Õ   
  51.    //send 8 Clock Impulse   
  52.    Write_Byte_SPI(0xFF);   
  53.    
  54.    //set MMC_Chip_Select to low (MMC/SD-Card active)   
  55.   *AT91C_PIOA_CODR|=SD_CS;      //SD¿¨Ê¹ÄÜ   
  56.    
  57.    Write_Byte_SPI(cmd|0x40);   //ËÍÍ·ÃüÁî   
  58.    Write_Byte_SPI(arg>>24);   
  59.    Write_Byte_SPI(arg>>16);     //send 6 Byte Command to MMC/SD-Card   
  60.    Write_Byte_SPI(arg>>8);   
  61.    Write_Byte_SPI(arg&0xff);   
  62.    Write_Byte_SPI(0x95);       //½ö½ö¶ÔRESETÓÐЧµÄCRCЧÑéÂë   
  63.    
  64.    //get 8 bit response   
  65.    //Read_Byte_MMC(); //read the first byte,ignore it.   
  66.    do   
  67.    {  //Only last 8 bit is used here.Read it out.   
  68.       tmp = Read_Byte_SPI();   
  69.       retry++;   
  70.    }   
  71.    while((tmp==0xff)&&(retry<100));  //µ±Ã»ÓÐÊÕµ½ÓÐЧµÄÃüÁîµÄʱºò   
  72.    
  73.    if(reading==0)   
  74.    *AT91C_PIOA_SODR|=SD_CS;           //MMC_CS_PIN=1;   
  75.    else *AT91C_PIOA_CODR|=SD_CS;       //MMC_CS_PIN=0;   
  76.    return(tmp);   
  77. }   
  78. //****************************************************************************   
  79. //SD¿¨³õʼ»¯(SPI-MODE)   
  80. //****************************************************************************   
  81. uchar SD_Init(void)   
  82. {   
  83.    uchar retry,temp;   
  84.    uchar i;   
  85.    *AT91C_PIOA_CODR|=SD_CS;       //SD¿¨Ê¹ÄÜ   
  86.    
  87.   delay_Nus(250);  //Wait MMC/SD ready...   
  88.    for (i=0;i<16;i++)   
  89.    {   
  90.       Write_Byte_SPI(0xff); //send 74 clock at least!!!   
  91.    }   
  92.    //Send Command CMD0 to MMC/SD Card   
  93.    retry=0;   
  94.    
  95.    do   
  96.    { //retry 200 times to send CMD0 command   
  97.      temp=SD_Write_Command(0,0);   
  98.      retry++;   
  99.      if(retry==100)   
  100.      {   
  101.       ;//CMD0 Error!   
  102.      }   
  103.    }   
  104.    while(temp!=1);   
  105.    
  106.    //Send Command CMD1 to MMC/SD-Card   
  107.    retry=0;   
  108.    do   
  109.    { //retry 100 times to send CMD1 command   
  110.      temp=SD_Write_Command(1,0);   
  111.      retry++;   
  112.      if(retry==100)   
  113.      {   
  114.      ;   
  115.      }   
  116.    }   
  117.    while(temp!=0);   
  118.    retry=0;   
  119.     SD_Write_Command(16,512);     //ÉèÖÃÒ»´Î¶ÁдBLOCKµÄ³¤¶ÈΪ512¸ö×Ö½Ú   
  120.    
  121.    *AT91C_PIOA_SODR|=SD_CS;    //MMC_CS_PIN=1;  //set MMC_Chip_Select to high   
  122.    return(0); //All commands have been taken.   
  123. }   
  124. //****************************************************************************   
  125. //´ÓSD¿¨¶ÁÒ»¸öÉÈÇø  Return 0 if no Error.   
  126. //****************************************************************************   
  127. uchar SD_Read_Block(unsigned long address)   
  128. {   
  129.    uchar temp=0;uint i=0;   
  130.    reading=1;   
  131.    temp=SD_Write_Command(17,address);     //¶Á³öRESPONSE   
  132.    while (Read_Byte_SPI()!= 0xfe)   
  133.    {;}  //Ö±µ½¶ÁÈ¡µ½ÁËÊý¾ÝµÄ¿ªÊ¼Í·0XFE£¬²ÅÄüÌÐø   
  134.    for(i=0; i<512; i++)   
  135.     {   
  136.     BUFFER[i]=Read_Byte_SPI();   
  137.     }   
  138.    Read_Byte_SPI();//CRC - Byte   
  139.    Read_Byte_SPI();//CRC - Byte   
  140.    reading=0;   
  141.    *AT91C_PIOA_SODR|=SD_CS;         //¹Ø±ÕSD¿¨   
  142.    return(temp);   
  143. }