Subversion Repositories NaviCtrl

Compare Revisions

Ignore whitespace Rev 379 → Rev 380

/trunk/fat16.c
836,7 → 836,7
/* */
/* Description: This function sets the pointer of the stream relative to the position */
/* specified by origin (SEEK_SET, SEEK_CUR, SEEK_END) */
/* Returnvalue: Is 0 if seek was successful */
/* Returnvalue: Is 0 if seek was successful */
/****************************************************************************************************************************************************/
s16 fseek_(File_t *file, s32 offset, s16 origin)
{
843,55 → 843,61
s32 fposition = 0;
s16 retvalue = 1;
 
// the byteindex within a sector
u32 byte_index = 0;
// the sectorindex within a cluster
u32 sector_index = 0;
// the index of the cluster within the clusterchain inside the fat
u32 cluster_index = 0;
 
// check if the partition is valid
if((!Partition.IsValid) || (file == NULL)) return(retvalue);
switch(origin)
//......................................................
if(origin == SEEK_SET) // Fileposition relative to the beginning of the file.
{
case SEEK_SET: // Fileposition relative to the beginning of the file.
fposition = 0;
break;
case SEEK_END: // Fileposition relative to the end of the file.
fposition = (s32)file->Size;
break;
case SEEK_CUR: // Fileposition relative to the current position of the file.
default:
fposition = file->Position;
break;
}
fposition = 0;
}
//......................................................
else if(origin == SEEK_END) // Fileposition relative to the end of the file.
{
fposition = (s32) file->Size;
}
//......................................................
else if(origin == SEEK_CUR) // Fileposition relative to the current position of the file.
{
fposition = (s32)file->Position;
}
 
fposition += offset;
 
if((fposition >= 0) && (fposition <= (s32)file->Size)) // is the pointer still within the file?
// calculate the specified fileposition according to the selected mode
fposition += offset; // Die Absolute Dateiposition welche durch fseek angesprungen werden soll.
// is the fileposition within the file?
if((fposition >= 0) && (fposition <= (s32)file->Size)) // Ist die berechnete Dateiposition innerhalb der geƶffneten Datei?
{
// reset file position to start of the file
// initialize the filepointer
file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
file->SectorOfCurrCluster = 0;
file->ByteOfCurrSector = 0;
file->Position = 0;
// has the specified file at least one valid sector attached?
if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue);
while(file->Position < fposition) // repeat until the current position is less than target
{
file->Position++; // increment file position
file->ByteOfCurrSector++; // next byte in current sector
if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)
{
file->ByteOfCurrSector = 0; // reading at the beginning of new sector.
file->SectorOfCurrCluster++; // continue reading in next sector
if(file->SectorOfCurrCluster >= Partition.SectorsPerCluster) // if end of cluster is reached, the next datacluster has to be searched in the FAT.
{
if(GetNextCluster(file)) // Sets the clusterpointer of the file to the next datacluster.
{
file->SectorOfCurrCluster = 0;
}
else // the last cluster was allready reached
{
file->SectorOfCurrCluster--; // jump back to the last sector in the last cluster
file->ByteOfCurrSector = BYTES_PER_SECTOR; // set ByteOfCurrSector one byte over sector end
}
}
}
}
}
if(file->Position == fposition) retvalue = 0;
// calculate the absolute number of the sector wich contains the fileposition we are looking for
sector_index = (u32) ((u32)fposition >> 9);
// calculate the index of the cluster containing the specified sector
cluster_index = (u32) sector_index / Partition.SectorsPerCluster;
// the absolute sectornumber becomes relative to the beginning of the specified cluster
sector_index = (sector_index % Partition.SectorsPerCluster);
// calculate the index of the byteposition the fileposition points to
byte_index = (u32) fposition % 512;
// parse the fat till the calculated cluster has been reached
while(cluster_index--) GetNextCluster(file);
// set the filepointer to the specified sector and byteposition
file->SectorOfCurrCluster = (u8) sector_index;
file->ByteOfCurrSector = (u16) byte_index;
// the fileposition now equals the filepointer
file->Position = (u32)fposition;
// the specified fileposition has been reached
retvalue = 0;
}
return(retvalue);
}
 
971,19 → 977,32
/* */
/* Returnvalue: The function returns the appened cluster number or CLUSTER_UNDEFINED of no cluster was appended. */
/****************************************************************************************************************************************/
 
u16 AppendCluster(File_t *file)
{
u16 last_cluster, new_cluster = CLUSTER_UNDEFINED;
u32 fat_byte_offset, sector, byte;
Fat16Entry_t * fat;
// s8 text[64];
 
if((!Partition.IsValid) || (file == NULL)) return(new_cluster);
 
new_cluster = FindNextFreeCluster(file); // the next free cluster found on the disk.
if(new_cluster != CLUSTER_UNDEFINED)
{ // A free cluster was found and can be added to the end of the file.
fseek_(file, 0, SEEK_END); // jump to the end of the file
last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster); // determine current file cluster
{ // A free cluster was found and can be added to the end of the file.
// is there at least one cluster appended to the file?
if(file->FirstSectorOfLastCluster == CLUSTER_UNDEFINED)
{
fseek_(file, 0, SEEK_END); // jump to the end of the file
// remember the first sector of the last cluster
file->FirstSectorOfLastCluster = file->FirstSectorOfCurrCluster;
last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster); // determine current file cluster
}
else
{
last_cluster = SectorToFat16Cluster(file->FirstSectorOfLastCluster); // determine current file cluster
}
 
if(last_cluster != CLUSTER_UNDEFINED)
{
// update FAT entry of last cluster
1007,6 → 1026,8
Fat16_Deinit();
return(0);
}
// now the new cluster appended to the fat is the last cluster
file->FirstSectorOfLastCluster = Fat16ClusterToSector(new_cluster);
}
else // last cluster of the file is undefined
{ // then the new cluster must be the first one of the file
1035,6 → 1056,7
}
// update file info
file->FirstSectorOfFirstCluster = Fat16ClusterToSector(new_cluster);
file->FirstSectorOfLastCluster = file->FirstSectorOfFirstCluster;
file->Size = 0;
file->Position = 0;
}
1046,6 → 1068,7
return(new_cluster);
}
 
 
/****************************************************************************************************************************************************/
/* Function: DirectoryEntryExist(s8 *, u8, u8, File_t *) */
/* */
/trunk/fat16.h
25,6 → 25,7
{
u32 FirstSectorOfFirstCluster; // First sector of the first cluster of the file.
u32 FirstSectorOfCurrCluster; // First sector of the cluster which is edited at the moment.
u32 FirstSectorOfLastCluster; // First sector of the last cluster of the file
u8 SectorOfCurrCluster; // The sector within the current cluster.
u16 ByteOfCurrSector; // The byte location within the current sector.
u8 Mode; // Mode of fileoperation (read,write)
/trunk/fifo.c
13,7 → 13,7
return(1);
}
 
u8 fifo_put (fifo_t *f, const u8 data)
u8 fifo_put(fifo_t *f, const u8 data)
{
if(f->buffer == 0) return(0);
if (f->count >= f->size) return(0); // return 0 in case of FIFO overflow.
/trunk/fifo.h
17,6 → 17,7
u16 getvicsource; // IRQ source to block, during get
} fifo_t;
 
extern fifo_t UART1_rx_fifo;
/*
The initialization of the FIFO sets the read/write pointers etc..
The FIFO uses the buffer 'buf' which byte length must 'size'.
/trunk/gpx.c
67,6 → 67,7
#include "main.h"
#include "led.h"
#include "timer2.h"
#include "logging.h"
 
//________________________________________________________________________________________________________________________________________
// Function: GPX_DocumentInit(GPX_Document_t *)
115,6 → 116,7
}
Logging_FCStatusFlags1 = 0;
Logging_FCStatusFlags2 = 0;
Logged_GPX_Counter = 0;
return(retvalue);
}
 
301,6 → 303,7
{
case 0:
DebugOut.Analog[19]++;
Logged_GPX_Counter++;
if(GPSData.Position.Latitude < 0) u8_1 = '-';
else u8_1 = '+';
i32_1 = abs(GPSData.Position.Latitude)/10000000L;
/trunk/kml.c
59,8 → 59,8
#include "kml.h"
#include "kml_header.h"
#include "uart1.h"
#include "logging.h"
 
 
//________________________________________________________________________________________________________________________________________
// Module name: kml.c
// Compiler used: avr-gcc 3.4.5
253,6 → 253,7
{
doc->state = KML_DOC_LINESTRING_OPENED;
fwrite_((void*)KML_LINESTRING_HEADER, sizeof(KML_LINESTRING_HEADER)-1,1,doc->file);
Logged_KML_Counter = 0;
retvalue = 1;
}
}
330,6 → 331,7
i2 = rel_altitude%1000L;
sprintf(string,"%ld.%03ld",i1, i2);
fputs_(string, doc->file);
Logged_KML_Counter++;
retvalue = 1;
}
}
/trunk/logging.c
63,8 → 63,10
#include "ssc.h"
#include "settings.h"
#include "led.h"
#include "logging.h"
 
#define MIN_SD_INTERVAL 500
#define MIN_SD_INTERVAL_KML 200
#define MIN_SD_INTERVAL_GPX 500
 
u8 SD_LoggingError = 0;
 
83,13 → 85,8
logfilestate_t Logging_KML(u32 LogDelay);
logfilestate_t Logging_GPX(u32 LogDelay);
 
typedef struct
{
u32 KML_Interval; // the kml-log interval (0 = off)
u32 GPX_Interval; // the gpx-log interval (0 = off)
} LogCfg_t;
 
LogCfg_t LogCfg = {500 , 1000};
u32 Logged_GPX_Counter = 0, Logged_KML_Counter = 0;
 
 
//----------------------------------------------------------------------------------------------------
375,11 → 372,7
if(CheckDelay(flushtimer))
{
flushtimer = SetDelay(LOG_FLUSH_INTERVAL);
LED_RED_ON;
 
fflush_(logfile.file);
LED_RED_OFF;
 
}
}
}
428,12 → 421,12
SD_LoggingError = 0;
LogCfg.KML_Interval = 1000; //default
Settings_GetParamValue(PID_KML_LOGGING, (u16*)&LogCfg.KML_Interval); // overwrite by settings value
if(LogCfg.KML_Interval != 0 && LogCfg.KML_Interval < MIN_SD_INTERVAL) LogCfg.KML_Interval = MIN_SD_INTERVAL;
if(LogCfg.KML_Interval != 0 && LogCfg.KML_Interval < MIN_SD_INTERVAL_KML) LogCfg.KML_Interval = MIN_SD_INTERVAL_KML;
 
Logging_KML(0); // initialize
LogCfg.GPX_Interval = 0; //default
Settings_GetParamValue(PID_GPX_LOGGING, (u16*)&LogCfg.GPX_Interval); // overwrite by settings value
if(LogCfg.GPX_Interval != 0 && LogCfg.GPX_Interval < MIN_SD_INTERVAL) LogCfg.GPX_Interval = MIN_SD_INTERVAL;
if(LogCfg.GPX_Interval != 0 && LogCfg.GPX_Interval < MIN_SD_INTERVAL_GPX) LogCfg.GPX_Interval = MIN_SD_INTERVAL_GPX;
Logging_GPX(0); // initialize
}
 
/trunk/logging.h
4,5 → 4,15
void Logging_Init(void);
void Logging_Update(void); // logs the current gps position to a kml file
extern u8 SD_LoggingError;
extern u32 Logged_GPX_Counter, Logged_KML_Counter;
 
typedef struct
{
u32 KML_Interval; // the kml-log interval (0 = off)
u32 GPX_Interval; // the gpx-log interval (0 = off)
} LogCfg_t;
 
extern LogCfg_t LogCfg;
 
 
#endif //_LOGGING_H
/trunk/main.c
80,6 → 80,7
#include "eeprom.h"
#include "ssc.h"
#include "sdc.h"
#include "uart1.h"
 
#ifdef FOLLOW_ME
u8 TransmitAlsoToFC = 0;
152,7 → 153,7
 
if(CheckDelay(SPI0_Timeout))
{
LED_RED_ON;
LED_RED_ON;
sprintf(ErrorMSG,"no FC communication ");
newErrorCode = 3;
StopNavigation = 1;
163,7 → 164,7
else if(CheckDelay(I2C1_Timeout))
{
LED_RED_ON;
sprintf(ErrorMSG,"no compass communication");
sprintf(ErrorMSG,"no compass communica");
//Reset I2CBus
I2C1_Deinit();
I2C1_Init();
230,7 → 231,7
}
else if(FC.Error[0] & FC_ERROR0_PRESSURE)
{
LED_RED_ON;
LED_RED_ON;
sprintf(ErrorMSG,"ERR:Pressure sensor");
newErrorCode = 16;
}
257,8 → 258,8
LED_RED_ON;
// if(!(Parameter.GlobalConfig & FC_CFG_GPS_AKTIV)) sprintf(ErrorMSG,"GPS disconnected ");
// else
{
sprintf(ErrorMSG,"no GPS communication ");
{
sprintf(ErrorMSG,"no GPS communication");
UART_VersionInfo.HardwareError[0] |= NC_ERROR0_GPS_RX;
newErrorCode = 5;
}
337,7 → 338,7
else if((SD_LoggingError || (SD_WatchDog == 0)) && Parameter.GlobalConfig3 & CFG3_NO_SDCARD_NO_START )
{
LED_RED_ON;
sprintf(ErrorMSG,"ERR:SD Logging aborted");
sprintf(ErrorMSG,"ERR:SD Logging abort");
newErrorCode = 27;
DebugOut.StatusRed |= AMPEL_NC;
SD_LoggingError = 0;
355,8 → 356,8
LED_RED_OFF;
if(no_error_delay) { no_error_delay--; }
else
{
sprintf(ErrorMSG,"No Error ");
{
sprintf(ErrorMSG,"No Error ");
ErrorCode = 0;
}
}
374,9 → 375,6
ErrorGpsFixLost = 0;
}
 
// the handler will be cyclic called by the timer 1 ISR
// used is for critical timing parts that normaly would handled
// within the main loop that could block longer at logging activities
 
 
void Polling(void)
384,19 → 382,34
static u8 running = 0;
if(running) return;
running = 1;
LED_GRN_OFF;
// PollingTimeout = 20;
SPI0_UpdateBuffer(); // also calls the GPS-functions
UART0_ProcessRxData(); // GPS process request
UART0_TransmitTxData(); // GPS send answer
UART1_ProcessRxData(); // PC process request
UART1_TransmitTxData(); // PC send answer
UART2_TransmitTxData(); // FC send answer
CalcHeadFree();
LED_GRN_ON;
// ---------------- Error Check Timing ----------------------------
if(CheckDelay(TimerCheckError))
{
TimerCheckError = SetDelay(1000);
if(CheckDelay(SPI0_Timeout) && (DebugUART == UART1)) GPS_Navigation(&GPSData, &(ToFlightCtrl.GPSStick)); // process the GPS data even if the FC is not connected
if(!CheckDelay(SPI0_Timeout) || (DebugUART == UART1)) CheckErrors();
if(FC.StatusFlags & FC_STATUS_FLY) NaviData.FlyingTime++; // we want to count the battery-time
// else NaviData.FlyingTime = 0; // not the time per flight
if(SerialLinkOkay) SerialLinkOkay--;
if(SerialLinkOkay < 250 - 5) NCFlags |= NC_FLAG_NOSERIALLINK; // 5 seconds timeout for serial communication
else NCFlags &= ~NC_FLAG_NOSERIALLINK;
if(StopNavigation && (Parameter.NaviGpsModeControl >= 50) && (Parameter.GlobalConfig & FC_CFG_GPS_AKTIV)) BeepTime = 1000;
}
running = 0;
}
 
 
// the handler will be cyclic called by the timer 1 ISR
// used is for critical timing parts that normaly would handled
// within the main loop that could block longer at logging activities
void EXTIT3_IRQHandler(void)
{
IENABLE;
404,11 → 417,11
Compass_Update(); // update compass communication
Analog_Update(); // get new ADC values
 
if(!PollingTimeout)
{
PollingTimeout = 3;
Polling();
}
if(!PollingTimeout)
{
PollingTimeout = 5;
Polling();
}
 
VIC_SWITCmd(EXTIT3_ITLine,DISABLE); // clear pending bit
VIC_ITCmd(EXTIT3_ITLine, ENABLE); // enable irq
497,44 → 510,23
 
Debug_OK("START");
UART1_PutString("\r\n");
 
Polling();
fifo_purge(&UART1_rx_fifo); // flush the whole fifo init buffer
LED_GRN_ON;
LED_RED_OFF;
for (;;) // the endless main loop
{
Polling();
PollingTimeout = 15;
DebugOut.Analog[17] = CountMilliseconds;
UART1_ProcessRxData(); // PC process request
// UART1_TransmitTxData(); // PC send answer
 
// ---------------- Error Check Timing ----------------------------
if(CheckDelay(TimerCheckError))
{
TimerCheckError = SetDelay(1000);
if(CheckDelay(SPI0_Timeout) && (DebugUART == UART1)) GPS_Navigation(&GPSData, &(ToFlightCtrl.GPSStick)); // process the GPS data even if the FC is not connected
if(!CheckDelay(SPI0_Timeout) || (DebugUART == UART1)) CheckErrors();
if(FC.StatusFlags & FC_STATUS_FLY) NaviData.FlyingTime++; // we want to count the battery-time
// else NaviData.FlyingTime = 0; // not the time per flight
if(SerialLinkOkay) SerialLinkOkay--;
if(SerialLinkOkay < 250 - 5) NCFlags |= NC_FLAG_NOSERIALLINK; // 5 seconds timeout for serial communication
else NCFlags &= ~NC_FLAG_NOSERIALLINK;
if(StopNavigation && (Parameter.NaviGpsModeControl >= 50) && (Parameter.GlobalConfig & FC_CFG_GPS_AKTIV)) BeepTime = 1000;
}
// ---------------- Logging ---------------------------------------
 
 
if(SD_WatchDog)
// ---------------- Logging ---------------------------------------
if(SD_WatchDog)
{
SD_WatchDog = 10000;
SD_WatchDog = 30000;
if(SDCardInfo.Valid == 1) Logging_Update(); // could be block some time for at max. 2 seconds, therefore move time critical part of the mainloop into the ISR of timer 1
else if(FC.StatusFlags & FC_STATUS_START) SD_LoggingError = 100;
if(!SD_WatchDog) UART1_PutString("\n\rSD-Watchdog - Logging aborted\n\r");
}
 
/*
// test
if(CheckDelay(ftimer))
{
 
/trunk/menu.c
66,6 → 66,7
#include "menu.h"
#include "uart1.h"
#include "ncmag.h"
#include "logging.h"
 
u8 DispPtr = 0;
s8 DisplayBuff[DISPLAYBUFFSIZE];
120,8 → 121,8
LCD_printfxy(0,3,"%s",ErrorMSG);
}
else
{
LCD_printfxy(0,3,"(c) Buss, Busker");
{
LCD_printfxy(0,3,"(c) HiSystems GmbH");
LCD_printfxy(0,2,"%s",ErrorMSG);
}
break;
369,7 → 370,12
LCD_printfxy(0,2,"UP5:%3i UP6:%3i",Parameter.User5,Parameter.User6);
LCD_printfxy(0,3,"UP7:%3i UP8:%3i",Parameter.User7,Parameter.User8);
break;
case 17: // magnetic field
case 17: // User Parameter
LCD_printfxy(0,0,"SD-Card Logs",Parameter.User1,Parameter.User2);
LCD_printfxy(0,1,"GPX:%4i (%3ims) ",Logged_GPX_Counter,LogCfg.GPX_Interval);
LCD_printfxy(0,2,"KML:%4i (%3ims) ",Logged_KML_Counter,LogCfg.KML_Interval);
break;
case 18: // magnetic field
if(Compass_CalState)
{
LCD_printfxy(0,0,"Calibration:");
420,7 → 426,7
}
if(Keys & KEY3)Compass_SetCalState(0); // cancel
break;
case 18:
case 19:
if(GeoMagDec < 0) sign = '-';
else sign = '+';
LCD_printfxy(0,0,"Magnetic Field");
/trunk/sdc.c
176,7 → 176,7
{
rsp = SSC_GetChar();
if(CheckDelay(timestamp)) break;
}while(rsp != 0xFF && (SD_WatchDog)); // wait while card is busy (data out low)
}while(rsp != 0xFF); // wait while card is busy (data out low)
return(rsp);
}
 
219,7 → 219,7
{
r1 = SSC_GetChar(); // get byte from sd-card
if (timeout++ >500) break;
}while(r1 == 0xFF && (SD_WatchDog)); // wait for the response byte from sd-card.
}while(r1 == 0xFF); // wait for the response byte from sd-card.
return(r1);
}
 
275,7 → 275,7
result = SD_ERROR_READ_DATA;
goto end;
}
}while(rsp != DATA_START_TOKEN && (SD_WatchDog));
}while(rsp != DATA_START_TOKEN);
// data start token received
for (a = 0; a < len; a++) // read the block from the SSC
{
/trunk/spi_slave.c
193,10 → 193,6
memcpy((u8 *) &FromFlightCtrl, (u8 *) SPI_RxBuffer, sizeof(FromFlightCtrl));
SPI_RxBuffer_Request = 1;
}
else
{
DebugOut.Analog[16]++;
}
// reset timeout counter on good packet
SPI0_Timeout = SetDelay(SPI0_TIMEOUT);
DebugOut.Analog[13]++;
/trunk/uart1.c
280,8 → 280,6
static u8 abortState = 0;
u8 c;
 
IENABLE;
 
if((UART_GetITStatus(UART1, UART_IT_Receive) != RESET) || (UART_GetITStatus(UART1, UART_IT_ReceiveTimeOut) != RESET) )
{
// clear the pending bits!
352,7 → 350,8
} // eof DebugUart = UART1
}
 
IDISABLE;
 
 
VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register
}
 
362,8 → 361,8
void UART1_ProcessRxData(void)
{
// return on forwarding uart or unlocked rx buffer
u8 c;
if(DebugUART != UART1) return;
u8 c;
// if rx buffer is not locked
if(UART1_rx_buffer.Locked == FALSE)
{
/trunk/uart1.h
136,8 → 136,8
extern UART_TypeDef *DebugUART;
extern volatile u8 SerialLinkOkay;
extern Buffer_t UART1_tx_buffer;
extern Buffer_t UART1_rx_buffer;
 
 
void UART1_Init(void);
void UART1_Transmit(void);
void UART1_TransmitTxData(void);
/trunk/uart2.c
174,8 → 174,8
/********************************************************/
void UART2_IRQHandler(void)
{
IENABLE;
 
 
// if receive irq or receive timeout irq has occured
if((UART_GetITStatus(UART2, UART_IT_Receive) != RESET) || (UART_GetITStatus(UART2, UART_IT_ReceiveTimeOut) != RESET) )
{
203,7 → 203,7
}
} // eof receive irq or receive timeout irq
IDISABLE;
 
VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register
}