Exemple #1
0
//***************************************************************************
//Function: get cluster entry value from FAT to find out the next cluster in the chain
//or set new cluster entry in FAT
//Arguments: 1. current cluster number, 2. get_set (=GET, if next cluster is to be found or = SET,
//if next cluster is to be set 3. next cluster number, if argument#2 = SET, else 0
//return: next cluster number, if if argument#2 = GET, else 0
//****************************************************************************
unsigned long getSetNextCluster (unsigned long clusterNumber,
                                 unsigned char get_set,
                                 unsigned long clusterEntry)
{
    unsigned int  FATEntryOffset;
    unsigned long *FATEntryValue;
    unsigned long FATEntrySector;
    unsigned char retry = 0;

    //get sector number of the cluster entry in the FAT
    FATEntrySector = unusedSectors + reservedSectorCount + ((clusterNumber * 4) / bytesPerSector) ;
    //get the offset address in that sector number
    FATEntryOffset = (unsigned int) ((clusterNumber * 4) % bytesPerSector);
    //read the sector into a buffer
    while(retry <10)
    {
        if(!SD_readSingleBlock(FATEntrySector)) break;
        retry++;
    }

    //get the cluster address from the buffer
    FATEntryValue = (unsigned long *) &buffer[FATEntryOffset];

    if(get_set == GET) return ((*FATEntryValue) & 0x0fffffff);

    *FATEntryValue = clusterEntry;   //for setting new value in cluster entry in FAT

    SD_writeSingleBlock(FATEntrySector);

    return 0;
}
Exemple #2
0
//********************************************************************************************
//Function: to get or set next free cluster or total free clusters in FSinfo sector of SD card
//Arguments: 1.flag:TOTAL_FREE or NEXT_FREE,
//           2.flag: GET or SET
//           3.new FS entry, when argument2 is SET; or 0, when argument2 is GET
//return: -next free cluster, if arg1 is NEXT_FREE & arg2 is GET
//        -total number of free clusters, if arg1 is TOTAL_FREE & arg2 is GET
//        -0xffffffff, if any error or if arg2 is SET
//********************************************************************************************
unsigned long getSetFreeCluster(unsigned char totOrNext, unsigned char get_set, unsigned long FSEntry)
{
    struct FSInfo_Structure *FS = (struct FSInfo_Structure *) &buffer;
    unsigned char error;

    SD_readSingleBlock(unusedSectors + 1);

    if((FS->leadSignature != 0x41615252) || (FS->structureSignature != 0x61417272) || (FS->trailSignature !=0xaa550000))
        return 0xffffffff;


    if(get_set == GET)
    {
        if(totOrNext == TOTAL_FREE) return(FS->freeClusterCount);
        else // when totOrNext = NEXT_FREE
            return(FS->nextFreeCluster);
    }
    else
    {
        if(totOrNext == TOTAL_FREE) FS->freeClusterCount = FSEntry;
        else // when totOrNext = NEXT_FREE
            FS->nextFreeCluster = FSEntry;
        error = SD_writeSingleBlock(unusedSectors + 1);
        return error;   //update FSinfo
    }
    return 0xffffffff;
}
unsigned char readBootSector(void)
{
    unsigned int signature;
    unsigned long firstSector;
    unsigned long bootfilestart;
    unsigned long hiddenSectors;
    unsigned char numberofFATs;
    unsigned long FATsize_F32;
    unsigned char found;
    
    unusedSectors = 0;
    
    // read first block on card
    SD_readSingleBlock(0);
    
    // check if it is boot sector
    if (buffer[JUMPBOOT] != 0xE9 && buffer[JUMPBOOT] != 0xEB)
    {
        firstSector = *(unsigned long *)&buffer[FIRSTSECTOR];
        unusedSectors = firstSector;
        
        SD_readSingleBlock(firstSector);
        
        if (buffer[JUMPBOOT] != 0xE9 && buffer[JUMPBOOT] != 0xEB)
        {
            return 1;
        }
    }
    
    // read data from bpb
    bytesPerSector = *(unsigned int*)&buffer[BYTESPERSECTOR];
    hiddenSectors = *(unsigned long*)&buffer[28];
    reservedSectorCount = *(unsigned int*)&buffer[RESERVEDSECTORCOUNT];
    numberofFATs = *(unsigned char*)&buffer[16];
    FATsize_F32 = *(unsigned long*)&buffer[FATSIZEF32];
    sectorPerCluster = *(unsigned char*)&buffer[SECTORPERCLUSTER];
    rootCluster = *(unsigned char*)&buffer[ROOTCLUSTER];
    
    firstDataSector = hiddenSectors + reservedSectorCount + (numberofFATs * FATsize_F32);
    return 0;
}
Exemple #4
0
//***************************************************************************
//Function: to get DIR/FILE list or a single file address (cluster number) or to delete a specified file
//Arguments: #1 - flag: GET_LIST, GET_FILE or DELETE #2 - pointer to file name (0 if arg#1 is GET_LIST)
//return: first cluster of the file, if flag = GET_FILE
//        print file/dir list of the root directory, if flag = GET_LIST
//        Delete the file mentioned in arg#2, if flag = DELETE
//****************************************************************************
struct dir_Structure* findFiles (unsigned char flag, unsigned char *fileName)
{
    unsigned long cluster, sector, firstSector;
    struct dir_Structure *dir;
    unsigned int i;
    unsigned char j;

    cluster = rootCluster; //root cluster

    while(1)
    {
        firstSector = getFirstSector (cluster);

        for(sector = 0; sector < sectorPerCluster; sector++)
        {
            SD_readSingleBlock (firstSector + sector);

            for(i=0; i<bytesPerSector; i+=32)
            {
                dir = (struct dir_Structure *) &buffer[i];

                if(dir->name[0] == EMPTY) //indicates end of the file list of the directory
                {
                    if((flag == GET_FILE) || (flag == DELETE))
                        //transmitString("File does not exist!");
                        return 0;
                }

                else if((dir->name[0] != DELETED) && (dir->attrib != ATTR_LONG_NAME))
                {
                    if((flag == GET_FILE) || (flag == DELETE))
                    {
                        for(j=0; j<11; j++)
                            if(dir->name[j] != fileName[j]) break;
                        if(j == 11)
                        {
                            if(flag == GET_FILE)
                                return (dir);
                        }
                    }
                }
            }
        }
        cluster = (getSetNextCluster (cluster, GET, 0));
        if(cluster > 0x0ffffff6) return 0;
        if(cluster == 0)
        {
            //transmitString("Error in getting cluster");
            return 0;
        }
    }
    return 0;
}
Exemple #5
0
//***************************************************************************
//Function: to read data from boot sector of SD card, to determine important
//parameters like bytesPerSector, sectorsPerCluster etc.
//Arguments: none
//return: none
//***************************************************************************
unsigned char getBootSectorData (void)
{
    struct BS_Structure *bpb; //mapping the buffer onto the structure
    struct MBRinfo_Structure *mbr;
    struct partitionInfo_Structure *partition;
    unsigned long dataSectors;

    unusedSectors = 0;

    SD_readSingleBlock(0);
    bpb = (struct BS_Structure *)buffer;

    if(bpb->jumpBoot[0]!=0xE9 && bpb->jumpBoot[0]!=0xEB) //check if it is boot sector
    {
        mbr = (struct MBRinfo_Structure *) buffer;         //if it is not boot sector, it must be MBR
        if(mbr->signature != 0xaa55) return 1;            //if it is not even MBR then it's not FAT32
        partition = (struct partitionInfo_Structure *)(mbr->partitionData);//first partition
        unusedSectors = partition->firstSector; //the unused sectors, hidden to the FAT
        SD_readSingleBlock(partition->firstSector);//read the bpb sector
        bpb = (struct BS_Structure *)buffer;
        if(bpb->jumpBoot[0]!=0xE9 && bpb->jumpBoot[0]!=0xEB)  return 1;
    }

    bytesPerSector      = bpb->bytesPerSector;
    sectorPerCluster    = bpb->sectorPerCluster;
    reservedSectorCount = bpb->reservedSectorCount;
    rootCluster         = bpb->rootCluster;// + (sector / sectorPerCluster) +1;
    firstDataSector     = bpb->hiddenSectors + reservedSectorCount + (bpb->numberofFATs * bpb->FATsize_F32);
    dataSectors         = bpb->totalSectors_F32 - bpb->reservedSectorCount - ( bpb->numberofFATs * bpb->FATsize_F32);
    totalClusters       = dataSectors / sectorPerCluster;

    if((getSetFreeCluster (TOTAL_FREE, GET, 0)) > totalClusters)  //check if FSinfo free clusters count is valid
        freeClusterCountUpdated = 0;
    else freeClusterCountUpdated = 1;

    return 0;
}
unsigned long findFirmware()
{
    unsigned long cluster, firstSector;
    unsigned char attrib;
    unsigned int firstClusterHI; // high word of first cluster
    unsigned int firstClusterLO; // low word of first cluster
    unsigned long firstCluster;
    unsigned long theCluster;
    unsigned long sector;
    int i,j;
    cluster = rootCluster;
    
    firstSector = getFirstSector(cluster);
    
    SD_readSingleBlock(firstSector);
    
    for (i = 0; i < bytesPerSector; i += 32)
    {
        if (buffer[i] == EMPTY)
        {
            return 0;
        }
        
        attrib = buffer[ATTRIB+i];
        if ((buffer[i] != DELETED) && attrib != ATTR_LONG_NAME)
        {
            // check for firmware file
            if ((buffer[i] == 'F') &&
                (buffer[i+1] == 'I') &&
                (buffer[i+2] == 'R') &&
                (buffer[i+3] == 'M') &&
                (buffer[i+8] == 'B') && 
                (buffer[i+9] == 'I') &&
                (buffer[i+10] == 'N'))
            {
                firstClusterLO = *(unsigned int*)&buffer[i+FIRSTCLUSTERLO];
                
                // assume firstClusterHI is 0
                firstCluster = firstClusterLO;
                
                return firstCluster;
            }
        }
    }
    
    return 0;
    
}
Exemple #7
0
//uint8_t readCfgFile(DATE *adate,TIME *atime, uint8_t *filename_dat, uint8_t atomic)
uint8_t readCfgFile(char *filename_dat)				//, uint8_t atomic)
{
	DIR *dir;
	uint32_t cluster, fileSize, firstSector;
	uint16_t k;
	uint8_t i,j,ld,lt;
	uint8_t filename[]= "CONFIG  CFG";
	uint8_t filename2[]="_CONFIG CFG";
	
	
	dir = findFiles (GET_FILE, filename, filename);		//, atomic); 	//get the file location
	if(dir == 0) 
		return(0);

	cluster = (((uint32_t) dir->firstClusterHI) << 16) | dir->firstClusterLO;
	fileSize = dir->fileSize;
	
	ld = 0;
	lt = 0;
	
	while(1)
	{
		ClusterNumber = cluster;
		firstSector = getFirstSector ();
		for(j=0; j<SectorPerCluster; j++)
		{
			SD_readSingleBlock(firstSector + j);			//, atomic);
			for(k=0; k<512; k++)
			{
				switch(buffer[k])
				{
					case	'S':
								k++;
								if(buffer[k]=='T')
								{
									k++;
									Time.h = getDec((uint8_t*)buffer+k);
									//k +=2;
									Time.m = getDec((uint8_t*)buffer+k+2);
									//k +=2;
									Time.s = getDec((uint8_t*)buffer+k+4);
								}
								else if(buffer[k]=='D')
								{	
									k++;
									Date.d = getDec(&buffer[k]);
									//k +=2;
									Date.m = getDec(&buffer[k+2]);
									//k +=2;
									Date.y = 20 + getDec(&buffer[k+4]);
								}
								else if(buffer[k]=='F')
								{
									k = k+2;
									for(i=0;i<8;i++)
									{
										if(buffer[k+i] < 0x21)		//if any control code and space
										{
											filename_dat[i] = 0x00;
											break;
										}
										filename_dat[i] = buffer[k+i];
									}
									filename_dat[i+1] = 0x00;

//									i = strlcpy(filename_dat,&(buffer[k]),9);
									k = k+i;
								}
								else if(buffer[k]=='I')
								{
									k +=2;
									for(i=0;i<13;i++)
									{
										if(buffer[k+i] < 0x20)		//if any control code
											break;
										inset[i] = buffer[k+i];
									}
								}
								break;
					case	'A':
								k++;
								if(buffer[k]=='D')
								{	
									k++;
									ADate[ld].d = getDec((uint8_t*)buffer+k);
									//k +=2;
									ADate[ld].m = getDec((uint8_t*)buffer+k+2);
									//k +=2;
									ADate[ld].y = 20 + getDec((uint8_t*)buffer+k+4);
									ld++;
								}
								else if(buffer[k]=='T')
								{	
									k++;
									ATime[lt].h = getDec((uint8_t*)buffer+k);
									//k +=2;
									ATime[lt].m = getDec((uint8_t*)buffer+k+2);
									//k +=2;
									ATime[lt].s = getDec((uint8_t*)buffer+k+4);
									lt++;
								}
								break;
					
				}
				
				if (k >= fileSize ) 
				{
					findFiles(RENAME, filename, filename2);			//, atomic);
					return(lt);
				}
			}
		}
		ClusterNumber = cluster;
		cluster = getSetNextCluster (GET);						//, 0, atomic);
		if(cluster == 0) 
		{
//#if BIGAVR == 1
//			printf_P(PSTR("ERR GETTING CLUSTERb\n")); 
//#endif		//BIGAVR
			return(0);
		}
	}
	return(0);
}
Exemple #8
0
int main(void)
{
unsigned char option, error, data, FAT32_active;
unsigned int i;
unsigned char fileName[13];

_delay_ms(100);  //delay for VCC stabilization

init_devices();

PORTD |= 0x04; //switching ON the LED (for testing purpose only)

TX_NEWLINE;
TX_NEWLINE;
transmitString_F (PSTR("***********************************"));
TX_NEWLINE;
transmitString_F (PSTR(" Dharmani's microSD Card Testing.."));
TX_NEWLINE;
transmitString_F (PSTR("***********************************"));
TX_NEWLINE;

SD_init();
SPI_HIGH_SPEED;   //SCK - 4 MHz

_delay_ms(1);

FAT32_active = 1;
error = getBootSectorData (); //read boot sector and keep necessary data in global variables
if(error)  
{
  transmitString_F (PSTR("FAT32 not found!"));  //FAT32 incompatible drive
  FAT32_active = 0;
}

while(1)
{
TX_NEWLINE;
transmitString_F(PSTR("Press any key..."));
TX_NEWLINE;
option = receiveByte();
TX_NEWLINE;
transmitString_F(PSTR("> 0 : Erase Blocks"));
TX_NEWLINE;
transmitString_F(PSTR("> 1 : Write single Block"));
TX_NEWLINE;
transmitString_F(PSTR("> 2 : Read single Block"));

#ifndef FAT_TESTING_ONLY
TX_NEWLINE;
transmitString_F(PSTR("> 3 : Write multiple Blocks"));
TX_NEWLINE;
transmitString_F(PSTR("> 4 : Read multiple Blocks"));
#endif


TX_NEWLINE;
transmitString_F(PSTR("> 5 : Get file list"));
TX_NEWLINE;
transmitString_F(PSTR("> 6 : Read File"));
TX_NEWLINE;
transmitString_F(PSTR("> 7 : Create File"));
TX_NEWLINE;
transmitString_F(PSTR("> 8 : Delete File"));
TX_NEWLINE;
transmitString_F(PSTR("> 9 : Read SD Memory Capacity (Total/Free)"));

TX_NEWLINE;
TX_NEWLINE;
transmitString_F(PSTR("> Select Option (0-9): "));


/*WARNING: If option 0, 1 or 3 is selected, the card may not be detected by PC/Laptop again,
as it disturbs the FAT format, and you may have to format it again with FAT32.
This options are given for learning the raw data transfer to & from the SD Card*/

option = receiveByte();
transmitByte(option);

if(option >= 0x35 && option <= 0x39)  //options 5 to 9 disabled if FAT32 not found
{
  if(!FAT32_active)
  {
    TX_NEWLINE;
    TX_NEWLINE;
      transmitString_F(PSTR("FAT32 options disabled!"));
      continue;
  }
}


if((option >= 0x30) && (option <=0x34)) //get starting block address for options 0 to 4
{
TX_NEWLINE;
TX_NEWLINE;
transmitString_F(PSTR("Enter the Block number (0000-9999):"));
data = receiveByte(); transmitByte(data);
startBlock = (data & 0x0f) * 1000;
data = receiveByte(); transmitByte(data);
startBlock += (data & 0x0f) * 100;
data = receiveByte(); transmitByte(data);
startBlock += (data & 0x0f) * 10;
data = receiveByte(); transmitByte(data);
startBlock += (data & 0x0f);
TX_NEWLINE;
}

totalBlocks = 1;

#ifndef FAT_TESTING_ONLY

if((option == 0x30) || (option == 0x33) || (option == 0x34)) //get total number of blocks for options 0, 3 or 4
{
TX_NEWLINE;
TX_NEWLINE;
transmitString_F(PSTR("How many blocks? (000-999):"));
data = receiveByte(); transmitByte(data);
totalBlocks = (data & 0x0f) * 100;
data = receiveByte(); transmitByte(data);
totalBlocks += (data & 0x0f) * 10;
data = receiveByte(); transmitByte(data);
totalBlocks += (data & 0x0f);
TX_NEWLINE;
}
#endif

switch (option)
{
case '0': //error = SD_erase (block, totalBlocks);
          error = SD_erase (startBlock, totalBlocks);
          TX_NEWLINE;
          if(error)
              transmitString_F(PSTR("Erase failed.."));
          else
              transmitString_F(PSTR("Erased!"));
          break;

case '1': TX_NEWLINE;
          transmitString_F(PSTR(" Enter text (End with ~):"));
          i=0;
            do
            {
                data = receiveByte();
                transmitByte(data);
                buffer[i++] = data;
                if(data == '\r')    //append 'newline' character whenevr 'carriage return' is received
                {
                    transmitByte('\n');
                    buffer[i++] = '\n';
                }
                if(i == 512) break;
            }while (data != '~');

            error = SD_writeSingleBlock (startBlock);
            TX_NEWLINE;
            TX_NEWLINE;
            if(error)
                transmitString_F(PSTR("Write failed.."));
            else
                transmitString_F(PSTR("Write successful!"));
            break;

case '2': error = SD_readSingleBlock (startBlock);
          TX_NEWLINE;
          if(error)
            transmitString_F(PSTR("Read failed.."));
          else
          {
            for(i=0;i<512;i++)
            {
                if(buffer[i] == '~') break;
                transmitByte(buffer[i]);
            }
            TX_NEWLINE;
            TX_NEWLINE;
            transmitString_F(PSTR("Read successful!"));
          }

          break;
//next two options will work only if following macro is cleared from SD_routines.h
#ifndef FAT_TESTING_ONLY

case '3':
          error = SD_writeMultipleBlock (startBlock, totalBlocks);
          TX_NEWLINE;
          if(error)
            transmitString_F(PSTR("Write failed.."));
          else
            transmitString_F(PSTR("Write successful!"));
          break;

case '4': error = SD_readMultipleBlock (startBlock, totalBlocks);
          TX_NEWLINE;
          if(error)
            transmitString_F(PSTR("Read failed.."));
          else
            transmitString_F(PSTR("Read successful!"));
          break;
#endif

case '5': TX_NEWLINE;
              findFiles(GET_LIST,0);
          break;

case '6':
case '7':
case '8': TX_NEWLINE;
              TX_NEWLINE;
          transmitString_F(PSTR("Enter file name: "));
          for(i=0; i<13; i++)
                  fileName[i] = 0x00;   //clearing any previously stored file name
          i=0;
          while(1)
          {
            data = receiveByte();
            if(data == '\r') break;  //'ENTER' key pressed
            if(data == 0x08)  //'Back Space' key pressed
            {
              if(i != 0)
              {
                transmitByte(data);
                transmitByte(' ');
                transmitByte(data);
                i--;
              }
              continue;    
            }
            if(data <0x20 || data > 0x7e) continue;  //check for valid English text character
            transmitByte(data);
            fileName[i++] = data;
            if(i==13){transmitString_F(PSTR(" file name too long..")); break;}
          }
          if(i>12) break;
      
          TX_NEWLINE;
          if(option == '6')
            readFile( READ, fileName);
          if(option == '7')
            createFile(fileName);
          if(option == '8')
            deleteFile(fileName);
          break;

case '9': memoryStatistics();
          break;

default: TX_NEWLINE;
         TX_NEWLINE;
         transmitString_F(PSTR(" Invalid option!"));
         TX_NEWLINE;
}

TX_NEWLINE;
}
return 0;
}
Exemple #9
0
//uint8_t readCfgFile(DATE *adate,TIME *atime, uint8_t *filename_dat, uint8_t atomic)
uint8_t readCfgFile(uint8_t *filename_dat, uint8_t atomic)
{
	DIR *dir;
	uint32_t cluster, fileSize, firstSector;
	uint16_t k;
	uint8_t i,j,ld,lt;
	uint8_t filename[]="CONFIG  CFG";
	uint8_t filename2[]="_CONFIG CFG";
	
	TIME_t time;
	DATE_t date;
	
	
	dir = findFiles (GET_FILE, filename, filename, atomic); 	//get the file location
	if(dir == 0) 
		return(0);

	cluster = (((uint32_t) dir->firstClusterHI) << 16) | dir->firstClusterLO;
	fileSize = dir->fileSize;
	
	ld = 0;
	lt = 0;
	
	while(1)
	{
		firstSector = getFirstSector (cluster);
		for(j=0; j<SectorPerCluster; j++)
		{
			SD_readSingleBlock(firstSector + j, atomic);
			for(k=0; k<512; k++)
			{
				switch(buffer[k])
				{
					case	'S':
								k++;
								switch(buffer[k])
								{
								case 'T':
                             k++;
                             time.h = getDec((uint8_t*)buffer+k);
                             time.m = getDec((uint8_t*)buffer+k+2);
                             time.s = getDec((uint8_t*)buffer+k+4);
                             break;
								case 'D':
                             k++;
                             date.d = getDec(&buffer[k]);
									           date.m = getDec(&buffer[k+2]);
                             date.y = 20 + getDec(&buffer[k+4]);
                             break;
								case 'F':
                             k = k+2;
                             for(i=0;i<13;i++)
                             {
                                if(buffer[k+i] < 0x20)		//if any control code
                                   break;
                                filename_dat[i] = buffer[k+i];
                             }
                             k = k+i;
                             break;
								case 'M':    //mask definitions: M - mic only, S - SHT sensor only, T - DS1820 1-wire sensor, X - Mic+SHT, '-' - nothing
                             k++;
                             for(i=0;i<12;i++)
                             {
                               Mask.SHT = Mask.SHT<<1;
                               Mask.MIC = Mask.MIC<<1;
                               switch(buffer[k+i])
                               {
 //                                case 'X':					//SHT mask generated from mic mask!
 //                                        Mask.SHT |= 0x0001;
                                 case 'M':
                                         Mask.MIC |= 0x0001;
                                         break;
 //                                case 'S':
 //                                        Mask.SHT |= 0x0001;
 //                                        break;
                                 case 'T':
                                         Mask.DS |= 0x01;		// any T will cause DS mask to be one...
                                         break;
                                 default:
                                         break;
                               }
                             }      
                             k = k+i;
								}
								break;
					case 'A':
								k++;
								if(buffer[k]=='D')
								{	
									k++;
									ADate[ld].d = getDec((uint8_t*)buffer+k);
									//k +=2;
									ADate[ld].m = getDec((uint8_t*)buffer+k+2);
									//k +=2;
									ADate[ld].y = 20 + getDec((uint8_t*)buffer+k+4);
									ld++;
								}
								else if(buffer[k]=='T')
								{	
									k++;
									ATime[lt].h = getDec((uint8_t*)buffer+k);
									//k +=2;
									ATime[lt].m = getDec((uint8_t*)buffer+k+2);
									//k +=2;
									ATime[lt].s = getDec((uint8_t*)buffer+k+4);
									lt++;
								}
								break;
					
				}
				
				if (k >= fileSize )
				{
					findFiles(RENAME,filename, filename2, atomic);
					RTC_SetDateTime(&date, &time);
//??				if(Mask.SHT)
//					{
						generate_mask_bm();
//					}
					return(lt);
				}
			}
		}
		cluster = getSetNextCluster (cluster, GET, 0, atomic);
		if(cluster == 0) 
		{
#if RSCOM == 1
			printf_P(PSTR("ERR GETTING CLUSTERb\n")); 
#endif		//BIGAVR
			return(0);
		}
	}
	return(0);
}