Subversion Repositories NaviCtrl

Compare Revisions

Ignore whitespace Rev 23 → Rev 24

/trunk/Navi-Ctrl.Uv2
23,8 → 23,8
File 1,1,<.\GPSUart.c><GPSUart.c>
File 1,1,<.\usb.c><usb.c>
File 1,1,<.\fat16.c><fat16.c>
File 1,1,<.\settings.c><settings.c>
File 1,1,<.\sdc.c><sdc.c>
File 1,1,<.\settings.c><settings.c>
File 1,1,<.\ssc.c><ssc.c>
File 1,1,<.\usb_desc.c><usb_desc.c>
File 1,1,<.\usb_endp.c><usb_endp.c>
31,6 → 31,10
File 1,1,<.\usb_istr.c><usb_istr.c>
File 1,1,<.\usb_prop.c><usb_prop.c>
File 1,1,<.\usb_pwr.c><usb_pwr.c>
File 1,1,<.\crc16.c><crc16.c>
File 1,1,<.\kml.c><kml.c>
File 2,5,<.\kml.h><kml.h>
File 2,5,<.\crc16.h><crc16.h>
File 2,5,<.\ramfunc.h><ramfunc.h>
File 2,5,<.\main.h><main.h>
File 2,5,<.\uart.h><uart.h>
47,6 → 51,7
File 2,5,<.\GPS.h><GPS.h>
File 2,5,<.\GPSUart.h><GPSUart.h>
File 2,5,<.\settings.h><settings.h>
File 2,5,<.\kml_header.h><kml_header.h>
File 3,2,<.\startup912.s><startup912.s>
File 4,1,<.\libstr91x\src\91x_scu.c><91x_scu.c>
File 4,1,<.\libstr91x\src\91x_gpio.c><91x_gpio.c>
56,6 → 61,7
File 4,1,<.\libstr91x\src\91x_ssp.c><91x_ssp.c>
File 4,1,<.\libstr91x\src\91x_i2c.c><91x_i2c.c>
File 4,1,<.\libstr91x\src\91x_fmi.c><91x_fmi.c>
File 4,1,<.\libstr91x\src\91x_wiu.c><91x_wiu.c>
File 6,1,<.\usblibrary\src\usb_regs.c><usb_regs.c>
File 6,1,<.\usblibrary\src\usb_core.c><usb_core.c>
File 6,1,<.\usblibrary\src\usb_init.c><usb_init.c>
155,3 → 161,25
FLASH4 ()
EndOpt
 
Options 1,1,0 // Group 'Source Code'
PropFld { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
IncBld=2
AlwaysBuild=2
GenAsm=2
AsmAsm=2
PublicsOnly=2
StopCode=11
CustArgs ()
LibMods ()
ACCFLG { 170,2,16,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
ACMISC ()
ACDEFN ()
ACUDEF ()
ACINCD ()
AASFLG { 10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
AAMISC ()
AADEFN ()
AAUDEF ()
AAINCD ()
EndOpt
 
/trunk/crc16.c
0,0 → 1,47
#include "91x_lib.h"
 
static const u16 crc16tab[256]=
{
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
};
u16 CRC16(const u8 *pBuffer, u32 len)
{
register u32 counter;
register u16 crc = 0;
for( counter = 0; counter < len; counter++)
crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *pBuffer++)&0x00FF];
return crc;
}
 
/trunk/crc16.h
0,0 → 1,6
#ifndef _CRC16_H
#define _CRC16_H
 
extern u16 CRC16(const u8 * pBuffer, u32 len);
 
#endif // _CRC16_H
/trunk/fat16.c
60,23 → 60,30
//________________________________________________________________________________________________________________________________________
// Module name: fat16.c
// Compiler used: avr-gcc 3.4.5
// Last Modifikation: 24.07.2007
// Version: 1.24
// Last Modifikation: 21.04.2008
// Version: 1.28
// Authors: Stephan Busker
// Description: Source files for FAT16 implementation with read and write-access using AVR-Mikrocontrollers
// Copyright (C) 2007 Stephan Busker
//........................................................................................................................................
// Functions: extern u8 InitFat16(void);
// u8 fopen_(u8 *fname,s8 mode, File *file);
// void fclose_(File *file);
// u32 fread_(void *buffer, u32 size, u32 count, File *file);
// u32 fwrite_(void *buffer, u32 size, u32 count, File *file);
// s16 fseek_(File *file, s32 offset, s16 origin);
// s8 fgets8_(File *file);
// u8 fopen_(s8 *fname,s8 mode, File *file);
// void fclose_(File *file);
// u32 fread_(void *buffer, u32 size, u32 count, File *file);
// u32 fwrite_(void *buffer, u32 size, u32 count, File *file);
// s16 fseek_(File *file, s32 offset, s16 origin);
// s8 fgets_(s8 *string, s16 count, File *file);
// u8 fputchar_(File *file,s8 c);
// u8 fputs_(File *file,s8 *string);
// s8 * fgets(s8 *, s16, File);
// u8 fexist_(u8*, File *file);
// s8 * fgets(s8 *, s16, File);
// u8 fexist_(u8*);
// u8 mkdir__(s8 *name);
// u8 chdir__(s8 *name);
// u8 findfirst_(s8 *fname, Find *item, u8 attribute);
// u8 findnext_(Find *item);
// u8 fdelete_(s8 *fname)
// u8 rmdir_(s8 *dname)
// u16 feof_(File);
//........................................................................................................................................
// ext. functions: extern u8 SDC_GetSector (u32,u8 *);
// extern u8 SDC_PutSector (u32,u8 *);
88,7 → 95,6
 
 
 
 
//________________________________________________________________________________________________________________________________________
//
// Global variables needed for read- or write-acces to the FAT16- filesystem.
95,25 → 101,24
//
//________________________________________________________________________________________________________________________________________
 
u8 SectorsPerCluster = 0; // how many sectors does a cluster contain?
u8 FatCopies = 0; // Numbers of copies of the FAT
u16 PossibleRootEntries = 0; // Possible number of entries in the root directory.
u16 SectorsPerFat = 0; // how many sectors does a fat16 contain?
u32 ReservedSectors = 0; // Sectors reserved by the filesystem.
u32 FirstPartitionSector = 0; // Distance in sectors between the first partition and the master bootrecord.
u32 FileAllocationTable = 0; // pointer to the first FAT
u32 RootDirectory = 0; // Pointer to the rootdirectory of the first partition.
u32 FirstDataCluster = 0; // Pointer to the first cluster containing data (cluster0).
//u8 FileBuffer[512]; // Buffer for read and write operation from or to the mmc.
u8 SectorsPerCluster = 0; // how many sectors does a cluster contain?
u8 FatCopies = 0; // Numbers of copies of the FAT
u16 PossibleRootEntries = 0; // Possible number of entries in the root directory.
u16 SectorsPerFat = 0; // how many sectors does a fat16 contain?
u32 ReservedSectors = 0; // Sectors reserved by the filesystem.
u32 FirstPartitionSector = 0; // Distance in sectors between the first partition and the master bootrecord.
u32 FileAllocationTable = 0; // pointer to the first FAT
u32 RootDirectory = 0; // Pointer to the rootdirectory of the first partition.
u32 FirstDataCluster = 0; // Pointer to the first cluster containing data (cluster0).
u32 CWD = 0; // Pointer startcluster to the current working directory
 
struct DirEntry *DirectoryEntry; // Pointer to an entry of the directory.
struct FatEntry *Fat; // Pointer to an entry of the fat (next clusterposition).
 
File FilePointer[__MAX_FILES_USED]; // Allocate Memmoryspace for each filepointer used.
struct DirEntry *DirectoryEntry; // Pointer to an entry of the directory.
struct FatEntry *Fat; // Pointer to an entry of the fat (next clusterposition).
 
File FilePointer[__MAX_FILES_USED]; // Allocate Memmoryspace for each filepointer used.
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: InitFat16(void);
//
120,7 → 125,7
// Description: This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdirectory
// and stores the information in global variables.
//
// Returnvalue: The function returns "0" if the filesystem could not be initialized because no partition was found on the disc.
// Returnvalue: The function returns "0" if the filesystem could not be initialized because no partition was found on the volume.
//________________________________________________________________________________________________________________________________________
 
u8 InitFat16(void)
127,122 → 132,109
{
u8 retvalue = 0;
u8 cnt = 0;
struct VBR_Entry *VBR; // Pointer to the VolumeBootRecord.
struct MBR_Entry *MBR; // Pointer to the masterbootrecord.
struct VBR_Entry *VBR; // Pointer to the VolumeBootRecord.
struct MBR_Entry *MBR; // Pointer to the masterbootrecord.
File *file;
 
for(cnt=0;cnt<__MAX_FILES_USED;cnt++)
{
FilePointer[cnt].state = _UNUSED; // declare the filepointers as unused.
FilePointer[cnt].state = _UNUSED; // declare the filepointers as unused.
}
file = &FilePointer[0];
 
while((SDC_Init() != 0) && (cnt++<200)); // initialise the sdcard.
if(cnt <200) //sdcard initialised succesfully
SerialPutString("\n\rFAT16 init...");
while((SDC_Init() != SD_SUCCESS) && (cnt++<100));
 
if(cnt <100) // sdcard initialised succesfully
{
SDC_GetSector((u32)MBR_SECTOR,file->buffer); // Read the MasterBootRecord from mmc.
SDC_GetSector((u32)_MBR_SECTOR,file->buffer); // Read the MasterBootRecord from mmc.
MBR = (struct MBR_Entry *) file->buffer;
FirstPartitionSector = MBR->PartitionEntry1.NoSectorsBeforePartition;
SDC_GetSector(FirstPartitionSector,file->buffer); // Read the volume bootrecord from mmc.
if((MBR->PartitionEntry1.Type == _FAT16_32_MB_BIOS_Extension) ||
(MBR->PartitionEntry1.Type == _FAT16_ST_32_MB) ||
(MBR->PartitionEntry1.Type == _FAT16_LT_32_MB))
{
SDC_GetSector(FirstPartitionSector,file->buffer); // Read the volume bootrecord from mmc.
VBR = (struct VBR_Entry *) file->buffer; // Enter the VBR using the structure VBR_Entry.
SectorsPerCluster = VBR->SectorsPerCluster; // Number of sectors per cluster. Depends on the memorysize of the sd-card.
FatCopies = VBR->NoFATCopies; // Number of fatcopies.
PossibleRootEntries = VBR->MaxRootEntries; // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
SectorsPerFat = VBR->SectorsPerFAT; // The number of sectors per FAT.
ReservedSectors = VBR->ReservedSectors; // calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster.
 
VBR = (struct VBR_Entry *) file->buffer; // Enter the VBR using the structure VBR_Entry.
SectorsPerCluster = VBR->SectorsPerCluster; // Number of sectors per cluster. Depends on the memorysize of the sd-card.
FatCopies = VBR->NoFATCopies; // Number of fatcopies.
PossibleRootEntries = VBR->MaxRootEntries; // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
SectorsPerFat = VBR->SectorsPerFAT; // The number of sectors per FAT.
ReservedSectors = VBR->ReservedSectors; // calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster.
 
FileAllocationTable = (u32)(FirstPartitionSector + (u32)ReservedSectors); // Calculate the position of the FileAllocationTable.
RootDirectory = (u32)((u32)FileAllocationTable + (u32)((u32)SectorsPerFat*(u32)FatCopies)); // Calculate the position of the Rootdirectory.
FirstDataCluster = (u32)((u32)RootDirectory + ((u32)(PossibleRootEntries>>4))); // Calculate the position of the first datacluster.
if((file->buffer[0x36]=='F') &&(file->buffer[0x37]=='A')&&(file->buffer[0x38]=='T')&&(file->buffer[0x39]=='1')&&(file->buffer[0x3A]=='6'))
{
FileAllocationTable = (u32)(FirstPartitionSector + (u32)ReservedSectors); // Calculate the position of the FileAllocationTable.
RootDirectory = (u32)((u32)FileAllocationTable + (u32)((u32)SectorsPerFat*(u32)FatCopies)); // Calculate the position of the Rootdirectory.
FirstDataCluster = (u32)((u32)RootDirectory + ((u32)(PossibleRootEntries>>4))); // Calculate the position of the first datacluster.
CWD = RootDirectory; // The actual directory is the rootdirectory.
retvalue = 1;
SerialPutString("\n\rfilesystem ok");
str_Volume.state = INITIALIZED;
}
else
{
str_Volume.state = NOT_INITIALIZED;
SerialPutString("\n\rfilesystem nok");
}
}
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: File * fopen_(u8*, u8 *, File *file);
// Funtion: File * fopen_(u8*, u8 *);
//
// Description: This function looks for the specified file in the rootdirectory of the drive. If the file is found the number of the
// corrosponding datacluster is returned to main. Only modes 'r' (reading) and 'a' append are implemented yet.
// Description: This function looks for the file to be opened in the directory specified by the variable "CWD" of the drive.
// If the file was found this function returns a filepoiner to the opened file otherwise NULL//
//
// Return: 0 = faild to open speicified file
// 1 = file opened
// Return: Pointer to the opened file or NULL
//
//________________________________________________________________________________________________________________________________________
 
File * fopen_(u8 *fname, s8 mode)
File * fopen_(s8 *fname, s8 mode)
{
u32 cluster_temp = 0;
u8 name[11] = " ";
u16 temp = 0;
File *file;
file=0;
for(temp = 0;temp<__MAX_FILES_USED;temp++)
file = ReserveFilePointer(); // reserve a filepointer.
if(file != NULL) // A free filepointer was found.
{
if(FilePointer[temp].state == _UNUSED) // free filepointer found?
{
file = &FilePointer[temp];
FilePointer[temp].state = _USED; // mark as used.
break;
}
}
if(file == 0) return(file); // no valid pointer
file->mode = mode; // mode of fileoperation (read,write)
 
file->start_cluster = 0; // Sectorpointer to the first sector of the first datacluster of the file.
file->cluster_pointer = 0; // Pointer to the cluster which is edited at the moment.
file->sector_index = 0; // The sector which is edited at the moment (cluster_pointer + sector_index).
file->byte_index = 0; // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
file->mode = mode; // mode of fileoperation (read,write)
file->filesize = 0; // the size of the opend file in bytes.
file->fileposition = 0; // pointer to a character within the file 0 < fileposition < filesize
file->sector_in_buffer = 0; // the last sector read, wich is still in the sectorbuffer.
file->directory_sector = 0; // the sectorposition where the directoryentry has been made.
file->directory_index = 0; // the index to the directoryentry within the specified sector.
file->attribute = 0; // the attribute of the file opened.
 
if(ScanSubDirectories(&fname[0], file)) // Is the specified filepath available?
{
SeperateFileName(&fname[0], &name[0]); // seperate the filename and attribute from the filepath and bring them in the correct format.
file->attribute = _FILE;
if(SeekDirectoryEntry(&name[0], file)) // if file was found
if(SeekFileInDirectory(fname, file)) // if file was found
{
SerialPutString("ok");
if(mode == 'a') // open existing file for writing (append data at the end of the file)
{
fseek_(file, 0, SEEK_END); // fseek points to the end of the file
}
return(file);
}
}
else
{
if((mode == 'a') || (mode == 'w')) // specified file doesn't exist so create new file for writing data.
{
cluster_temp = (u32)FindNextFreeCluster(file); // the next free cluster on the disk.
if(cluster_temp) // if a free cluster is available:
if(CreateFileInDirectory(fname,file)) // Could an entry for the new file in the rootdirectory be created?
{
temp = (u16)cluster_temp; // remember the index of the free datacluster found for the directory entry.
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
cluster_temp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster.
file->start_cluster = (FirstDataCluster + cluster_temp); // Calculate absolute sectorposition of first datacluster.
file->cluster_pointer = file->start_cluster; // start reading the file with the first sector of the first datacluster.
if(CreateDirectoryEntry(&name[0],temp,file,_FILE)) // Could an entry for the new file in the rootdirectory be created?
{
return(file);
}
}
return(file);
}
else
{
FreeFilePointer(file); // free the filepointer.
file = NULL;
}
}
else // file with mode 'r' not found
{
FreeFilePointer(file); // free the filepointer.
file = NULL; // file not found
}
}
}
return(0);
return(file);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: fflush_(File *file);
//
255,21 → 247,14
u16 time=0;
u16 date=0;
 
#ifdef __USE_TIME_DATE_ATTRIBUTE // has the date and time attribute of the file to be set?
time = (((rtctime.hour)<<11) | ((rtctime.minute)<<5) | rtctime.second);
date = ((((rtctime.year)-1980) <<9) | ((rtctime.month) <<5) | rtctime.day);
 
#endif
if(file && file->mode =='a')
if(file && ((file->mode =='a') || (file->mode =='w')))
{
if(file->byte_index > 0) // has data been added to the file?
{
SDC_PutSector((u32)(file->cluster_pointer + file->sector_index),file->buffer); // save the data still in the buffer
SDC_PutSector((u32)(file->cluster_pointer + file->sector_index),file->buffer);// save the data still in the buffer
}
SDC_GetSector((u32)file->directory_sector,file->buffer); // read the directoryentry for this file.
SDC_GetSector((u32)file->directory_sector,file->buffer); // read the directoryentry for this file.
DirectoryEntry = (struct DirEntry *)file->buffer;
DirectoryEntry[file->directory_index].size = (u32) file->filesize;
DirectoryEntry[file->directory_index].time = (u16) time;
288,33 → 273,16
 
void fclose_(File *file)
{
u8 cnt = 0;
for(cnt=0;cnt<__MAX_FILES_USED;cnt++)
 
if(file != NULL)
{
if(&FilePointer[cnt] == file) // filepointer to be freed found?
{
FilePointer[cnt].state = _UNUSED;
}
 
fflush_(file); // save buffercontent to the sdcard
 
file->start_cluster = 0; // Sectorpointer to the first sector of the first datacluster of the file.
file->cluster_pointer = 0; // Pointer to the cluster which is edited at the moment.
file->sector_index = 0; // The sector which is edited at the moment (cluster_pointer + sector_index).
file->byte_index = 0; // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
file->mode = 0; // mode of fileoperation (read,write)
file->filesize = 0; // the size of the opend file in bytes.
file->fileposition = 0; // pointer to a character within the file 0 < fileposition < filesize
file->sector_in_buffer = 0; // the last sector read, wich is still in the sectorbuffer.
file->directory_sector = 0; // the sectorposition where the directoryentry has been made.
file->directory_index = 0; // the index to the directoryentry within the specified sector.
file->attribute = 0; // the attribute of the file opened.
fflush_(file); // save buffered data to the disk
}
FreeFilePointer(file); // and free the filepointer.
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: s32 fread_(void *buffer, s32 size, s32 count, File *file);
// Funtion: u32 fread_(void *buffer, s32 size, s32 count, File *file);
//
// Description: This function reads count objects of the specified size from the actual position of the file to the specified buffer.
//
324,12 → 292,12
 
u32 fread_(void *buffer, u32 size, u32 count, File *file)
{
u32 object_cnt = 0; // count the number of objects read from the file.
u32 object_cnt = 0; // count the number of objects read from the file.
u32 object_size = 0; // count the number of bytes read from the actual object.
u8 *buff_pnt = 0; // a pointer to the actual bufferposition.
u8 success = 1; // no error occured during read operation to the file.
u8 *buff_pnt = 0; // a pointer to the actual bufferposition.
u8 success = 1; // no error occured during read operation to the file.
buff_pnt = (u8 *) buffer; // cast the void pointer to an u8 *
buff_pnt = (u8 *) buffer; // cast the void pointer to an u8 *
while((object_cnt < count) && success)
{
336,7 → 304,7
object_size = size;
while((size > 0) && success)
{
*buff_pnt = (u8) fgetchar_(file); // read a byte from the buffer to the opened file.
*buff_pnt = (u8) fgetchar_(file); // read a byte from the buffer to the opened file.
buff_pnt++;
size--;
}
343,11 → 311,11
if(success) object_cnt++;
}
return(object_cnt); // return the number of objects succesfully read from the file
return(object_cnt); // return the number of objects succesfully read from the file
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: s32 fwrite_(void *buffer, s32 size, s32 count, File *file);
// Funtion: u32 fwrite_(void *buffer, s32 size, s32 count, File *file);
//
// Description: This function writes count objects of the specified size from the buffer to the actual positon within the file.
//
357,12 → 325,12
 
u32 fwrite_(void *buffer, u32 size, u32 count, File *file)
{
u32 object_cnt = 0; // count the number of objects written to the file.
u32 object_cnt = 0; // count the number of objects written to the file.
u32 object_size = 0; // count the number of bytes written from the actual object.
u8 *buff_pnt = 0; // a pointer to the actual bufferposition.
u8 success = 1; // no error occured during write operation to the file.
u8 *buff_pnt = 0; // a pointer to the actual bufferposition.
u8 success = 1; // no error occured during write operation to the file.
buff_pnt = (u8 *) buffer; // cast the void pointer to an u8 *
buff_pnt = (u8 *) buffer; // cast the void pointer to an u8 *
while((object_cnt < count) && success)
{
369,7 → 337,7
object_size = size;
while((size > 0) && success)
{
success = fputchar_(file, *buff_pnt); // write a byte from the buffer to the opened file.
success = fputchar_(file, *buff_pnt); // write a byte from the buffer to the opened file.
buff_pnt++;
size--;
}
376,8 → 344,8
if(success) object_cnt++;
}
return(object_cnt); // return the number of objects succesfully written to the file
} // (!!!!! objects and not bytes !!!!)
return(object_cnt); // return the number of objects succesfully written to the file
} // (!!!!! objects and not bytes !!!!)
 
//________________________________________________________________________________________________________________________________________
// Funtion: s16 fseek_(File *, s32, s16)
394,17 → 362,17
u32 temp = 0;
//......................................................
if(origin == SEEK_SET) // Fileposition relative to the beginning of the file.
if(origin == SEEK_SET) // Fileposition relative to the beginning of the file.
{
fposition = 0;
}
//......................................................
else if(origin == SEEK_END) // Fileposition relative to the end of the file.
else if(origin == SEEK_END) // Fileposition relative to the end of the file.
{
fposition = (s32) file->filesize;
}
//......................................................
else if(origin == SEEK_CUR) // Fileposition relative to the current position of the file.
else if(origin == SEEK_CUR) // Fileposition relative to the current position of the file.
{
fposition = file->fileposition;
}
411,7 → 379,7
 
fposition += offset;
 
if((fposition >= 0) && (fposition <= (s32)file->filesize)) // is the pointer still within the file?
if((fposition >= 0) && (fposition <= (s32)file->filesize)) // is the pointer still within the file?
{
retvalue = 0;
file->sector_index = 0;
428,14 → 396,14
}
else
{
file->byte_index=0; // reading at the beginning of new sector.
file->sector_index++; // continue reading in next sector
if(file->sector_index >= SectorsPerCluster) // When end of cluster is reached, the next datacluster has to be searched in the FAT.
file->byte_index=0; // reading at the beginning of new sector.
file->sector_index++; // continue reading in next sector
if(file->sector_index >= SectorsPerCluster) // When end of cluster is reached, the next datacluster has to be searched in the FAT.
{
if(file->fileposition < fposition)
{
file->sector_index = 0; // start reading new cluster at first sector of the cluster.
GetNextCluster(file); // Sets the clusterpointer of the file to the next datacluster.
file->sector_index = 0; // start reading new cluster at first sector of the cluster.
GetNextCluster(file); // Sets the clusterpointer of the file to the next datacluster.
}
}
}
443,7 → 411,7
if(file->byte_index)
{
temp = (u32)((u32)file->cluster_pointer + (u32)file->sector_index);
SDC_GetSector((u32)temp,file->buffer); // FileBuffer will be written at once at the end of the cluster and has to be updated.
SDC_GetSector((u32)temp,file->buffer); // FileBuffer will be written at once at the end of the cluster and has to be updated.
}
}
return(retvalue);
452,8 → 420,8
//________________________________________________________________________________________________________________________________________
// Funtion: fgetchar_(File *file);
//
// Description: This function reads and returns one character from the specified file. Is the end of the actual sector reached the
// next sector of the cluster is read. Is the last sector of the cluster read the next cluster will be searched in FAT.
// Description: This function reads and returns one character from the specified file.
//
// Returnvalue: The function returns the character read from the specified memorylocation as u8 casted to s16 or EOF.
//________________________________________________________________________________________________________________________________________
 
462,18 → 430,18
s16 c = EOF;
u32 temp1;
if(file->filesize > 0) // wen the end of the file is not reached, get the next character.
if(((file->fileposition)+1) < file->filesize) // wen the end of the file is not reached, get the next character.
{
temp1 = (u32)file->cluster_pointer; // calculate the adress of the next character to be read.
temp1 = (u32)file->cluster_pointer; // calculate the adress of the next character to be read.
temp1 += (u32)file->sector_index;
if(file->sector_in_buffer != temp1) // Has the content of the buffer been modified and has to be updated?
{
SDC_GetSector((u32)temp1,file->buffer); // Read the calculated cluster.
SDC_GetSector((u32)temp1,file->buffer); // Read the calculated cluster.
file->sector_in_buffer = (u32)temp1;
}
c = (s16) file->buffer[file->byte_index];
file->filesize--; // decrement the number of characters available.
file->fileposition++;
if(file->byte_index < 511) // continue reading from this sector until the end of the sector is reached.
{
494,7 → 462,7
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: fputchar_(File *file);
// Funtion: fputchar_(File *file, s8 *);
//
// Description: This function writes a byte to the specified file and takes care of writing the necessary FAT- Entries.
//
506,32 → 474,32
u32 ul_temp = 0;
u8 retvalue = 1;
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster
{
file->sector_index = 0;
if(!AppendCluster(file)) retvalue = 0; // append a new and free cluster at the end of the file.
if(!AppendCluster(file)) retvalue = 0; // append a new and free cluster at the end of the file.
}
 
file->buffer[file->byte_index] = c; // write databyte into the buffer. The byte will be written to the device at once
if(file->filesize == file->fileposition) file->filesize++; // a character has been written to the file so the size is inkremented but only when the character has been added at the end of the file.
file->fileposition++; // the actual positon within the file.
// if the buffer contains the complete sectordata.
if(file->byte_index < 511) // if the end of this sector is not reached yet
file->buffer[file->byte_index] = c; // write databyte into the buffer. The byte will be written to the device at once
if(file->filesize == file->fileposition) file->filesize++; // a character has been written to the file so the size is inkremented but only when the character has been added at the end of the file.
file->fileposition++; // the actual positon within the file.
// if the buffer contains the complete sectordata.
if(file->byte_index < 511) // if the end of this sector is not reached yet
{
file->byte_index++; // the next byte will be written to the next byteposition in this sector.
file->byte_index++; // the next byte will be written to the next byteposition in this sector.
}
else // otherwise the data in the sectorbuffer will be written to the device and the next sector will be selected.
else // otherwise the data in the sectorbuffer will be written to the device and the next sector will be selected.
{
ul_temp = (u32)file->cluster_pointer;
ul_temp += (u32)file->sector_index;
SDC_PutSector((u32)ul_temp,file->buffer);
file->byte_index=0; // and the next byte will be written at the beginning of this new sector.
file->byte_index=0; // and the next byte will be written at the beginning of this new sector.
file->sector_index++;
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster
{
file->sector_index = 0;
if(!AppendCluster(file)) retvalue = 0; // append a new and free cluster at the end of the file.
if(!AppendCluster(file)) retvalue = 0; // append a new and free cluster at the end of the file.
}
}
return(retvalue);
538,9 → 506,9
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: fputs_(File *file);
// Funtion: fputs_(File *file, s8 *string);
//
// Description: This function writes a string to the specified file.
// Description: This function writes a zero terminated string to the specified file.
//
//________________________________________________________________________________________________________________________________________
 
557,11 → 525,11
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: fgets_(File *file);
// Funtion: s8 * fgets_(s8 *string, s16 count, File *file)
//
// Description: This function reads a string from the file to the specifies string.
// Description: This function reads a string from the file to the specifies string until EOF or end of line was detected..
//
// Returnvalue: A pointer to the string written from the file.
// Returnvalue: A pointer to the string or NULL if EOF was read from the file with no other characters before.
//________________________________________________________________________________________________________________________________________
 
s8 * fgets_(s8 *string, s16 count, File *file)
568,40 → 536,44
{
s16 buff_pnt = 0;
s16 buff_tmp = 0;
u8 state = 0; // Variable used for a statemachine to recognize the end of a line.
s8 *retvalue = 0;
while(count > 1) // read the count-1 characters from the file to the string.
retvalue = string;
 
while(count > 1) // read the count-1 characters from the file to the string.
{
buff_tmp = fgetchar_(file); // read a character from the opened file.
switch(state)
buff_tmp = fgetchar_(file); // read a character from the opened file.
if(buff_tmp == EOF) // is the end of the file reached, terminate the string with zero.
{
case 0:
if(buff_tmp == 0x0A)// state++;
{
count = 1;
}
state = 0;
if(buff_pnt != 0) // are there characters within the string?
{
break;
}
else
{
retvalue = NULL; // first character read was EOF -> return(NULL);
break;
}
}
else if(buff_tmp == 0x0A) // lf detected.
{
string[buff_pnt] = (s8) buff_tmp; // add lf to the string.
buff_pnt++;
break;
case 1:
if(buff_tmp == 0x0A)
{
count = 1;
}
state = 0;
break;
}
if(buff_tmp == EOF) {buff_tmp = 0; count = 1;} // is the end of the file reached, terminate the string with zero.
string[buff_pnt] = (s8) buff_tmp;
count--;
buff_pnt++;
else
{
string[buff_pnt] = (s8) buff_tmp;
count--;
buff_pnt++;
}
}
string[buff_pnt] = 0;
string[buff_pnt] = 0; // terminate string with zero
return(string);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 fexist_(u8*, File *file);
// Funtion: u8 fexist_(u8*);
//
// Description: This function searches the specified file and returns 0 if the file was not found.
//
610,18 → 582,20
// 1 = file exists
//________________________________________________________________________________________________________________________________________
 
u8 fexist_(u8 *fname)
u8 fexist_(s8 *fname)
{
File *file;
 
file = fopen_(fname,'r'); // try to open the specified file.
if((file = fopen_(fname,'r')) != 0)
if(file != NULL)
{
fclose_(file);
return(1);
FreeFilePointer(file); // Free the filepoint // free the filepointer
return(1); // file was found so return(1);
}
else
{
return(0);
return(0); // file not found return(0);
}
}
 
638,7 → 612,7
u32 fat_pointer = 0;
u32 fat_sector_offset = 0;
u32 ul_tmp = 0;
u8 retvalue = 0; // no new cluster found yet.
u8 retvalue = 0; // no new cluster found yet.
if((file->cluster_pointer >= RootDirectory) && (file->cluster_pointer < (RootDirectory + 31)))
655,9 → 629,9
fat_sector_offset = (fat_sector_offset>>8); // and the position within the sector.
 
SDC_GetSector((u32)(FileAllocationTable + fat_sector_offset),file->buffer);
file->sector_in_buffer = (FileAllocationTable + fat_sector_offset); // Mark that new sector has been read.
file->sector_in_buffer = (FileAllocationTable + fat_sector_offset); // Mark that new sector has been read.
ul_tmp = (u32)file->buffer[((fat_pointer << 1)+1)]; // Read next sector information from calculated clusterposition.
ul_tmp = (u32)file->buffer[((fat_pointer << 1)+1)]; // Read next sector information from calculated clusterposition.
ul_tmp = (ul_tmp << 8);
ul_tmp |= (u32)file->buffer[(fat_pointer << 1)];
ul_tmp -=2; // next datacluster is clusterposition in fat - 2.
666,7 → 640,7
if(ul_tmp < 0xfff7) // has a new cluster been read or was the end of the fat reached?
{
file->cluster_pointer = (u32) ul_tmp; // continue reading the file at the beginning of new datacluster.
file->cluster_pointer = (u32) ul_tmp; // continue reading the file at the beginning of new datacluster.
retvalue = 1; // a new cluster was found.
}
}
683,29 → 657,29
 
u16 FindNextFreeCluster(File *file)
{
u32 fat_pointer = 0; // Pointer to the first sector of the FAT.
u32 ul_tmp = 0; // temporary variable used to calculate a sectornumber.
u16 fat_sector_offset = 0; // index to a sector within the FAT.
u16 fat_entry = 0; // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
u16 free_cluster = 0; // a pointer to the first sector of the next free cluster.
u32 fat_pointer = 0; // Pointer to the first sector of the FAT.
u32 ul_tmp = 0; // temporary variable used to calculate a sectornumber.
u16 fat_sector_offset = 0; // index to a sector within the FAT.
u16 fat_entry = 0; // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
u16 free_cluster = 0; // a pointer to the first sector of the next free cluster.
fat_pointer = (u32) FileAllocationTable; // start searching for empty cluster at the beginning of the fat.
// if the end of the fat is not reached yet and no free cluster has been found
fat_pointer = (u32) FileAllocationTable; // start searching for empty cluster at the beginning of the fat.
// if the end of the fat is not reached yet and no free cluster has been found
while((fat_sector_offset < SectorsPerFat) && (!free_cluster))
{
ul_tmp = (u32) ((u32)fat_pointer + (u32)fat_sector_offset);
SDC_GetSector((u32)ul_tmp,file->buffer); // read next sector of FAT.
file->sector_in_buffer = ul_tmp; // remember the number of the sector in FileBuffer.
SDC_GetSector((u32)ul_tmp,file->buffer); // read next sector of FAT.
file->sector_in_buffer = ul_tmp; // remember the number of the sector in FileBuffer.
Fat = (struct FatEntry *)file->buffer;
for(fat_entry=0;fat_entry<256;fat_entry++) // look for an free cluster at all entries in this sector of the fat.
for(fat_entry=0;fat_entry<256;fat_entry++) // look for an free cluster at all entries in this sector of the fat.
{
if(Fat[fat_entry].next_cluster == 0x0000) // empty cluster found!!
if(Fat[fat_entry].next_cluster == 0x0000) // empty cluster found!!
{
Fat[fat_entry].next_cluster = 0xffff; // mark this fat-entry as used and save it to the device.
Fat[fat_entry].next_cluster = 0xffff; // mark this fat-entry as used and save it to the device.
SDC_PutSector((u32)file->sector_in_buffer,file->buffer);
free_cluster = fat_entry; // the relative position of the free cluster found in this sector of the FAT.
free_cluster += (fat_sector_offset << 8); // calculate the absolute position of the free cluster in the FAT;
fat_entry = 256; // terminate the search for a free cluster in this sector.
free_cluster = fat_entry; // the relative position of the free cluster found in this sector of the FAT.
free_cluster += (fat_sector_offset << 8); // calculate the absolute position of the free cluster in the FAT;
fat_entry = 256; // terminate the search for a free cluster in this sector.
}
}
fat_sector_offset++;
727,15 → 701,15
u32 fat_pointer = 0;
u8 retvalue = 0;
free_cluster = FindNextFreeCluster(file); // the next free cluster found on the disk.
if(free_cluster) retvalue = 1; // A free cluster was found and can be added to the end of the file.
fat_pointer = FileAllocationTable; // Set Pointer to the beginnig of the FAT.
fat_pointer += (u32)((u32)GetFatClusterOffset(file) >> 8); // find the sector in the FAT with 256 entries per sector.
free_cluster = FindNextFreeCluster(file); // the next free cluster found on the disk.
if(free_cluster) retvalue = 1; // A free cluster was found and can be added to the end of the file.
fat_pointer = FileAllocationTable; // Set Pointer to the beginnig of the FAT.
fat_pointer += (u32)((u32)GetFatClusterOffset(file) >> 8); // find the sector in the FAT with 256 entries per sector.
SDC_GetSector(fat_pointer,file->buffer);
Fat = (struct FatEntry *)file->buffer;
Fat[GetFatSectorIndex(file)].next_cluster = free_cluster; // append the free cluster to the end of the file in the FAT.
SDC_PutSector((u32)fat_pointer,file->buffer); // save the modified sector to the FAT.
Fat[GetFatSectorIndex(file)].next_cluster = free_cluster; // append the free cluster to the end of the file in the FAT.
SDC_PutSector((u32)fat_pointer,file->buffer); // save the modified sector to the FAT.
 
fat_pointer = (u32)free_cluster;
fat_pointer -= 2;
742,11 → 716,57
fat_pointer *= SectorsPerCluster;
fat_pointer += FirstDataCluster;
 
file->cluster_pointer = fat_pointer; // continue wrtiting to the file in the new and free datacluster.
return(retvalue); // return 1 when a new cluster was appended to the file
file->cluster_pointer = fat_pointer; // continue wrtiting to the file in the new and free datacluster.
return(retvalue); // return 1 when a new cluster was appended to the file
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: void DeleteClusterChain(u16 startcluster);
//
// Description: This function frees all the clusters used for file from the fat.
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
void DeleteClusterChain(u16 startcluster)
{
u16 fat_index = 0;
u16 fat_sector_offset = 0;
u32 sector_in_buffer = 0;
u32 ul_temp = 0;
u8 buffer[512];
fat_index = (startcluster % 0x100); // Calculate the sector within the cluster.
fat_sector_offset = (startcluster >> 8); // and the position within the sector.
ul_temp = (u32)(FileAllocationTable + fat_sector_offset);
do
{
if(sector_in_buffer != ul_temp)
{
sector_in_buffer = ul_temp;
SDC_GetSector(ul_temp,buffer);
}
Fat = (struct FatEntry *)buffer;
startcluster = Fat[fat_index].next_cluster;
Fat[fat_index].next_cluster = 0x0000; // free the cluster within the fat.
 
fat_index = (startcluster % 0x100); // Calculate the sector within the cluster.
fat_sector_offset = (startcluster >> 8); // and the position within the sector.
ul_temp = (u32)(FileAllocationTable + fat_sector_offset);
if((sector_in_buffer != ul_temp) || (startcluster == 0xffff))
{
SDC_PutSector(sector_in_buffer,buffer);
}
}
while(startcluster != 0xffff); // last cluster has been deleted.
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u16 GetFatClusterIndex(File *file);
//
// Description: This function returns the clusterindex of the cluster specified by file->cluster_pointer of the specified file.
757,9 → 777,9
{
u32 fat_sector_offset = 0;
 
fat_sector_offset = ((file->cluster_pointer) - (FirstDataCluster)); // Calculate index of actual cluster in FAT.
fat_sector_offset = ((file->cluster_pointer) - (FirstDataCluster)); // Calculate index of actual cluster in FAT.
fat_sector_offset /= SectorsPerCluster;
fat_sector_offset += 2; // In Fat16 clusterpositions have an offset of two.
fat_sector_offset += 2; // In Fat16 clusterpositions have an offset of two.
return((u16)fat_sector_offset);
}
776,13 → 796,13
u16 fat_pointer = 0;
fat_pointer = GetFatClusterOffset(file);
fat_pointer = fat_pointer % 0x100; // Calculate the clusterposition in the fat
fat_pointer = fat_pointer % 0x100; // Calculate the clusterposition in the fat
return(fat_pointer);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u16 CreateDirectoryEntry(u8 *, u16, u8 attrib)
// Funtion: u16 CreateFileInDirectory(u8 *, File *)
//
// Description: This function looks for the next free position in the directory and creates an entry. The type of an directoryentry is
// specified by the attribute.
794,88 → 814,110
// bit5: volume
//________________________________________________________________________________________________________________________________________
 
u8 CreateDirectoryEntry(u8 *fname, u16 cluster, File *file,u8 attrib)
u8 CreateFileInDirectory(s8 *fname, File *file)
{
u16 rootentry = 0; // index to an entry in the rootdirectory.
u16 cnt_enries_searched = 0; // count the number of rootentries which have been searched already.
u8 i = 0;
u16 sector_offset = 0; // index to the sector of the Rootentry which is searched momentarily
u8 retvalue = 0;
u16 rootentry = 0; // index to an entry in the rootdirectory.
u16 cnt_enries_searched = 0; // count the number of rootentries which have been searched already.
u8 i = 0;
u16 sector_offset = 0; // index to the sector of the Rootentry which is searched momentarily
u8 retvalue = 0;
u32 cluster_temp = 0;
u16 cluster = 0;
s8 name[11] = " ";
 
SeperateFileName(fname,name);
 
cluster_temp = (u32)FindNextFreeCluster(file); // the next free cluster on the disk.
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
do
{ // search the next 16 rootentries in this sector of the roordirectory.
rootentry=0;
SDC_GetSector((u32)(RootDirectory + sector_offset),file->buffer); // Read the Rootdirectory.
DirectoryEntry = (struct DirEntry *)file->buffer;
while((rootentry<16) && (!retvalue))
{
if((DirectoryEntry[rootentry].attribute == 0) || (DirectoryEntry[rootentry].attribute == 0xE5)) // empty directory entry found
if(cluster_temp) // if a free cluster is available:
{
cluster = (u16)cluster_temp; // remember the index of the free datacluster found for the directory entry.
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
cluster_temp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster.
file->start_cluster = (FirstDataCluster + cluster_temp); // Calculate absolute sectorposition of first datacluster.
file->cluster_pointer = file->start_cluster; // start reading the file with the first sector of the first datacluster.
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
do
{ // search the next 16 rootentries in this sector of the roordirectory.
rootentry=0;
SDC_GetSector((u32)(CWD + sector_offset),file->buffer); // Read the Rootdirectory.
DirectoryEntry = (struct DirEntry *)file->buffer;
while((rootentry<16) && (!retvalue))
{
for(i=0;i<11;i++) DirectoryEntry[rootentry].name[i] = fname[i]; // Kopie the filename and the file extension to the directoryentry.
DirectoryEntry[rootentry].attribute = attrib; // Set the fileattribute to archive to reserve the directoryentry.
DirectoryEntry[rootentry].startcluster = cluster; // copy the location of the first datacluster to the directoryentry.
DirectoryEntry[rootentry].size = 0; // the new createted file has no content yet.
file->directory_sector = (u32) (RootDirectory + sector_offset);
file->directory_index = (u8) rootentry;
retvalue = 1;
SDC_PutSector((u32)(RootDirectory + sector_offset),file->buffer);
}
rootentry++;
cnt_enries_searched++;
if((DirectoryEntry[rootentry].attribute == 0) || (DirectoryEntry[rootentry].attribute == 0xE5)) // empty directory entry found
{
for(i=0;i<11;i++) DirectoryEntry[rootentry].name[i] = name[i];// Kopie the filename and the file extension to the directoryentry.
DirectoryEntry[rootentry].attribute = _FILE; // Set the fileattribute to archive to reserve the directoryentry.
DirectoryEntry[rootentry].startcluster = cluster; // copy the location of the first datacluster to the directoryentry.
DirectoryEntry[rootentry].size = 0; // the new createted file has no content yet.
file->directory_sector = (u32) (CWD + sector_offset);
file->directory_index = (u8) rootentry;
retvalue = 1;
SDC_PutSector((u32)(CWD + sector_offset),file->buffer);
}
rootentry++;
cnt_enries_searched++;
}
if(!retvalue) // file not found in this sector so take next sector.
{
rootentry = 0;
sector_offset++;
}
}
if(!retvalue) // file not found in this sector so take next sector.
{
rootentry = 0;
sector_offset++;
}
while((cnt_enries_searched< PossibleRootEntries) && (!retvalue));
 
}
while((cnt_enries_searched< PossibleRootEntries) && (!retvalue));
 
return(retvalue); // return 1 if file has been created otherwise return 0.
return(retvalue); // return 1 if file has been created otherwise return 0.
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u16 SeekDirectoryEntry(u8*, File *, u8)
// Funtion: u16 SeekFileInDirectory(s8 *fname, File *)
//
// Description: this function searches all possible rootentries until the file or directory is found or the end of the rootdirectory is reached
// Description: this function searches all possible entries withint the actual directory for the specified object.
//
// Returnvalue: This function returns 1 if the directoryentry specified was found.
//________________________________________________________________________________________________________________________________________
 
u8 SeekDirectoryEntry(u8 *fname, File *file)
u8 SeekFileInDirectory(s8 *fname, File *file)
{
u16 rootentry=0;
u16 end_of_directory_not_reached = 0; // the directory has been read completely without a result.
u8 i=0;
u16 end_of_directory_not_reached = 0; // the directory has been read completely without a result.
u8 i=0;
u8 retvalue = 0;
u32 cluster_temp = 0;
u16 cnt=0;
s8 name[11] = " ";
SeperateFileName(fname,name);
file->cluster_pointer = CWD; // start looking for the file in the actual directory.
 
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
do
{ // search the next 16 rootentries in this sector of the roordirectory.
{ // search the next 16 rootentries in this sector of the roordirectory.
rootentry=0;
SDC_GetSector((u32) file->cluster_pointer,file->buffer); // Read the Rootdirectory.
SDC_GetSector((u32) file->cluster_pointer,file->buffer); // Read the Rootdirectory.
DirectoryEntry = (struct DirEntry *)file->buffer;
 
while((!retvalue)&&(rootentry<16))
{
cnt++;
 
i=0;
while((i<10)&&(DirectoryEntry[rootentry].name[i] == fname[i]))
if(DirectoryEntry[rootentry].name[0] != 0xe5) // ignore deleted items.
{
i++;
while((i<=10)&&(DirectoryEntry[rootentry].name[i] == name[i]))
{
i++;
}
}
if((i==10) && (DirectoryEntry[rootentry].attribute == file->attribute)) // entry found!! -> reading startcluster of entry from offset 26.
 
if((i==11) && (DirectoryEntry[rootentry].attribute & _FILE)) // entry found!! -> reading startcluster of entry from offset 26.
{
cluster_temp = (u32)DirectoryEntry[rootentry].startcluster;
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
cluster_temp *= (u32)SectorsPerCluster; // Calculate positon of first cluster.
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
cluster_temp *= (u32)SectorsPerCluster; // Calculate positon of first cluster.
file->start_cluster = (FirstDataCluster + cluster_temp);
file->directory_sector = (u32) file->cluster_pointer;
file->cluster_pointer = file->start_cluster; // start reading the file with the first cluster.
file->cluster_pointer = file->start_cluster; // start reading the file with the first cluster.
file->filesize = (u32) DirectoryEntry[rootentry].size;
file->directory_index = (u8) rootentry;
retvalue = 1;
882,7 → 924,7
}
rootentry++;
}
if(!retvalue) // file not found in this sector so take next sector.
if(!retvalue) // file not found in this sector so take next sector.
{
end_of_directory_not_reached = GetNextCluster(file);
}
891,117 → 933,609
return(retvalue);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: void ScanSubDirectories(u8*, File *file);
// Funtion: void SeperateFileName(u8*);
//
// Description: This function scans the filename for subdirectories and changes the directory until the last directory is reached.
// here the specified file is searched.
// Description: This function seperates the filename and the fileattribute and brings them into the needed format ('test.txt' -> 'TEST TXT');
//
// Returnvalue:
//________________________________________________________________________________________________________________________________________
 
u8 ScanSubDirectories(u8 *fname, File *file)
void SeperateFileName(s8 *fname, s8 *name)
{
u8 readpointer = 0; // pointer to read a character within the filepath.
u8 writepointer = 0; // pointer to write a character into the string dirname.
u8 dircnt = 0; // the number of subdirectories found in filepath.
u8 dirname[11]; // temporary variable containing the name of a directory within the filepath.
u8 retvalue = 1; // no error opening a subdirectory occured yet.
u8 cnt = 0; // maximun number of characters in a path is 256;
u8 readpointer = 0;
u8 writepointer = 0;
u8 attribute = 1;
u8 i = 0;
while((writepointer<=10) && (fname[readpointer]!=0)) // the rootdirectoryentry is 8bytes for filename and 3bytes for fileattribute.
{ // the filename in the rootdirectory is in the format "TEST TXT" without the dot.
if(fname[readpointer]=='.') // seperating filename and attribute.
{
if(attribute) // is the filename "." or ".." ?
{
name[writepointer] = fname[readpointer];
readpointer++;
writepointer++;
}
else
{
if(fname[(readpointer-1)] != '*')
{
for(i=writepointer;i<8;i++)
{
name[i] = ' ';
}
}
readpointer++;
writepointer = 8;
}
}
else if(fname[readpointer] == '*') // wildcard found within the filename + extension.
{
if(writepointer < 8) // in extension.
{
readpointer++;
writepointer = 8;
}
else // in filename.
{
writepointer = 11; // jump to the end of the string to terminate this function.
}
attribute = 0;
}
else
{
if((fname[readpointer]>96) && (fname[readpointer]<123))
{
name[writepointer]=(fname[readpointer] - 32); // all characters must be upper case.
}
else
{
name[writepointer]=fname[readpointer];
}
readpointer++;
writepointer++;
attribute = 0;
}
}
}
 
while((fname[readpointer]!=0) && (cnt < 255)) // search the string until the end is reached.
//________________________________________________________________________________________________________________________________________
// Funtion: File * ReserveFilePointer_(void);
//
// Description: This function looks for a free filepointer and reserves it.
//
//
// Return: NULL = faild to reserve a filepointer
// otherwise filepointer
//________________________________________________________________________________________________________________________________________
 
File * ReserveFilePointer(void)
{
File *file;
file = NULL;
u8 temp;
for(temp = 0;temp<__MAX_FILES_USED;temp++)
{
cnt++;
if((fname[readpointer] == '/') && readpointer) // subdirectory found. ignore first "/" as directory.
if(FilePointer[temp].state == _UNUSED) // free filepointer found?
{
dircnt++; // count the number of subdirectories found within the filepath.
file = &FilePointer[temp];
FilePointer[temp].state = _USED; // mark as used.
FilePointer[temp].mode = 0; // type of access (read/write) not defined yet.
FilePointer[temp].start_cluster = 0; // Sectorpointer to the first sector of the first datacluster of the file.
FilePointer[temp].cluster_pointer = 0; // Pointer to the cluster which is edited at the moment.
FilePointer[temp].sector_index = 0; // The sector which is edited at the moment (cluster_pointer + sector_index).
FilePointer[temp].byte_index = 0; // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
FilePointer[temp].filesize = 0; // the size of the opend file in bytes.
FilePointer[temp].fileposition = 0; // pointer to a character within the file 0 < fileposition < filesize
FilePointer[temp].sector_in_buffer = 0; // the last sector read, wich is still in the sectorbuffer.
FilePointer[temp].directory_sector = 0; // the sectorposition where the directoryentry has been made.
FilePointer[temp].directory_index = 0; // the index to the directoryentry within the specified sector.
FilePointer[temp].attribute = 0; // the attribute of the file opened.
break;
}
readpointer++;
}
return(file);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: void FreeFilePointer_(File *);
//
// Description: This function free's the filepointer by marking it as unused.
//
//
// Return: none
//
//________________________________________________________________________________________________________________________________________
 
void FreeFilePointer(File *file)
{
u8 cnt = 0;
for(writepointer=0;writepointer<10;writepointer++) dirname[writepointer] = ' ';
writepointer = 0;
readpointer = 0; // start scanning the string at the beginning.
for(cnt=0;cnt<__MAX_FILES_USED;cnt++) // Is the filepointeradress vaild?
{
if(&FilePointer[cnt] == file) // filepointer found therefore it must be valid
{
FilePointer[cnt].state = _UNUSED; // and can be marked as unused.
}
}
}
 
file->cluster_pointer = RootDirectory; // always start searching in the rootdirectory.
file->attribute = _DIRECTORY; // the attribute of the item to be searched in the specified directory.
 
//________________________________________________________________________________________________________________________________________
// Funtion: void DelteDirectoryEntry(Find *)
//
// Description: This function deletes the directoryentry of the specified item.
//
//
// returnvalue: 1 if the directory could be created.
//________________________________________________________________________________________________________________________________________
 
void DeleteDirectoryEntry(Find *item)
{
u8 buffer[512];
while(dircnt && retvalue) // scan all subdirectories found before.
SDC_GetSector((u32) item->cluster_pointer,buffer); // Read the Rootdirectory.
DirectoryEntry = (struct DirEntry *)buffer;
 
DirectoryEntry[(item->directory_index)-1].attribute = 0; // free the directoryentry.
DirectoryEntry[(item->directory_index)-1].name[0] = 0xE5; // free the directoryentry.
SDC_PutSector((u32) item->cluster_pointer,buffer); // Read the Rootdirectory.
}
 
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 CreateSubDirectory(u8 *)
//
// Description: This function creates an directory within the directory specified by CWD
//
//
// returnvalue: 1 if the directory could be created.
//________________________________________________________________________________________________________________________________________
 
u8 CreateSubDirectory(s8 *fname)
{
u16 index = 0; // index to an entry in the rootdirectory.
u16 cnt_entries_searched = 0; // count the number of rootentries which have been searched already.
u16 i = 0;
u16 sector_offset = 0; // index to the sector of the entry which is searched momentarily
u8 retvalue = 0;
u32 cluster_temp = 0;
u16 cluster = 0;
File file;
s8 name[11] = {" "};
 
SeperateFileName(fname,name);
cluster_temp = (u32)FindNextFreeCluster(&file); // the next free cluster on the disk.
if(cluster_temp) // if a free cluster is available:
{
if(fname[readpointer] != '/') // is the end of the subdirectory entry not reached yet?
cluster = (u16)cluster_temp; // remember the index of the free datacluster found for the directory entry.
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
cluster_temp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster.
file.start_cluster = (FirstDataCluster + cluster_temp); // Calculate absolute sectorposition of first datacluster.
file.cluster_pointer = file.start_cluster; // start reading the file with the first sector of the first datacluster.
// -Initialise new cluster to zero--------------------------------------------------------
for(i=0;i<512;i++)
{
if((fname[readpointer]>96) && (fname[readpointer]<123))
{ // all characters must be upper case.
dirname[writepointer]=(fname[readpointer] - 32);
file.buffer[i] = 0; // initialise buffer to zero
}
for(sector_offset=0;sector_offset<SectorsPerCluster;sector_offset++) // initialise all sectors of new cluster with buffer.
{
SDC_PutSector((u32)(file.start_cluster + sector_offset),file.buffer); // save the initialised sector to the card.
}
// -Create directoryentry "." -------------------------------------------------------------
DirectoryEntry = (struct DirEntry *)file.buffer;
DirectoryEntry[0].name[0] = '.';
DirectoryEntry[0].attribute = _DIRECTORY;
DirectoryEntry[0].startcluster = cluster;
// -Create directoryentry "." -------------------------------------------------------------
DirectoryEntry[1].name[0] = '.';
DirectoryEntry[1].name[1] = '.';
DirectoryEntry[1].attribute = _DIRECTORY;
if(CWD == RootDirectory)
{
DirectoryEntry[1].startcluster = 0;
}
else
{
cluster_temp = (CWD - FirstDataCluster);
cluster_temp /= SectorsPerCluster;
cluster_temp -= 2;
DirectoryEntry[1].startcluster = (u16) cluster_temp;
}
SDC_PutSector((u32) file.start_cluster,file.buffer); // save the initialised sector to the card.
// -create directoryentry within the cwd --------------------------------------------------
sector_offset = 0;
cnt_entries_searched = 0;
do
{ // search the next 16 rootentries in this sector of the roordirectory.
index=0;
SDC_GetSector((u32)(CWD + sector_offset),file.buffer); // Read the actual directory.
DirectoryEntry = (struct DirEntry *)file.buffer;
while((index<16) && (!retvalue))
{
if((DirectoryEntry[index].attribute == 0) || (DirectoryEntry[index].attribute == 0xE5)) // empty directory entry found
{
for(i=0;i<11;i++) DirectoryEntry[index].name[i] = name[i]; // Kopie the filename and the file extension to the directoryentry.
DirectoryEntry[index].attribute = _DIRECTORY; // Set the fileattribute to archive to reserve the directoryentry.
DirectoryEntry[index].startcluster = cluster; // copy the location of the first datacluster to the directoryentry.
DirectoryEntry[index].size = 0; // the new createted file has no content yet.
file.directory_sector = (u32) (CWD + sector_offset);
file.directory_index = (u8) index;
retvalue = 1;
SDC_PutSector((u32)(CWD + sector_offset),file.buffer);
}
index++;
cnt_entries_searched++;
}
else
if(!retvalue) // file not found in this sector so take next sector.
{
dirname[writepointer]=fname[readpointer];
}
writepointer++;
}
else
{
dircnt--;
if(!(SeekDirectoryEntry(dirname, file))) // was the seperated subdirectory not found?
index = 0;
sector_offset++;
}
}
while((cnt_entries_searched< PossibleRootEntries) && (!retvalue));
 
}
return(retvalue); // return 1 if file has been created otherwise return 0.
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u16 SeekSubDirectory(s8 *fname)
//
// Description: looks for the specified directory within the CWD.
//
// Returnvalue: If the specified directory was found the startcluster is returned. otherwise 0.
//________________________________________________________________________________________________________________________________________
 
u16 SeekSubDirectory(s8 *fname)
{
u16 index = 0;
u16 end_of_directory_not_reached = 0; // the directory has been read completely without a result.
u8 i = 0;
u16 cluster_temp = 0;
s8 name[11] = " ";
File file;
 
SeperateFileName(fname,name);
file.cluster_pointer = CWD; // start looking for the file in the actual directory.
file.start_cluster = CWD; // start looking for the file in the actual directory.
 
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
do
{ // search the next 16 rootentries in this sector of the roordirectory.
index=0;
SDC_GetSector((u32) file.cluster_pointer,file.buffer); // Read the Rootdirectory.
DirectoryEntry = (struct DirEntry *)file.buffer;
 
while((!cluster_temp)&&(index<16))
{
i=0;
if(DirectoryEntry[index].name[0] != 0xe5) // ignore deleted items.
{
retvalue = 0; // leave the function with return(0) otherwise continue with the next subdirectory until all directories have been searched.
while((i<=10)&&(DirectoryEntry[index].name[i] == name[i]))
{
i++;
}
}
for(writepointer=0;writepointer<10;writepointer++) dirname[writepointer] = ' ';
writepointer = 0;
 
if((i==11) && (DirectoryEntry[index].attribute & _DIRECTORY)) // entry found!! -> reading startcluster of entry from offset 26.
{
cluster_temp = (u16)DirectoryEntry[index].startcluster;
}
index++;
}
readpointer++;
if(!cluster_temp) // file not found in this sector so take next sector.
{
end_of_directory_not_reached = GetNextCluster(&file);
}
}
file->attribute = _FILE; // All subdirectories have been searched. the next thing to find is the specified file.
while((end_of_directory_not_reached) && (!cluster_temp));
return(cluster_temp);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 mkdir_(u8 *)
//
// Description: This function checks if the directory to be created already exists. If not the directory will be created.
//
//
// returnvalue: 1 if the directory could be created.
//________________________________________________________________________________________________________________________________________
 
u8 mkdir_(s8 *fname)
{
u8 retvalue = 0;
retvalue = SeekSubDirectory(fname); // check wether the specified directory already exists.
if(!retvalue)
{
CreateSubDirectory(fname); // if directory doesn't exist, create it.
retvalue = 1;
}
else
{
retvalue = 0;
}
return(retvalue);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: void SeperateFileName(u8*);
// Funtion: u8 chdir_(u8 *)
//
// Description: This function seperates the filename and the fileattribute and brings them into the needed format ('test.txt' -> 'TEST TXT');
// Description: This function changes the CWD to the directory specified.
//
//
// returnvalue: 1 if the directory could be changed.
//________________________________________________________________________________________________________________________________________
 
void SeperateFileName(u8 *fname, u8 *name)
u8 chdir_(s8 *fname)
{
u8 readpointer = 0;
u8 writepointer = 0;
u8 dircnt = 0; // the number of subdirectories found in filepath.
u8 fileindex = 0; // the position in the filenamestring where the last "/" is found.
u8 retvalue = 0;
s8 name[11] = {" "};
while(fname[readpointer]!=0) // search the string until the end is reached.
u32 ultemp = 0;
 
SeperateFileName(fname,name);
ultemp = (u32)SeekSubDirectory(name);
if(ultemp >= 2)
{
if((fname[readpointer] == '/') && readpointer) // subdirectory found. ignore first "/" as directory.
ultemp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
ultemp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster.
ultemp += FirstDataCluster;
CWD = ultemp;
retvalue = 1;
}
else
{
CWD = RootDirectory;
retvalue = 1;
}
 
return(retvalue);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 FindItem(s8 *fname, Find *)
//
// Description: finds an item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
//
// Returnvalue: If an item was found this function returns '1' else '0'.
//________________________________________________________________________________________________________________________________________
 
u8 FindItem(Find *item)
{
u16 index = 0;
u16 end_of_directory_not_reached = 0; // the directory has been read completely without a result.
u8 i = 0;
u8 readpointer = 0;
u8 writepointer = 0;
u8 retvalue = 0;
File file;
 
file.cluster_pointer = item->cluster_pointer;
file.start_cluster = item->cluster_pointer;
index = item->directory_index;
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
do
{ // search the next 16 rootentries in this sector of the roordirectory.
SDC_GetSector((u32) file.cluster_pointer,file.buffer); // Read the Rootdirectory.
DirectoryEntry = (struct DirEntry *)file.buffer;
 
while((!retvalue)&&(index<16))
{
dircnt++; // subdirectory entry found.
fileindex = (readpointer + 1); // store the index of the last slash found as the beginning of the filename.
i=0;
if(DirectoryEntry[index].name[0] != 0xe5) // ignore deleted items.
{
while((i<=10)&&((DirectoryEntry[index].name[i] == item->searchstring[i]) || (item->searchstring[i]=='*') || item->searchstring[i]=='?'))
{
i++;
}
}
 
if((i==11) && (DirectoryEntry[index].attribute & item->attribute))
{
for(readpointer=0;readpointer<=10;readpointer++)
{
if(DirectoryEntry[index].name[readpointer] != ' ')
{
item->name[writepointer] = DirectoryEntry[index].name[readpointer]; // copy the name of the item found to the find_structure.
writepointer++;
}
else if((readpointer==7) && (DirectoryEntry[index].attribute == _FILE)) // if the item found is a file
{
if(DirectoryEntry[index].name[readpointer] != ' ')
{
item->name[writepointer] = DirectoryEntry[index].name[readpointer]; // copy the name of the item found to the find_structure.
writepointer++;
}
item->name[writepointer] = '.'; // then seperate the name and the extension by a '.' at index 8.
writepointer++;
}
}
item->startcluster = (u16)DirectoryEntry[index].startcluster;
item->directory_index = ++index;
item->cluster_pointer = file.cluster_pointer;
retvalue = 1;
}
index++;
}
readpointer++;
if(!retvalue) // file not found in this sector so take next sector.
{
end_of_directory_not_reached = GetNextCluster(&file);
}
index = 0;
}
readpointer = fileindex; // start seperating the filename from the directory at the stored position.
dircnt = 0;
while((end_of_directory_not_reached) && (!retvalue));
return(retvalue);
}
 
while((writepointer<=10) && (fname[readpointer]!=0)) // the rootdirectoryentry is 8bytes for filename and 3bytes for fileattribute.
{ // the filename in the rootdirectory is in the format "TEST TXT" without the dot.
if(fname[readpointer]=='.') // seperating filename and attribute.
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 findfirst(s8 *fname, Find *)
//
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
//
// Returnvalue: If an item was found this function returns '1' else '0'.
//________________________________________________________________________________________________________________________________________
 
u8 findfirst_(s8 *fname, Find *item, u8 attribute)
{
u8 retvalue = 0;
u8 i = 0;
 
for(i=0;i<=11;i++)
{
item->searchstring[i] = '*'; // initialise the searchstring with wildcards.
item->name[i] = 0;
}
 
SeperateFileName(fname,item->searchstring);
item->cluster_pointer = CWD; // findfirst_ starts at the beginning of the cwd.
item->directory_index = 0;
item->attribute = attribute;
retvalue = FindItem(item);
 
return(retvalue);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 findnext(Find *)
//
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
//
// Returnvalue: If an item was found this function returns '1' else '0'.
//________________________________________________________________________________________________________________________________________
 
u8 findnext_(Find *item)
{
u8 retvalue = 0;
u8 i = 0;
 
for(i=0;i<=11;i++) // copy the name of the searched item to the findstructure.
{
item->name[i] = 0;
}
 
retvalue = FindItem(item); // search the item.
 
return(retvalue);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 fdelete(s8 *fname)
//
// Description: Deletes the file specified by fname.
//
// Returnvalue:
//________________________________________________________________________________________________________________________________________
 
u8 fdelete_(s8 *fname)
{
u8 retvalue = 0;
Find item;
retvalue = findfirst_(fname,&item, _FILE); // look for the item to be deleted.
 
if(retvalue); // item found?
{
DeleteClusterChain(item.startcluster); // delete all fatentries of the item.
DeleteDirectoryEntry(&item); // free the directoryentry.
do
{
readpointer++;
writepointer=8;
retvalue = findnext_(&item);
if(retvalue)
{
DeleteClusterChain(item.startcluster); // delete all fatentries of the item.
DeleteDirectoryEntry(&item); // free the directoryentry.
}
}
else
while(retvalue);
}
 
return(retvalue);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 rmdir(s8 *fname)
//
// Description: Deletes the directory specified by dname.
//
// Returnvalue:
//________________________________________________________________________________________________________________________________________
 
u8 rmdir_(s8 *dname)
{
u8 retvalue = 0;
Find item;
retvalue = findfirst_(dname,&item, _DIRECTORY); // look for the item to be deleted.
 
if(retvalue); // item found?
{
DeleteClusterChain(item.startcluster); // delete all fatentries of the item.
DeleteDirectoryEntry(&item); // free the directoryentry.
do
{
if((fname[readpointer]>96) && (fname[readpointer]<123))
retvalue = findnext_(&item);
if(retvalue)
{
name[writepointer]=(fname[readpointer] - 32); // all characters must be upper case.
DeleteClusterChain(item.startcluster); // delete all fatentries of the item.
DeleteDirectoryEntry(&item); // free the directoryentry.
}
else
{
name[writepointer]=fname[readpointer];
}
readpointer++;
writepointer++;
}
}
while(retvalue);
}
 
return(retvalue);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: u16 feof_(File *file)
//
// Description: This function checks wether the end of the file has been reached.
//
// Returnvalue: 0 if the end of the file was not reached otherwise 1.
//________________________________________________________________________________________________________________________________________
 
u16 feof_(File *file)
{
if(((file->fileposition)+1) < (file->filesize))
{
return(0);
}
else
{
return(1);
}
}
/trunk/fat16.h
2,17 → 2,23
#define __fat16_h
 
 
 
//________________________________________________________________________________________________________________________________________
//
// Definitions
// Userspecific definitions
//
//________________________________________________________________________________________________________________________________________
 
//#define __USE_TIME_DATE_ATTRIBUTE
#define __MAX_FILES_USED 2 // The number of files that can accessed simultaneously.
#define __MAX_FILES_USED 1 // The number of files that can be opened simultaneously.
 
#define MBR_SECTOR 0 // the masterboot record is located in sector 0.
#define _UNUSED 1 // Bits used in the attribute of an directory entry.
 
//________________________________________________________________________________________________________________________________________
//
// Structure of a filepointer
//
//________________________________________________________________________________________________________________________________________
 
#define _UNUSED 1 // Bits used in the attribute of an directory entry.
#define _USED 2
#define _ARCHIVE 2
#define _READ_ONLY 4
21,47 → 27,79
#define _FILE 32
 
 
typedef struct afile
{
u32 start_cluster; // Sectorpointer to the first sector of the first datacluster of the file.
u32 cluster_pointer; // Pointer to the cluster which is edited at the moment.
u8 sector_index; // The sector which is edited at the moment (cluster_pointer + sector_index).
u16 byte_index; // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
u8 mode; // mode of fileoperation (read,write)
u32 filesize; // the size of the opend file in bytes.
u32 fileposition; // pointer to a character within the file 0 < fileposition < filesize
u32 sector_in_buffer; // the last sector read, wich is still in the sectorbuffer.
u32 directory_root_sector; // pointer to the root of the
u32 directory_sector; // the sectorposition where the directoryentry has been made.
u8 directory_index; // the index to the directoryentry within the specified sector.
u8 attribute; // the attribute of the file opened.
u8 buffer[512]; // Buffer for read and write operation from or to the mmc.
u8 state; // state of the filepointer (used/unused/...)
} File;
 
 
typedef enum
{
NOT_INITIALIZED,
INITIALIZED
}Fat16_VolumeState_t;
 
//________________________________________________________________________________________________________________________________________
//
// Structure of a filepointer
// Structure of an item to find within the cwd
//
//________________________________________________________________________________________________________________________________________
 
typedef struct afile
struct volume
{
u32 start_cluster; // Sectorpointer to the first sector of the first datacluster of the file.
u32 cluster_pointer; // Pointer to the cluster which is edited at the moment.
u8 sector_index; // The sector which is edited at the moment (cluster_pointer + sector_index).
u16 byte_index; // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
u8 mode; // mode of fileoperation (read,write)
u32 filesize; // the size of the opend file in bytes.
u32 fileposition; // pointer to a character within the file 0 < fileposition < filesize
u32 sector_in_buffer; // the last sector read, wich is still in the sectorbuffer.
u32 directory_sector; // the sectorposition where the directoryentry has been made.
u8 directory_index; // the index to the directoryentry within the specified sector.
u8 attribute; // the attribute of the file opened.
u8 buffer[512]; // Buffer for read and write operation from or to the mmc.
u8 state; // state of the filepointer (used/unused/...)
} File;
Fat16_VolumeState_t state; // state of the volume
} str_Volume;
 
//________________________________________________________________________________________________________________________________________
//
// Structure of an directoryentry
// Structure of an item to find within the cwd
//
//________________________________________________________________________________________________________________________________________
 
typedef struct find
{
s8 name[12]; // filename + extension or directoryname of the item found within the cwd.
s8 searchstring[13];
u32 cluster_pointer; // Sectorpointer to the sector of the item searched within the cwd.
u16 startcluster; // pointer to the first datacluster of the item found in the cwd.
u32 filesize; // the size of the opend file in bytes.
u32 directory_sector; // the sector within the actual cluster where the directoryentry was found.
u8 directory_index; // the index to the directoryentry within the specified sector.
u8 attribute; // the attribute of the file opened.
} Find;
 
//________________________________________________________________________________________________________________________________________
//
// Directoryentries
//
//________________________________________________________________________________________________________________________________________
 
 
 
struct DirEntry
{
u8 name[8]; // 8 bytes name.
u8 extension[3]; // 3 bytes extension.
u8 attribute; // attribute of the directory entry (unused,archive,read-only,system,directory,volume)
u8 reserved[10]; // reserved bytes within the directory entry.
u8 name[8]; // 8 bytes name.
u8 extension[3]; // 3 bytes extension.
u8 attribute; // attribute of the directory entry (unused,archive,read-only,system,directory,volume)
u8 reserved[10]; // reserved bytes within the directory entry.
u16 time; // time and
u16 date; // date of last write acces to the file or directory.
u16 startcluster; // first cluster of the file or directory.
u32 size; // size of the file or directory in bytes.
};
u32 size; // size of the file or directory in bytes.
} __attribute__((packed));
 
//________________________________________________________________________________________________________________________________________
//
72,7 → 110,7
struct FatEntry
{
u16 next_cluster; // the next cluster of the file.
};
} __attribute__((packed));
 
 
 
80,10 → 118,30
 
//________________________________________________________________________________________________________________________________________
//
// Structure of an partitionentry
// Partitions
//
//________________________________________________________________________________________________________________________________________
 
#define _EMPTY 0x00
#define _FAT12 0x01
#define _FAT16_ST_32_MB 0x04
#define _EXTENDED 0x05
#define _FAT16_LT_32_MB 0x06
#define _HPFS 0x07
#define _FAT32 0x0B
#define _FAT32_BIOS_Extension 0x0C
#define _FAT16_32_MB_BIOS_Extension 0x0E
#define _EXTENDED_BIOS_Extension 0x0F
#define _EISA 0x12
#define _DYNAMIC 0x42
#define _Linux_Swap 0x82
#define _Linux_Native 0x83
#define _Linux_LVM 0x8E
#define _FreeBSD 0xA5
#define _OpenBSD 0xA6
#define _NetBSD 0xA9
 
 
struct PartitionEntry
{
u8 PartitionState;
124,6 → 182,8
//
//________________________________________________________________________________________________________________________________________
 
#define _MBR_SECTOR 0 // The MasterBootRecord is located in sector 0
 
struct MBR_Entry
{
u8 ExecutableCode[446];
144,19 → 204,26
//________________________________________________________________________________________________________________________________________
 
extern u8 InitFat16(void);
extern File * fopen_(u8 *fname,s8 mode);
extern File * fopen_(s8 *fname,s8 mode);
extern s16 fflush_(File *file);
extern void fclose_(File *file);
extern u32 fread_(void *buffer, u32 size, u32 count, File *file);
extern u32 fwrite_(void *buffer, u32 size, u32 count, File *file);
extern s16 fseek_(File *file, s32 offset, s16 origin);
extern s16 fgetchar_(File *file);
extern s16 fgetchar_(File *file);
extern u8 fputchar_(File *file,s8 c);
extern u8 fputs_(File *file,s8 *string);
extern s8 * fgets_(s8 *s, s16 count, File *file);
extern s16 frename_(s8 *oldname, s8 *newname);
extern u8 fexist_(u8*fname);
extern u8 fexist_(s8 *fname);
extern u8 mkdir_(s8 *fname);
extern u8 chdir_(s8 *fname);
extern u8 findfirst_(s8 *fname, Find *item, u8 attribute);
extern u8 findnext_(Find *item);
extern u16 feof_(File *);
 
 
 
//________________________________________________________________________________________________________________________________________
//
// Functions needed internaly for the fat16 implementation
163,17 → 230,21
//
//________________________________________________________________________________________________________________________________________
 
extern u8 CreateDirectoryEntry(u8*fname, u16 cluster, File *file,u8 attrib);
extern u8 SeekFileInDirectory(s8*fname, File *file);
extern u8 CreateFileInDirectory(s8*fname, File *file);
extern u16 FindNextFreeCluster(File *file);
extern u8 SeekDirectoryEntry(u8*fname, File *file);
extern void SeperateFileName(u8*fname, u8*name);
extern u8 ScanSubDirectories(u8*fname, File *file);
extern void SeperateFileName(s8*fname, s8*name);
extern u8 ScanSubDirectories(s8*fname, File *file);
extern u16 GetNextCluster(File *file);
extern u8 AppendCluster(File *file);
extern u16 GetFatClusterOffset(File *file);
extern u16 GetFatSectorIndex(File *file);
extern File * ReserveFilePointer(void);
extern u16 SeekSubDirectory(s8 *fname);
extern u8 CreateSubDirectory_(s8 *fname);
extern u8 FindItem(Find *);
extern void FreeFilePointer(File *file);
 
 
//________________________________________________________________________________________________________________________________________
//
// Vaiables needed internaly for the fat16 implementation
181,9 → 252,10
//________________________________________________________________________________________________________________________________________
 
extern u8 SectorsPerCluster;
extern u8 SectorsPerCluster;
extern u32 CWD;
 
extern struct time rtctime;
 
 
#endif
 
 
/trunk/interrupt.c
304,6 → 304,16
*******************************************************************************/
void EXTIT1_IRQHandler(void)
{
VIC_ITCmd(EXTIT1_ITLine, DISABLE);
if(WIU_GetITStatus(WIU_Line11) != RESET)
{
BeepTime = 100;
InitFat16(); // initialize sd-card file system.
 
WIU_ClearFlag(WIU_Line1);
WIU_ClearITPendingBit(WIU_Line11);
}
VIC_ITCmd(EXTIT1_ITLine, ENABLE);
}
/*******************************************************************************
* Function Name : EXTIT2_IRQHandler
/trunk/kml.c
0,0 → 1,357
/*#######################################################################################*/
/* !!! THIS IS NOT FREE SOFTWARE !!! */
/*#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 2008 Ingo Busker, Holger Buss
// + Nur für den privaten Gebrauch
// + FOR NON COMMERCIAL USE ONLY
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
// + Verkauf von Luftbildaufnahmen, usw.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
// + eindeutig als Ursprung verlinkt werden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
// + Benutzung auf eigene Gefahr
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die PORTIERUNG der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permitted
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * PORTING this software (or part of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
//
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include <stdio.h>
#include "main.h"
#include "kml.h"
#include "kml_header.h"
#include "fat16.h"
 
 
//________________________________________________________________________________________________________________________________________
// Module name: kml.c
// Compiler used: avr-gcc 3.4.5
// Last Modifikation: 17.03.2008
// Version: 1.02
// Authors: Stephan Busker
// Description: Source files to write gps-coordinates to a file in the kml (keyhole markup language) fileformat
// Copyright (C) 2007 Stephan Busker
//........................................................................................................................................
// Functions: extern u8 KML_LoggGPSCoordinates(struct str_gps_nav_data , KML_Document_t *); // intializes the kml-document with standard filename and adds points to the file
// extern u8 KML_DocumentInit(KML_Document_t *doc) // initializes the kml-document to resetvalues.
// extern u8 KML_DocumentOpen(s8 *, KML_Document_t *); // opens a new kml document. A filename can be specified.
// extern u8 KML_DocumentClose(KML_Document_t *doc); // closes an open document
// extern u8 KML_PlaceMarkOpen(s8 *name, KML_Document_t *); // opens a new placemark within the specified document
// extern u8 KML_PlaceMarkClose( KML_Document_t *); // Closes the placemark
// extern u8 KML_LineStringBegin(KML_Document_t *); // begins a new line within the actual placemark
// extern u8 KML_LineStringEnd(KML_Document_t *doc); // ends the actual linestring
// extern u8 KML_LineStringAddPoint(struct str_gps_nav_data, KML_Document_t *); // adds a new point (gps-coordinates) to the actual linestring
//........................................................................................................................................
// ext. functions:
//
//........................................................................................................................................
//
// URL: www.Mikro-Control.de
// mailto: stephan.busker@mikro-control.de
//________________________________________________________________________________________________________________________________________
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: KML_DocumentInit(KML_Document_t *)
//
// Description: This function initializes the kml-document for further use.
//
//
// Returnvalue: '1' if document was initialized
//________________________________________________________________________________________________________________________________________
 
u8 KML_DocumentInit(KML_Document_t *doc)
{
doc->name[0] = 0; // name of the document
doc->state = DOC_CLOSED; // state of the kml-document
doc->file = NULL;
doc->place.name[0]=0;
doc->place.description[0]=0;
return(1);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: KML_Document_Open(void);
//
// Description: This function opens a new KML- document with the specified name and creates the document header within the file.
//
//
// Returnvalue: '1' if the KML- file could be created.
//________________________________________________________________________________________________________________________________________
 
u8 KML_DocumentOpen(s8 *name, KML_Document_t *doc)
{
 
u8 retvalue = 0;
KML_DocumentInit(doc); // intialize the document with resetvalues
doc->file = fopen_(name,'a'); // open a new file with the specified filename on the memorycard.
 
if(doc->file != NULL) // could the file be opened?
{
retvalue = 1; // the document could be created on the drive.
doc->state = DOC_OPENED; // change document state to opened. At next a placemark has to be opened.
fwrite_(KML_DOCUMENT_HEADER, sizeof(KML_DOCUMENT_HEADER)-1,1,doc->file); // write the KML- footer to the document.
}
 
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: DocumentClose(KML_Document_t *doc);
//
// Description: This function closes the document specified by doc.
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
u8 KML_DocumentClose(KML_Document_t *doc)
{
 
u8 retvalue = 0;
 
while(doc->state != DOC_CLOSED) // close linestring, placemark and document before closing the file on the memorycard
{
switch(doc->state)
{
case DOC_LINESTRING_OPENED:
KML_LineStringEnd(doc); // write terminating tag to end linestring.
doc->state = DOC_PLACEMARK_OPENED;
break;
 
case DOC_PLACEMARK_OPENED: // write terminating tag to close placemark.
KML_PlaceMarkClose(doc);
doc->state = DOC_OPENED;
break;
case DOC_OPENED: // close the file on the memorycard
if(doc->file != NULL)
{
fwrite_(KML_DOCUMENT_FOOTER, sizeof(KML_DOCUMENT_FOOTER)-1,1,doc->file); // write the KML- footer to the document.
fclose_(doc->file);
retvalue = 1;
}
doc->state = DOC_CLOSED;
break;
}
};
 
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 PlaceMarkOpen(s8 *name, File *file);
//
// Description: This function adds a placemark to the document.
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
u8 KML_PlaceMarkOpen(s8 *name, KML_Document_t *doc)
{
 
u8 retvalue = 0;
 
if(doc->file != NULL)
{
doc->state = DOC_PLACEMARK_OPENED;
retvalue = 1;
fwrite_(KML_PLACEMARK_HEADER, sizeof(KML_PLACEMARK_HEADER)-1,1,doc->file);
}
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 PlaceMarkClose(KML_PlaceMark_t *place, File *file);
//
// Description: This function ends the placemark opened before.
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
u8 KML_PlaceMarkClose(KML_Document_t *doc)
{
 
u8 retvalue = 0; // close the Placemark-tag of the corosponding document.
 
if(doc->state == DOC_PLACEMARK_OPENED)
{
if(doc->file != NULL)
{
doc->state =DOC_OPENED;
fwrite_(KML_PLACEMARK_FOOTER, sizeof(KML_PLACEMARK_FOOTER)-1,1,doc->file);
retvalue = 1;
}
}
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 LineStringBegin(KML_Document_t *doc);
//
// Description: This function ends the placemark opened before.
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
u8 KML_LineStringBegin(KML_Document_t *doc)
{
 
u8 retvalue = 0;
if(doc->file != NULL)
{
doc->state = DOC_LINESTRING_OPENED;
fwrite_(KML_LINESTRING_HEADER, sizeof(KML_LINESTRING_HEADER)-1,1,doc->file);
retvalue = 1;
}
 
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 LineStringEnd(KML_Document_t *doc)
//
// Description: This function ends the placemark opened before.
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
u8 KML_LineStringEnd(KML_Document_t *doc)
{
 
u8 retvalue = 0;
if(doc->state == DOC_LINESTRING_OPENED);
if(doc->file != NULL)
{
doc->state = DOC_PLACEMARK_OPENED;
fwrite_(KML_LINESTRING_FOOTER, sizeof(KML_LINESTRING_FOOTER)-1,1,doc->file);
retvalue = 1;
}
 
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 LineStringAddPoint(struct str_GPSPosition, KML_Document_t *doc)
//
// Description: This function adds a point to the specified document.
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
u8 KML_LineStringAddPoint(struct str_gps_nav_data gps_data ,KML_Document_t *doc)
{
 
u8 retvalue = 0;
s8 string[50];
if(doc->state == DOC_LINESTRING_OPENED)
{
if(doc->file != NULL)
{
sprintf(string,"\r\n%d.%d,%d.%d,%d.0",(gps_data.Longitude/10000000),(gps_data.Longitude%10000000),(gps_data.Latitude/10000000),(gps_data.Latitude%10000000),0);
fputs_(doc->file,string);
retvalue = 1;
}
}
 
return(retvalue);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: u8 KML_LoggGPSCoordinates(struct str_gps_nav_data, KML_Document_t *)
//
// Description: This function opens adds gpscoordinates to an KML-Document. The document will be opened, if not already done
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
u8 KML_LoggGPSCoordinates(struct str_gps_nav_data gps_data, KML_Document_t *doc)
{
while(doc->state != DOC_LINESTRING_OPENED) // automatic create document with default filename on the card.
{
switch(doc->state)
{
case DOC_CLOSED: // document hasn't been opened yet therefore it will be initialized automatically
KML_DocumentInit(doc); // initialize the document to default values
if(KML_DocumentOpen("default.kml",doc)) // open the kml-document with a standardname.
{
doc->state = DOC_OPENED;
}
break;
 
case DOC_OPENED: // if a document has been opened before but no placemark exists:
if(KML_PlaceMarkOpen("MIKROKOPTER",doc))
{
doc->state = DOC_PLACEMARK_OPENED; // add a placemark to the document.
}
break;
 
case DOC_PLACEMARK_OPENED: // add linestring to the placemark
if(KML_LineStringBegin(doc))
{
doc->state = DOC_LINESTRING_OPENED;
}
break;
 
}
};
 
if(doc->state == DOC_LINESTRING_OPENED) // if the document was opened add coordinates to the document.
{
KML_LineStringAddPoint(gps_data , doc);
}
}
/trunk/kml.h
0,0 → 1,49
#ifndef _KML_H
#define _KML_H
 
#include "fat16.h"
 
 
// possible state of an kml-document
typedef enum
{
DOC_CLOSED,
DOC_OPENED,
DOC_PLACEMARK_OPENED,
DOC_LINESTRING_OPENED,
DOC_END
}KML_DocState_t;
 
 
// structure of an kml-placemarkt
typedef struct kml_place
{
s8 name[10]; // the name of the placemark
s8 description[40]; // some text as a description to the placemark
} KML_PlaceMark_t;
 
 
 
// structure of an kml-document
typedef struct kml_doc
{
u8 name[40]; // name of the document
KML_DocState_t state; // state of the kml-document
File *file; // filepointer to the file where the data should be saved.
KML_PlaceMark_t place;
 
} KML_Document_t;
 
 
#endif
 
extern u8 KML_LoggGPSCoordinates(struct str_gps_nav_data , KML_Document_t *);
extern u8 KML_DocumentInit(KML_Document_t *); // Init the new kml-document
extern u8 KML_DocumentOpen(s8 *, KML_Document_t *); // opens a new kml-document. a new file is created on the sd-memorycard
extern u8 KML_DocumentClose(KML_Document_t *doc); // closes the specified document saving remaining data to the file.
extern u8 KML_PlaceMarkOpen(s8 *name, KML_Document_t *doc); // opens a new placemark within the open kml-document
extern u8 KML_PlaceMarkClose(KML_Document_t *doc); // closes the actual placemark
extern u8 KML_LineStringBegin(KML_Document_t *doc); // begins a new linestring within the actual placemark
extern u8 KML_LineStringEnd(KML_Document_t *doc); // close the actual linestring within the actual placemark
extern u8 KML_LineStringAddPoint(struct str_gps_nav_data, KML_Document_t *); // adds a point from the gps (longitude, altitude, height) to the linestring
/trunk/kml_header.h
0,0 → 1,107
//________________________________________________________________________________________________________________________________________
//
// Definition of KML header and footer elements for documents, placemarks and linestrings
//
//________________________________________________________________________________________________________________________________________
 
 
const s8 KML_DOCUMENT_HEADER[] =
{
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
"<kml xmlns=\"http://earth.google.com/kml/2.2\">\r\n"
"<Document>\r\n"
" <name>Mikrokopter GPS logging</name>\r\n"
" <StyleMap id=\"msn_ylw-pushpin\">\r\n"
" <Pair>\r\n"
" <key>normal</key>\r\n"
" <styleUrl>#sn_ylw-pushpin</styleUrl>\r\n"
" </Pair>\r\n"
" <Pair>\r\n"
" <key>highlight</key>\r\n"
" <styleUrl>#sh_ylw-pushpin</styleUrl>\r\n"
" </Pair>\r\n"
" </StyleMap>\r\n"
" <Style id=\"sn_ylw-pushpin\">\r\n"
" <IconStyle>\r\n"
" <scale>1.1</scale>\r\n"
" <Icon>\r\n"
" <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>\r\n"
" </Icon>\r\n"
" <hotSpot x=\"20\" y=\"2\" xunits=\"pixels\" yunits=\"pixels\"/>\r\n"
" </IconStyle>\r\n"
" </Style>\r\n"
" <Style id=\"sh_ylw-pushpin\">\r\n"
" <IconStyle>\r\n"
" <scale>1.3</scale>\r\n"
" <Icon>\r\n"
" <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>\r\n"
" </Icon>\r\n"
" <hotSpot x=\"20\" y=\"2\" xunits=\"pixels\" yunits=\"pixels\"/>\r\n"
" </IconStyle>\r\n"
" </Style>\r\n"
};
 
 
 
 
//________________________________________________________________________________________________________________________________________
//
// footer of an KML- file.
//
//________________________________________________________________________________________________________________________________________
 
 
const s8 KML_DOCUMENT_FOOTER[] =
{
" </Document>\r\n"
"</kml>\r\n"
};
 
 
 
//________________________________________________________________________________________________________________________________________
//
// Header of an placemark
//
//________________________________________________________________________________________________________________________________________
 
const s8 KML_PLACEMARK_HEADER[] =
{" <Placemark>\r\n"
" <name>flight</name>\r\n"
" <styleUrl>#msn_ylw-pushpin</styleUrl>\r\n"};
 
//________________________________________________________________________________________________________________________________________
//
// Footer of an placemark
//
//________________________________________________________________________________________________________________________________________
 
const s8 KML_PLACEMARK_FOOTER[] = {
" </Placemark>\r\n"};
 
 
//________________________________________________________________________________________________________________________________________
//
// Footer of an placemark
//
//________________________________________________________________________________________________________________________________________
 
const s8 KML_LINESTRING_HEADER[] = {
" <LineString>\r\n"
" <extrude>1</extrude>\r\n"
" <tessellate>1</tessellate>\r\n"
" <altitudeMode>relativeToGround</altitudeMode>\r\n"
" <coordinates>\r\n"
};
 
//________________________________________________________________________________________________________________________________________
//
// Footer of an linestring
//
//________________________________________________________________________________________________________________________________________
 
const s8 KML_LINESTRING_FOOTER[] = {
"\r\n </coordinates>"
"\r\n </LineString>\r\n"
};
 
/trunk/main.c
58,10 → 58,12
const unsigned long _Main_Crystal = 25000;
 
#include "main.h"
#include "kml.h"
 
u32 TimerCompassUpdate;
u32 TimerI2CReadDelay;
u32 TimerDebugDataDelay;
u32 KmlAddPointDelay;
 
u8 BeepTime;
void Init_Undef(void);
99,6 → 101,7
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt1 ;
GPIO_Init(GPIO5, &GPIO_InitStructure);
 
//SD_SWITCH
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
105,13 → 108,12
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init(GPIO5, &GPIO_InitStructure);
 
}
//
void OutputStartupData(void)
{
char text[20];
char tex[20];
SerialPutString("\n\r--------------\n\r");
sprintf(text,"NaviCtrl V%d.%d\n\r", VersionInfo.Hauptversion, VersionInfo.Nebenversion); SerialPutString(text);
124,6 → 126,19
{
static u8 oldCompassCalState = 0;
 
 
static u8 kml_state = 0;
u8 kml_cnt = 0;
KML_Document_t mydocument;
File *file1;
 
u8 str[80];
KML_DocumentInit(&mydocument); // Initialise the new kml-document for further use.
 
 
// SCU_MCLKSourceConfig(SCU_MCLK_OSC);
// SCU_PCLKDivisorConfig(SCU_PCLK_Div2);
// SCU_MCLKSourceConfig(SCU_MCLK_PLL);
178,14 → 193,18
TimerCompassUpdate = SetDelay(5);
TimerI2CReadDelay = SetDelay(5);
 
/*
KmlAddPointDelay = SetDelay(250);
 
 
SerialPutString("\r\n---------------------------------------------");
 
 
// ReadSetting(1);
SerialPutString("\r\n---------------------------------------------\r\n\r\n");
InitFat16();
 
ReadSetting(1);
*/
SerialPutString("Init done\n\r.");
SerialPutString("--------------\n\n\r");
for (;;)
{
if(NeuerDatensatzEmpfangen)
238,7 → 257,51
 
TimerDebugDataDelay = SetDelay(500);
}
// ----------------------------------------------------
}
 
 
// ----------- KML Timing -------------------------
if(CheckDelay(KmlAddPointDelay))
{
KmlAddPointDelay = SetDelay(500);
 
switch(kml_state)
{
case 0:
if((GPS_Data.Flags & GPS_FIX) && (GPS_Data.Used_Sat >= GPS_SAT_MIN))
{
if(str_Volume.state == INITIALIZED) // has the volume and filesystem been initialized?
{
if(KML_DocumentOpen("flight01.kml",&mydocument)) // create a new kml-document on the memorycard.
{
SerialPutString("\r\nopening kml-file\r\nadding data");
kml_state = 1;
}
}
else
{
InitFat16();
}
}
break; // document.state will be changed to DOC_OPENED automatic.
case 1: // linestring opened, so datapoint (gps_coordinates) can be added to the document.
if(kml_cnt++ < 20) // add 10 datapoints to the document.
{
KML_LoggGPSCoordinates(GPS_Data,&mydocument);
}
else // after the datapoints have been written to the document close the document.
{
KML_DocumentClose(&mydocument);
SerialPutString("\r\nfile closed");
kml_state = 2;
}
break;
 
default: // all data has been written to card. open new document to add new data.
}
}
}
}
 
 
 
/trunk/main.h
1,6 → 1,7
 
#include "91x_conf.h"
#include "91x_lib.h"
#include "91x_wiu.h"
#include "uart.h"
#include "ramfunc.h"
#include "menu.h"
16,9 → 17,7
#include "sdc.h"
#include "ssc.h"
#include "fat16.h"
 
#include "usb.h"
 
#include "string.h"
#include "settings.h"
 
/trunk/menu.c
78,6 → 78,7
void Menu(void)
{
static u8 MaxMenue = 1,MenuePunkt=0;
u8 text[20];
if(RemoteTasten & KEY1) { if(MenuePunkt) MenuePunkt--; else MenuePunkt = MaxMenue; LcdClear(); }
if(RemoteTasten & KEY2) { MenuePunkt++; LcdClear(); }
93,6 → 94,17
// if(RemoteTasten & KEY3) TestInt--;
// if(RemoteTasten & KEY4) TestInt++;
break;
case 1:
LCD_printfxy(0,0,"++ GPS-Logging ++");
sprintf(text, "latitude: %u",GPS_Data.Latitude);
LCD_printfxy(0,1,text);
sprintf(text, "longitude:%u",GPS_Data.Longitude);
LCD_printfxy(0,2,text);
sprintf(text, "used sat: %d",GPS_Data.Used_Sat);
LCD_printfxy(0,3,text);
break;
 
default: MaxMenue = MenuePunkt - 1;
MenuePunkt = 0;
break;
/trunk/sdc.c
54,30 → 54,37
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdio.h>
#include <string.h>
#include "91x_lib.h"
#include "uart.h"
#include "sdc.h"
#include "ssc.h"
#include "timer.h"
#include "main.h"
#include "crc16.h"
 
 
//________________________________________________________________________________________________________________________________________
// Module name: mmc.c
// Module name: sdc.c
// Compiler used: avr-gcc 3.4.5
// Last Modifikation: 24.07.2007
// Version: 1.05
// Authors: Stephan Busker
// Description: Source files for connecting to an sdcard using the SSC
// Last Modifikation: 08.06.2008
// Version: 1.07
// Authors: Stephan Busker, Gregor Stobrawa
// Description: Source files for connecting to an sd-card using the SSC
//
//........................................................................................................................................
// Functions: u8 SDC_init(void);
// u8 SDC_PutCommand (u8 *CMD);
// u8 SDC_PutSector(u32 addr,u8 *Buffer);
// u8 SDC_GetSector(u32 addr,u8 *Buffer);
// void SDC_GetBlock(u8 *CMD,u8 *Buffer,u16 Bytes);
// Functions: SD_Result_t SDC_init(void);
// u8 SDC_PutCommand (u8 *cmd);
// SD_Result_t SDC_PutSector(u32 addr,u8 *Buffer);
// SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer);
//
////........................................................................................................................................
// ext. functions: extern void SSC_Init(void);
// extern u8 SSC_GetChar (void);
// extern u8 SSC_GetChar (void);
// extern void SSC_PutChar (u8);
// extern void SSC_Enable(void);
// extern void SSC_Disable(void);
// extern void SSC_ClearRxFifo();
//........................................................................................................................................
//
// URL: www.Mikro-Control.de
86,209 → 93,690
 
 
 
#define CMD_GO_IDLE_STATE 0x00 /* CMD00: response R1 */
#define CMD_SEND_OP_COND 0x01 /* CMD01: response R1 */
#define CMD_SEND_IF_COND 0x08 /* CMD08: response R7 */
#define CMD_SEND_CSD 0x09 /* CMD09: response R1 */
#define CMD_SEND_CID 0x0A /* CMD10: response R1 */
#define CMD_SEND_STATUS 0x0D /* CMD13: response R2 */
#define CMD_SET_BLOCKLEN 0x10 /* CMD16: arg0[31:0]: block length, response R1*/
#define CMD_READ_SINGLE_BLOCK 0x11 /* CMD17: arg0[31:0]: data address, response R1 */
#define CMD_WRITE_SINGLE_BLOCK 0x18 /* CMD24: arg0[31:0]: data address, response R1 */
#define CMD_APP_CMD 0x37 /* CMD55: response R1 */
#define CMD_READ_OCR 0x3A /* CMD58: response R3 */
#define CMD_CRC_ON_OFF 0x3B /* CMD59: arg0[31:1]: stuff bits, arg0[0:0]: crc option, response R1 */
#define ACMD_SEND_OP_COND 0x29 /* ACMD41: arg0[31]: stuff bits, arg0[30]: HCS, arg0[29:0] stuff bits*, response R1 */
 
#define R1_NO_ERR 0x00
#define R1_IDLE_STATE 0x01
#define R1_ERASE_RESET 0x02
#define R1_ILLEGAL_CMD 0x04
#define R1_COM_CRC_ERR 0x08
#define R1_ERASE_SEQUENCE_ERR 0x10
#define R1_ADDRESS_ERR 0x20
#define R1_PARAMETER_ERR 0x40
#define R1_BAD_RESPONSE 0x80
 
#define R2_NO_ERR 0x00
#define R2_CARD_LOCKED 0x01
#define R2_ERASE_WRITE_PROT_ERR 0x02
#define R2_UNKOWN_ERR 0x04
#define R2_CARD_CTRL_ERR 0x08
#define R2_CARD_ECC_ERR 0x10
#define R2_WRITE_PROT_ERR 0x20
#define R2_ERASE_PARAM_ERR 0x40
#define R2_OUT_OF_RANGE_ERR 0x80
 
#define DATA_START_TOKEN 0xFE
#define DATA_RESPONSE_MASK 0x1F
#define DATA_RESPONSE_OK 0x05
#define DATA_RESPONSE_CRC_ERR 0x0B
#define DATA_RESPONSE_WRITE_ERR 0x1D
 
typedef enum
{
VER_UNKNOWN,
VER_1X,
VER_20
} SDVersion_t;
 
typedef struct
{
u8 Valid;
SDVersion_t Version; // HW-Version
u32 Capacity; // Memory capacity in bytes
u8 CID[16]; // CID register
u8 CSD[16]; // CSD register
} __attribute__((packed)) SDCardInfo_t;
 
volatile SDCardInfo_t SDCardInfo;
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_Init(void);
// Function: CRC7(u8* cmd, u32 len);
//
// Description: This function initialises the SDCard to spi-mode.
// Description: This function calculated the CRC7 checksum used in the last byte of a spi command frame.
//
//
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
// Returnvalue: the function returns the crc7 including bit 0 set to 1
//________________________________________________________________________________________________________________________________________
 
u8 SDC_Init(void)
u8 CRC7(u8 * cmd, u32 len)
{
u16 Timeout = 0;
u8 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
u8 i, a;
u8 crc, Data;
 
u8 b;
crc = 0; // init CRC buffer
for (a = 0; a < len ;a++) // for every byte in the msg
{
Data = cmd[a];
for (i=0;i<8;i++) // for every bit in the byte
{
crc <<= 1; // shift crc
if ((Data & 0x80)^(crc & 0x80)) crc ^=0x09; //xor
Data <<= 1; // shift data for next bit
}
}
crc = (crc<<1)|1; // set terminating bit to 1
return(crc);
}
 
SSC_Init(); // Initialise SSC to transmit data to the sdcard.
SerialPutString("Init SD...");
// Delay_ms(10);
u8 SDC_WaitForBusy()
{
u8 rsp = 0;
u16 timeout=0;
 
for (b = 0;b<0x0f;b++) // sending 74Clocks brings the sdcard into spimode.
SSC_ClearRxFifo();
SSC_Enable(); // enable chipselect.
do
{
SSC_PutChar(0xff);
rsp = SSC_GetChar();
if(timeout++>500) break;
}while(rsp != 0xFF); // wait while card is busy (data out low)
return(rsp);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Function: SDC_SendCMDR1(u8 CmdNo, u32 arg);
//
// Description: This function send a command frame to the SD-Card in spi-mode.
//
//
// Returnvalue: The function returns the first response byte like for R1 commands
//________________________________________________________________________________________________________________________________________
u8 SDC_SendCMDR1(u8 CmdNo, u32 arg)
{
u8 r1;
u16 Timeout = 0;
u16 a;
u8 cmd[6];
 
SSC_ClearRxFifo(); // clear the rx fifo
SSC_Enable(); // enable chipselect.
SDC_WaitForBusy();
SSC_ClearRxFifo(); // clear the rx fifo
SSC_GetChar(); // dummy to sync
 
/* Send cmd10 (SEND_CID) */;
cmd[0] = 0x40|CmdNo; // set command index
cmd[1] = (arg & 0xFF000000)>>24;
cmd[2] = (arg & 0x00FF0000)>>16;
cmd[3] = (arg & 0x0000FF00)>>8;
cmd[4] = (arg & 0x000000FF);
cmd[5] = CRC7(cmd, 5); // update checksum
for (a = 0;a < 6; a++) // send the command sequence to the sdcard (6 bytes)
{
SSC_PutChar(cmd[a]);
}
SerialPutString("reset...");
while(SDC_PutCommand (CMD) !=1) // Sending CMD0 (Reset) to the sdcard.
SSC_ClearRxFifo(); // clear the rx fifo to discard the bytes received during the transmission of the 6 command bytes
do
{
if (Timeout++ > 200)
{
return(1);
}
}
SerialPutString("ok.");
Timeout = 0;
CMD[0] = 0x41;
CMD[5] = 0xFF;
while( SDC_PutCommand (CMD) !=0) // Sending CMD1 to the sdcard.
{
if (Timeout++ > 100)
{
return(2);
}
}
 
SSC_Disable(); // disable sdcard.
return(0);
r1 = SSC_GetChar(); // get byte from sd-card
if (Timeout++ > 500) return(r1);
}while(r1 == 0xFF); // wait for the response byte from sd-card.
return(r1);
}
 
 
//________________________________________________________________________________________________________________________________________
// Function: SDC_SendACMDR1(u8 CmdNo, u32 arg);
//
// Description: This function send a application command frame to the SD-Card in spi-mode.
//
//
// Returnvalue: The function returns the first response byte like for R1 commands
//________________________________________________________________________________________________________________________________________
u8 SDC_SendACMDR1(u8 CmdNo, u32 arg)
{
u8 r1 = 0xFF;
r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
if(r1 & R1_BAD_RESPONSE) return(r1);
r1 = SDC_SendCMDR1(CmdNo, arg);
return(r1);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_PutCommand(* CMD);
// Function: SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
//
// Description: This function initialises the SDCard to spi-mode.
// Description: This function sneds cmd an reads a datablock of len from the sd-card
//
//
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
// Returnvalue: SD_Result_t
//________________________________________________________________________________________________________________________________________
 
u8 SDC_PutCommand (u8 *CMD)
SD_Result_t SDC_GetData(u8 CmdNo, u32 addr, u8 *Buffer, u32 len)
{
u8 tmp = 0xff;
u16 Timeout = 0;
u16 a;
SSC_ClearRxFifo();
SSC_Disable(); // disable chipselect
SSC_PutChar(0xFF); // Send 8 Clocks to the sdcard while card is not selected.
SSC_Enable(); // enable chipselect.
u8 rsp;
u16 timeout;
u16 a, Crc16;
SD_Result_t result = SD_ERROR_UNKNOWN;
 
// if (*CMD == 0x41) Delay_ms(10); // if command is CMD0 generate a short delay.
for (a = 0;a<0x06;a++) // send the command sequence to the sdcard (6 bytes)
// send the command
rsp = SDC_SendCMDR1(CmdNo, addr);
if (rsp != R1_NO_ERR)
{
SSC_PutChar(*CMD++);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
SSC_ClearRxFifo();
while (tmp == 0xff) // Wait for response from sdcard.
do
{
tmp = SSC_GetChar();
if (Timeout++ > 200)
rsp = SSC_GetChar();
if((rsp & 0xF0) == 0x00) // data error token
{
break; // or timeout.
result = SD_ERROR_READ_DATA;
goto end;
}
// if(timeout++>500) break;
}while(rsp != DATA_START_TOKEN);
// data start token received
for (a = 0; a < len; a++) // read the block from the SSC
{
Buffer[a] = SSC_GetChar();
}
// Read two bytes CRC16-Data checksum
Crc16 = SSC_GetChar(); // highbyte fisrt
Crc16 = (Crc16<<8)|SSC_GetChar(); // lowbyte last
// if(Crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
/* else */result = SD_SUCCESS;
end:
//SSC_Disable(); // disable sdcard.
if(result != SD_SUCCESS)
{
sprintf(text,"Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
SerialPutString(text);
}
return(result);
}
 
return(tmp);
 
//________________________________________________________________________________________________________________________________________
// Function: SDC_PrintCID(u8 * pCID);
//
// Description: This function prints the CIS register in a human readable format.
//
//
// Returnvalue: the function returns nothing
//________________________________________________________________________________________________________________________________________
 
void SDC_PrintCID(u8 * pCID)
{
u8 text[50];
u8 pn[6];
u16 temp1, temp2;
 
sprintf(text, "\r\nManufacturer ID: %i\r\n", pCID[0]);
SerialPutString(text);
memcpy(pn, &pCID[1], 2);
pn[2] = '\0'; // terminate string
sprintf(text, "Application ID: %s\r\n",pn);
SerialPutString(text);
memcpy(pn, &pCID[3], 5);
pn[5] = '\0'; // terminate string
sprintf(text, "Product Name: %s\r\n",pn);
SerialPutString(text);
sprintf(text, "Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
SerialPutString(text);
SerialPutString("Serial No.: ");
for(temp1 = 0; temp1<4; temp1++)
{
sprintf(text,"%02X", pCID[9+temp1]);
SerialPutString(text);
}
SerialPutString("\r\n");
temp1 = pCID[14] & 0x0F; // month
temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year
sprintf(text, "Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
SerialPutString(text);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetCID(u8 * pCID);
//
// Description: This function reads the CIS register form the sd card in spi mode.
//
//
// Returnvalue: the function returns error state
//________________________________________________________________________________________________________________________________________
 
SD_Result_t SDC_GetCID(u8 * pCID)
{
return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetCSD(u8 * pCSD);
//
// Description: This function reads the CSD register form the sd card in spi mode.
//
//
// Returnvalue: the function returns error state
//________________________________________________________________________________________________________________________________________
 
SD_Result_t SDC_GetCSD(u8 * pCSD)
{
return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_PutSector(void);
// Funtion: SDC_Init(void);
//
// Description: This function writes one sector of data to the SSC
// Description: This function initialises the SDCard to spi-mode.
//
//
// Returnvalue: none
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
//________________________________________________________________________________________________________________________________________
 
u8 SDC_PutSector(u32 addr,u8 *Buffer)
SD_Result_t SDC_Init(void)
{
u8 tmp;
u8 CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
u16 a;
addr = addr << 9; // convert sectoradress to byteadress
u32 Timeout = 0;
u8 text[50];
u8 rsp[6]; // SD-SPI response buffer
SD_Result_t result = SD_ERROR_UNKNOWN;
if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
{
SerialPutString("\r\n SSC init...");
SSC_Init();
SerialPutString("ok");
SerialPutString("\r\n SDC init...");
SDCardInfo.Valid = 0;
/* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
start to supply at least 74 SD clocks to the SD card with keeping cmd line to high. In case of SPI
mode, CS shall be held to high during 74 clock cycles. */
SSC_Disable(); // set SD_CS high
SSC_ClearRxFifo(); // clear the rx fifo
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
for (Timeout = 0; Timeout < 15; Timeout++) // 15*8 = 120 cycles
{
SSC_PutChar(0xFF);
}
// switch to idle state
while(SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL) != R1_IDLE_STATE)
{
if (Timeout++ > 20)
{
SerialPutString("reset timeout");
result = SD_ERROR_RESET;
goto end;
}
}
// enable crc feature
/* if(SDC_SendCMDR1(CMD_CRC_ON_OFF, 1UL) != R1_IDLE_STATE)
{
sprintf(text,"Bad cmd59 R1=%02X.\r\n", rsp[0]);
SerialPutString(text);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}*/
// check for card hw version
// 2.7-3.6V Range = 0x01, check pattern 0xAA
rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
// answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
if(rsp[0] & R1_BAD_RESPONSE)
{
sprintf(text,"Bad cmd8 R1=%02X.\r\n", rsp[0]);
SerialPutString(text);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if(rsp[0] & R1_ILLEGAL_CMD)
{
//Ver1.X SD Memory Card or not a SD Memory Card
SDCardInfo.Version = VER_1X;
}
else
{
// Ver2.00 or later SD Memory Card
// reading the remaining bytes of the R7 response
SDCardInfo.Version = VER_20;
for(Timeout = 1; Timeout < 5; Timeout++)
{
rsp[Timeout] = SSC_GetChar();
}
//check pattern
if(rsp[4]!= 0xAA)
{
SerialPutString("Bad cmd8 R7 check pattern.\r\n");
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
{
SerialPutString("Card is incompatible to 3.3V.\r\n");
result = SD_ERROR_BAD_VOLTAGE_RANGE;
goto end;
}
}
rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
// answer to cmd58 is an R3 response (R1 + 4Byte OCR)
if(rsp[0] & R1_BAD_RESPONSE)
{
sprintf(text,"Bad cmd58 R1 %02x.\r\n", rsp[0]);
SerialPutString(text);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if(rsp[0] & R1_ILLEGAL_CMD)
{
SerialPutString("Not an SD-CARD.\r\n");
result = SD_ERROR_NO_SDCARD;
goto end;
}
// read 4 bytes of OCR register
for(Timeout = 1; Timeout < 5; Timeout++)
{
rsp[Timeout] = SSC_GetChar();
}
// NavicCtrl uses 3.3 V, therefore check for bit 20 & 21
if((rsp[2] & 0x30) != 0x30)
{
// supply voltage is not supported by sd-card
SerialPutString("Card is incompatible to 3.3V.\r\n");
result = SD_ERROR_BAD_VOLTAGE_RANGE;
goto end;
}
// Initialize the sd-card sending continously ACMD_SEND_OP_COND (only supported by SD cards)
Timeout = SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer)
do
{
rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
if(rsp[0] & R1_BAD_RESPONSE)
{
sprintf(text,"Bad Acmd41 R1=%02X.\r\n", rsp[0]);
SerialPutString(text);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if(CheckDelay(Timeout))
{
SerialPutString("Init timeout.\r\n");
result = SD_ERROR_INITIALIZE;
goto end;
}
} while(rsp[0] & R1_IDLE_STATE); // loop until idle state
if(rsp[0] != R1_NO_ERR)
{
SerialPutString("Init error.\r\n");
result = SD_ERROR_INITIALIZE;
goto end;
}
/* set block size to 512 bytes */
if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
{
SerialPutString("Error setting block length to 512.\r\n");
result = SD_ERROR_SET_BLOCKLEN;
goto end;
}
 
tmp = SDC_PutCommand (CMD); // send command to sdcard.
if (tmp != 0)
{
return(tmp);
}
SSC_ClearRxFifo();
for (a=0;a<100;a++) // wait until sdcard is ready
{
SSC_GetChar();
}
 
//SSC_Disable(); // set SD_CS high
// here is the right place to inrease the SPI boud rate to maximum
//SSC_Enable(); // set SD_CS high
 
// read CID register
result = SDC_GetCID((u8 *)&SDCardInfo.CID);
if(result != SD_SUCCESS)
{
SerialPutString("Error reading CID.\r\n");
goto end;
}
SSC_PutChar(0xFE); // send start of header to the SSC
// read CSD register
result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
if(result != SD_SUCCESS)
{
SerialPutString("Error reading CSD.\r\n");
goto end;
}
for (a=0;a<512;a++) // transmitt one sector (normaly 512bytes) of data to the sdcard.
SerialPutString("ok\r\n");
u8 c_size_mult, read_bl_len;
u32 c_size;
switch(SDCardInfo.CSD[0]>>6) // check CSD Version
{
case 0x00: // if CSD is V1.0 structure (2GB limit)
/*
memory capacity = BLOCKNR * BLOCK_LEN
BLOCKNR = (C_SIZE+1) * MULT
MULT = 2^(C_SIZE_MULT+2)
BLOCK_LEN = 2^READ_BL_LEN
C_SIZE is 12 bits [73:62] in CSD register
C_SIZE_MULT is 3 bits [49:47] in CSD register
READ_BL_LEN is 4 bits [83:80] in CSD register
*/
read_bl_len = (SDCardInfo.CSD[5] & 0x0F); //CSD[05] -> [87:80]
c_size = ((u32)(SDCardInfo.CSD[6] & 0x03))<<10; //CSD[06] -> [79:72]
c_size |= ((u32)SDCardInfo.CSD[7])<<2; //CSD[07] -> [71:64]
c_size |= (u32)(SDCardInfo.CSD[8]>>6); //CSD[08] -> [63:56]
c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1; //CSD[09] -> [55:48]
c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7; //CSD[10] -> [47:40]
SDCardInfo.Capacity = (u32)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
break;
case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB)
/*
memory capacity = (C_SIZE+1) * 512K byte
C_SIZE is 22 bits [69:48] in CSR register
*/
c_size = ((u32)(SDCardInfo.CSD[7] & 0x3F))<<16; //CSD[07] -> [71:64]
c_size |= ((u32)SDCardInfo.CSD[8])<<8; //CSD[08] -> [63:56]
c_size |= (u32)SDCardInfo.CSD[9]; //CSD[09] -> [55:48];
SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
break;
default: //unknown CSD Version
SDCardInfo.Capacity = 0;
break;
}
switch(SDCardInfo.Version)
{
case VER_1X:
SerialPutString(" SD-CARD V1.x");
break;
case VER_20:
SerialPutString(" SD-CARD V2.0 or later");
default:
break;
}
u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));
sprintf(text, "\r\n Capacity = %i MB", mb_size);
SerialPutString(text);
// SDC_PrintCID((u8 *)&SDCardInfo.CID);
SDCardInfo.Valid = 1;
// jump point for error condition before
end:
SSC_Disable();
}
else
{
SSC_PutChar(*Buffer++);
//SerialPutString("\r\nNo Card in Slot.");
SSC_Deinit();
SDCardInfo.Valid = 0;
result = SD_ERROR_NOCARD;
}
SSC_PutChar(0xFF); // write two bytes of crc to the sdcard (not used in spi-mode)
SSC_PutChar(0xFF);
SSC_ClearRxFifo();
while (SSC_GetChar() != 0xff){}; // wait untile the sdcard is ready.
SSC_Disable(); // disable sdcard.
if(result != SD_SUCCESS) SerialPutString("nok");
 
return(0);
return(result);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetSector(u32 addr,u8 *Buffer);
// Funtion: SDC_Deinit(void);
//
// Description: This function reads one sector of data from the SSC
// Description: This function deinitialises the SDCard interface.
//
//
// Returnvalue: none
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
//________________________________________________________________________________________________________________________________________
 
u8 SDC_GetSector(u32 addr,u8 *Buffer)
{
u8 CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
addr = addr << 9; // convert sectoradress to byteadress.
SD_Result_t SDC_Deinit(void)
{
SerialPutString("SDC deinit...");
SSC_Deinit();
 
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
SDCardInfo.Valid = 0;
SDCardInfo.Capacity = 0;
SDCardInfo.Version = VER_UNKNOWN;
 
// sprintf(text,"\n\rGetSector: (%lu)", (u32)addr ); SerialPutString(text);
 
SDC_GetBlock(CMD,Buffer,512); // read specified sector from sdcard.
 
return(0);
SerialPutString("ok\r\n");
return(SD_SUCCESS);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetBlock(void);
// Funtion: SDC_PutSector(void);
//
// Description: This function reads one block of data of int bytes from the SSC.
// Description: This function writes one sector of data to the SSC
//
//
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
// Returnvalue: SD_Result_t
//________________________________________________________________________________________________________________________________________
 
void SDC_GetBlock(u8 *CMD,u8 *Buffer,u16 Bytes)
{
if (SDC_PutCommand (CMD) != 0) // Send command to the sdcard.
SD_Result_t SDC_PutSector(u32 addr, const u8 *Buffer)
{
u8 rsp;
u16 timeout = 0;
u16 a, Crc16;
//u32 Timeout = 0;
SD_Result_t result = SD_ERROR_UNKNOWN;
 
addr = addr << 9; // convert sectoradress to byteadress
rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
if (rsp != R1_NO_ERR)
{
return;
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
SSC_ClearRxFifo();
// SerialPutString("\n\rWait.");
while (SSC_GetChar() != 0xfe){}; // wait until the sdcard is ready to transmitt data.
// SerialPutString("Ok.");
u16 a;
for (a=0;a<Bytes;a++) // read the block from the SSC (normaly 512Bytes)
for (a=0;a<20;a++) // at least one byte
{
*Buffer++ = SSC_GetChar();
SSC_GetChar();
}
Crc16 = CRC16(Buffer, 512); // calc checksum for data block
SSC_PutChar(DATA_START_TOKEN); // send data start of header to the SSC
SSC_GetChar(); // Read two bytes CRC- checksum (not used in spi-mode)
SSC_GetChar();
SSC_Disable(); // disable sdcard.
for (a=0;a<512;a++) // transmit one sector (normaly 512bytes) of data to the sdcard.
{
SSC_PutChar(Buffer[a]);
}
// write two bytes of crc16 to the sdcard
SSC_PutChar((u8)(Crc16>>8)); // write high byte first
SSC_PutChar((u8)(0x00FF&Crc16)); // lowbyte last
SSC_ClearRxFifo();
do // wait for data response token
{
rsp = SSC_GetChar();
if(timeout++>500) break;
}while((rsp & 0x11) != 0x01 );
// analyse data response token
switch(rsp & DATA_RESPONSE_MASK)
{
case DATA_RESPONSE_OK:
result = SD_SUCCESS;
break;
case DATA_RESPONSE_CRC_ERR:
result = SD_ERROR_CRC_DATA;
goto end;
break;
case DATA_RESPONSE_WRITE_ERR:
result = SD_ERROR_WRITE_DATA;
goto end;
break;
default:
result = SD_ERROR_UNKNOWN;
goto end;
break;
 
}
// wait until the sdcard is busy.
rsp = SDC_WaitForBusy();
if(rsp != 0xFF)
{
result = SD_ERROR_TIMEOUT;
goto end;
}
// check card status
rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
if(rsp != R1_NO_ERR)
{
result = SD_ERROR_BAD_RESPONSE;
SSC_GetChar();
goto end;
}
// 2nd byte of r2 response
rsp = SSC_GetChar();
if(rsp != R2_NO_ERR)
{
result = SD_ERROR_WRITE_DATA;
SSC_GetChar();
goto end;
}
end:
//SSC_Disable(); // disable sdcard.
if(result != SD_SUCCESS)
{
sprintf(text,"Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
SerialPutString(text);
}
return(result);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetSector(u32 addr,u8 *Buffer);
//
// Description: This function reads one sector of data from the SSC
//
//
// Returnvalue: SD_Result_t
//________________________________________________________________________________________________________________________________________
 
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
{
addr = addr << 9; // convert sectoradress to byteadress
return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
}
 
 
/trunk/sdc.h
1,33 → 1,36
#ifndef _SDC_H_
#define _SDC_H_
#ifndef _SDC_H
#define _SDC_H
 
extern unsigned char SDC_Init(void);
#include "91x_lib.h"
 
//________________________________________________________________________________________________________________________________________
//
// Functions needed for access to the sdcard.
// Functions needed for accessing the sdcard.
//
//________________________________________________________________________________________________________________________________________
 
extern unsigned char SSC_GetChar(void);
extern void SSC_PutChar(u8);
extern void MMC_Read_Block(u8 *,u8 *,u16);
typedef enum
{
SD_SUCCESS = 0,
SD_ERROR_NOCARD,
SD_ERROR_RESET,
SD_ERROR_INITIALIZE,
SD_ERROR_BAD_RESPONSE,
SD_ERROR_BAD_VOLTAGE_RANGE,
SD_ERROR_NO_SDCARD,
SD_ERROR_TIMEOUT,
SD_ERROR_CRC_DATA,
SD_ERROR_WRITE_DATA,
SD_ERROR_READ_DATA,
SD_ERROR_SET_BLOCKLEN,
SD_ERROR_UNKNOWN
} SD_Result_t;
 
extern SD_Result_t SDC_Init(void);
extern SD_Result_t SDC_GetSector (u32 ,u8 *);
extern SD_Result_t SDC_PutSector (u32, const u8 *);
extern SD_Result_t SDC_Deinit(void);
 
//________________________________________________________________________________________________________________________________________
//
// Functions needed internaly for the fat16 implementation
//
//________________________________________________________________________________________________________________________________________
#endif // _SDC_H
 
extern unsigned char SDC_GetSector (u32,u8 *);
extern unsigned char SDC_PutSector (u32,u8 *);
extern unsigned char SDC_PutCommand (u8 *);
extern void SDC_GetBlock(u8 *CMD,u8 *Buffer,u16 Bytes);
 
 
#define nop() __asm__ __volatile__ ("nop" ::)
 
#endif
 
 
/trunk/ssc.c
54,10 → 54,10
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "main.h"
#include "91x_lib.h"
 
//________________________________________________________________________________________________________________________________________
// Module name: fat16.c
// Module name: ssc.c
// Compiler used: avr-gcc 3.4.5
// Last Modifikation: 24.07.2007
// Version: 1.02
65,16 → 65,13
// Description: Source files for access to the synchrnous serial channel.
// Copyright (C) 2007 Stephan Busker
//........................................................................................................................................
// Functions: extern void SSC_Init(void);
// extern u8 SSC_GetChar (void);
// ext. Functions: extern void SSC_Init(void);
// extern u8 SSC_GetChar (void);
// extern void SSC_PutChar (u8 Byte);
// extern void SSC_Disable(void);
// extern void SSC_Enable(void);
// extern void SSC_ClearRxFifo();
//........................................................................................................................................
// ext. functions: extern u8 SDC_GetSector (unsigned long,u8 *);
// extern u8 SDC_PutSector (unsigned long,u8 *);
//........................................................................................................................................
//
// URL: www.Mikro-Control.de
// mailto: stephan.busker@mikro-control.de
//________________________________________________________________________________________________________________________________________
81,10 → 78,40
 
 
 
//________________________________________________________________________________________________________________________________________
// Function: SSC_Enable(void);
//
// Description: This function enables chipselect of the sdcard (active low)
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
void SSC_Enable(void)
{
// enable chipselect of the sd-card (P5.4 -> SD-CS, active low).
GPIO_WriteBit(GPIO5, GPIO_Pin_4 , Bit_RESET);
}
//________________________________________________________________________________________________________________________________________
// Funtion: SSC_Init(void);
// Function: SSC_Disable(void);
//
// Description: This function disables chipselect of the sdcard (active low)
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
void SSC_Disable(void)
{
// disable chipselect of the sd-card (P5.4 -> SD-CS, active low).
GPIO_WriteBit(GPIO5, GPIO_Pin_4 , Bit_SET);
}
 
 
//________________________________________________________________________________________________________________________________________
// Function: SSC_Init(void);
//
// Description: This function initialises the synchronus serial channel to the sdcard.
//
//
93,69 → 120,119
 
void SSC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SSP_InitTypeDef SSP_InitStructure;
WIU_InitTypeDef WIU_InitStructure;
// enable APB clock for SPI1
SCU_APBPeriphClockConfig(__SSP1 ,ENABLE);
// configure P5.4 -> SD-CS as an output pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt1;
GPIO_Init (GPIO5, &GPIO_InitStructure);
// configure P3.4 -> SCK1 and P3.6 -> MOSI1 as an output pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2;
GPIO_Init (GPIO3, &GPIO_InitStructure);
// configure P3.5 <- MISO1 as an input pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO3, &GPIO_InitStructure);
// configure SPI1
SSP_DeInit(SSP1);
SSP_StructInit(&SSP_InitStructure);
SSP_InitStructure.SSP_FrameFormat = SSP_FrameFormat_Motorola;
SSP_InitStructure.SSP_Mode = SSP_Mode_Master;
SSP_InitStructure.SSP_CPHA = SSP_CPHA_1Edge;
SSP_InitStructure.SSP_CPOL = SSP_CPOL_Low;
// Set Baud Rate (Prescaler)
// bit rate is BRCLK/SSP_ClockPrescaler/(1+SSP_ClockRate))
// With MSCLK = 48MHz/2 = BRCLK we get for the SPICLK = 24Mhz / 8 / (1+5) = 500 kHz
SSP_InitStructure.SSP_ClockRate = 14; //5
SSP_InitStructure.SSP_ClockPrescaler = 8;
SSP_Init(SSP1, &SSP_InitStructure);
SSC_Disable();
SSP_Cmd(SSP1, ENABLE);
 
SerialPutString("SPI1 init...");
GPIO_InitTypeDef GPIO_InitStructure;
SSP_InitTypeDef SSP_InitStructure;
// Configure SD_SWITCH at pin GPIO5.3 as an external irq 11
 
SCU_APBPeriphClockConfig(__SSP1 ,ENABLE);
// GPIO_DeInit(GPIO2);
GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2;
GPIO_Init (GPIO3, &GPIO_InitStructure);
// configure the port
SCU_APBPeriphClockConfig(__GPIO5, ENABLE); // Enable the GPIO5 Clock
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init(GPIO5, &GPIO_InitStructure);
// configure the EXT11 interrupt line (P5.3) as an IRQ with the lowest priority
SCU_APBPeriphClockConfig(__WIU, ENABLE);
WIU_Cmd(ENABLE );
WIU_ClearITPendingBit(WIU_Line11);
WIU_DeInit();
WIU_InitStructure.WIU_TriggerEdge = WIU_FallingEdge;
WIU_InitStructure.WIU_Line = WIU_Line11;
WIU_Init(&WIU_InitStructure);
// The EXTIT1_IRQHandler() is called every time the SD-Switch is activated (falling edge)
// by inserting an sd-card
SCU_WakeUpLineConfig(11);
VIC_Config(EXTIT1_ITLine, VIC_IRQ, 7);
VIC_ITCmd(EXTIT1_ITLine, ENABLE);
}
 
GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt1;
GPIO_Init (GPIO5, &GPIO_InitStructure);
void SSC_Deinit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
 
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO3, &GPIO_InitStructure);
SSP_DeInit(SSP1);
SSP_StructInit(&SSP_InitStructure);
SSP_InitStructure.SSP_FrameFormat = SSP_FrameFormat_Motorola;
SSP_InitStructure.SSP_Mode = SSP_Mode_Master;
SSP_InitStructure.SSP_CPHA = SSP_CPHA_1Edge;
SSP_InitStructure.SSP_CPOL = SSP_CPOL_Low;
// Hier muss die Baudrate noch richtig eingestellt werden (mit Prescaler)
SSP_InitStructure.SSP_ClockRate = 5;
SSP_InitStructure.SSP_ClockPrescaler = 8;
SSP_Init(SSP1, &SSP_InitStructure);
SSC_Disable();
SSP_Cmd(SSP1, ENABLE);
/* MMC_Direction_REG &=~(1<<SPI_DI); // Set the direction of the ssc-port
MMC_Direction_REG |= (1<<SPI_Clock); // _______ _______
MMC_Direction_REG |= (1<<SPI_DO); // CS \________________________/
MMC_Direction_REG |= (1<<MMC_Chip_Select); //
MMC_Direction_REG |= (1<<SPI_SS); // ___ ___ ___
// clk __________/ \___/ \___/ \_________
//
// ___ ___
// data_________/ \___________/ \___________
SSP_Cmd(SSP1, DISABLE);
SSP_DeInit(SSP1);
 
// initialise ssc, clock = Idel low
// devide clock by 32
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<CPOL); // Enable SSC in mastermode, invert clockpolarity (idle high)
SPSR = SPSR|(1<<SPI2X);*/
SerialPutString("ok\n\r");
// configure P5.4 -> SD-CS as an input pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO5, &GPIO_InitStructure);
// configure P3.4 -> SCK1 and P3.6 -> MOSI1 as an input pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO3, &GPIO_InitStructure);
// configure P3.5 <- MISO1 as an input pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO3, &GPIO_InitStructure);
 
// disable APB clock for SPI1
SCU_APBPeriphClockConfig(__SSP1 ,DISABLE);
 
// configure the port of the SDC-Switch
SCU_APBPeriphClockConfig(__GPIO5, ENABLE); // Enable the GPIO5 Clock
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init(GPIO5, &GPIO_InitStructure);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SSC_GetChar(void);
// Function: SSC_GetChar(void);
//
// Description: This function reads one byte from the SSC
//
166,29 → 243,23
u8 SSC_GetChar (void)
{
u8 Byte = 0;
// SerialPutString("\n\rGetChar.");
SSP_SendData(SSP1, 0xFF);
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoEmpty) != SET);
Byte = SSP_ReceiveData(SSP1);
/* SPDR = 0x00; // read one byte of data from the SSC
while(!(SPSR & (1<<SPIF))){}; // wait until the data has been read.
Byte = SPDR;
*/
// sprintf(text," %02X ", Byte); SerialPutString(text);SerialPutString("done.");
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoNotFull) != SET); // wait for space in the tx fifo
SSP_SendData(SSP1, 0xFF);// send dymmy byte (0xFF) as master to receive a byte from the slave
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoEmpty) != SET); // wait for the byte to be sent
Byte = SSP_ReceiveData(SSP1); // read the byte transmitted from the slave
return (Byte);
 
}
 
//________________________________________________________________________________________________________________________________________
void SSC_ClearRxFifo (void)
{
// SerialPutString("\n\rClr RxFifo ");
// wait that the tx fifo is empty
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoEmpty) != SET);
// then empty the rx fifo by reading all the bytes that are available
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_RxFifoNotEmpty) == SET) SSP_ReceiveData(SSP1);
// SerialPutString("done.");
}
//________________________________________________________________________________________________________________________________________
// Funtion: SSC_PutChar(u8 Byte);
// Function: SSC_PutChar(u8 Byte);
//
// Description: This function writes one byte to the SSC
//
198,43 → 269,16
 
void SSC_PutChar (u8 Byte)
{
//SerialPutString("\n\rPutChar."); sprintf(text," %02X ", Byte); SerialPutString(text);
// wait for some space in the tx fifo
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoNotFull) != SET);
// put the byte to send in the tx fifo
SSP_SendData(SSP1, Byte);
//SerialPutString("done.");
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SSC_Disable(void);
//
// Description: This function enables chipselect of the sdcard (active low)
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
void SSC_Disable(void)
{
//MMC_Write &= ~(1<<MMC_Chip_Select); // disable chipselect of the sdcard (active low).
GPIO_WriteBit(GPIO5, GPIO_Pin_4 , Bit_SET);
}
 
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SSC_Enable(void);
//
// Description: This function disables chipselect of the sdcard (active low)
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
 
void SSC_Enable(void)
{
//MMC_Write |= (1<<MMC_Chip_Select); // enable chipselect of the sdcard (active low).
GPIO_WriteBit(GPIO5, GPIO_Pin_4 , Bit_RESET);
}
/trunk/ssc.h
1,50 → 1,23
#ifndef __SSC_H
#define __SSC_H
#ifndef _SSC_H
#define _SSC_H
 
#define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI
#define MMC_Read PINB
#define MMC_Direction_REG DDRB
 
 
#if defined (__AVR_ATmega128__)
#define SPI_DI 3 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
#define SPI_DO 2 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist
#define SPI_Clock 1 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk)
#define MMC_Chip_Select 4 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist
#define SPI_SS 0 //Nicht Benutz muß aber definiert werden
#endif
 
 
#if defined (__AVR_ATmega32__)
#define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
#define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist
#define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk)
#define MMC_Chip_Select 3 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist
#define SPI_SS 4 //Nicht Benutz muß aber definiert werden
#endif
 
 
#if defined (__AVR_ATmega644__)
#define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
#define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist
#define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk)
#define MMC_Chip_Select 4 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist
#define SPI_SS 3 //Nicht Benutz muß aber definiert werden
#endif
 
 
#include "91x_lib.h"
//________________________________________________________________________________________________________________________________________
//
// Functions needed for accessing the sdcard.
// Functions needed for accessing the sdcard low level via SPI.
//
//________________________________________________________________________________________________________________________________________
 
extern void SSC_Init(void);
extern unsigned char SSC_GetChar (void);
extern void SSC_PutChar (unsigned char);
extern void SSC_Enable(void);
extern void SSC_Disable(void);
extern void SSC_ClearRxFifo(void);
#define SD_SWITCH !(GPIO_ReadBit(GPIO5, GPIO_Pin_3))
 
extern void SSC_Init(void);
extern void SSC_Deinit(void);
extern u8 SSC_GetChar (void);
extern void SSC_PutChar (u8);
extern void SSC_Enable(void);
extern void SSC_Disable(void);
extern void SSC_ClearRxFifo(void);
 
#endif
 
#endif //_SSC_H