Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 2440 → Rev 2441

/I2C_Telemetry/trunk/Spektrum.c
29,9 → 29,9
// -- Start of USART1 initialisation for Spekturm seriell-mode
// USART1 Control and Status Register A, B, C and baud rate register
uint8_t sreg = SREG;
 
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * 115200) - 1);
 
// disable all interrupts before reconfiguration
cli();
// disable RX-Interrupt
48,7 → 48,7
// set TXD1 (PD3) as an output pin
PORTD |= (1 << PORTD3);
DDRD |= (1 << DDD3);
*/
*/
// USART0 Baud Rate Register
// set clock divider
UBRR1H = (uint8_t)(ubrr>>8);
77,7 → 77,7
UCSR1B |= (1 << RXCIE1);
// -- End of USART1 initialisation
// restore global interrupt flags
 
SREG = sreg;
return;
}
232,7 → 232,7
Sync = 2;
FrameCnt ++;
Channel = ((unsigned int)ByteHigh << 8) | c;
if(EE_Parameter.Receiver == RECEIVER_SPEKTRUM)
if(Receiver == RECEIVER_SPEKTRUM)
{
signal = Channel & 0x3ff;
signal -= 0x200; // Offset, range 0x000..0x3ff?
239,16 → 239,16
signal = signal/3; // scaling to fit PPM resolution
index = (ByteHigh >> 2) & 0x0f;
}
else
if(EE_Parameter.Receiver == RECEIVER_SPEKTRUM_HI_RES)
else
if(Receiver == RECEIVER_SPEKTRUM_HI_RES)
{
signal = Channel & 0x7ff;
signal -= 0x400; // Offset, range 0x000..0x7ff?
signal = signal/6; // scaling to fit PPM resolution
index = (ByteHigh >> 3) & 0x0f;
}
else
//if(EE_Parameter.Receiver == RECEIVER_SPEKTRUM_LOW_RES)
}
else
//if(Receiver == RECEIVER_SPEKTRUM_LOW_RES)
{
signal = Channel & 0x3ff;
signal -= 360; // Offset, range 0x000..0x3ff?
266,8 → 266,7
#endif
if(abs(signal - PPM_in[index]) < 6)
{
if(EE_Parameter.FailsafeChannel == 0 || PPM_in[EE_Parameter.FailsafeChannel] < 100) // forces Failsafe if the receiver doesn't have 'signal loss' on Failsafe
{
 
if(SenderOkay < 200) SenderOkay += 10;
else
{
274,12 → 273,11
SenderOkay = 200;
TIMSK1 &= ~_BV(ICIE1); // disable PPM-Input
}
}
}
}
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
 
#ifdef RECEIVER_SPEKTRUM_DX7EXP
if(index == 6) // FLIGHT-MODE - The channel used for our data uplink
{
368,8 → 366,6
else if (index == 8) s_update(11,signal); // AUX3 (CH11)
 
#else
if(SenderOkay >= 180) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
else PPM_diff[index] = 0;
PPM_in[index] = tmp;
#endif
}
402,5 → 398,5
}
}
}
 
 
/I2C_Telemetry/trunk/analog.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
52,12 → 52,9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include "main.h"
#include "eeprom.h"
volatile int Aktuell_Nick,Aktuell_Roll,Aktuell_Gier,Aktuell_ax, Aktuell_ay,Aktuell_az, UBat = 100;
volatile int AdWertNickFilter = 0, AdWertRollFilter = 0, AdWertGierFilter = 0;
volatile int HiResNick = 2500, HiResRoll = 2500;
volatile int AdWertNick = 0, AdWertRoll = 0, AdWertGier = 0;
volatile int AdWertAccRoll = 0,AdWertAccNick = 0,AdWertAccHoch = 0;
 
volatile unsigned int U_Bat = 100, U_recv = 50, U_mess = 100;
volatile unsigned int Res4 = 0, Res5 = 0;
volatile long Luftdruck = 32000;
volatile long SummenHoehe = 0;
volatile long StartLuftdruck;
66,17 → 63,15
signed char ExpandBaro = 0;
volatile int VarioMeter = 0;
volatile unsigned int ZaehlMessungen = 0;
unsigned char AnalogOffsetNick = 115,AnalogOffsetRoll = 115,AnalogOffsetGier = 115;
volatile unsigned char AdReady = 1;
unsigned int BaroStep = 500;
long ExpandBaroStep = 0;
volatile long HoehenWertF = 0;
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
unsigned char CalAthmospheare = 16;
unsigned char AD_ACC_Y = 6;
unsigned char AD_ACC_X = 7;
#endif
 
 
 
//#######################################################################################
void ADC_Init(void)
//#######################################################################################
89,223 → 84,102
 
void CalcExpandBaroStep(void)
{
if(ACC_AltitudeControl) ExpandBaroStep = BaroStep * (long)ExpandBaro;
else ExpandBaroStep = (16 * BaroStep) * (long)ExpandBaro - 4;
ExpandBaroStep = (16 * BaroStep) * (long)ExpandBaro - 4;
}
 
void SucheLuftruckOffset(void)
{
unsigned int off;
ExpandBaro = 0;
CalcExpandBaroStep();
off = GetParamByte(PID_PRESSURE_OFFSET);
if(off < 240) off += 10;
OCR0A = off;
OCR0B = 255-off;
Delay_ms_Mess(150);
if(MessLuftdruck > DESIRED_H_ADC) off = 240;
for(; off > 5; off--)
{
OCR0A = off;
OCR0B = 255-off;
Delay_ms_Mess(100);
printf(".");
if(MessLuftdruck > DESIRED_H_ADC) break;
}
DruckOffsetSetting = off;
SetParamByte(PID_PRESSURE_OFFSET, off);
if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG) && (DruckOffsetSetting < 10 || DruckOffsetSetting >= 230)) VersionInfo.HardwareError[0] |= FC_ERROR0_PRESSURE;
unsigned int off;
char txt[10];
ExpandBaro = 0;
CalcExpandBaroStep();
off = GetParamByte(PID_PRESSURE_OFFSET);
if(off < 240) off += 10;
OCR0A = off;
OCR0B = 255-off;
Delay_ms_Mess(150);
if(MessLuftdruck > DESIRED_H_ADC) off = 240;
for(; off > 5; off--)
{
OCR0A = off;
OCR0B = 255-off;
Delay_ms_Mess(100);
printf(".");
printf("%d",MessLuftdruck);
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + correction of the altitude error in higher altitudes
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CalAthmospheare = 16;
if(ACC_AltitudeControl)
{
if(PlatinenVersion < 23) { if(off < 140) CalAthmospheare += (160 - off) / 26; }
else { if(off < 170) CalAthmospheare += (188 - off) / 19; }
}
Luftdruck = MessLuftdruck * CalAthmospheare;
#endif
Delay_ms_Mess(300);
}
if(MessLuftdruck > DESIRED_H_ADC) break;
}
DruckOffsetSetting = off;
SetParamByte(PID_PRESSURE_OFFSET, off);
if((DruckOffsetSetting < 10) || (DruckOffsetSetting >= 230)) UART_VersionInfo.HardwareError[0] |= FC_ERROR0_PRESSURE;
 
CalAthmospheare = 16;
Luftdruck = MessLuftdruck * CalAthmospheare;
 
void SucheGyroOffset(void)
{
unsigned char i, ready = 0;
int timeout;
timeout = SetDelay(2000);
for(i=140; i != 0; i--)
{
if(ready == 3 && i > 10) i = 9;
ready = 0;
if(AdWertNick < 1020) AnalogOffsetNick--; else if(AdWertNick > 1030) AnalogOffsetNick++; else ready++;
if(AdWertRoll < 1020) AnalogOffsetRoll--; else if(AdWertRoll > 1030) AnalogOffsetRoll++; else ready++;
if(AdWertGier < 1020) AnalogOffsetGier--; else if(AdWertGier > 1030) AnalogOffsetGier++; else ready++;
I2C_Start(TWI_STATE_GYRO_OFFSET_TX);
if(AnalogOffsetNick < 10) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_NICK; AnalogOffsetNick = 10;}; if(AnalogOffsetNick > 245) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_NICK; AnalogOffsetNick = 245;};
if(AnalogOffsetRoll < 10) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_ROLL; AnalogOffsetRoll = 10;}; if(AnalogOffsetRoll > 245) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_ROLL; AnalogOffsetRoll = 245;};
if(AnalogOffsetGier < 10) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_YAW; AnalogOffsetGier = 10;}; if(AnalogOffsetGier > 245) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_YAW; AnalogOffsetGier = 245;};
while(twi_state) if(CheckDelay(timeout)) {printf("\n\r DAC or I2C ERROR! Check I2C, 3Vref, DAC and BL-Ctrl"); break;}
AdReady = 0;
ANALOG_ON;
while(!AdReady);
if(i<10) Delay_ms_Mess(10);
}
Delay_ms_Mess(70);
Delay_ms_Mess(300);
}
 
/*
0 n
1 r
2 g
3 y
4 x
5 n
6 r
7 u
8 z
9 L
10 n
11 r
12 g
13 y
14 x
15 n
16 r
17 L
*/
 
 
//#######################################################################################
//
ISR(ADC_vect)
//#######################################################################################
{
unsigned int dummy;
static unsigned char kanal=0,state = 0;
static unsigned char kanal = AD_U_RECV, state = 0;
static long tmpLuftdruck = 0;
static char messanzahl_Druck = 0;
 
switch(state++)
{
{
case 0:
dummy = ADC;
kanal = AD_ROLL;
U_recv = (3 * U_recv + (100 * ADC) / 106) / 4; // 10K/22K @ Vref = 3V
kanal = AD_U_MESS;
break;
case 1:
dummy = ADC;
kanal = AD_GIER;
U_mess = (3 * U_mess + (100 * ADC) / 31) / 4; // 1K/10K @ Vref = 3V
kanal = AD_U_BAT;
break;
case 2:
dummy = ADC;
kanal = AD_ACC_Y;
U_Bat = (3 * U_Bat + (100 * ADC) / 31) / 4; // 1K/10K @ Vref = 3V
kanal = AD_RES4;
break;
case 3:
dummy = ADC;
kanal = AD_ACC_X;
Res4 = (3 * Res4 + ADC) / 4;
kanal = AD_RES5;
break;
case 4:
dummy = ADC;
kanal = AD_NICK;
Res5 = (3 * Res5 + ADC) / 4;
kanal = AD_DRUCK;
break;
case 5:
dummy = ADC;
kanal = AD_ROLL;
break;
case 6:
dummy = ADC;
kanal = AD_UBAT;
break;
case 7:
UBat = (3 * UBat + ADC / 3) / 4;
kanal = AD_ACC_Z;
break;
case 8:
dummy = ADC;
kanal = AD_DRUCK;
break;
// "case 9:" fehlt hier absichtlich
case 10:
dummy = ADC;
kanal = AD_ROLL;
break;
case 11:
dummy = ADC;
kanal = AD_GIER;
break;
case 12:
dummy = ADC;
kanal = AD_ACC_Y;
break;
case 13:
dummy = ADC;
kanal = AD_ACC_X;
break;
case 14:
dummy = ADC;
kanal = AD_NICK;
break;
case 15:
dummy = ADC;
kanal = AD_ROLL;
break;
case 16:
dummy = ADC;
kanal = AD_DRUCK;
break;
case 17:
if(ACC_AltitudeControl)
{
HoehenWertF = (ACC_AltitudeFusion(0) + SA_FILTER/2)/SA_FILTER; // cm
}
else HoehenWertF = HoehenWert;
state = 0;
AdReady = 1;
ZaehlMessungen++;
// "break" fehlt hier absichtlich
case 9:
MessLuftdruck = ADC;
if(ACC_AltitudeControl)
{
// ExpandBaroStep = BaroStep * (long)ExpandBaro; // wird in fc.c aufgerufen
// tmpLuftdruck = MessLuftdruck - BaroStep * (long)ExpandBaro; // -523 counts per offset step
tmpLuftdruck = MessLuftdruck - ExpandBaroStep; // -523 counts per offset step
Luftdruck -= Luftdruck / CalAthmospheare; // 16
Luftdruck += tmpLuftdruck;
HoehenWert = StartLuftdruck - Luftdruck; // cm
}
else
{ // old version (until FC V2.1)
{
tmpLuftdruck += MessLuftdruck;
if(++messanzahl_Druck >= 16) // war bis 0.86 "18"
if(++messanzahl_Druck >= 16)
{
signed int tmp;
// Luftdruck = (7 * Luftdruck + tmpLuftdruck - (16 * BaroStep) * (long)ExpandBaro + 4) / 8; // -523.19 counts per 10 counts offset step
// ExpandBaroStep = (16 * BaroStep) * (long)ExpandBaro - 4; // wird in fc.c aufgerufen
Luftdruck = (7 * Luftdruck + tmpLuftdruck - ExpandBaroStep) / 8; // -523.19 counts per 10 counts offset step
HoehenWert = StartLuftdruck - Luftdruck;
SummenHoehe -= SummenHoehe/SM_FILTER;
SummenHoehe += HoehenWert;
tmp = (HoehenWert - SummenHoehe/SM_FILTER);
if(tmp > 1024) tmp = 1024; else if(tmp < -1024) tmp = -1024;
if(abs(VarioMeter) > 700) VarioMeter = (15 * VarioMeter + 8 * tmp)/16;
else VarioMeter = (31 * VarioMeter + 8 * tmp)/32;
tmpLuftdruck /= 2;
messanzahl_Druck = 16/2;
signed int tmp;
Luftdruck = (7 * Luftdruck + tmpLuftdruck - ExpandBaroStep) / 8; // -523.19 counts per 10 counts offset step
HoehenWert = StartLuftdruck - Luftdruck;
SummenHoehe -= SummenHoehe/SM_FILTER;
SummenHoehe += HoehenWert;
tmp = (HoehenWert - SummenHoehe/SM_FILTER);
if(tmp > 1024) tmp = 1024; else if(tmp < -1024) tmp = -1024;
if(abs(VarioMeter) > 700) VarioMeter = (15 * VarioMeter + 8 * tmp)/16;
else VarioMeter = (31 * VarioMeter + 8 * tmp)/32;
tmpLuftdruck /= 2;
messanzahl_Druck = 16/2;
}
}
kanal = AD_NICK;
kanal = AD_U_RECV;
state = 0; // stop state machine
AdReady = 1;
ZaehlMessungen++;
break;
default:
kanal = 0; state = 0; kanal = AD_NICK;
state = 0;
kanal = AD_U_RECV;
break;
}
}
ADMUX = kanal;
if(state != 0) ANALOG_ON;
}
/I2C_Telemetry/trunk/analog.h
1,18 → 1,10
#ifndef _ANALOG_H
#define _ANALOG_H
/*#######################################################################################
#define _ANALOG_H
 
#######################################################################################*/
 
#define SM_FILTER 16
#define SA_FILTER 512
 
extern volatile int UBat;
extern volatile int AdWertNick, AdWertRoll, AdWertGier;
extern volatile int AdWertAccRoll,AdWertAccNick,AdWertAccHoch;
extern volatile int HiResNick, HiResRoll;
extern volatile int AdWertNickFilter, AdWertRollFilter, AdWertGierFilter;
extern volatile int Aktuell_Nick,Aktuell_Roll,Aktuell_Gier,Aktuell_ax, Aktuell_ay,Aktuell_az;
extern volatile unsigned int U_Bat, U_recv, U_mess; // in steps of 0.1V
extern volatile unsigned int Res4, Res5;
extern volatile long Luftdruck;
extern volatile long SummenHoehe;
extern volatile char messanzahl_Druck;
23,36 → 15,23
extern volatile unsigned int MessLuftdruck;
extern volatile long StartLuftdruck;
extern volatile char MessanzahlNick;
extern unsigned char AnalogOffsetNick,AnalogOffsetRoll,AnalogOffsetGier;
extern volatile unsigned char AdReady;
extern unsigned int BaroStep;
volatile long HoehenWertF;
unsigned int ReadADC(unsigned char adc_input);
extern unsigned char CalAthmospheare;
 
void ADC_Init(void);
void SucheLuftruckOffset(void);
void SucheGyroOffset(void);
void CalcExpandBaroStep(void);
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
extern unsigned char CalAthmospheare;
#endif
 
#define AD_GIER 0
#define AD_ROLL 1
#define AD_NICK 2
 
#define AD_U_RECV 1
#define AD_U_MESS 2
#define AD_DRUCK 3
#define AD_UBAT 4
#define AD_ACC_Z 5
#define AD_U_BAT 4
#define AD_RES4 6
#define AD_RES5 7
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
extern unsigned char AD_ACC_Y;
extern unsigned char AD_ACC_X;
#else
#define AD_ACC_Y 6
#define AD_ACC_X 7
#endif
 
#define ANALOG_OFF ADCSRA=0
#define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE)
 
#define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE)
//Signle trigger Mode, Interrupt on
#endif //_ANALOG_H
/I2C_Telemetry/trunk/buffer.c
0,0 → 1,91
/*#######################################################################################*/
/* !!! THIS IS NOT FREE SOFTWARE !!! */
/*#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt.
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software.
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####'
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
// + agreement shall be the property of the Licensor.
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other
// + features that can be used to identify the program may not be altered or defaced by the customer.
// + The customer shall be responsible for taking reasonable precautions
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence.
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test
// + the software for his purpose before any operational usage. The customer will backup his data before using the software.
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations.
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
// + #### END OF LICENSING TERMS ####
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include <string.h>
#include <inttypes.h>
#include "buffer.h"
 
void Buffer_Clear(Buffer_t* pBuffer)
{
pBuffer->DataBytes = 0;
pBuffer->Position = 0;
pBuffer->Locked = 0;
}
 
void Buffer_Init(Buffer_t* pBuffer, uint8_t* pDataBuffer, uint16_t DataBufferSize)
{
pBuffer->pData = pDataBuffer;
pBuffer->Size = DataBufferSize;
Buffer_Clear(pBuffer);
}
 
uint8_t Buffer_Copy(Buffer_t* pSrcBuffer, Buffer_t* pDstBuffer)
{
uint8_t retval = 0;
 
if( (pSrcBuffer != NULL) && (pDstBuffer != NULL) )
{
if(pSrcBuffer->Locked && !(pDstBuffer->Locked) && (pDstBuffer->Size >= pSrcBuffer->DataBytes))
{
memcpy(pDstBuffer->pData, pSrcBuffer->pData, pSrcBuffer->DataBytes);
pDstBuffer->DataBytes = pSrcBuffer->DataBytes;
pDstBuffer->Position = 0;
pDstBuffer->Locked = 1;
retval = 1;
}
}
return retval;
}
/I2C_Telemetry/trunk/buffer.h
0,0 → 1,16
#ifndef __BUFFER_H
#define __BUFFER_H
 
typedef struct
{
uint8_t* pData;
uint16_t Size;
uint16_t DataBytes;
uint16_t Position;
uint8_t Locked;
} __attribute__((packed)) Buffer_t;
 
void Buffer_Init(Buffer_t* pBuffer, uint8_t* pDataBuffer, uint16_t DataBufferSize);
void Buffer_Clear(Buffer_t* pBuffer);
uint8_t Buffer_Copy(Buffer_t* pSrcBuffer, Buffer_t* pDstBuffer);
#endif // __BUFFER_H
/I2C_Telemetry/trunk/capacity.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
81,12 → 81,12
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
unsigned int BL3_Current(unsigned char who) // in 0,1A
{
/*if(Motor[who].Current <= 200) return(Motor[who].Current);
else
{
if(Motor[who].Version & MOTOR_STATE_BL30) return(200 + 10 * ((unsigned int)Motor[who].Current-200));
else return(Motor[who].Current);
}*/
if(Motor[who].Current <= 200) return(Motor[who].Current);
else
{
if(Motor[who].Version & MOTOR_STATE_BL30) return(200 + 10 * ((unsigned int)Motor[who].Current-200));
else return(Motor[who].Current);
}
}
 
// called in main loop at a regular interval
142,8 → 142,8
// update actual Current
Capacity.ActualCurrent = Current;
// update actual Power
if(Current < 255) Capacity.ActualPower = (UBat * Current) / 100; // in W higher resolution
else Capacity.ActualPower = (UBat * (Current/4)) / 25; // in W
if(Current < 255) Capacity.ActualPower = (U_Bat * Current) / 100; // in W higher resolution
else Capacity.ActualPower = (U_Bat * (Current/4)) / 25; // in W
 
// update used capacity
SubCounter += Current;
/I2C_Telemetry/trunk/eeprom.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
60,276 → 60,9
#include <avr/eeprom.h>
#include <string.h>
#include "eeprom.h"
#include "uart.h"
#include "led.h"
#include "main.h"
#include "fc.h"
#include "twimaster.h"
 
paramset_t EE_Parameter;
MixerTable_t Mixer;
uint8_t RequiredMotors;
 
 
uint8_t RAM_Checksum(uint8_t* pBuffer, uint16_t len)
{
uint8_t crc = 0xAA;
uint16_t i;
 
for(i=0; i<len; i++)
{
crc += pBuffer[i];
}
return crc;
}
 
uint8_t EEProm_Checksum(uint16_t EEAddr, uint16_t len)
{
uint8_t crc = 0xAA;
uint16_t off;
 
for(off=0; off<len; off++)
{
crc += eeprom_read_byte((uint8_t*)(EEAddr + off));;
}
return crc;
}
 
void ParamSet_DefaultStickMapping(void)
{
EE_Parameter.Kanalbelegung[K_GAS] = 1;
EE_Parameter.Kanalbelegung[K_ROLL] = 2;
EE_Parameter.Kanalbelegung[K_NICK] = 3;
EE_Parameter.Kanalbelegung[K_GIER] = 4;
EE_Parameter.Kanalbelegung[K_POTI1] = 5;
EE_Parameter.Kanalbelegung[K_POTI2] = 6;
EE_Parameter.Kanalbelegung[K_POTI3] = 7;
EE_Parameter.Kanalbelegung[K_POTI4] = 8;
EE_Parameter.Kanalbelegung[K_POTI5] = 9;
EE_Parameter.Kanalbelegung[K_POTI6] = 10;
EE_Parameter.Kanalbelegung[K_POTI7] = 11;
EE_Parameter.Kanalbelegung[K_POTI8] = 12;
}
 
 
/***************************************************/
/* Default Values for parameter set 1 */
/***************************************************/
void CommonDefaults(void)
{
EE_Parameter.Revision = EEPARAM_REVISION;
memset(EE_Parameter.Name,0,12); // delete name
if(PlatinenVersion >= 20)
{
EE_Parameter.Gyro_D = 10;
EE_Parameter.Driftkomp = 0;
EE_Parameter.GyroAccFaktor = 27;
EE_Parameter.WinkelUmschlagNick = 78;
EE_Parameter.WinkelUmschlagRoll = 78;
}
else
{
EE_Parameter.Gyro_D = 3;
EE_Parameter.Driftkomp = 32;
EE_Parameter.GyroAccFaktor = 30;
EE_Parameter.WinkelUmschlagNick = 85;
EE_Parameter.WinkelUmschlagRoll = 85;
}
EE_Parameter.GyroAccAbgleich = 32; // 1/k
EE_Parameter.BitConfig = 0; // Looping usw.
EE_Parameter.GlobalConfig = CFG_ACHSENKOPPLUNG_AKTIV | CFG_KOMPASS_AKTIV | CFG_GPS_AKTIV | CFG_HOEHEN_SCHALTER;
EE_Parameter.ExtraConfig = CFG_GPS_AID | CFG2_VARIO_BEEP | CFG_LEARNABLE_CAREFREE | CFG_NO_RCOFF_BEEPING;
EE_Parameter.GlobalConfig3 = CFG3_SPEAK_ALL | CFG3_NO_GPSFIX_NO_START;//
EE_Parameter.Receiver = RECEIVER_HOTT;
EE_Parameter.MotorSafetySwitch = 0;
EE_Parameter.ExternalControl = 0;
 
EE_Parameter.Gas_Min = 8; // Wert : 0-32
EE_Parameter.Gas_Max = 230; // Wert : 33-247
EE_Parameter.KompassWirkung = 64; // Wert : 0-247
 
EE_Parameter.Hoehe_MinGas = 30;
EE_Parameter.HoeheChannel = 5; // Wert : 0-32
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(ACC_AltitudeControl)
{
EE_Parameter.Hoehe_P = 20; // Wert : 0-32
EE_Parameter.Luftdruck_D = 40; // Wert : 0-247
EE_Parameter.Hoehe_ACC_Wirkung = 30; // Wert : 0-247
EE_Parameter.Hoehe_HoverBand = 1; // Wert : 0-247
EE_Parameter.Hoehe_GPS_Z = 0; // Wert : 0-247
EE_Parameter.Hoehe_StickNeutralPoint = 127;// Wert : 0-247 (0 = Hover-Estimation)
EE_Parameter.FailSafeTime = 30; // 0 = off
}
else
#endif
{
EE_Parameter.Hoehe_P = 15; // Wert : 0-32
EE_Parameter.Luftdruck_D = 30; // Wert : 0-247
EE_Parameter.Hoehe_ACC_Wirkung = 0; // Wert : 0-247
EE_Parameter.Hoehe_HoverBand = 8; // Wert : 0-247
EE_Parameter.Hoehe_GPS_Z = 20; // Wert : 0-247
EE_Parameter.Hoehe_StickNeutralPoint = 0;// Wert : 0-247 (0 = Hover-Estimation)
EE_Parameter.FailSafeTime = 0; // 0 = off
}
EE_Parameter.Hoehe_Verstaerkung = 15; // Wert : 0-50 (15 -> ca. +/- 5m/sek bei Stick-Voll-Ausschlag)
EE_Parameter.StartLandChannel = 0;
EE_Parameter.LandingSpeed = 12;
 
EE_Parameter.UserParam1 = 0; // zur freien Verwendung
EE_Parameter.UserParam2 = 0; // zur freien Verwendung
EE_Parameter.UserParam3 = 0; // zur freien Verwendung
EE_Parameter.UserParam4 = 0; // zur freien Verwendung
EE_Parameter.UserParam5 = 0; // zur freien Verwendung
EE_Parameter.UserParam6 = 0; // zur freien Verwendung
EE_Parameter.UserParam7 = 0; // zur freien Verwendung
EE_Parameter.UserParam8 = 0; // zur freien Verwendung
 
EE_Parameter.ServoNickControl = 128; // Wert : 0-247 // Stellung des Servos
EE_Parameter.ServoNickComp = 50; // Wert : 0-247 // Einfluss Gyro/Servo
EE_Parameter.ServoCompInvert = 2; // Wert : 0-247 // Richtung Einfluss Gyro/Servo
EE_Parameter.ServoNickMin = 24; // Wert : 0-247 // Anschlag
EE_Parameter.ServoNickMax = 230; // Wert : 0-247 // Anschlag
EE_Parameter.ServoNickRefresh = 3;
EE_Parameter.Servo3 = 125;
EE_Parameter.Servo4 = 125;
EE_Parameter.Servo5 = 125;
EE_Parameter.ServoRollControl = 128; // Wert : 0-247 // Stellung des Servos
EE_Parameter.ServoRollComp = 85; // Wert : 0-247 // Einfluss Gyro/Servo
EE_Parameter.ServoRollMin = 70; // Wert : 0-247 // Anschlag
EE_Parameter.ServoRollMax = 220; // Wert : 0-247 // Anschlag
EE_Parameter.ServoManualControlSpeed = 60;
EE_Parameter.CamOrientation = 0; // Wert : 0-24 -> 0-360 -> 15° steps
 
EE_Parameter.J16Bitmask = 0xAA;
EE_Parameter.J17Bitmask = 0xCC;
EE_Parameter.WARN_J16_Bitmask = 0x00;
EE_Parameter.WARN_J17_Bitmask = 0xAA;
EE_Parameter.J16Timing = 40;
EE_Parameter.J17Timing = 40;
EE_Parameter.NaviOut1Parameter = 0; // Photo release in meter
EE_Parameter.LoopGasLimit = 50;
EE_Parameter.LoopThreshold = 90; // Wert: 0-247 Schwelle für Stickausschlag
EE_Parameter.LoopHysterese = 50;
 
EE_Parameter.NaviGpsModeChannel = 6; // Kanal 6
EE_Parameter.NaviGpsGain = 100;
EE_Parameter.NaviGpsP = 100;
EE_Parameter.NaviGpsI = 90;
EE_Parameter.NaviGpsD = 120;
EE_Parameter.NaviGpsA = 40;
EE_Parameter.NaviGpsPLimit = 75;
EE_Parameter.NaviGpsILimit = 85;
EE_Parameter.NaviGpsDLimit = 75;
EE_Parameter.NaviGpsMinSat = 6;
EE_Parameter.NaviStickThreshold = 8;
EE_Parameter.NaviWindCorrection = 50;
EE_Parameter.NaviAccCompensation = 42;
EE_Parameter.NaviOperatingRadius = 245;
EE_Parameter.NaviAngleLimitation = 140;
EE_Parameter.NaviPH_LoginTime = 2;
EE_Parameter.OrientationAngle = 0;
EE_Parameter.CareFreeChannel = 0;
EE_Parameter.UnterspannungsWarnung = 33; // Wert : 0-247 ( Automatische Zellenerkennung bei < 50)
EE_Parameter.NotGas = 65; // Wert : 0-247 // Gaswert bei Empangsverlust (ggf. in Prozent)
EE_Parameter.NotGasZeit = 90; // Wert : 0-247 // Zeit bis auf NotGas geschaltet wird, wg. Rx-Problemen
EE_Parameter.MotorSmooth = 0;
EE_Parameter.ComingHomeAltitude = 0; // 0 = don't change
EE_Parameter.MaxAltitude = 150; // 0 = off
EE_Parameter.AchsKopplung1 = 125;
EE_Parameter.AchsKopplung2 = 52;
EE_Parameter.FailsafeChannel = 0;
EE_Parameter.ServoFilterNick = 0;
EE_Parameter.ServoFilterRoll = 0;
}
/*
void ParamSet_DefaultSet1(void) // sport
{
CommonDefaults();
EE_Parameter.Stick_P = 14; // Wert : 1-20
EE_Parameter.Stick_D = 16; // Wert : 0-20
EE_Parameter.StickGier_P = 12; // Wert : 1-20
EE_Parameter.Gyro_P = 80; // Wert : 0-247
EE_Parameter.Gyro_I = 150; // Wert : 0-247
EE_Parameter.Gyro_Gier_P = 80; // Wert : 0-247
EE_Parameter.Gyro_Gier_I = 150; // Wert : 0-247
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8
EE_Parameter.I_Faktor = 32;
EE_Parameter.CouplingYawCorrection = 1;
EE_Parameter.GyroAccAbgleich = 16; // 1/k;
EE_Parameter.DynamicStability = 100;
memcpy(EE_Parameter.Name, "Sport\0", 12);
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1);
}
*/
 
/***************************************************/
/* Default Values for parameter set 1 */
/***************************************************/
void ParamSet_DefaultSet1(void) // normal
{
CommonDefaults();
EE_Parameter.Stick_P = 10; // Wert : 1-20
EE_Parameter.Stick_D = 16; // Wert : 0-20
EE_Parameter.StickGier_P = 6; // Wert : 1-20
EE_Parameter.Gyro_P = 90; // Wert : 0-247
EE_Parameter.Gyro_I = 120; // Wert : 0-247
EE_Parameter.Gyro_Gier_P = 90; // Wert : 0-247
EE_Parameter.Gyro_Gier_I = 120; // Wert : 0-247
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8
EE_Parameter.I_Faktor = 32;
EE_Parameter.CouplingYawCorrection = 60;
EE_Parameter.DynamicStability = 75;
memcpy(EE_Parameter.Name, "Fast",4);
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1);
}
 
 
/***************************************************/
/* Default Values for parameter set 2 */
/***************************************************/
void ParamSet_DefaultSet2(void) // Agil
{
CommonDefaults();
EE_Parameter.Stick_P = 8; // Wert : 1-20
EE_Parameter.Stick_D = 16; // Wert : 0-20
EE_Parameter.StickGier_P = 6; // Wert : 1-20
EE_Parameter.Gyro_P = 100; // Wert : 0-247
EE_Parameter.Gyro_I = 120; // Wert : 0-247
EE_Parameter.Gyro_Gier_P = 100; // Wert : 0-247
EE_Parameter.Gyro_Gier_I = 120; // Wert : 0-247
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8
EE_Parameter.I_Faktor = 16;
EE_Parameter.CouplingYawCorrection = 70;
EE_Parameter.DynamicStability = 70;
memcpy(EE_Parameter.Name, "Agile",5);
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1);
}
 
/***************************************************/
/* Default Values for parameter set 3 */
/***************************************************/
void ParamSet_DefaultSet3(void) // Easy
{
CommonDefaults();
EE_Parameter.Stick_P = 6; // Wert : 1-20
EE_Parameter.Stick_D = 10; // Wert : 0-20
EE_Parameter.StickGier_P = 4; // Wert : 1-20
EE_Parameter.Gyro_P = 100; // Wert : 0-247
EE_Parameter.Gyro_I = 120; // Wert : 0-247
EE_Parameter.Gyro_Gier_P = 100; // Wert : 0-247
EE_Parameter.Gyro_Gier_I = 120; // Wert : 0-247
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8
EE_Parameter.I_Faktor = 16;
EE_Parameter.CouplingYawCorrection = 70;
EE_Parameter.DynamicStability = 70;
memcpy(EE_Parameter.Name, "Easy", 4);
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1);
}
 
 
/***************************************************/
/* Read Parameter from EEPROM as byte */
/***************************************************/
uint8_t GetParamByte(uint16_t param_id)
360,293 → 93,3
{
eeprom_write_word((uint16_t*)(EEPROM_ADR_PARAM_BEGIN + param_id), value);
}
 
/***************************************************/
/* Read Parameter Set from EEPROM */
/***************************************************/
// number [1..5]
uint8_t ParamSet_ReadFromEEProm(uint8_t setnumber)
{
uint8_t crc;
uint16_t eeaddr;
 
// range the setnumber
if((1 > setnumber) || (setnumber > 5)) setnumber = 3;
 
// calculate eeprom addr
eeaddr = EEPROM_ADR_PARAMSET + PARAMSET_STRUCT_LEN * (setnumber - 1);
 
// calculate checksum from eeprom
crc = EEProm_Checksum(eeaddr, PARAMSET_STRUCT_LEN - 1);
 
// check crc
if(crc != eeprom_read_byte((uint8_t*)(eeaddr + PARAMSET_STRUCT_LEN - 1))) return 0;
 
// check revision
if(eeprom_read_byte((uint8_t*)(eeaddr)) != EEPARAM_REVISION) return 0;
 
// read paramset from eeprom
eeprom_read_block((void *) &EE_Parameter, (void*)(EEPROM_ADR_PARAMSET + PARAMSET_STRUCT_LEN * (setnumber - 1)), PARAMSET_STRUCT_LEN);
LED_Init();
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
LIBTEL_HoTT_Clear();
#endif
return 1;
}
 
/***************************************************/
/* Write Parameter Set to EEPROM */
/***************************************************/
// number [1..5]
uint8_t ParamSet_WriteToEEProm(uint8_t setnumber)
{
uint8_t crc;
 
if(EE_Parameter.Revision == EEPARAM_REVISION) // write only the right revision to eeprom
{
if(setnumber > 5) setnumber = 5;
if(setnumber < 1) return 0;
LIBTEL_CheckSettings();
if(EE_Parameter.GlobalConfig3 & CFG3_VARIO_FAILSAFE) // check the Setting: Not more than 100% emergency gas
{
if(EE_Parameter.NotGas > 99) EE_Parameter.NotGas = 80; // i.e. 80% of Hovergas
}
// update checksum
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1);
 
// write paramset to eeprom
eeprom_write_block((void *) &EE_Parameter, (void*)(EEPROM_ADR_PARAMSET + PARAMSET_STRUCT_LEN * (setnumber - 1)), PARAMSET_STRUCT_LEN);
 
// backup channel settings to separate block in eeprom
eeprom_write_block( (void*)(EE_Parameter.Kanalbelegung), (void*)(EEPROM_ADR_CHANNELS), sizeof(EE_Parameter.Kanalbelegung));
 
// write crc of channel block to eeprom
crc = RAM_Checksum((uint8_t*)(EE_Parameter.Kanalbelegung), sizeof(EE_Parameter.Kanalbelegung));
eeprom_write_byte((uint8_t*)(EEPROM_ADR_CHANNELS + sizeof(EE_Parameter.Kanalbelegung)), crc);
 
// update active settings number
SetActiveParamSet(setnumber);
LED_Init();
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
LIBTEL_HoTT_Clear();
#endif
return 1;
}
// wrong revision
return 0;
}
 
/***************************************************/
/* Read MixerTable from EEPROM */
/***************************************************/
uint8_t MixerTable_ReadFromEEProm(void)
{
uint8_t crc;
 
// calculate checksum in eeprom
crc = EEProm_Checksum(EEPROM_ADR_MIXERTABLE, sizeof(Mixer) - 1);
 
// check crc
if( crc != eeprom_read_byte((uint8_t*)(EEPROM_ADR_MIXERTABLE + sizeof(Mixer) - 1)) ) return 0;
 
// check revision
if(eeprom_read_byte((uint8_t*)(EEPROM_ADR_MIXERTABLE)) != EEMIXER_REVISION) return 0;
 
// read mixer table
eeprom_read_block((void *) &Mixer, (void*)(EEPROM_ADR_MIXERTABLE), sizeof(Mixer));
return 1;
}
 
/***************************************************/
/* Write Mixer Table to EEPROM */
/***************************************************/
uint8_t MixerTable_WriteToEEProm(void)
{
if(Mixer.Revision == EEMIXER_REVISION)
{
// update crc
Mixer.crc = RAM_Checksum((uint8_t*)(&Mixer), sizeof(Mixer) - 1);
 
// write to eeprom
eeprom_write_block((void *) &Mixer, (void*)(EEPROM_ADR_MIXERTABLE), sizeof(Mixer));
return 1;
}
else return 0;
}
 
/***************************************************/
/* Default Values for Mixer Table */
/***************************************************/
void MixerTable_Default(void) // Quadro
{
uint8_t i;
 
Mixer.Revision = EEMIXER_REVISION;
// clear mixer table
for(i = 0; i < 16; i++)
{
Mixer.Motor[i][MIX_GAS] = 0;
Mixer.Motor[i][MIX_NICK] = 0;
Mixer.Motor[i][MIX_ROLL] = 0;
Mixer.Motor[i][MIX_YAW] = 0;
}
// default = Quadro
Mixer.Motor[0][MIX_GAS] = 64; Mixer.Motor[0][MIX_NICK] = +64; Mixer.Motor[0][MIX_ROLL] = 0; Mixer.Motor[0][MIX_YAW] = +64;
Mixer.Motor[1][MIX_GAS] = 64; Mixer.Motor[1][MIX_NICK] = -64; Mixer.Motor[1][MIX_ROLL] = 0; Mixer.Motor[1][MIX_YAW] = +64;
Mixer.Motor[2][MIX_GAS] = 64; Mixer.Motor[2][MIX_NICK] = 0; Mixer.Motor[2][MIX_ROLL] = -64; Mixer.Motor[2][MIX_YAW] = -64;
Mixer.Motor[3][MIX_GAS] = 64; Mixer.Motor[3][MIX_NICK] = 0; Mixer.Motor[3][MIX_ROLL] = +64; Mixer.Motor[3][MIX_YAW] = -64;
memcpy(Mixer.Name, "Quadro\0\0\0\0\0\0", 12);
Mixer.crc = RAM_Checksum((uint8_t*)(&Mixer), sizeof(Mixer) - 1);
}
 
/***************************************************/
/* Get active parameter set */
/***************************************************/
uint8_t GetActiveParamSet(void)
{
uint8_t setnumber;
setnumber = eeprom_read_byte((uint8_t*)(EEPROM_ADR_PARAM_BEGIN + PID_ACTIVE_SET));
if(setnumber > 5)
{
setnumber = 3;
eeprom_write_byte((void*)(EEPROM_ADR_PARAM_BEGIN+PID_ACTIVE_SET), setnumber);
}
ActiveParamSet = setnumber;
return(setnumber);
}
 
/***************************************************/
/* Set active parameter set */
/***************************************************/
void SetActiveParamSet(uint8_t setnumber)
{
if(setnumber > 5) setnumber = 5;
if(setnumber < 1) setnumber = 1;
ActiveParamSet = setnumber;
eeprom_write_byte((uint8_t*)(EEPROM_ADR_PARAM_BEGIN + PID_ACTIVE_SET), setnumber);
}
 
/***************************************************/
/* Set default parameter set */
/***************************************************/
void SetDefaultParameter(uint8_t set, uint8_t restore_channels)
{
 
if(set > 5) set = 5;
else if(set < 1) set = 1;
 
switch(set)
{
case 1:
ParamSet_DefaultSet1(); // Fill ParamSet Structure to default parameter set 1 (Sport)
break;
case 2:
ParamSet_DefaultSet2(); // Kamera
break;
case 3:
ParamSet_DefaultSet3(); // Beginner
break;
default:
ParamSet_DefaultSet3(); // Beginner
break;
}
if(restore_channels)
{
uint8_t crc;
// 1st check for a valid channel backup in eeprom
crc = EEProm_Checksum(EEPROM_ADR_CHANNELS, sizeof(EE_Parameter.Kanalbelegung));
if(crc == eeprom_read_byte((uint8_t*)(EEPROM_ADR_CHANNELS + sizeof(EE_Parameter.Kanalbelegung))) )
{
eeprom_read_block((void *)EE_Parameter.Kanalbelegung, (void*)(EEPROM_ADR_CHANNELS), sizeof(EE_Parameter.Kanalbelegung));
}
else ParamSet_DefaultStickMapping();
}
else ParamSet_DefaultStickMapping();
ParamSet_WriteToEEProm(set);
}
 
/***************************************************/
/* Initialize EEPROM Parameter Sets */
/***************************************************/
void ParamSet_Init(void)
{
uint8_t channel_backup = 0, bad_params = 0, ee_default = 0,i;
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(PlatinenVersion != GetParamByte(PID_HARDWARE_VERSION))
{
if(PlatinenVersion == 22 && GetParamByte(PID_HARDWARE_VERSION) == 21 && !(PIND & 0x10)) SetParamByte(PID_EE_REVISION,0); // reset the Settings if the Version changed to V2.2
SetParamByte(PID_HARDWARE_VERSION,PlatinenVersion); // Remember the Version number
wdt_enable(WDTO_15MS); // Reset-Commando
printf("\n\r--> Hardware Version Byte Changed <--");
while(1);
}
#endif
if((EEPARAM_REVISION) != GetParamByte(PID_EE_REVISION))
{
ee_default = 1; // software update or forced by mktool
}
// 1st check for a valid channel backup in eeprom
i = EEProm_Checksum(EEPROM_ADR_CHANNELS, sizeof(EE_Parameter.Kanalbelegung));
if(i == eeprom_read_byte((uint8_t*)(EEPROM_ADR_CHANNELS + sizeof(EE_Parameter.Kanalbelegung)))) channel_backup = 1;
 
// parameter check
 
// check all 5 parameter settings
for (i = 1;i < 6; i++)
{
if(ee_default || !ParamSet_ReadFromEEProm(i)) // could not read paramset from eeprom
{
bad_params = 1;
printf("\n\rGenerating default Parameter Set %d",i);
switch(i)
{
case 1:
ParamSet_DefaultSet1(); // Fill ParamSet Structure to default parameter set 1 (Sport)
break;
case 2:
ParamSet_DefaultSet2(); // Normal
break;
default:
ParamSet_DefaultSet3(); // Easy
break;
}
if(channel_backup) // if we have an channel mapping backup in eeprom
{ // restore it from eeprom
eeprom_read_block((void *)EE_Parameter.Kanalbelegung, (void*)(EEPROM_ADR_CHANNELS), sizeof(EE_Parameter.Kanalbelegung));
}
else
{ // use default mapping
ParamSet_DefaultStickMapping();
}
ParamSet_WriteToEEProm(i);
}
}
if(bad_params) // at least one of the parameter settings were invalid
{
// default-Setting is parameter set 3
SetActiveParamSet(3);
}
// read active parameter set to ParamSet stucture
i = GetActiveParamSet();
ParamSet_ReadFromEEProm(i);
printf("\n\rUsing Parameter Set %d", i);
 
// load mixer table
if(GetParamByte(PID_EE_REVISION) == 0xff || !MixerTable_ReadFromEEProm() )
{
printf("\n\rGenerating default Mixer Table");
MixerTable_Default(); // Quadro
MixerTable_WriteToEEProm();
}
if(ee_default) SetParamByte(PID_EE_REVISION, (EEPARAM_REVISION));
// determine motornumber
RequiredMotors = 0;
for(i = 0; i < 16; i++)
{
if(Mixer.Motor[i][MIX_GAS] > 0) RequiredMotors++;
}
 
printf("\n\rMixer-Config: '%s' (%u Motors)",Mixer.Name, RequiredMotors);
PrintLine();// ("\n\r===================================");
 
}
/I2C_Telemetry/trunk/eeprom.h
5,17 → 5,13
#include "twimaster.h"
 
#define EEPARAM_REVISION 96 // is count up, if paramater stucture has changed (compatibility)
#define EEMIXER_REVISION 1 // is count up, if mixer stucture has changed (compatibility)
 
#define EEPROM_ADR_PARAM_BEGIN 0
#define EE_DUMMY 0 // Byte
#define PID_EE_REVISION 1 // byte
#define PID_ACTIVE_SET 2 // byte
#define EE_DUMMY2 2 // Byte
#define PID_PRESSURE_OFFSET 3 // byte
 
#define PID_ACC_NICK 4 // word
#define PID_ACC_ROLL 6 // word
#define PID_ACC_TOP 8 // word
 
#define PID_FLIGHT_MINUTES_TOTAL 10 // word
#define PID_FLIGHT_MINUTES 14 // word
23,256 → 19,9
#define PID_SPEAK_HOTT_CFG 16 // Byte
#define PID_HARDWARE_VERSION 17 // Byte
 
#define EEPROM_ADR_CHANNELS 80 // 80 - 93, 12 bytes + 1 byte crc
#define EEPROM_ADR_PARAMSET 100 // 100 - 725, 5 * 125 bytes
#define EEPROM_ADR_MIXERTABLE 1000 // 1000 - 1078, 78 bytes
#define EEPROM_ADR_BLCONFIG 1200 // 1200 - 1296, 12 * 8 bytes
 
#define MIX_GAS 0
#define MIX_NICK 1
#define MIX_ROLL 2
#define MIX_YAW 3
 
typedef struct
{
uint8_t Revision;
int8_t Name[12];
int8_t Motor[16][4];
uint8_t crc;
} __attribute__((packed)) MixerTable_t;
 
extern MixerTable_t Mixer;
extern uint8_t RequiredMotors;
 
//GlobalConfig3
#define CFG3_NO_SDCARD_NO_START 0x01
#define CFG3_DPH_MAX_RADIUS 0x02
#define CFG3_VARIO_FAILSAFE 0x04
#define CFG3_MOTOR_SWITCH_MODE 0x08
#define CFG3_NO_GPSFIX_NO_START 0x10
#define CFG3_USE_NC_FOR_OUT1 0x20
#define CFG3_SPEAK_ALL 0x40
#define CFG3_SERVO_NICK_COMP_OFF 0x80
 
//GlobalConfig
#define CFG_HOEHENREGELUNG 0x01
#define CFG_HOEHEN_SCHALTER 0x02
#define CFG_HEADING_HOLD 0x04
#define CFG_KOMPASS_AKTIV 0x08
#define CFG_KOMPASS_FIX 0x10
#define CFG_GPS_AKTIV 0x20
#define CFG_ACHSENKOPPLUNG_AKTIV 0x40
#define CFG_DREHRATEN_BEGRENZER 0x80
 
//BitConfig
#define CFG_LOOP_OBEN 0x01
#define CFG_LOOP_UNTEN 0x02
#define CFG_LOOP_LINKS 0x04
#define CFG_LOOP_RECHTS 0x08
#define CFG_MOTOR_BLINK1 0x10
#define CFG_MOTOR_OFF_LED1 0x20
#define CFG_MOTOR_OFF_LED2 0x40
#define CFG_MOTOR_BLINK2 0x80
 
// ExtraConfig
#define CFG2_HEIGHT_LIMIT 0x01
#define CFG2_VARIO_BEEP 0x02
#define CFG_SENSITIVE_RC 0x04
#define CFG_3_3V_REFERENCE 0x08
#define CFG_NO_RCOFF_BEEPING 0x10
#define CFG_GPS_AID 0x20
#define CFG_LEARNABLE_CAREFREE 0x40
#define CFG_IGNORE_MAG_ERR_AT_STARTUP 0x80
 
// bit mask for ParamSet.Config0
#define CFG0_AIRPRESS_SENSOR 0x01
#define CFG0_HEIGHT_SWITCH 0x02
#define CFG0_HEADING_HOLD 0x04
#define CFG0_COMPASS_ACTIVE 0x08
#define CFG0_COMPASS_FIX 0x10
#define CFG0_GPS_ACTIVE 0x20
#define CFG0_AXIS_COUPLING_ACTIVE 0x40
#define CFG0_ROTARY_RATE_LIMITER 0x80
 
// bitcoding for EE_Parameter.ServoCompInvert
#define SERVO_NICK_INV 0x01
#define SERVO_ROLL_INV 0x02
#define SERVO_RELATIVE 0x04 // direct poti control or relative moving of the servo value
 
// defines for the receiver selection
#define RECEIVER_PPM 0
#define RECEIVER_SPEKTRUM 1
#define RECEIVER_SPEKTRUM_HI_RES 2
#define RECEIVER_SPEKTRUM_LOW_RES 3
#define RECEIVER_JETI 4
#define RECEIVER_ACT_DSL 5
#define RECEIVER_HOTT 6
#define RECEIVER_SBUS 7
#define RECEIVER_USER 8
 
#define RECEIVER_UNKNOWN 0xFF
 
// defines for lookup ParamSet.ChannelAssignment
#define K_NICK 0
#define K_ROLL 1
#define K_GAS 2
#define K_GIER 3
#define K_POTI1 4
#define K_POTI2 5
#define K_POTI3 6
#define K_POTI4 7
#define K_POTI5 8
#define K_POTI6 9
#define K_POTI7 10
#define K_POTI8 11
 
 
// values above 247 representing poti1 to poti8
// poti1 = 255
// poti2 = 254
// poti3 = 253
// poti4 = 252
// poti5 = 251
// poti6 = 250
// poti7 = 249
// poti8 = 248
 
 
typedef struct
{
unsigned char Revision;
unsigned char Kanalbelegung[12]; // GAS[0], GIER[1],NICK[2], ROLL[3], POTI1, POTI2, POTI3
unsigned char GlobalConfig; // 0x01=Höhenregler aktiv,0x02=Kompass aktiv, 0x04=GPS aktiv, 0x08=Heading Hold aktiv
unsigned char Hoehe_MinGas; // Wert : 0-100
unsigned char Luftdruck_D; // Wert : 0-250
unsigned char HoeheChannel; // Wert : 0-32
unsigned char Hoehe_P; // Wert : 0-32
unsigned char Hoehe_Verstaerkung; // Wert : 0-50
unsigned char Hoehe_ACC_Wirkung; // Wert : 0-250
unsigned char Hoehe_HoverBand; // Wert : 0-250
unsigned char Hoehe_GPS_Z; // Wert : 0-250
unsigned char Hoehe_StickNeutralPoint;// Wert : 0-250
unsigned char Stick_P; // Wert : 1-6
unsigned char Stick_D; // Wert : 0-64
unsigned char StickGier_P; // Wert : 1-20
unsigned char Gas_Min; // Wert : 0-32
unsigned char Gas_Max; // Wert : 33-250
unsigned char GyroAccFaktor; // Wert : 1-64
unsigned char KompassWirkung; // Wert : 0-32
unsigned char Gyro_P; // Wert : 10-250
unsigned char Gyro_I; // Wert : 0-250
unsigned char Gyro_D; // Wert : 0-250
unsigned char Gyro_Gier_P; // Wert : 10-250
unsigned char Gyro_Gier_I; // Wert : 0-250
unsigned char Gyro_Stability; // Wert : 0-16
unsigned char UnterspannungsWarnung; // Wert : 0-250
unsigned char NotGas; // Wert : 0-250 //Gaswert bei Empängsverlust
unsigned char NotGasZeit; // Wert : 0-250 // Zeitbis auf NotGas geschaltet wird, wg. Rx-Problemen
unsigned char Receiver; // 0= Summensignal, 1= Spektrum, 2 =Jeti, 3=ACT DSL, 4=ACT S3D
unsigned char I_Faktor; // Wert : 0-250
unsigned char UserParam1; // Wert : 0-250
unsigned char UserParam2; // Wert : 0-250
unsigned char UserParam3; // Wert : 0-250
unsigned char UserParam4; // Wert : 0-250
unsigned char ServoNickControl; // Wert : 0-250 // Stellung des Servos
unsigned char ServoNickComp; // Wert : 0-250 // Einfluss Gyro/Servo
unsigned char ServoNickMin; // Wert : 0-250 // Anschlag
unsigned char ServoNickMax; // Wert : 0-250 // Anschlag
//--- Seit V0.75
unsigned char ServoRollControl; // Wert : 0-250 // Stellung des Servos
unsigned char ServoRollComp; // Wert : 0-250
unsigned char ServoRollMin; // Wert : 0-250
unsigned char ServoRollMax; // Wert : 0-250
//---
unsigned char ServoNickRefresh; // Speed of the Servo
unsigned char ServoManualControlSpeed;//
unsigned char CamOrientation; //
unsigned char Servo3; // Value or mapping of the Servo Output
unsigned char Servo4; // Value or mapping of the Servo Output
unsigned char Servo5; // Value or mapping of the Servo Output
unsigned char LoopGasLimit; // Wert: 0-250 max. Gas während Looping
unsigned char LoopThreshold; // Wert: 0-250 Schwelle für Stickausschlag
unsigned char LoopHysterese; // Wert: 0-250 Hysterese für Stickausschlag
unsigned char AchsKopplung1; // Wert: 0-250 Faktor, mit dem Gier die Achsen Roll und Nick koppelt (NickRollMitkopplung)
unsigned char AchsKopplung2; // Wert: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden
unsigned char CouplingYawCorrection; // Wert: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden
unsigned char WinkelUmschlagNick; // Wert: 0-250 180°-Punkt
unsigned char WinkelUmschlagRoll; // Wert: 0-250 180°-Punkt
unsigned char GyroAccAbgleich; // 1/k (Koppel_ACC_Wirkung)
unsigned char Driftkomp;
unsigned char DynamicStability;
unsigned char UserParam5; // Wert : 0-250
unsigned char UserParam6; // Wert : 0-250
unsigned char UserParam7; // Wert : 0-250
unsigned char UserParam8; // Wert : 0-250
//---Output ---------------------------------------------
unsigned char J16Bitmask; // for the J16 Output
unsigned char J16Timing; // for the J16 Output
unsigned char J17Bitmask; // for the J17 Output
unsigned char J17Timing; // for the J17 Output
// seit version V0.75c
unsigned char WARN_J16_Bitmask; // for the J16 Output
unsigned char WARN_J17_Bitmask; // for the J17 Output
//---NaviCtrl---------------------------------------------
unsigned char NaviOut1Parameter; // for the J16 Output
unsigned char NaviGpsModeChannel; // Parameters for the Naviboard
unsigned char NaviGpsGain;
unsigned char NaviGpsP;
unsigned char NaviGpsI;
unsigned char NaviGpsD;
unsigned char NaviGpsPLimit;
unsigned char NaviGpsILimit;
unsigned char NaviGpsDLimit;
unsigned char NaviGpsA;
unsigned char NaviGpsMinSat;
unsigned char NaviStickThreshold;
unsigned char NaviWindCorrection;
unsigned char NaviAccCompensation; // New since 0.86 -> was: SpeedCompensation
unsigned char NaviOperatingRadius;
unsigned char NaviAngleLimitation;
unsigned char NaviPH_LoginTime;
//---Ext.Ctrl---------------------------------------------
unsigned char ExternalControl; // for serial Control
//---CareFree---------------------------------------------
unsigned char OrientationAngle; // Where is the front-direction?
unsigned char CareFreeChannel; // switch for CareFree
unsigned char MotorSafetySwitch;
unsigned char MotorSmooth;
unsigned char ComingHomeAltitude;
unsigned char FailSafeTime;
unsigned char MaxAltitude;
unsigned char FailsafeChannel; // if the value of this channel is > 100, the MK reports "RC-Lost"
unsigned char ServoFilterNick;
unsigned char ServoFilterRoll;
unsigned char StartLandChannel;
unsigned char LandingSpeed;
//------------------------------------------------
unsigned char BitConfig; // (war Loop-Cfg) Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts / wird getrennt behandelt
unsigned char ServoCompInvert; // // 0x01 = Nick, 0x02 = Roll, 0x04 = relative moving // WICHTIG!!! am Ende lassen
unsigned char ExtraConfig; // bitcodiert
unsigned char GlobalConfig3; // bitcodiert
char Name[12];
unsigned char crc; // must be the last byte!
} paramset_t; // 127 bytes
 
#define PARAMSET_STRUCT_LEN sizeof(paramset_t)
 
extern paramset_t EE_Parameter;
 
extern uint8_t RAM_Checksum(uint8_t* pBuffer, uint16_t len);
 
extern void ParamSet_Init(void);
extern void SetDefaultParameter(uint8_t set, uint8_t restore_channels);
 
extern uint8_t ParamSet_ReadFromEEProm(uint8_t setnumber);
extern uint8_t ParamSet_WriteToEEProm(uint8_t setnumber);
 
extern uint8_t GetActiveParamSet(void);
extern void SetActiveParamSet(uint8_t setnumber);
 
extern uint8_t MixerTable_ReadFromEEProm(void);
extern uint8_t MixerTable_WriteToEEProm(void);
 
extern uint8_t GetParamByte(uint16_t param_id);
extern void SetParamByte(uint16_t param_id, uint8_t value);
extern uint16_t GetParamWord(uint16_t param_id);
/I2C_Telemetry/trunk/fat16.c
1495,7 → 1495,6
signed char *subpath = 0;
unsigned char af, am, file_created = 0;
signed char dirname[12];
signed char txt[60];
unsigned char i=0;
 
// if incomming pointers are useless return immediatly
1540,7 → 1539,6
}
else if(*subpath == 0) file_created = 1; // last element of path chain was created
}
sprintf(txt+i, "s:%06d",file->FirstSectorOfFirstCluster);
i+=8;
}
else // error seperating the subpath
1597,10 → 1595,8
file->Mode = mode; // mode of fileoperation (read,write)
file->Attribute = 0; // the attribute of the file opened.
 
printf("\r\nFilename: %s", filename);
// bring the path into the correct syntax
Slashing_Path(filename);
printf("\r\nFilename: %s", filename);
 
cptr = filename;
 
/I2C_Telemetry/trunk/fc.c
7,7 → 7,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18,7 → 18,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
32,7 → 32,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
62,103 → 62,33
 
unsigned char h,m,s;
unsigned int BaroExpandActive = 0;
unsigned char ControlHeading = 0;// in 2°
long SummeNick=0,SummeRoll=0;
volatile long Mess_Integral_Hoch = 0;
//int KompassRichtung = 0;
unsigned char MAX_GAS,MIN_GAS;
unsigned char HoehenReglerAktiv = 0;
 
 
int StickNick = 0,StickRoll = 0,StickGier = 0,StickGas = 0;
//int Poti1 = 0, Poti2 = 0, Poti3 = 0, Poti4 = 0, Poti5 = 0, Poti6 = 0, Poti7 = 0, Poti8 = 0;
unsigned char Poti[9] = {0,0,0,0,0,0,0,0};
volatile unsigned char SenderOkay = 0;
char MotorenEin = 0,StartTrigger = 0;
char MotorenEin = 0, StartTrigger = 0;
long HoehenWert = 0;
long SollHoehe = 0;
signed int AltitudeSetpointTrimming = 0;
long FromNC_AltitudeSetpoint = 0;
unsigned char CalibrationDone = 0;
int HoverGas = 0;
//float Ki = FAKTOR_I;
int Ki = 10300 / 33;
 
unsigned char Parameter_Luftdruck_D = 48; // Wert : 0-250
unsigned char Parameter_HoehenSchalter = 0; // Wert : 0-250
unsigned char Parameter_Hoehe_P = 16; // Wert : 0-32
unsigned char Parameter_Hoehe_ACC_Wirkung = 58; // Wert : 0-250
unsigned char Parameter_KompassWirkung = 64; // Wert : 0-250
unsigned char Parameter_Hoehe_GPS_Z = 64; // Wert : 0-250
unsigned char Parameter_Gyro_D = 8; // Wert : 0-250
unsigned char Parameter_Gyro_P = 150; // Wert : 10-250
unsigned char Parameter_Gyro_I = 150; // Wert : 0-250
unsigned char Parameter_Gyro_Gier_P = 150; // Wert : 10-250
unsigned char Parameter_Gyro_Gier_I = 150; // Wert : 10-250
unsigned char Parameter_Gier_P = 2; // Wert : 1-20
unsigned char Parameter_I_Faktor = 10; // Wert : 1-20
unsigned char Parameter_UserParam1 = 0;
unsigned char Parameter_UserParam2 = 0;
unsigned char Parameter_UserParam3 = 0;
unsigned char Parameter_UserParam4 = 0;
unsigned char Parameter_UserParam5 = 0;
unsigned char Parameter_UserParam6 = 0;
unsigned char Parameter_UserParam7 = 0;
unsigned char Parameter_UserParam8 = 0;
unsigned char Parameter_NickControl = 100;
unsigned char Parameter_ServoNickControl = 100;
unsigned char Parameter_ServoRollControl = 100;
unsigned char Parameter_ServoNickComp = 50;
unsigned char Parameter_ServoRollComp = 85;
unsigned char Parameter_LoopGasLimit = 70;
unsigned char Parameter_AchsKopplung1 = 90;
unsigned char Parameter_AchsKopplung2 = 65;
unsigned char Parameter_CouplingYawCorrection = 64;
//unsigned char Parameter_AchsGegenKopplung1 = 0;
unsigned char Parameter_DynamicStability = 100;
unsigned char Parameter_J16Bitmask; // for the J16 Output
unsigned char Parameter_J16Timing; // for the J16 Output
unsigned char Parameter_J17Bitmask; // for the J17 Output
unsigned char Parameter_J17Timing; // for the J17 Output
unsigned char Parameter_NaviGpsGain;
unsigned char Parameter_NaviGpsP;
unsigned char Parameter_NaviGpsI;
unsigned char Parameter_NaviGpsD;
unsigned char Parameter_NaviGpsA;
unsigned char Parameter_NaviOperatingRadius;
unsigned char Parameter_NaviWindCorrection;
unsigned char Parameter_NaviSpeedCompensation;
unsigned char Parameter_ExternalControl;
unsigned char Parameter_GlobalConfig;
unsigned char Parameter_ExtraConfig;
unsigned char Parameter_MaximumAltitude;
unsigned char Parameter_Servo3,Parameter_Servo4,Parameter_Servo5;
unsigned char CareFree = 0;
const signed char sintab[31] = { 0, 2, 4, 6, 7, 8, 8, 8, 7, 6, 4, 2, 0, -2, -4, -6, -7, -8, -8, -8, -7, -6, -4, -2, 0, 2, 4, 6, 7, 8, 8}; // 15° steps
 
signed int ExternStickNick = 0,ExternStickRoll = 0,ExternStickGier = 0, ExternHoehenValue = -20;
int MaxStickNick = 0,MaxStickRoll = 0;
unsigned int modell_fliegt = 0;
volatile unsigned char FC_StatusFlags = 0, FC_StatusFlags2 = 0;
signed int tmp_motorwert[MAX_MOTORS];
char VarioCharacter = ' ';
unsigned int HooverGasEmergencyPercent = 0; // The gas value for Emergency landing
unsigned int GasIsZeroCnt = 0; // to detect that the gas-stick is down for a while
signed int Variance = 0;
signed int CosAttitude; // for projection of hoover gas
unsigned char ACC_AltitudeControl = 0;
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
#define OPA_OFFSET_STEP 5
#else
#define OPA_OFFSET_STEP 10
#endif
 
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Debugwerte zuordnen
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void CopyDebugValues(void)
{
DebugOut.Analog[5] = HoehenWert/10;
DebugOut.Analog[9] = UBat;
DebugOut.Analog[0] = MessLuftdruck;
DebugOut.Analog[5] = HoehenWert;
DebugOut.Analog[9] = U_Bat;
DebugOut.Analog[10] = SenderOkay;
DebugOut.Analog[12] = Motor[0].SetPoint;
DebugOut.Analog[13] = Motor[1].SetPoint;
165,20 → 95,14
DebugOut.Analog[14] = Motor[2].SetPoint;
DebugOut.Analog[15] = Motor[3].SetPoint;
DebugOut.Analog[20] = ServoNickValue;
DebugOut.Analog[21] = HoverGas;
DebugOut.Analog[22] = Capacity.ActualCurrent;
DebugOut.Analog[23] = Capacity.UsedCapacity;
DebugOut.Analog[24] = SollHoehe/10;
DebugOut.Analog[29] = Capacity.MinOfMaxPWM;
if(VersionInfo.HardwareError[0] || VersionInfo.HardwareError[1]) DebugOut.Status[1] |= 1; else DebugOut.Status[1] &= 0xfe;
//DebugOut.Analog[16] = MinBlTemperture;
//DebugOut.Analog[17] = MaxBlTemperture;
//DebugOut.Analog[16] = Variance;
//DebugOut.Analog[17] = VarioMeter;
//DebugOut.Analog[16] = GasIsZeroCnt;
//DebugOut.Analog[18] = HoehenWertF;
//DebugOut.Analog[25] = Parameter_Hoehe_P;
//DebugOut.Analog[26] = Parameter_Luftdruck_D;
if(UART_VersionInfo.HardwareError[0] || UART_VersionInfo.HardwareError[1]) DebugOut.Status[1] |= 1; else DebugOut.Status[1] &= 0xfe;
//DebugOut.Analog[16] = MinBlTemperture;
//DebugOut.Analog[17] = MaxBlTemperture;
//DebugOut.Analog[16] = Variance;
//DebugOut.Analog[17] = VarioMeter;
}
 
 
187,13 → 111,6
 
}
 
//############################################################################
// Messwerte beim Ermitteln der Nullage
void CalibrierMittelwert(void)
//############################################################################
{
}
 
//############################################################################
// Nullwerte ermitteln
203,72 → 120,42
unsigned char SetNeutral(unsigned char AdjustmentMode) // retuns: "sucess"
//############################################################################
{
unsigned char i, sucess = 1;
unsigned char sucess = 1;
unsigned int barotest;
VersionInfo.HardwareError[0] = 0;
// HEF4017Reset_ON;
 
ExpandBaro = 0;
UART_VersionInfo.HardwareError[0] = 0;
ExpandBaro = 0;
 
 
 
 
if((MessLuftdruck > 950) || (MessLuftdruck < 750) || ExpandBaro) SucheLuftruckOffset();
barotest = MessLuftdruck;
#define NEUTRAL_FILTER 32
#define NEUTRAL_FILTER 32
OCR0A += OPA_OFFSET_STEP;
OCR0B = 255 - OCR0A;
 
if(MessLuftdruck < 1010 && MessLuftdruck > 20) BaroStep = barotest - MessLuftdruck;
 
OCR0A -= OPA_OFFSET_STEP;
OCR0B = 255 - OCR0A;
 
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space
beeptime = 50;
ExternHoehenValue = 0;
 
LED_Init();
FC_StatusFlags |= FC_STATUS_CALIBRATE;
for(i=0;i<8;i++)
{
Poti[i] = PPM_in[EE_Parameter.Kanalbelegung[K_POTI1 + i]] + 127;
}
 
SenderOkay = 100;
 
/* if(ServoActive) DDRD |=0x80; // enable J7 -> Servo signal
else
{
if((EE_Parameter.ServoCompInvert & SERVO_NICK_INV) && (EE_Parameter.ServoCompInvert & SERVO_RELATIVE)) NickServoValue = 12000;//((128 + 60) * 4 * 16); // neutral position = upper 1/4// else
else NickServoValue = ((128 - 60) * 4 * 16); // neutral position = lower 1/4
CalculateServoSignals = 1;
CalculateServo(); // nick
CalculateServo(); // roll
}
*/
if(UART_VersionInfo.HardwareError[0]) sucess = 0;
 
if(VersionInfo.HardwareError[0]) sucess = 0;
LIBTEL_HoTT_Clear();
 
 
StartLuftdruck = Luftdruck;
VarioMeter = 0;
SummenHoehe = 0; Mess_Integral_Hoch = 0;
SummenHoehe = 0;
DebugOut.Analog[28] = 0; // I2C-Counter
CalcExpandBaroStep();
return(sucess);
return(sucess);
}
 
 
277,7 → 164,8
void Mittelwert(void)
//############################################################################
{
 
ANALOG_ON;
AdReady = 0;
}
 
//############################################################################
285,365 → 173,153
void SendMotorData(void)
//############################################################################
{
unsigned char i;
unsigned char i;
if(!MotorenEin)
{
FC_StatusFlags &= ~(FC_STATUS_MOTOR_RUN | FC_STATUS_FLY);
FC_StatusFlags2 &= ~FC_STATUS2_WAIT_FOR_TAKEOFF;
for(i=0;i<MAX_MOTORS;i++)
{
if(!PC_MotortestActive) MotorTest[i] = 0;
{
FC_StatusFlags &= ~(FC_STATUS_MOTOR_RUN | FC_STATUS_FLY);
FC_StatusFlags2 &= ~FC_STATUS2_WAIT_FOR_TAKEOFF;
for(i=0;i<MAX_MOTORS;i++)
{
if(!MotorTest_Active) MotorTest[i] = 0;
Motor[i].SetPoint = MotorTest[i];
Motor[i].SetPointLowerBits = 0;
}
if(PC_MotortestActive) PC_MotortestActive--;
}
}
if(MotorTest_Active) MotorTest_Active--;
}
else FC_StatusFlags |= FC_STATUS_MOTOR_RUN;
 
if(I2C_TransferActive)
{
I2C_TransferActive = 0; // enable for the next time
}
if(I2C_TransferActive)
{
I2C_TransferActive = 0; // enable for the next time
}
else
{
motor_write = 0;
I2C_Start(TWI_STATE_MOTOR_TX); //Start I2C Interrupt Mode
motor_write = 0;
I2C_Start(TWI_STATE_MOTOR_TX); //Start I2C Interrupt Mode
}
 
}
 
unsigned char GetChannelValue(unsigned char ch) // gives the unsigned value of the channel
{
int tmp2;
if(ch == 0) return(0);
tmp2 = PPM_in[ch] + 127;
if(tmp2 > 255) tmp2 = 255; else if(tmp2 < 0) tmp2 = 0;
return(tmp2);
int tmp2;
if(ch == 0) return(0);
tmp2 = PPM_in[ch] + 127;
if(tmp2 > 255) tmp2 = 255; else if(tmp2 < 0) tmp2 = 0;
return(tmp2);
}
 
//############################################################################
// Trägt ggf. das Poti als Parameter ein
void ParameterZuordnung(void)
//############################################################################
{
unsigned char tmp,i;
for(i=0;i<8;i++)
{
int tmp2;
tmp = EE_Parameter.Kanalbelegung[K_POTI1 + i];
tmp2 = PPM_in[tmp] + 127;
if(tmp2 > 255) tmp2 = 255; else if(tmp2 < 0) tmp2 = 0;
 
if(tmp == 25) Poti[i] = tmp2; // 25 = WaypointEvent channel -> no filter
else
if(tmp2 != Poti[i])
{
Poti[i] += (tmp2 - Poti[i]) / 4;
if(Poti[i] > tmp2) Poti[i]--;
else Poti[i]++;
}
}
CHK_POTI_MM(Parameter_Luftdruck_D,EE_Parameter.Luftdruck_D,0,100);
CHK_POTI_MM(Parameter_Hoehe_P,EE_Parameter.Hoehe_P,0,100);
CHK_POTI_MM(Parameter_Gyro_P,EE_Parameter.Gyro_P,10,255);
CHK_POTI_MM(Parameter_J16Timing,EE_Parameter.J16Timing,5,255);
CHK_POTI_MM(Parameter_J17Timing,EE_Parameter.J17Timing,5,255);
 
if(EE_Parameter.Servo3 == 247) { if(PORTC & (1<<PORTC2)) Parameter_Servo3 = 140; else Parameter_Servo3 = 70;} // Out1 (J16)
else if(EE_Parameter.Servo3 == 246) { if(PORTC & (1<<PORTC3)) Parameter_Servo3 = 140; else Parameter_Servo3 = 70;}
else CHK_POTI_MM(Parameter_Servo3,EE_Parameter.Servo3, 24, 255);
 
if(EE_Parameter.Servo4 == 247) { if(PORTC & (1<<PORTC2)) Parameter_Servo4 = 140; else Parameter_Servo4 = 70;}
else if(EE_Parameter.Servo4 == 246) { if(PORTC & (1<<PORTC3)) Parameter_Servo4 = 140; else Parameter_Servo4 = 70;} // Out2 (J17)
else CHK_POTI_MM(Parameter_Servo4,EE_Parameter.Servo4, 24, 255);
 
CHK_POTI_MM(Parameter_Servo5,EE_Parameter.Servo5, 24, 255);
Parameter_HoehenSchalter = GetChannelValue(EE_Parameter.HoeheChannel);
CHK_POTI(Parameter_Hoehe_ACC_Wirkung,EE_Parameter.Hoehe_ACC_Wirkung);
CHK_POTI(Parameter_Hoehe_GPS_Z,EE_Parameter.Hoehe_GPS_Z);
CHK_POTI(Parameter_KompassWirkung,EE_Parameter.KompassWirkung);
CHK_POTI(Parameter_Gyro_I,EE_Parameter.Gyro_I);
CHK_POTI(Parameter_Gyro_D,EE_Parameter.Gyro_D);
CHK_POTI(Parameter_Gyro_Gier_P,EE_Parameter.Gyro_Gier_P);
CHK_POTI(Parameter_Gyro_Gier_I,EE_Parameter.Gyro_Gier_I);
CHK_POTI(Parameter_I_Faktor,EE_Parameter.I_Faktor);
CHK_POTI(Parameter_UserParam1,EE_Parameter.UserParam1);
CHK_POTI(Parameter_UserParam2,EE_Parameter.UserParam2);
CHK_POTI(Parameter_UserParam3,EE_Parameter.UserParam3);
CHK_POTI(Parameter_UserParam4,EE_Parameter.UserParam4);
CHK_POTI(Parameter_UserParam5,EE_Parameter.UserParam5);
CHK_POTI(Parameter_UserParam6,EE_Parameter.UserParam6);
CHK_POTI(Parameter_UserParam7,EE_Parameter.UserParam7);
CHK_POTI(Parameter_UserParam8,EE_Parameter.UserParam8);
CHK_POTI(Parameter_ServoNickControl,EE_Parameter.ServoNickControl);
CHK_POTI(Parameter_ServoRollControl,EE_Parameter.ServoRollControl);
CHK_POTI(Parameter_ServoNickComp,EE_Parameter.ServoNickComp);
CHK_POTI(Parameter_ServoRollComp,EE_Parameter.ServoRollComp);
CHK_POTI(Parameter_LoopGasLimit,EE_Parameter.LoopGasLimit);
CHK_POTI(Parameter_AchsKopplung1,EE_Parameter.AchsKopplung1);
CHK_POTI(Parameter_AchsKopplung2,EE_Parameter.AchsKopplung2);
CHK_POTI(Parameter_CouplingYawCorrection,EE_Parameter.CouplingYawCorrection);
CHK_POTI(Parameter_MaximumAltitude,EE_Parameter.MaxAltitude);
Parameter_GlobalConfig = EE_Parameter.GlobalConfig;
Parameter_ExtraConfig = EE_Parameter.ExtraConfig;
// CHK_POTI(Parameter_AchsGegenKopplung1,EE_Parameter.AchsGegenKopplung1,0,255);
CHK_POTI(Parameter_DynamicStability,EE_Parameter.DynamicStability);
CHK_POTI(Parameter_ExternalControl,EE_Parameter.ExternalControl);
 
 
 
}
 
//############################################################################
//
void MotorRegler(void)
//############################################################################
{
static unsigned int RcLostTimer;
 
int GasMischanteil;
static unsigned int RcLostTimer;
Mittelwert();
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Empfang schlecht
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(SenderOkay < 100 && !(FC_StatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE))
{
if(RcLostTimer) RcLostTimer--;
else
{
MotorenEin = 0;
modell_fliegt = 0;
FC_StatusFlags &= ~(FC_STATUS_EMERGENCY_LANDING | FC_STATUS_FLY);
}
ROT_ON;
if(modell_fliegt > 1000 && Capacity.MinOfMaxPWM > 100) // wahrscheinlich in der Luft --> langsam absenken
{
GasMischanteil = HooverGasEmergencyPercent;
FC_StatusFlags |= FC_STATUS_EMERGENCY_LANDING;
PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] = 0;
PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] = 0;
PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] = 0;
PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] = 0;
PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] = 0;
}
else
{
MotorenEin = 0;
}
}
else
if(SenderOkay < 100 && !(FC_StatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE))
{
if(RcLostTimer) RcLostTimer--;
RED_ON;
}
else
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Emfang gut
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(SenderOkay > 140)
{
if(SenderOkay > 140)
{
 
 
static unsigned char old_switch = 100;
}
else // Empfang zwischen 100 und 140 -> schlecht
{
 
FC_StatusFlags &= ~FC_STATUS_EMERGENCY_LANDING;
RcLostTimer = EE_Parameter.NotGasZeit * 50;
if(GasMischanteil > 40 && MotorenEin)
{
if(modell_fliegt < 0xffff) modell_fliegt++;
}
if((modell_fliegt < 256))
{
FC_StatusFlags2 |= FC_STATUS2_WAIT_FOR_TAKEOFF;
 
old_switch = 100;
 
}
else
{
FC_StatusFlags |= FC_STATUS_FLY;
} // end of: modell_fliegt > 256
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gas ist unten
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
else // Empfang zwischen 100 und 140 -> schlecht
{
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// neue Werte von der Funke
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
if(!NewPpmData-- || (FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING))
{
static int stick_nick,stick_roll;
unsigned char stick_p;
ParameterZuordnung();
stick_p = EE_Parameter.Stick_P;
stick_nick = (stick_nick * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] * stick_p) / 4;
stick_nick += PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] * EE_Parameter.Stick_D;
stick_roll = (stick_roll * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] * stick_p) / 4;
stick_roll += PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] * EE_Parameter.Stick_D;
if(!NewPpmData-- || (FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING))
{
static int stick_nick, stick_roll;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// CareFree und freie Wahl der vorderen Richtung
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
stick_nick = (stick_nick * 3 + PPM_in[1]) / 4;
stick_roll = (stick_roll * 3 + PPM_in[2]) / 4;
 
 
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ Analoge Steuerung per Seriell
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Bei Empfangsausfall im Flug
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(FC_StatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE)
{
Parameter_GlobalConfig &= ~(CFG_HEADING_HOLD | CFG_DREHRATEN_BEGRENZER);
Parameter_GlobalConfig |= CFG_HOEHENREGELUNG | CFG_ACHSENKOPPLUNG_AKTIV | CFG_KOMPASS_AKTIV | CFG_GPS_AKTIV | CFG_HOEHEN_SCHALTER | CFG_GPS_AKTIV;
Parameter_ExtraConfig &= ~(CFG2_HEIGHT_LIMIT | CFG_LEARNABLE_CAREFREE | CFG2_VARIO_BEEP);
Parameter_HoehenSchalter = 200; // switch on
}
else
if(FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING)
{
StickGier = 0;
StickNick = 0;
StickRoll = 0;
 
}
 
 
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Höhenregelung
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(UBat > BattLowVoltageWarning) GasMischanteil = ((unsigned int)GasMischanteil * BattLowVoltageWarning) / UBat; // Gas auf das aktuelle Spannungvieveau beziehen
GasMischanteil *= STICK_GAIN;
// if height control is activated
if((Parameter_GlobalConfig & CFG_HOEHENREGELUNG) && !(VersionInfo.HardwareError[0] & 0x7F)) // Höhenregelung
{
#define HOVER_GAS_AVERAGE 16384L // 16384 * 2ms = 32s averaging
#define HC_GAS_AVERAGE 4 // 4 * 2ms= 8ms averaging
 
static unsigned char BaroAtUpperLimit = 0, BaroAtLowerLimit = 0;
// Expand the measurement
// measurement of air pressure close to upper limit and no overflow in correction of the new OCR0A value occurs
if(!BaroExpandActive)
{
if(MessLuftdruck > 920)
{ // increase offset
if(OCR0A < (255 - OPA_OFFSET_STEP))
{
ExpandBaro -= 1;
OCR0A = DruckOffsetSetting - OPA_OFFSET_STEP * ExpandBaro; // increase offset to shift ADC down
OCR0B = 255 - OCR0A;
beeptime = 300;
BaroExpandActive = 350;
CalcExpandBaroStep();
}
else
{
BaroAtLowerLimit = 1;
}
// if height control is activated
if(!(UART_VersionInfo.HardwareError[0] & 0x7F)) // Höhenregelung
{
static unsigned char BaroAtUpperLimit = 0, BaroAtLowerLimit = 0;
// Expand the measurement
// measurement of air pressure close to upper limit and no overflow in correction of the new OCR0A value occurs
if(!BaroExpandActive)
{
if(MessLuftdruck > 920)
{ // increase offset
if(OCR0A < (255 - OPA_OFFSET_STEP))
{
ExpandBaro -= 1;
OCR0A = DruckOffsetSetting - OPA_OFFSET_STEP * ExpandBaro; // increase offset to shift ADC down
OCR0B = 255 - OCR0A;
beeptime = 300;
BaroExpandActive = 350;
CalcExpandBaroStep();
}
else
{
BaroAtLowerLimit = 1;
}
}
// measurement of air pressure close to lower limit and
else
if(MessLuftdruck < 100)
{ // decrease offset
if(OCR0A > OPA_OFFSET_STEP)
{
ExpandBaro += 1;
OCR0A = DruckOffsetSetting - OPA_OFFSET_STEP * ExpandBaro; // decrease offset to shift ADC up
OCR0B = 255 - OCR0A;
beeptime = 300;
BaroExpandActive = 350;
CalcExpandBaroStep();
}
else
{
BaroAtUpperLimit = 1;
}
}
else
{
BaroAtUpperLimit = 0;
BaroAtLowerLimit = 0;
}
}
// measurement of air pressure close to lower limit and
else
if(MessLuftdruck < 100)
{ // decrease offset
if(OCR0A > OPA_OFFSET_STEP)
{
ExpandBaro += 1;
OCR0A = DruckOffsetSetting - OPA_OFFSET_STEP * ExpandBaro; // decrease offset to shift ADC up
OCR0B = 255 - OCR0A;
beeptime = 300;
BaroExpandActive = 350;
CalcExpandBaroStep();
}
else
{
BaroAtUpperLimit = 1;
}
}
else
else // delay, because of expanding the Baro-Range
{
BaroAtUpperLimit = 0;
BaroAtLowerLimit = 0;
// now clear the D-values
VarioMeter = 0;
SummenHoehe = HoehenWert * SM_FILTER;
BaroExpandActive--;
}
}
else // delay, because of expanding the Baro-Range
{
// now clear the D-values
VarioMeter = 0;
 
if(ACC_AltitudeControl) ACC_AltitudeFusion(1); // init
else SummenHoehe = HoehenWert * SM_FILTER;
 
 
BaroExpandActive--;
}
VarioCharacter = ' ';
AltitudeSetpointTrimming = 0;
if(BaroExpandActive) SollHoehe = HoehenWertF; // update setpoint to current altitude if Expanding is active
} //if FCFlags & MKFCFLAG_FLY
}
 
 
 
 
 
 
 
VarioCharacter = ' ';
}//if FCFlags & MKFCFLAG_FLY
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// all BL-Ctrl connected?
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(MissingMotor || Capacity.MinOfMaxPWM != 255 ) // wait until all BL-Ctrls started and no Errors
if(modell_fliegt > 1 && modell_fliegt < 50 && GasMischanteil > 0) // only during start-phase
{
modell_fliegt = 1;
GasMischanteil = (MIN_GAS + 10) * STICK_GAIN;
 
if(Capacity.MinOfMaxPWM < 40) SpeakHoTT = SPEAK_ERR_MOTOR;
 
}
 
 
 
 
 
if(MissingMotor || Capacity.MinOfMaxPWM != 255 ) // wait until all BL-Ctrls started and no Errors
if(modell_fliegt > 1 && modell_fliegt < 50) // only during start-phase
{
modell_fliegt = 1;
if(Capacity.MinOfMaxPWM < 40) SpeakHoTT = SPEAK_ERR_MOTOR;
}
}
 
/I2C_Telemetry/trunk/fc.h
1,13 → 1,5
/*#######################################################################################
Flight Control
#######################################################################################*/
 
#ifndef _FC_H
#define _FC_H
//#define GIER_GRAD_FAKTOR 1291L // Abhängigkeit zwischen GyroIntegral und Winkel
//#define GIER_GRAD_FAKTOR 1160L
#define STICK_GAIN 4
#define ACC_AMPLIFY 6
 
// FC_StatusFlags
#define FC_STATUS_MOTOR_RUN 0x01
19,7 → 11,7
#define FC_STATUS_VARIO_TRIM_UP 0x40
#define FC_STATUS_VARIO_TRIM_DOWN 0x80
 
// FC_StatusFlags2
// FC_StatusFlags2
#define FC_STATUS2_CAREFREE 0x01
#define FC_STATUS2_ALTITUDE_CONTROL 0x02
#define FC_STATUS2_RC_FAILSAVE_ACTIVE 0x04
29,15 → 21,7
#define FC_STATUS2_AUTO_STARTING 0x40
#define FC_STATUS2_AUTO_LANDING 0x80
 
//NC_To_FC_Flags
#define NC_TO_FC_FLYING_RANGE 0x01
#define NC_TO_FC_EMERGENCY_LANDING 0x02
#define NC_TO_FC_AUTOSTART 0x04
#define NC_TO_FC_AUTOLANDING 0x08 // not used
 
extern volatile unsigned char FC_StatusFlags, FC_StatusFlags2;
extern void ParameterZuordnung(void);
extern unsigned char GetChannelValue(unsigned char ch); // gives the unsigned value of the channel
 
#define Poti1 Poti[0]
#define Poti2 Poti[1]
61,63 → 45,22
extern unsigned int BaroExpandActive;
extern unsigned char Poti[9];
 
extern volatile long Mess_Integral_Hoch;
extern unsigned char ControlHeading;
extern long HoehenWert;
extern long SollHoehe;
extern unsigned char Parameter_HoehenSchalter; // Wert : 0-250
 
extern unsigned char HoehenReglerAktiv;
extern signed int ExternStickNick,ExternStickRoll,ExternStickGier;
extern unsigned char Parameter_UserParam1,Parameter_UserParam2,Parameter_UserParam3,Parameter_UserParam4,Parameter_UserParam5,Parameter_UserParam6,Parameter_UserParam7,Parameter_UserParam8;
extern unsigned int modell_fliegt;
extern void MotorRegler(void);
extern void SendMotorData(void);
//void CalibrierMittelwert(void);
//void Mittelwert(void);
extern unsigned char SetNeutral(unsigned char AccAdjustment); // retuns: "sucess"
extern void Piep(unsigned char Anzahl, unsigned int dauer);
extern void CopyDebugValues(void);
extern unsigned char ACC_AltitudeControl;
extern signed int CosAttitude; // for projection of hoover gas
 
extern unsigned char h,m,s;
extern int StickNick,StickRoll,StickGier,StickGas;
extern volatile unsigned char Timeout ;
extern unsigned char CosinusNickWinkel, CosinusRollWinkel;
extern int DiffNick,DiffRoll;
//extern int Poti1, Poti2, Poti3, Poti4;
extern volatile unsigned char SenderOkay;
extern int StickNick,StickRoll,StickGier;
extern volatile unsigned char Timeout;
extern char MotorenEin;
extern unsigned char CalibrationDone;
extern unsigned char Parameter_Servo3,Parameter_Servo4,Parameter_Servo5;
 
extern char VarioCharacter;
extern signed int AltitudeSetpointTrimming;
extern signed char WaypointTrimming;
extern int HoverGas;
extern unsigned char Parameter_Luftdruck_D;
//extern unsigned char Parameter_MaxHoehe;
extern unsigned char Parameter_Hoehe_P;
extern unsigned char Parameter_Hoehe_ACC_Wirkung;
extern unsigned char Parameter_KompassWirkung;
extern unsigned char Parameter_Gyro_P;
extern unsigned char Parameter_Gyro_I;
extern unsigned char Parameter_Gier_P;
extern unsigned char Parameter_ServoNickControl;
extern unsigned char Parameter_ServoRollControl;
extern unsigned char Parameter_ServoNickComp;
extern unsigned char Parameter_ServoRollComp;
extern unsigned char Parameter_AchsKopplung1;
extern unsigned char Parameter_AchsKopplung2;
//extern unsigned char Parameter_AchsGegenKopplung1;
extern unsigned char Parameter_J16Bitmask; // for the J16 Output
extern unsigned char Parameter_J16Timing; // for the J16 Output
extern unsigned char Parameter_J17Bitmask; // for the J17 Output
extern unsigned char Parameter_J17Timing; // for the J17 Output
extern unsigned char Parameter_GlobalConfig;
extern unsigned char Parameter_ExtraConfig;
extern signed char MixerTable[MAX_MOTORS][4];
extern const signed char sintab[31];
 
extern unsigned char ErrorCode;
 
/I2C_Telemetry/trunk/ftphelper.c
63,9 → 63,10
#include "ftphelper.h"
#include "debug.h"
#include "uart.h"
#include "mkprotocol.h"
 
 
typedef struct
typedef struct
{
unsigned char Name[13];
unsigned char Attribute;
77,8 → 78,8
char FTP_data[DATA_TRANSFER_SIZE+10]; // rx & tx buffer to avoid 2 buffers
 
#define KEYWORD_COUNT 47
// most used gpx tags can be compressed
const char keyword[KEYWORD_COUNT][16]=
// most used gpx tags can be compressed
const char keyword[KEYWORD_COUNT][16]=
{"Altimeter>\0 \0",
"MotorCurrent>\0 \0",
"Current>\0 \0",
123,7 → 124,7
"MagnetInclinati\0",
"BL_Temperature>\0",
"AvaiableMotorPo\0",
"FC_I2C_ErrorCou\0",
"FC_I2C_ErrorCou\0",
"FC_SPI_ErrorCou\0",
"TargetDistance>\0" };
 
136,20 → 137,20
for ( i = 0; i < KEYWORD_COUNT; i++)
{
s = strstr(start, keyword[i]);
if (s != NULL)
if (s != NULL)
{ unsigned char keylen = strlen(keyword[i]);
*s= 27;
*(s+1) = i+1;
count-= (keylen-2);
memcpy(s+2, s+keylen, count - (s-buf));
*s= 27;
*(s+1) = i+1;
count-= (keylen-2);
memcpy(s+2, s+keylen, count - (s-buf));
i--;
}
}
 
return (count);
}
// --------------------------------------------------------------------
void CheckFTPCommand(unsigned char FTP_command)
void CheckFTPCommand(unsigned char FTP_command, Buffer_t *pBuffer)
{
static Find_t fe;
static File_t *fp = NULL;
157,173 → 158,173
 
unsigned long filesize;
Debug("ftp %x", FTP_command);
 
switch (FTP_command)
{
case FTP_CMD_FINDFIRST:
FTP_direntry.Name[0] = 0;
// any file or directory except volume labels and hidden files
if(findfirst_("*.*", (ATTR_ARCHIVE|ATTR_SUBDIRECTORY|ATTR_SYSTEM|ATTR_READONLY), &fe))
// any file or directory except volume labels and hidden files
if(findfirst_("*.*", (ATTR_ARCHIVE|ATTR_SUBDIRECTORY|ATTR_SYSTEM|ATTR_READONLY), &fe))
{
memcpy(&FTP_direntry.Name, &fe.name, 13);
memcpy(&FTP_direntry.Name, &fe.name, 13);
FTP_direntry.Attribute = fe.fp.Attribute;
FTP_direntry.Size = fe.fp.Size;
}
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &FTP_direntry, sizeof(FTP_direntry));
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &FTP_direntry, sizeof(FTP_direntry));
 
break;
 
case FTP_CMD_FINDNEXT:
FTP_direntry.Name[0] = 0;
if (findnext_(&fe))
{
memcpy(&FTP_direntry.Name, &fe.name, 13);
memcpy(&FTP_direntry.Name, &fe.name, 13);
FTP_direntry.Attribute = fe.fp.Attribute;
FTP_direntry.Size = fe.fp.Size;
}
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &FTP_direntry, sizeof(FTP_direntry));
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &FTP_direntry, sizeof(FTP_direntry));
break;
 
case FTP_CMD_GET_CWD: // get current working directory
{
char data_null = 0;
SendOutData( 'F', NC_ADDRESS, 3, &FTP_command, 1, getcwd_(), strlen(getcwd_()), &data_null, 1 );
char data_null = 0;
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 3, &FTP_command, 1, getcwd_(), strlen(getcwd_()), &data_null, 1 );
}
break;
 
case FTP_CMD_SET_CWD: // set current working directory
{
unsigned char cmd_successful;
cmd_successful = chdir_(FTP_data);
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
unsigned char cmd_successful;
cmd_successful = chdir_(FTP_data);
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
}
break;
 
case FTP_CMD_CDUP: // change dir up
{
unsigned char cmd_successful;
cmd_successful = chdir_("..");
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
unsigned char cmd_successful;
cmd_successful = chdir_("..");
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
}
break;
 
case FTP_CMD_MKDIR: // create directory
case FTP_CMD_MKDIR: // create directory
{
unsigned char cmd_successful;
cmd_successful = mkdir_(&FTP_data[0]);
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
unsigned char cmd_successful;
cmd_successful = mkdir_(&FTP_data[0]);
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
}
break;
case FTP_CMD_RMDIR: // delete directory
 
case FTP_CMD_RMDIR: // delete directory
{
unsigned char cmd_successful;
cmd_successful = rmdir_(&FTP_data[0]);
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
unsigned char cmd_successful;
cmd_successful = rmdir_(&FTP_data[0]);
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
}
break;
 
case FTP_CMD_DELETE_FILE: // delete file
case FTP_CMD_DELETE_FILE: // delete file
{
unsigned char cmd_successful;
cmd_successful = fdelete_(&FTP_data[0]);
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
unsigned char cmd_successful;
cmd_successful = fdelete_(&FTP_data[0]);
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &cmd_successful, 1);
}
break;
 
case FTP_CMD_OPEN_FILE: // open the file for reading
{
unsigned char filefound;
compressLevel = FTP_data[0];
fp = fopen_(&FTP_data[1], 'r');
if (fp != NULL)
{
filefound = 1;
filesize = fp->Size;
blockindex = 0; // reset index counter
unsigned char filefound;
compressLevel = FTP_data[0];
fp = fopen_(&FTP_data[1], 'r');
if (fp != NULL)
{
filefound = 1;
filesize = fp->Size;
blockindex = 0; // reset index counter
}
else filefound = 0; // this means, no valid file found for transfer
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 3, &FTP_command, 1, &filefound, 1, &filesize, sizeof(filesize));
}
else filefound = 0; // this means, no valid file found for transfer
SendOutData( 'F', NC_ADDRESS, 3, &FTP_command, 1, &filefound, 1, &filesize, sizeof(filesize));
}
break;
 
case FTP_CMD_GET_FILE_DATA:
{
unsigned int size = DATA_TRANSFER_SIZE;
if (FTP_data[0] == blockindex + 1) // next block is requested
{
blockindex++;
}
else
{
unsigned long filepos;
blockindex = FTP_data[0];
filepos = FTP_data[1];
filepos |= ((unsigned long)FTP_data[2] * 0x100);
filepos |= ((unsigned long) FTP_data[3] * 0x10000L);
filepos |= ((unsigned long) FTP_data[4] * 0x1000000L);
fseek_(fp, filepos, SEEK_SET); // set filepointer to beginning of requested block
}
fread_(FTP_data, DATA_TRANSFER_SIZE, 1, fp); // read data block to buffer);
FTP_data[DATA_TRANSFER_SIZE] = 0;
if (compressLevel)
{
size = CompressBuffer(FTP_data, DATA_TRANSFER_SIZE, 0);
if (compressLevel > 1)
{
if (size < DATA_TRANSFER_SIZE - 50)
{
fread_(&FTP_data[size], DATA_TRANSFER_SIZE - size, 1, fp); // read data block to buffer);
FTP_data[DATA_TRANSFER_SIZE] = 0;
size = CompressBuffer(FTP_data, DATA_TRANSFER_SIZE, size);
}
unsigned int size = DATA_TRANSFER_SIZE;
if (FTP_data[0] == blockindex + 1) // next block is requested
{
blockindex++;
}
}
SendOutData( 'F', NC_ADDRESS, 4, &FTP_command, 1, &blockindex, 1, &size, 2, &FTP_data, size);
else
{
unsigned long filepos;
blockindex = FTP_data[0];
filepos = FTP_data[1];
filepos |= ((unsigned long)FTP_data[2] * 0x100);
filepos |= ((unsigned long) FTP_data[3] * 0x10000L);
filepos |= ((unsigned long) FTP_data[4] * 0x1000000L);
fseek_(fp, filepos, SEEK_SET); // set filepointer to beginning of requested block
}
 
fread_(FTP_data, DATA_TRANSFER_SIZE, 1, fp); // read data block to buffer);
FTP_data[DATA_TRANSFER_SIZE] = 0;
 
if (compressLevel)
{
size = CompressBuffer(FTP_data, DATA_TRANSFER_SIZE, 0);
 
if (compressLevel > 1)
{
if (size < DATA_TRANSFER_SIZE - 50)
{
fread_(&FTP_data[size], DATA_TRANSFER_SIZE - size, 1, fp); // read data block to buffer);
FTP_data[DATA_TRANSFER_SIZE] = 0;
size = CompressBuffer(FTP_data, DATA_TRANSFER_SIZE, size);
}
}
}
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 4, &FTP_command, 1, &blockindex, 1, &size, 2, &FTP_data, size);
}
break;
 
case FTP_CMD_CLOSE_FILE:
fclose_(fp);
Debug("ftp: CloseFile");
Debug("ftp: CloseFile");
break;
 
case FTP_CMD_CREATE_FILE: // open the file for writing
{
unsigned int size = DATA_TRANSFER_SIZE;
//compressLevel = FTP_data[0];
// FTP_data[1..4] contains filesize in bytes
compressLevel = 0; // no compression for writing
fp = fopen_(&FTP_data[5], 'w');
if (fp != NULL)
{
blockindex = 0; // reset index counter
unsigned int size = DATA_TRANSFER_SIZE;
//compressLevel = FTP_data[0];
// FTP_data[1..4] contains filesize in bytes
compressLevel = 0; // no compression for writing
fp = fopen_(&FTP_data[5], 'w');
if (fp != NULL)
{
blockindex = 0; // reset index counter
}
else size = 0; // this means, no valid file for transfer (maybe readonly)
//if (size == 0) Debug("ftp: create ERR ");
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &size, 2);
}
else size = 0; // this means, no valid file for transfer (maybe readonly)
//if (size == 0) Debug("ftp: create ERR ");
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &size, 2);
}
break;
 
case FTP_CMD_SEND_FILE_DATA:
{
unsigned int size = (unsigned char)FTP_data[2];
size *= 0x100;
size += (unsigned char) FTP_data[1];
// if (FTP_data[0] == blockindex) // next block is requested
{
blockindex++;
fwrite_(&FTP_data[3], size, 1, fp); // write data block to buffer);
}
SendOutData( 'F', NC_ADDRESS, 2, &FTP_command, 1, &blockindex, 1 );
unsigned int size = (unsigned char)FTP_data[2];
size *= 0x100;
size += (unsigned char) FTP_data[1];
// if (FTP_data[0] == blockindex) // next block is requested
{
blockindex++;
fwrite_(&FTP_data[3], size, 1, fp); // write data block to buffer);
}
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 2, &FTP_command, 1, &blockindex, 1 );
}
break;
 
case FTP_CMD_NONE:
default:
default:
FTP_command = FTP_CMD_NONE;
Debug("ftp: CMD None");
break;
330,13 → 331,11
 
case FTP_CMD_GET_KEYWORDS:
{
unsigned char count = KEYWORD_COUNT;
unsigned char count = KEYWORD_COUNT;
 
SendOutData( 'F', NC_ADDRESS, 3, &FTP_command, 1, &count, 1, keyword, sizeof(keyword) );
MKProtocol_CreateSerialFrame(pBuffer, 'F', NC_ADDRESS, 3, &FTP_command, 1, &count, 1, keyword, sizeof(keyword) );
}
break;
 
 
}
}
 
/I2C_Telemetry/trunk/ftphelper.h
1,7 → 1,8
#ifndef _FTPHELPER_H
#define _FTPHELPER_H
 
#include "buffer.h"
 
#define FTP_CMD_ERROR 255 // global ERROR - CMD
#define FTP_ERROR_NONE 0
#define FTP_ERROR_NO_SDCARD 1
29,8 → 30,8
 
#define DATA_TRANSFER_SIZE 750 // size of 1 data block for filetransfer
 
char FTP_data[DATA_TRANSFER_SIZE+10]; // parameter from FTP_CMD_SET_CWD
char FTP_data[DATA_TRANSFER_SIZE+10];// parameter from FTP_CMD_SET_CWD
 
extern void CheckFTPCommand(unsigned char FTP_command);
extern void CheckFTPCommand(uint8_t FTP_command, Buffer_t *pBuffer);
 
#endif
/I2C_Telemetry/trunk/gpx.c
7,7 → 7,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18,7 → 18,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
32,7 → 32,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
296,7 → 296,6
 
unsigned char retvalue = 0;
signed char string[100];
signed char name[] = "----\0";
 
if(doc == NULL) return(0);
 
307,8 → 306,7
if(doc->file != NULL)
{
signed long i32_1, i32_2;
signed int i16_1;
unsigned char u8_1, u8_2;
unsigned char u8_1;
// write <trkpt> tag
switch(part)
{
428,7 → 426,7
if(GPS_pWaypoint != NULL) // if WP exist
{ // copy that name
unsigned char i;
for(i=0;i<4;i++)
for(i=0;i<4;i++)
{
name[i] = GPS_pWaypoint->Name[i];
if(name[i] < ' ') name[i] = ' ';
/I2C_Telemetry/trunk/hottmenu.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
56,8 → 56,6
 
#include "capacity.h"
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
#define HoTT_printf(format, args...) { _printf_P(&LIBTEL_HoTT_Putchar, PSTR(format) , ## args);}
#define HoTT_printfxy(x,y,format, args...) { LIBTEL_HoTT_SetPos(y * 21 + x); _printf_P(&LIBTEL_HoTT_Putchar, PSTR(format) , ## args);}
#define HoTT_printfxy_INV(x,y,format, args...) { LIBTEL_HoTT_SetPos(y * 21 + x); _printf_P(&LIBTEL_HoTT_Putchar_INV, PSTR(format) , ## args);}
92,13 → 90,13
ASCIIPacket_t ASCIIPacket;
ElectricAirPacket_t ElectricAirPacket;
HoTTGeneral_t HoTTGeneral;
unsigned char SpeakHoTT = SPEAK_MIKROKOPTER;
unsigned char SpeakHoTT = SPEAK_MIKROKOPTER;
unsigned char ToNC_SpeakHoTT = 0, ShowSettingNameTime = 0;
int HoTTVarioMeter = 0;
const char PROGMEM MIKROKOPTER[] = {" MikroKopter "};
const char PROGMEM UNDERVOLTAGE[] = {" !! LiPo voltage !! "};
const char PROGMEM SETTING[] = {"Set :"};
const char PROGMEM NC_ERROR_TEXT[MAX_ERR_NUMBER][17] =
const char PROGMEM NC_ERROR_TEXT[MAX_ERR_NUMBER][17] =
{
//0123456789123456
"No Error \0", // 0
137,7 → 135,7
};
 
 
const char PROGMEM HOTT_ERROR[MAX_ERR_NUMBER][2] =
const char PROGMEM HOTT_ERROR[MAX_ERR_NUMBER][2] =
{ // 1 -> only in flight 0 -> also on ground
//0123456789123456
{0,0},// "No Error \0", // 0
182,13 → 180,13
if(Motor[search].Temperature > tmp_max) { tmp_max = Motor[search].Temperature; who = search;}
else
if(Motor[search].Temperature) if(Motor[search].Temperature < tmp_min) tmp_min = Motor[search].Temperature;
if(++search >= MAX_MOTORS)
{
search = 0;
if(++search >= MAX_MOTORS)
{
search = 0;
if(tmp_min != 255) MinBlTemperture = tmp_min; else MinBlTemperture = 0;
MaxBlTemperture = tmp_max;
MaxBlTemperture = tmp_max;
HottestBl = who;
tmp_min = 255;
tmp_min = 255;
tmp_max = 0;
who = 0;
}
207,16 → 205,14
unsigned char status = 0;
static char old_status = 0;
static int repeat;
//if(Parameter_UserParam1) return(Parameter_UserParam1);
//if(Parameter_UserParam1) return(Parameter_UserParam1);
ToNC_SpeakHoTT = SpeakHoTT;
if(FC_StatusFlags & FC_STATUS_LOWBAT) status = VOICE_MINIMALE_EINGANSSPANNUNG;
else
 
if(!status) // Sprachansagen
{
// if(!(GetParamByte(PID_SPEAK_HOTT_CFG) & 0x01)) SpeakHoTT = 0; // is the voice wanted?
if(!(EE_Parameter.GlobalConfig3 & CFG3_SPEAK_ALL)) SpeakHoTT = 0; // is the voice wanted?
else status = SpeakHoTT;
status = SpeakHoTT;
}
else ToNC_SpeakHoTT = status;
 
227,10 → 223,10
}
else repeat = SetDelay(2000);
 
if(status)
if(status)
{
if(status == SpeakHoTT) SpeakHoTT = 0;
}
}
old_status = status;
// DebugOut.Analog[16] = status;
return(status);
250,27 → 246,27
unsigned char max = 0,i,z;
switch(FromNaviCtrl.Param.Byte[11])
{
case HOTT_VARIO_PACKET_ID:
case HOTT_VARIO_PACKET_ID:
ptr = (unsigned char *) &VarioPacket;
max = sizeof(VarioPacket);
break;
case HOTT_GPS_PACKET_ID:
case HOTT_GPS_PACKET_ID:
ptr = (unsigned char *) &GPSPacket;
max = sizeof(GPSPacket);
break;
case HOTT_ELECTRIC_AIR_PACKET_ID:
case HOTT_ELECTRIC_AIR_PACKET_ID:
ptr = (unsigned char *) &ElectricAirPacket;
max = sizeof(ElectricAirPacket);
break;
case HOTT_GENERAL_PACKET_ID:
case HOTT_GENERAL_PACKET_ID:
ptr = (unsigned char *) &HoTTGeneral;
max = sizeof(HoTTGeneral);
break;
case JETI_GPS_PACKET_ID1:
case JETI_GPS_PACKET_ID1:
ptr = (unsigned char *) &JetiExData[14].Value;
max = sizeof(JetiExData[14].Value);
break;
case JETI_GPS_PACKET_ID2:
case JETI_GPS_PACKET_ID2:
ptr = (unsigned char *) &JetiExData[15].Value;
max = sizeof(JetiExData[15].Value);
break;
290,10 → 286,10
{
unsigned int tmp = VARIO_ZERO;
if(VarioCharacter == '+' || VarioCharacter == '-')
{
tmp = VARIO_ZERO + (AltitudeSetpointTrimming * EE_Parameter.Hoehe_Verstaerkung) / 3;
{
tmp = VARIO_ZERO;
if(tmp < VARIO_ZERO && tmp > VARIO_ZERO - 50) tmp = VARIO_ZERO - 50; // weil es sonst erst bei < 0,5m/sek piept
}
}
else
if((VarioCharacter == ' ') && (FC_StatusFlags & FC_STATUS_FLY))
{
300,18 → 296,18
tmp = VARIO_ZERO + HoTTVarioMeter;
if(tmp > VARIO_ZERO)
{
if(tmp < VARIO_ZERO + 100) tmp = VARIO_ZERO;
else tmp -= 100;
}
if(tmp < VARIO_ZERO + 100) tmp = VARIO_ZERO;
else tmp -= 100;
}
if(tmp < VARIO_ZERO)
{
if(tmp > VARIO_ZERO - 100) tmp = VARIO_ZERO;
else tmp += 100;
}
if(tmp > VARIO_ZERO - 100) tmp = VARIO_ZERO;
else tmp += 100;
}
}
/*else
if(VarioCharacter == '^') tmp = VARIO_ZERO + FromNC_AltitudeSpeed * 10;
else
else
if(VarioCharacter == 'v') tmp = VARIO_ZERO - FromNC_AltitudeSpeed * 10;
*/
return(tmp);
326,77 → 322,28
{
case HOTT_VARIO_PACKET_ID:
GPSPacket.WarnBeep = HoTT_Waring(); // Achtung: das ist richtig hier, damit der Varioton schon vorher abgestellt wird
VarioPacket.Altitude = HoehenWert/100 + 500;
VarioPacket.Altitude = HoehenWert/100 + 500;
if(!GPSPacket.WarnBeep) VarioPacket.m_sec = BuildHoTT_Vario(); else VarioPacket.m_sec = VARIO_ZERO;
VarioPacket.m_3sec = VarioPacket.m_sec;
VarioPacket.m_10sec = VarioPacket.m_sec;
if (VarioPacket.Altitude < VarioPacket.MinAltitude) VarioPacket.MinAltitude = VarioPacket.Altitude;
if (VarioPacket.Altitude > VarioPacket.MaxAltitude) VarioPacket.MaxAltitude = VarioPacket.Altitude;
if (VarioPacket.Altitude > VarioPacket.MaxAltitude) VarioPacket.MaxAltitude = VarioPacket.Altitude;
VarioPacket.WarnBeep = 0;//HoTT_Waring();
HoTT_DataPointer = (unsigned char *) &VarioPacket;
VarioPacket.FreeCharacters[0] = VarioCharacter;
if(FC_StatusFlags2 & FC_STATUS2_CAREFREE) VarioPacket.FreeCharacters[1] = 'C'; else VarioPacket.FreeCharacters[1] = ' ';
VarioPacket.FreeCharacters[1] = ' ';
// VarioPacket.FreeCharacters[2] = ' ';
 
if(FC_StatusFlags & FC_STATUS_LOWBAT) for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&UNDERVOLTAGE[i]); // no Error
else
if(ShowSettingNameTime) // no Error
{
for(i=0; i<sizeof(SETTING);i++) VarioPacket.Text[i] = pgm_read_byte(&SETTING[i]);
VarioPacket.Text[4] = '0' + ActiveParamSet;
for(i=0; i<sizeof(EE_Parameter.Name);i++) VarioPacket.Text[i+7] = EE_Parameter.Name[i]; // no Error
VarioPacket.Text[18] = ' ';
VarioPacket.Text[19] = ' ';
VarioPacket.Text[20] = ' ';
}
else
if(NaviData_WaypointNumber)
{
unsigned int tmp_int;
unsigned char tmp;
VarioPacket.Text[0] = 'W'; VarioPacket.Text[1] = 'P';
VarioPacket.Text[2] = ' ';
VarioPacket.Text[3] = '0'+(NaviData_WaypointIndex) / 10;
VarioPacket.Text[4] = '0'+(NaviData_WaypointIndex) % 10;
VarioPacket.Text[5] = '/';
VarioPacket.Text[6] = '0'+(NaviData_WaypointNumber) / 10;
VarioPacket.Text[7] = '0'+(NaviData_WaypointNumber) % 10;
VarioPacket.Text[8] = ' ';
tmp_int = NaviData_TargetDistance;
if(tmp_int > 1000) { VarioPacket.Text[9] = '0'+(tmp_int) / 1000; tmp_int %= 1000;}
else VarioPacket.Text[9] = ' ';
if(tmp_int > 100) { VarioPacket.Text[10] = '0'+(tmp_int) / 100; tmp_int %= 100;}
else VarioPacket.Text[10] = ' ';
VarioPacket.Text[11] = '0'+(tmp_int) / 10;
VarioPacket.Text[12] = '0'+(tmp_int) % 10;
VarioPacket.Text[13] = 'm';
VarioPacket.Text[14] = ' ';
tmp = NaviData_TargetHoldTime;
if(tmp > 100) { VarioPacket.Text[15] = '0'+(tmp) / 100; tmp %= 100;} else VarioPacket.Text[15] = ' ';
VarioPacket.Text[16] = '0'+(tmp) / 10;
VarioPacket.Text[17] = '0'+(tmp) % 10;
VarioPacket.Text[18] = 's';
VarioPacket.Text[19] = ' ';
}
else
if(!CalibrationDone)
{
for(i=0; i<17;i++) VarioPacket.Text[i] = pgm_read_byte(&MIKROKOPTER[i+2]); // no Error and not calibrated
VarioPacket.Text[16] = '0'+VERSION_MAJOR;
VarioPacket.Text[17] = '.';
VarioPacket.Text[18] = '0'+VERSION_MINOR/10;
VarioPacket.Text[19] = '0'+VERSION_MINOR%10;
VarioPacket.Text[20] = 'a'+VERSION_PATCH;
for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&MIKROKOPTER[i]); // no Error
}
else
{
for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&MIKROKOPTER[i]); // no Error
}
return(sizeof(VarioPacket));
return(sizeof(VarioPacket));
break;
 
case HOTT_GPS_PACKET_ID:
GPSPacket.Altitude = HoehenWert/100 + 500;
GPSPacket.Altitude = HoehenWert/100 + 500;
// GPSPacket.Distance = GPSInfo.HomeDistance/10; // macht die NC
// GPSPacket.Heading = GPSInfo.HomeBearing/2; // macht die NC
// GPSPacket.Speed = (GPSInfo.Speed * 36) / 10; // macht die NC
406,19 → 353,19
GPSPacket.NumOfSats = GPSData.NumOfSats;
if(GPSData.Flags & FLAG_DIFFSOLN) GPSPacket.SatFix = 'D';
else
if(GPSData.SatFix == SATFIX_3D) GPSPacket.SatFix = ' ';
if(GPSData.SatFix == SATFIX_3D) GPSPacket.SatFix = ' ';
else GPSPacket.SatFix = '!';
HoTT_DataPointer = (unsigned char *) &GPSPacket;
GPSPacket.FreeCharacters[0] = '?'; //NC_GPS_ModeCharacter;
GPSPacket.FreeCharacters[2] = GPSPacket.SatFix;
//GPSPacket.HomeDirection = GPSInfo.HomeBearing / 2;//230;
return(sizeof(GPSPacket));
return(sizeof(GPSPacket));
break;
case HOTT_ELECTRIC_AIR_PACKET_ID:
GetHottestBl();
ElectricAirPacket.Altitude = HoehenWert/100 + 500;
ElectricAirPacket.Battery1 = UBat;
ElectricAirPacket.Battery2 = UBat;
ElectricAirPacket.Altitude = HoehenWert/100 + 500;
ElectricAirPacket.Battery1 = U_Bat;
ElectricAirPacket.Battery2 = U_Bat;
ElectricAirPacket.VoltageCell1 = 0; //ErsatzKompassInGrad / 2;
ElectricAirPacket.VoltageCell8 = ElectricAirPacket.VoltageCell1;
//ElectricAirPacket.VoltageCell6 = GPSInfo.HomeBearing / 2;
427,7 → 374,7
ElectricAirPacket.VoltageCell14 = ElectricAirPacket.VoltageCell7;
if(!GPSPacket.WarnBeep) ElectricAirPacket.m_sec = BuildHoTT_Vario(); else ElectricAirPacket.m_sec = VARIO_ZERO;
ElectricAirPacket.m_3sec = 120;
ElectricAirPacket.InputVoltage = UBat;
ElectricAirPacket.InputVoltage = U_Bat;
ElectricAirPacket.Temperature1 = MinBlTemperture + 20;
ElectricAirPacket.Temperature2 = MaxBlTemperture + 20;
ElectricAirPacket.Capacity = Capacity.UsedCapacity/10;
436,8 → 383,8
ElectricAirPacket.Current = Capacity.ActualCurrent;
HoTT_DataPointer = (unsigned char *) &ElectricAirPacket;
ElectricAirPacket.FlightTimeMinutes = FlugSekunden / 60;
ElectricAirPacket.FlightTimeSeconds = FlugSekunden % 60;
return(sizeof(ElectricAirPacket));
ElectricAirPacket.FlightTimeSeconds = FlugSekunden % 60;
return(sizeof(ElectricAirPacket));
break;
case HOTT_GENERAL_PACKET_ID:
GetHottestBl();
448,17 → 395,17
//HoTTGeneral.VoltageCell4 = Inclinition -> macht NC
HoTTGeneral.VoltageCell5 = DebugOut.Analog[28]; // I2C ErrorCounter
//HoTTGeneral.VoltageCell6 = GPSInfo.HomeBearing / 2;
if(UBat > BattLowVoltageWarning + 2) HoTTGeneral.FuelPercent = (UBat - (BattLowVoltageWarning + 2)) * 3;
if(U_Bat > BattLowVoltageWarning + 2) HoTTGeneral.FuelPercent = (U_Bat - (BattLowVoltageWarning + 2)) * 3;
else HoTTGeneral.FuelPercent = 0;
if(HoTTGeneral.FuelPercent > 100) HoTTGeneral.FuelPercent = 100;
HoTTGeneral.FuelCapacity = 0 ; //NC_ErrorCode;//HoehenWert/100; // Oelpegel
// if(HoTTGeneral.FuelCapacity < 0) HoTTGeneral.FuelCapacity = 0;
HoTTGeneral.Altitude = HoehenWert/100 + 500;
HoTTGeneral.Battery1 = UBat;
HoTTGeneral.Battery2 = UBat;
HoTTGeneral.Altitude = HoehenWert/100 + 500;
HoTTGeneral.Battery1 = U_Bat;
HoTTGeneral.Battery2 = U_Bat;
if(!GPSPacket.WarnBeep) HoTTGeneral.m_sec = BuildHoTT_Vario(); else HoTTGeneral.m_sec = VARIO_ZERO;
HoTTGeneral.m_3sec = 120 + GPSPacket.WarnBeep;
HoTTGeneral.InputVoltage = UBat;
HoTTGeneral.InputVoltage = U_Bat;
HoTTGeneral.Temperature1 = MinBlTemperture + 20;
HoTTGeneral.Temperature2 = MaxBlTemperture + 20;
HoTTGeneral.Capacity = Capacity.UsedCapacity/10;
466,10 → 413,10
HoTTGeneral.Current = Capacity.ActualCurrent;
//HoTTGeneral.ErrorNumber = HoTTErrorCode();
HoTT_DataPointer = (unsigned char *) &HoTTGeneral;
return(sizeof(HoTTGeneral));
return(sizeof(HoTTGeneral));
break;
default: return(0);
}
}
}
 
//---------------------------------------------------------------
476,39 → 423,36
void HoTT_Menu(void)
{
static unsigned char line, page = 0,show_current = 0,show_mag = 0, show_poti = 0;
unsigned char tmp;
unsigned char tmp;
HoTTVarioMeter = (HoTTVarioMeter * 7 + VarioMeter) / 8;
 
if(page == 0)
switch(line++)
{
case 0:
if(FC_StatusFlags & FC_STATUS_LOWBAT)
HoTT_printfxy_BLINK(0,0," %2i.%1iV ",UBat/10, UBat%10)
else
HoTT_printfxy(0,0," %2i.%1iV ",UBat/10, UBat%10)
case 0:
if(FC_StatusFlags & FC_STATUS_LOWBAT)
HoTT_printfxy_BLINK(0,0," %2i.%1iV ",U_Bat/10, U_Bat%10)
else
HoTT_printfxy(0,0," %2i.%1iV ",U_Bat/10, U_Bat%10)
 
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG)
{
if(HoehenReglerAktiv) HoTT_printfxy_INV(10,0,"ALT:%4im %c", (int16_t)(HoehenWert/100),VarioCharacter)
else HoTT_printfxy(10,0,"ALT:%4im ", (int16_t)(HoehenWert/100))
}
else HoTT_printfxy(10,0,"ALT:---- ");
HoTT_printfxy(10,0,"ALT:%4im ", (int16_t)(HoehenWert/100))
 
 
break;
case 1:
if(FC_StatusFlags & FC_STATUS_LOWBAT)
case 1:
if(FC_StatusFlags & FC_STATUS_LOWBAT)
HoTT_printfxy_BLINK(0,1," %2i:%02i ",FlugSekunden/60,FlugSekunden%60)
else HoTT_printfxy(0,1," %2i:%02i ",FlugSekunden/60,FlugSekunden%60);
else HoTT_printfxy(0,1," %2i:%02i ",FlugSekunden/60,FlugSekunden%60);
//HoTT_printfxy(10,1,"DIR: %3d%c",ErsatzKompassInGrad, HoTT_GRAD);
if(FC_StatusFlags2 & FC_STATUS2_CAREFREE) HoTT_printfxy_INV(20,1,"C") else HoTT_printfxy(20,1," ");
break;
case 2:
if(FC_StatusFlags & FC_STATUS_LOWBAT)
if(FC_StatusFlags & FC_STATUS_LOWBAT)
HoTT_printfxy_BLINK(0,2," %5i ",Capacity.UsedCapacity)
else HoTT_printfxy(0,2," %5i ",Capacity.UsedCapacity);
else HoTT_printfxy(0,2," %5i ",Capacity.UsedCapacity);
HoTT_printfxy(12,2,"I:%2i.%1iA ",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10);
break;
case 3:
case 3:
HoTT_printfxy(9,0,":");
HoTT_printfxy(9,1,":");
HoTT_printfxy(9,2,":");
517,7 → 461,7
// HoTT_printfxy(0,3,"---------------------");
HoTT_printfxy(0,6,"---------------------");
break;
case 4:
case 4:
HoTT_printfxy(9,4,":");
HoTT_printfxy(0,4,"SAT:%2d ",GPSData.NumOfSats);
//HoTT_printfxy(10,4,"DIST:%3dm",GPSInfo.HomeDistance/10);
530,29 → 474,29
default:
HoTT_printfxy_BLINK(7,4,"!!");
break;
}
}
break;
case 5:
// HoTT_printfxy(0,5," %2um/s: HM:%3d%c %c",GPSData.GroundSpeed, GPSInfo.HomeBearing, HoTT_GRAD, '?' /* NC_GPS_ModeCharacter) */);
HoTT_printfxy(0,5," %2um/s",GPSData.Speed_Ground);
 
break;
case 6:
case 6:
break;
case 7:
if(FC_StatusFlags & FC_STATUS_LOWBAT) HoTT_printfxy(1,7,"!! LiPo voltage !!")
case 7:
if(FC_StatusFlags & FC_STATUS_LOWBAT) HoTT_printfxy(1,7,"!! LiPo voltage !!")
else HoTT_printfxy(0,7," www.MikroKopter.de ");
break;
case 8: //ASCIIPacket.WarnBeep = HoTT_Waring();
// ASCIIPacket.WarnBeep = Parameter_UserParam1;
case 9:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 14:
case 15:
case 16:
if(HottKeyboard == HOTT_KEY_SET) { if(show_mag) show_mag = 0; else show_mag = 1;}
else
if(HottKeyboard == HOTT_KEY_LEFT) { LIBTEL_HoTT_Clear(); page = 1; line = 0;};
561,23 → 505,17
default: line = 0;
break;
}
else
else
if(page == 1)
switch(line++)
{
case 0:
if(FC_StatusFlags & FC_STATUS_LOWBAT)
HoTT_printfxy_BLINK(0,0," %2i:%02i %2i.%1iV %4imAh",FlugSekunden/60,FlugSekunden%60,UBat/10, UBat%10,Capacity.UsedCapacity)
else HoTT_printfxy(0,0," %2i:%02i %2i.%1iV %4imAh",FlugSekunden/60,FlugSekunden%60,UBat/10, UBat%10,Capacity.UsedCapacity);
case 0:
if(FC_StatusFlags & FC_STATUS_LOWBAT)
HoTT_printfxy_BLINK(0,0," %2i:%02i %2i.%1iV %4imAh",FlugSekunden/60,FlugSekunden%60,U_Bat/10, U_Bat%10,Capacity.UsedCapacity)
else HoTT_printfxy(0,0," %2i:%02i %2i.%1iV %4imAh",FlugSekunden/60,FlugSekunden%60,U_Bat/10, U_Bat%10,Capacity.UsedCapacity);
break;
case 1:
//HoTT_printfxy(0,1,"DIR:%3d%c",KompassValue, HoTT_GRAD);
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG)
{
if(HoehenReglerAktiv) HoTT_printfxy_INV(10,1,"ALT:%4im", (int16_t)(HoehenWert/100))
else HoTT_printfxy(10,1,"ALT:%4im", (int16_t)(HoehenWert/100))
}
else HoTT_printfxy(10,1,"ALT:---- ");
case 1:
HoTT_printfxy(10,1,"ALT:%4im", (int16_t)(HoehenWert/100))
HoTT_printfxy(20,1,"%c",VarioCharacter);
break;
case 2:
587,7 → 525,7
HoTT_printfxy(0,3,"PWR:%2i.%1iA (%iW) ",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10,Capacity.ActualPower);
if(FC_StatusFlags2 & FC_STATUS2_CAREFREE) HoTT_printfxy_INV(19,3,"CF") else HoTT_printfxy(19,3," ");
break;
case 4:
case 4:
HoTT_printfxy(0,4,"GPS:%2um/s SAT:%d ",GPSData.Speed_Ground,GPSData.NumOfSats);
switch (GPSData.SatFix)
{
599,7 → 537,7
default:
HoTT_printfxy_BLINK(16,4,"NOFIX");
break;
}
}
if(GPSData.Flags & FLAG_DIFFSOLN)
{
HoTT_printfxy(16,4,"DGPS ");
616,7 → 554,7
HoTT_printfxy(0,5,"%3i %3i %3i %3i%cC", Motor[0].Temperature, Motor[1].Temperature, Motor[2].Temperature, Motor[3].Temperature,HoTT_GRAD);
}
break;
case 6:
case 6:
if(show_current)
{
if(RequiredMotors == 4) Hott_ClearLine(6);
636,20 → 574,20
if(RequiredMotors > 6) HoTT_printfxy(0,6,"%3i %3i %3i %3i%cC", Motor[4].Temperature, Motor[5].Temperature, Motor[6].Temperature, Motor[7].Temperature,HoTT_GRAD);
}
break;
case 7:
if(FC_StatusFlags & FC_STATUS_LOWBAT) HoTT_printfxy(1,7,"!! LiPo voltage !!")
case 7:
if(FC_StatusFlags & FC_STATUS_LOWBAT) HoTT_printfxy(1,7,"!! LiPo voltage !!")
else HoTT_printfxy(0,7," www.MikroKopter.de ");
break;
case 8: // ASCIIPacket.WarnBeep = HoTT_Waring();
// ASCIIPacket.WarnBeep = Parameter_UserParam1;
case 9:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 14:
case 15:
case 16:
if(HottKeyboard == HOTT_KEY_SET) { if(show_current) show_current = 0; else show_current = 1; Hott_ClearLine(5); Hott_ClearLine(6);}
else
if(HottKeyboard == HOTT_KEY_LEFT) { LIBTEL_HoTT_Clear(); page = 2; line = 0;}
661,81 → 599,47
default: line = 0;
break;
}
else
else
if(page == 2)
switch(line++)
{
case 0:
HoTT_printfxy_INV(0,0,"Setting:%u %s ",ActiveParamSet,EE_Parameter.Name);
case 0:
HoTT_printfxy_INV(0,0,"");
break;
case 1: HoTT_printfxy(0,1,"Min:%2i.%1iV %s ",BattLowVoltageWarning/10, BattLowVoltageWarning%10, Mixer.Name);
case 1: HoTT_printfxy(0,1,"Min:%2i.%1iV",BattLowVoltageWarning/10, BattLowVoltageWarning%10);
break;
case 2: HoTT_printfxy(0,2,"ALT:");
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG)
{
if(!(EE_Parameter.GlobalConfig & CFG_HOEHEN_SCHALTER)) HoTT_printf("POTI:%3u ", Parameter_HoehenSchalter)
else
{
if(Parameter_HoehenSchalter > 50) HoTT_printf("(ON) ") else HoTT_printf("(OFF) ");
if((Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT)) HoTT_printf("LIMIT", Parameter_HoehenSchalter)
else HoTT_printf("VARIO", Parameter_HoehenSchalter);
}
}
else
HoTT_printf("DISABLED");
break;
case 3: HoTT_printfxy(0,3,"CF:");
if(!EE_Parameter.CareFreeChannel) HoTT_printf("DISABLED")
else
{
if(EE_Parameter.ExtraConfig & CFG_LEARNABLE_CAREFREE) HoTT_printf(" TEACH");
}
HoTT_printf("DISABLED")
break;
case 4: HoTT_printfxy(0,4,"GPS:");
if(!(Parameter_GlobalConfig & CFG_GPS_AKTIV)) HoTT_printf("DISABLED")
else
if(!GPS_RC_Channel) HoTT_printf("DISABLED")
else
{
tmp = GetChannelValue(EE_Parameter.NaviGpsModeChannel);
tmp = PPM_in[GPS_RC_Channel];
if(tmp < 50) HoTT_printf("(FREE)")
else
if(tmp >= 180) HoTT_printf("(HOME)")
else
if(EE_Parameter.ExtraConfig & CFG_GPS_AID) HoTT_printf("(AID) ")
else HoTT_printf("(HOLD)")
else
if(tmp >= 180) HoTT_printf("(HOME)")
else HoTT_printf("(HOLD)")
}
if(EE_Parameter.FailSafeTime) HoTT_printfxy(10,4," FS:%usek ",EE_Parameter.FailSafeTime)
 
break;
case 5: HoTT_printfxy(0,5,"HOME ALT:");
if(EE_Parameter.ComingHomeAltitude) HoTT_printf("%um",EE_Parameter.ComingHomeAltitude) else HoTT_printf("HOLD ");
 
break;
case 6:
if(!show_poti)
{
HoTT_printfxy(0,6,"Ni:%4i Ro:%4i C:%3i",PPM_in[EE_Parameter.Kanalbelegung[K_NICK]],PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]], Parameter_ServoNickControl);
HoTT_printfxy(0,7,"Gs:%4i Ya:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_GAS]]+127,PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]);
}
else
{
HoTT_printfxy(0,6,"P1:%4i P2:%4i 3:%3i",Poti1,Poti2, Poti3);
HoTT_printfxy(0,7,"P4:%4i P5:%4i 6:%3i",Poti4,Poti5, Poti6);
}
HoTT_printfxy(0,6,"1:%4i 2:%4i 3:%3i",PPM_in[1],PPM_in[2], PPM_in[3]);
HoTT_printfxy(0,7,"4:%4i 5:%4i 6:%3i",PPM_in[4],PPM_in[5], PPM_in[6]);
 
break;
case 7: //HoTT_printfxy(0,6,"WARNINGS:");
if(HoTTBlink)
{
LIBTEL_HoTT_SetPos(6 * 21);
if(!(Parameter_GlobalConfig & CFG_ACHSENKOPPLUNG_AKTIV)) HoTT_printf_BLINK("COUPLING OFF! ");
if(EE_Parameter.BitConfig & (CFG_LOOP_LINKS | CFG_LOOP_RECHTS | CFG_LOOP_UNTEN | CFG_LOOP_OBEN)) HoTT_printf_BLINK("LOOPING! ");
if(Parameter_GlobalConfig & CFG_HEADING_HOLD) HoTT_printf_BLINK("HH! ");
if(!(Parameter_GlobalConfig & CFG_KOMPASS_AKTIV)) HoTT_printf_BLINK("COMPASS OFF! ");
}
case 7:
 
break;
case 8: //ASCIIPacket.WarnBeep = HoTT_Waring();
case 8:
break;
case 9:
case 9:
case 10:
case 11:
case 12:
744,8 → 648,6
case 15:
case 16:
if(HottKeyboard == HOTT_KEY_SET) { if(show_poti) show_poti = 0; else show_poti = 1; Hott_ClearLine(6); Hott_ClearLine(7);}
// else
// if(HottKeyboard == HOTT_KEY_LEFT) { LIBTEL_HoTT_Clear(); page = 3; line = 0;}
else
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBTEL_HoTT_Clear(); page = 1; line = 0;};
HottKeyboard = 0;
753,37 → 655,9
default: line = 0;
break;
}
/* else
if(page == 3)
switch(line++)
{
case 0:
HoTT_printfxy(0,2,"Speak:");
break;
case 1:
// if(GetParamByte(PID_SPEAK_HOTT_CFG) & 0x01)
if(!(GlobalConfig3 & CFG3_SPEAK_ALL) & 0x01)) HoTT_printfxy_INV(7,2,"All Messages ")
else HoTT_printfxy_INV(7,2,"Warnings only");
break;
case 2:
HoTT_printfxy(1,4,"Use (set) to select");
break;
default:
if(HottKeyboard == HOTT_KEY_SET)
{
SetParamByte(PID_SPEAK_HOTT_CFG, GetParamByte(PID_SPEAK_HOTT_CFG) ^ 0x01);
}
else
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBTEL_HoTT_Clear(); page = 2; line = 0;};
HottKeyboard = 0;
line = 0;
break;
}
*/
else page = 0;
}
 
#endif
 
 
 
/I2C_Telemetry/trunk/hottmenu.h
1,8 → 1,6
#ifndef _HOTTMENU_H
#define _HOTTMENU_H
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
#define SPEAK_ERR_CALIBARTION 1
#define SPEAK_ERR_RECEICER 2
#define SPEAK_ERR_DATABUS 3
71,10 → 69,10
typedef struct
{
unsigned char StartByte; // 0x7C
unsigned char Packet_ID; // HOTT_GENERAL_PACKET_ID
unsigned char Packet_ID; // HOTT_GENERAL_PACKET_ID
unsigned char WarnBeep; // 3 Anzahl der Töne 0..36
unsigned char SensorID; // 4 0xD0
unsigned char InverseStatus1; // 5
unsigned char InverseStatus1; // 5
unsigned char InverseStatus2; // 6
unsigned char VoltageCell1; // 7 208 = 4,16V (Voltage * 50 = Wert)
unsigned char VoltageCell2; // 8 209 = 4,18V
108,25 → 106,25
typedef struct
{
unsigned char StartByte; // 0x7C
unsigned char Packet_ID; // HOTT_ELECTRIC_AIR_PACKET_ID
unsigned char Packet_ID; // HOTT_ELECTRIC_AIR_PACKET_ID
unsigned char WarnBeep; // Anzahl der Töne 0..36
unsigned char SensorID; // 4 0xE0
unsigned char InverseStatus1; // 5
unsigned char InverseStatus1; // 5
unsigned char InverseStatus2; // 6
unsigned char VoltageCell1; // 7 208 = 4,16V (Voltage * 50 = Wert)
unsigned char VoltageCell2; // 209 = 4,18V
unsigned char VoltageCell3; //
unsigned char VoltageCell4; //
unsigned char VoltageCell5; //
unsigned char VoltageCell6; //
unsigned char VoltageCell7; //
unsigned char VoltageCell8; //
unsigned char VoltageCell9; //
unsigned char VoltageCell10; //
unsigned char VoltageCell11; //
unsigned char VoltageCell12; //
unsigned char VoltageCell13; //
unsigned char VoltageCell14; // 20
unsigned char VoltageCell3; //
unsigned char VoltageCell4; //
unsigned char VoltageCell5; //
unsigned char VoltageCell6; //
unsigned char VoltageCell7; //
unsigned char VoltageCell8; //
unsigned char VoltageCell9; //
unsigned char VoltageCell10; //
unsigned char VoltageCell11; //
unsigned char VoltageCell12; //
unsigned char VoltageCell13; //
unsigned char VoltageCell14; // 20
unsigned int Battery1; // 21+22 51 = 5,1V
unsigned int Battery2; // 23+24 51 = 5,1V
unsigned char Temperature1; // 25 44 = 24°C, 0 = -20°C
140,7 → 138,7
unsigned int Rpm; // 38+39
unsigned char FlightTimeMinutes; // 40
unsigned char FlightTimeSeconds; // 41
unsigned char Speed; // 42 1=2km
unsigned char Speed; // 42 1=2km
unsigned char Version; // 43 0x00
unsigned char EndByte; // 0x7D
} ElectricAirPacket_t;
149,15 → 147,15
typedef struct
{
unsigned char StartByte; // 0x7C
unsigned char Packet_ID; // 0x89 - Vario ID
unsigned char Packet_ID; // 0x89 - Vario ID
unsigned char WarnBeep; //3 // Anzahl der Töne 0..36
unsigned char SensorID; // 0x90
unsigned char InverseStatus;
unsigned char InverseStatus;
signed int Altitude; //6+7 // 500 = 0m
signed int MaxAltitude; //8+9 // 500 = 0m
signed int MinAltitude; //10+11 // 500 = 0m
unsigned int m_sec; //12+13 // 3000 = 0
unsigned int m_3sec; //14+15
unsigned int m_3sec; //14+15
unsigned int m_10sec; //26+17
char Text[21]; //18-38
char FreeCharacters[3]; // 39-41
169,23 → 167,23
typedef struct
{
unsigned char StartByte; //0 // 0x7C
unsigned char Packet_ID; //1 // 0x8A - GPS ID
unsigned char Packet_ID; //1 // 0x8A - GPS ID
unsigned char WarnBeep; //2 // Anzahl der Töne 0..36
unsigned char SensorID; // 4 0xA0
unsigned char InverseStatus1; // 5
unsigned char InverseStatus1; // 5
unsigned char InverseStatus2; // 6
unsigned char Heading; //7 // 1 = 2°
unsigned int Speed; //8+9 // in km/h
unsigned char Lat_North; //10
unsigned char Lat_North; //10
unsigned char Lat_G; //11
unsigned char Lat_M; //12
unsigned char Lat_Sek1; //13
unsigned char Lat_Sek2; //14
unsigned char Lon_East; //15
unsigned char Lat_Sek1; //13
unsigned char Lat_Sek2; //14
unsigned char Lon_East; //15
unsigned char Lon_G; //16
unsigned char Lon_M; //17
unsigned char Lon_Sek1; //18
unsigned char Lon_Sek2; //19
unsigned char Lon_Sek1; //18
unsigned char Lon_Sek2; //19
unsigned int Distance; //20+21 // 9000 = 0m
signed int Altitude; //22+23 // 500 = 0m
unsigned int m_sec; //24+25 // 3000 = 0
193,7 → 191,7
unsigned char NumOfSats; //27
unsigned char SatFix; //28
unsigned char HomeDirection; // 29
unsigned char AngleX; // 30
unsigned char AngleX; // 30
unsigned char AngleY; // 31
unsigned char AngleZ; // 32
signed int GyroX; //33+34
208,7 → 206,7
typedef struct
{
unsigned char StartByte; // 0x7B
unsigned char Packet_ID; //
unsigned char Packet_ID; //
unsigned char WarnBeep; // Anzahl der Töne 0..36
char Text[8*21];
unsigned char EndByte; // 0x7D
229,6 → 227,5
#define JETI_GPS_PACKET_ID1 0x01
#define JETI_GPS_PACKET_ID2 0x02
 
#endif
#endif
 
/I2C_Telemetry/trunk/jeti_ex.c
6,7 → 6,6
#include "jeti_ex.h"
#include "hottmenu.h"
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
const char PROGMEM JETI_CODE[53] =
{
65,16 → 64,16
'C' // SPEAK_STARTING 52
};
 
JetiExPacket_t JetiExData[JETI_EX_PARAMETER_COUNT + 1] = // Parameter count + DeviceName (ID0)
{
JetiExPacket_t JetiExData[JETI_EX_PARAMETER_COUNT + 1] = // Parameter count + DeviceName (ID0)
{
// Label[10] unit[3], data type, Data , position of decimal point
// "1234567890", "123",
// "1234567890", "123",
// { "-=.M_K.=-" , " ", 1, 0 , 0 }, // first one is device name // datatype 1 = -8192...8192
{ "MK " , " ", 1, 0 , 0 }, // first one is device name // datatype 1 = -8192...8192
{ "Voltage " , "V ", 1, 0 , 1 }, // ID 1
{ "Voltage " , "V ", 1, 0 , 1 }, // ID 1
{ "Current " , "A ", 1, 0 , 1 }, // ID 2
{ "Capacity " , "Ah ", 1, 0 , 2 }, // ID 3
{ "Altitude " , "m ", 1, 0 , 0 }, // ID 4
{ "Capacity " , "Ah ", 1, 0 , 2 }, // ID 3
{ "Altitude " , "m ", 1, 0 , 0 }, // ID 4
{ "Compass " , "° ", 1, 0 , 0 }, // ID 5
{ "Sats " , " ", 1, 0 , 0 }, // ID 6
{ "Speed " , "m/s", 1, 0 , 0 }, // ID 7
91,30 → 90,10
 
void BuildJeti_Vario(void)
{
signed int tmp = 0;
static signed int JetiVarioMeter = 0;
JetiVarioMeter = (JetiVarioMeter * 3 + VarioMeter) / 4;
static signed int JetiVarioMeter = 0;
 
if(VarioCharacter == '+')
{
tmp = (AltitudeSetpointTrimming * EE_Parameter.Hoehe_Verstaerkung) / 32 + 5;
}
else
if(VarioCharacter == '-')
{
tmp = (AltitudeSetpointTrimming * EE_Parameter.Hoehe_Verstaerkung) / 32 - 5;
}
else
if((VarioCharacter == ' ') && (FC_StatusFlags & FC_STATUS_FLY))
{
tmp = (JetiVarioMeter/32);
}
else
/*if(VarioCharacter == '^') tmp = FromNC_AltitudeSpeed;
else
if(VarioCharacter == 'v') tmp = tmp - FromNC_AltitudeSpeed;
*/
JetiExData[12].Value = tmp;
JetiVarioMeter = (JetiVarioMeter * 3 + VarioMeter) / 4;
JetiExData[12].Value = (JetiVarioMeter/32);
}
 
 
122,9 → 101,9
void JetiEX_Update(void)
{
 
GetHottestBl();
JetiExData[1].Value = UBat;
GetHottestBl();
 
JetiExData[1].Value = U_Bat;
JetiExData[2].Value = Capacity.ActualCurrent;
JetiExData[3].Value = Capacity.UsedCapacity / 10;
JetiExData[4].Value = HoehenWert / 100;
135,10 → 114,9
JetiExData[9].Value = 0; //GPSInfo.HomeBearing;
JetiExData[10].Value = MaxBlTemperture;
JetiExData[11].Value = 0; /* EarthMagneticField; */
// JetiExData[12].Value = Vario; // wird in BuildJeti_Vario() gemacht
// JetiExData[12].Value = Vario; // wird in BuildJeti_Vario() gemacht
JetiExData[13].Value = 0 ;//;NC_ErrorCode;
//JetiExData[14].Value = 53 * 0x10000 + 23467; // GPS-Latitude (macht NC_Fills_HoTT_Telemety() )
//JetiExData[15].Value = 7 * 0x10000 + 23467; // GPS-Longitude (macht NC_Fills_HoTT_Telemety() )
 
}
#endif
/I2C_Telemetry/trunk/jeti_ex.h
2,7 → 2,6
#define _JETI_EX_H
 
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
extern void BuildJeti_Vario(void);
 
// define here how many Jeti EX parameters should be transmitted (max. = 15)
12,7 → 11,7
// -------------------------------------------------------------------------
 
extern const char PROGMEM JETI_CODE[53];
 
typedef struct
{
char Label[10];
21,17 → 20,16
long Value;
unsigned char DecimalPointPos;
} JetiExPacket_t;
 
 
extern JetiExPacket_t JetiExData[];
extern void JetiEX_Update(void);
 
 
 
#if (JETI_EX_PARAMETER_COUNT > 15)
#if (JETI_EX_PARAMETER_COUNT > 15)
#error "ERROR: Too many Jeti EX parameters (max. allowed 15)"
#endif
 
#endif
 
#endif //_JETI_EX_H
/I2C_Telemetry/trunk/jetimenu.c
4,7 → 4,7
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
73,26 → 73,9
// -----------------------------------------------------------
void Menu_Status(uint8_t key)
{ //0123456789ABCDEF
JetiBox_printfxy(0,0,"%2i.%1iV",UBat/10, UBat%10);
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(ShowSettingNameTime)
{
LIBTEL_JetiBox_Clear();
JetiBox_printfxy(0,1,"Set%d:%s ",ActiveParamSet,EE_Parameter.Name);
return; // nichts weiter ausgeben
}
 
#else
if(NC_ErrorCode) { JetiBox_printfxy(6,0,"ERROR: %2d ",NC_ErrorCode); if(MotorenEin) JetiBeep = 'S';};
#endif
JetiBox_printfxy(0,0,"%2i.%1iV",U_Bat/10, U_Bat%10);
JetiBox_printfxy(0,1,"%4i %2i:%02i",Capacity.UsedCapacity,FlugSekunden/60,FlugSekunden%60);
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG)
{
JetiBox_printfxy(10,1,"%4im%c", (int16_t)(HoehenWert/100),VarioCharacter);
}
 
JetiBox_printfxy(10,1,"%4im%c", (int16_t)(HoehenWert/100),VarioCharacter);
}
 
 
108,13 → 91,13
if(RequiredMotors <= 6)
{
JetiBox_printfxy(8,1,"\%cC ",0xdf);
}
}
 
}
 
void Menu_Battery(uint8_t key)
{ //0123456789ABCDEF
JetiBox_printfxy(0,0,"%2i.%1iV %3i.%1iA", UBat/10, UBat%10, Capacity.ActualCurrent/10, Capacity.ActualCurrent%10);
JetiBox_printfxy(0,0,"%2i.%1iV %3i.%1iA", U_Bat/10, U_Bat%10, Capacity.ActualCurrent/10, Capacity.ActualCurrent%10);
JetiBox_printfxy(0,1,"%4iW %6imAh",Capacity.ActualPower, Capacity.UsedCapacity);
}
 
144,7 → 127,7
{
JetiBox_printfxy(12,0,"DGPS");
}
 
}
 
 
192,7 → 175,7
{
case JETIBOX_KEY_LEFT:
//if (item == 0) return (1); // switch back to jeti expander menu
// else
// else
item = pgm_read_byte(&JetiBox_Menu[item].left); //trigger to left menu item
break;
case JETIBOX_KEY_RIGHT:
211,13 → 194,13
// to avoid jumping over to items
if(item != last_item) key = JETIBOX_KEY_UNDEF;
 
if (updateDelay++ & 0x01)
{
if (updateDelay++ & 0x01)
{
 
LIBTEL_JetiBox_Clear();
//execute menu item handler
((pFctMenu)(pgm_read_word(&(JetiBox_Menu[item].pHandler))))(key);
}
}
return (0);
}
 
/I2C_Telemetry/trunk/led.c
1,132 → 1,9
#include <inttypes.h>
#include "main.h"
#include <led.h>
 
uint16_t LED1_Timing = 0;
uint16_t LED2_Timing = 0;
unsigned char J16Blinkcount = 0, J16Mask = 1;
unsigned char J17Blinkcount = 0, J17Mask = 1;
unsigned char NC_Wait_for_LED = 0; // signal to NC: Wait for the LAD PAtter before switching to the next WP
 
// initializes the LED control outputs J16, J17
void LED_Init(void)
{
// set PC2 & PC3 as output (control of J16 & J17)
// set PC2 & PC3 as output OUT1 & OUT2
DDRC |= (1<<DDC2)|(1<<DDC3);
J16_OFF;
J17_OFF;
J16Blinkcount = 0; J16Mask = 128;
J17Blinkcount = 0; J17Mask = 128;
}
 
// called in UpdateMotors() every 2ms
void LED_Update(void)
{
static char delay = 0;
static unsigned char J16Bitmask = 0;
static unsigned char J17Bitmask = 0;
static unsigned char J16Warn = 0, J17Warn = 0;
static unsigned char from_nc = 0;
 
if(FromNC_WP_EventChannel != -127) { from_nc = (unsigned char) FromNC_WP_EventChannel + 127; /*beeptime = 300;*/};
if(!delay--) // 20ms Intervall
{
delay = 9;
if(FC_StatusFlags & (FC_STATUS_LOWBAT | FC_STATUS_EMERGENCY_LANDING) || (VersionInfo.HardwareError[1] & FC_ERROR1_I2C))
{
if(EE_Parameter.WARN_J16_Bitmask)
{
if(!J16Warn) J16Blinkcount = 4;
J16Warn = 1;
}
if(EE_Parameter.WARN_J17_Bitmask)
{
if(!J17Warn) J17Blinkcount = 4;
J17Warn = 1;
}
}
else
{
J16Warn = 0;
J17Warn = 0;
J16Bitmask = EE_Parameter.J16Bitmask;
J17Bitmask = EE_Parameter.J17Bitmask;
}
//DebugOut.Analog[29] = EE_Parameter.GlobalConfig3;
// Output 1
if(!J16Warn)
{
if((EE_Parameter.BitConfig & CFG_MOTOR_BLINK1) && !MotorenEin) {if(EE_Parameter.BitConfig & CFG_MOTOR_OFF_LED1) J16_ON; else J16_OFF;}
else
if((EE_Parameter.J16Timing > 247) && (Parameter_J16Timing > 220)) {if(J16Bitmask & 128) J16_OFF; else J16_ON; J16Mask = 1; NC_Wait_for_LED = 0;} // Manual overwrite
else
if((EE_Parameter.J16Timing > 247) && (Parameter_J16Timing == 5)) {if(J16Bitmask & 128) J16_ON; else J16_OFF; J16Mask = 1; NC_Wait_for_LED = 0;} // Manual overwrite
else
if(!J16Blinkcount--)
{
if(EE_Parameter.GlobalConfig3 & CFG3_USE_NC_FOR_OUT1)
{
J16Blinkcount = from_nc / 2;
if(!from_nc) { NC_Wait_for_LED = 0; if(J16Bitmask & 128) J16_ON; else J16_OFF; J16Mask = 0; } // Ausschalten
else
{
NC_Wait_for_LED = 1;
if(J16Mask == 0)
{
from_nc = 0;
J16Mask = 64;
if(J16Bitmask & 128) J16_ON; else J16_OFF; // Ausschalten
}
else
{
//if(FromNC_WP_EventChannel != -127)
if(J16Mask & J16Bitmask) J16_ON; else J16_OFF;
J16Mask /= 2;
}
}
}
else
{
J16Blinkcount = Parameter_J16Timing / 2;
if(J16Mask == 1) { from_nc = 0; J16Mask = 128; } else J16Mask /= 2;
if(J16Mask & J16Bitmask) J16_ON; else J16_OFF;
NC_Wait_for_LED = 0;
}
}
}
else // warning case
if(!J16Blinkcount--)
{
J16Blinkcount = 10-1;
if(J16Mask == 1) J16Mask = 128; else J16Mask /= 2;
if(J16Mask & EE_Parameter.WARN_J16_Bitmask) J16_ON; else J16_OFF;
}
// Output 2
 
if(!J17Warn)
{
if((EE_Parameter.BitConfig & CFG_MOTOR_BLINK2) && !MotorenEin) {if(EE_Parameter.BitConfig & CFG_MOTOR_OFF_LED2) J17_ON; else J17_OFF;}
else
if((EE_Parameter.J17Timing > 247) && (Parameter_J17Timing > 220)) {if(J17Bitmask & 128) J17_OFF; else J17_ON; J17Mask = 1;}
else
if((EE_Parameter.J17Timing > 247) && (Parameter_J17Timing == 5)) {if(J17Bitmask & 128) J17_ON; else J17_OFF; J17Mask = 1;}
else
if(!J17Blinkcount--)
{
J17Blinkcount = Parameter_J17Timing / 2;
if(J17Mask == 1) J17Mask = 64; else J17Mask /= 2;
if(J17Mask & J17Bitmask) J17_OFF; else J17_ON;
}
}
else // warning case
if(!J17Blinkcount--)
{
J17Blinkcount = 10-1;
if(J17Mask == 1) J17Mask = 128; else J17Mask /= 2;
if(J17Mask & EE_Parameter.WARN_J17_Bitmask) J17_ON; else J17_OFF;
}
 
if(PORTC & (1<<PORTC2)) FC_StatusFlags2 |= FC_STATUS2_OUT1_ACTIVE; //else FC_StatusFlags2 &= ~FC_STATUS2_OUT1_ACTIVE; // Out1 (J16) -> wird in der SPI zurück gesetzt
if(PORTC & (1<<PORTC3)) FC_StatusFlags2 |= FC_STATUS2_OUT2_ACTIVE; else FC_StatusFlags2 &= ~FC_STATUS2_OUT2_ACTIVE; // Out2 (J17)
}
}
 
/I2C_Telemetry/trunk/led.h
1,3 → 1,6
#ifndef _LED_H
#define _LED_H
 
#include <avr/io.h>
 
#define J16_ON PORTC |= (1<<PORTC2)
8,5 → 11,6
#define J17_TOGGLE PORTC ^= (1<<PORTC3)
 
extern void LED_Init(void);
extern void LED_Update(void);
extern unsigned char NC_Wait_for_LED;
 
#endif // _LED_H
 
/I2C_Telemetry/trunk/libtel.h
7,18 → 7,13
#define CPU_ATMEGA1284 3
#define CPU_ATMEGA1284P 4
 
extern void LIBTEL_Init(unsigned char);
extern void LIBTEL_Init(unsigned char comp);
extern void LIBTEL_Polling(void);
extern void LIBTEL_ReceiverInit(unsigned char rtype);
extern void LIBTEL_ReceiverInit(void);
 
extern void LIBTEL_JetiBox_Putchar(char c);
extern void LIBTEL_JetiBox_SetPos(unsigned char index);
extern void LIBTEL_JetiBox_Clear(void);
extern void LIBTEL_CheckSettings(void);
extern unsigned char LIBTEL_GetCPUType(void);
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
extern long ACC_AltitudeFusion(unsigned char init);
#endif
 
#endif //_LIBTEL_H
/I2C_Telemetry/trunk/main.c
50,100 → 50,80
// + #### END OF LICENSING TERMS ####
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
//#include "stdio.h"
#include <util/delay.h>
#include "main.h"
unsigned char BoardRelease = 0;
unsigned int Receiver;
unsigned char DisableRcOffBeeping = 0;
unsigned char PlatinenVersion = 10;
unsigned char BattLowVoltageWarning = 94;
unsigned int FlugMinuten = 0,FlugMinutenGesamt = 0;
unsigned int FlugSekunden = 0;
unsigned int BattLowVoltageWarning = 94;
unsigned int FlugMinuten = 0,FlugMinutenGesamt = 0, FlugSekunden = 0;
 
pVoidFnct_pVoidFnctChar_const_fmt _printf_P;
 
unsigned char FoundMotors = 0;
unsigned char JetiBeep = 0; // to allow any Morse-Beeping of the Jeti-Box
unsigned char ActiveParamSet = 3;
unsigned int CountGpsProcessedIn5Sec = 0,CountNewGpsDataIn5Sec = 0, FreqGpsProcessedIn5Sec = 0, FreqNewGpsDataIn5Sec = 0;
unsigned int CountGpsProcessedIn5Sec = 0,CountNewGpsDataIn5Sec = 0, CountUpdateMotorIn5Sec = 0, FreqUpdateMotorIn5Sec = 0, FreqGpsProcessedIn5Sec = 0, FreqNewGpsDataIn5Sec = 0;
 
void PrintLine(void)
{
printf("\n\r===================================");
printf("\n\r===================================");
}
 
 
void CalMk3Mag(void)
unsigned char GetBoardRelease(void)
{
static unsigned char stick = 1;
if(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > -20) stick = 0;
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -70) && !stick)
{
stick = 1;
WinkelOut.CalcState++;
if(WinkelOut.CalcState > 4)
{
// WinkelOut.CalcState = 0; // in Uart.c
beeptime = 1000;
}
else Piep(WinkelOut.CalcState,150);
}
}
unsigned char BoardRelease = 10;
// the board release is coded via the pull up or down the 2 status LED
 
 
void LipoDetection(unsigned char print)
{
#define MAX_CELL_VOLTAGE 43 // max cell volatage for LiPO
unsigned int timer, cells;
if(print) printf("\n\rBatt:");
if(EE_Parameter.UnterspannungsWarnung < 50) // automatische Zellenerkennung
{
timer = SetDelay(500);
if(print) while (!CheckDelay(timer));
// up to 6s LiPo, less than 2s is technical impossible
for(cells = 2; cells < 7; cells++)
{
if(UBat < cells * MAX_CELL_VOLTAGE) break;
}
BoardRelease = 0;
 
BattLowVoltageWarning = cells * EE_Parameter.UnterspannungsWarnung;
if(print)
{
Piep(cells, 200);
printf(" %d Cells ", cells);
}
}
else BattLowVoltageWarning = EE_Parameter.UnterspannungsWarnung;
if(print) printf(" Low warning: %d.%d",BattLowVoltageWarning/10,BattLowVoltageWarning%10);
}
PORTB &= ~((1 << PORTB1)|(1 << PORTB0)); // set tristate
DDRB &= ~((1 << DDB0)|(1 << DDB0)); // set port direction as input
 
void TestFileWrite(void)
{
_delay_loop_2(1000); // make some delay
 
File_t* f = 0;
switch( PINB & ((1<<PINB1)|(1<<PINB0)) )
{
case 0x00:
BoardRelease = 10; // 1.0
break;
default:
break;
}
// set LED ports as output
DDRB |= (1<<DDB1)|(1<<DDB0);
RED_ON;
GRN_OFF;
 
signed char gregname[12];
return BoardRelease;
}
 
sprintf(gregname, "abc.txt");
 
uart_putchar(gregname[0]);
void LipoDetection(unsigned char print)
{
#define MAX_CELL_VOLTAGE 430 // max cell volatage for LiPO
#define MIN_CELL_VOLTAGE 330 // max cell volatage for LiPO
unsigned int timer, cells;
 
printf("\r\nWriting File: %s", gregname);
if(print) printf("\n\rBatt:");
 
 
f = fopen_(gregname, 'w');
if(f!= NULL)
timer = SetDelay(500);
if(print) while (!CheckDelay(timer));
// up to 6s LiPo, less than 2s is technical impossible
for(cells = 2; cells < 7; cells++)
{
printf("ok");
if(U_Bat < cells * MAX_CELL_VOLTAGE) break;
}
 
if(EOF == fputs_("\r\ntest edins sdv dsivbds iv dsivb disbv idsv bisd bv d suiv dsibsivbdis fbvisdöb visdbvisdb vidbfibds ibv", f))
printf("\r\nfputs error");
 
printf("\r\nClosing file:");
fclose_(f);
 
}
else
BattLowVoltageWarning = cells * MIN_CELL_VOLTAGE;
if(print)
{
printf("failed");
Piep(cells, 200);
printf(" %d Cells ", cells);
}
 
if(print) printf(" Low warning: %d.%02dV",BattLowVoltageWarning/100, BattLowVoltageWarning%100);
}
 
 
153,27 → 133,26
//############################################################################
{
unsigned int timer,i,timer2 = 0, timerPolling, timer1000ms;
unsigned char update_spi = 1, count5sec = 0;
unsigned char count5sec = 0;
 
// disable interrupts global
cli();
 
DDRB = 0x00;
PORTB = 0x00;
// analyze hardware environment
BoardRelease = GetBoardRelease();
 
// disable watchdog
MCUSR &=~(1<<WDRF);
WDTCSR |= (1<<WDCE)|(1<<WDE);
WDTCSR = 0;
 
beeptime = 2000;
 
 
DDRD = 0x0A; // UART & J3 J4 J5
PORTD = 0x5F; // PPM-Input & UART
for(timer = 0; timer < 1000; timer++); // verzögern
 
 
if(PINB & 0x02)
{
if(PIND & 0x10) PlatinenVersion = 21; // No Bridge from J4 to GND
else { PlatinenVersion = 22; ACC_AltitudeControl = 1;};
}
else
{
PlatinenVersion = 25; ACC_AltitudeControl = 1;
}
 
 
DDRC = 0x81; // I2C, Speaker, TXD_PC_OFF
DDRC |=0x40; // HEF4017 Reset, TXD_PC_OFF
PORTC = 0xff; // Pullup SDA
181,20 → 160,19
PORTB = 0x01; // LED_Rot
PORTB = 0xff;
 
HEF4017Reset_ON;
MCUSR &=~(1<<WDRF);
WDTCSR |= (1<<WDCE)|(1<<WDE);
WDTCSR = 0;
 
beeptime = 2500;
StickGier = 0; PPM_in[K_GAS] = 0; StickRoll = 0; StickNick = 0;
ROT_OFF;
 
StickGier = 0; StickGas = 0; StickRoll = 0; StickNick = 0;
RED_OFF;
GRN_ON;
 
Timer_Init();
TIMER2_Init();
UART_Init();
rc_sum_init();
Timer0_Init();
Timer2_Init();
USART0_Init();
RC_Init();
ADC_Init();
I2C_Init(1);
UBX_Init();
203,7 → 181,6
 
GRN_ON;
sei();
ParamSet_Init();
 
 
 
227,13 → 204,11
{
SendMotorData();
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
if(Mixer.Motor[i][0] > 0) // wait max 4 sec for the BL-Ctrls to wake up
 
while(!CheckDelay(timer) && !(Motor[i].State & MOTOR_STATE_PRESENT_MASK) )
{
while(!CheckDelay(timer) && !(Motor[i].State & MOTOR_STATE_PRESENT_MASK) )
{
SendMotorData();
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
}
SendMotorData();
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
}
if(Motor[i].State & MOTOR_STATE_PRESENT_MASK)
{
245,43 → 220,42
}
for(i=0; i < MAX_MOTORS; i++)
{
if(!(Motor[i].State & MOTOR_STATE_PRESENT_MASK) && Mixer.Motor[i][0] > 0)
if(!(Motor[i].State & MOTOR_STATE_PRESENT_MASK))
{
printf("\n\r\n\r!! MISSING BL-CTRL: %d !!",i+1);
ServoActive = 2; // just in case the FC would be used as camera-stabilizer
}
Motor[i].State &= ~MOTOR_STATE_ERROR_MASK; // clear error counter
}
PrintLine();// ("\n\r===================================");
PrintLine();// ("\n\r===================================");
 
 
if(RequiredMotors < FoundMotors) VersionInfo.HardwareError[1] |= FC_ERROR1_MIXER;
if(RequiredMotors < FoundMotors) UART_VersionInfo.HardwareError[1] |= FC_ERROR1_MIXER;
 
 
Fat16_Init();
// initialize the settings
Settings_Init();
 
// initialize logging (needs settings)
Logging_Init();
 
 
//if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)
{
printf("\n\rCalibrating pressure sensor..");
timer = SetDelay(1000);
SucheLuftruckOffset();
while (!CheckDelay(timer));
printf("OK\n\r");
}
 
printf("\n\rCalibrating pressure sensor..");
timer = SetDelay(1000);
SucheLuftruckOffset();
while (!CheckDelay(timer));
printf("OK\n\r");
 
 
SetNeutral(0);
 
ROT_OFF;
RED_OFF;
 
beeptime = 2000;
ExternControl.Digital[0] = 0x55;
 
 
 
FlugMinuten = (unsigned int)GetParamByte(PID_FLIGHT_MINUTES) * 256 + (unsigned int)GetParamByte(PID_FLIGHT_MINUTES + 1);
FlugMinutenGesamt = (unsigned int)GetParamByte(PID_FLIGHT_MINUTES_TOTAL) * 256 + (unsigned int)GetParamByte(PID_FLIGHT_MINUTES_TOTAL + 1);
 
293,9 → 267,8
printf("\n\rFlight-time %u min Total:%u min", FlugMinuten, FlugMinutenGesamt);
LcdClear();
I2CTimeout = 5000;
WinkelOut.Orientation = 1;
LipoDetection(1);
LIBTEL_ReceiverInit(EE_Parameter.Receiver);
LIBTEL_ReceiverInit();
PrintLine();// ("\n\r===================================");
//SpektrumBinding();
timer = SetDelay(2000);
302,224 → 275,180
timerPolling = SetDelay(250);
 
Debug(ANSI_CLEAR "FC-Start!\n\rFlugzeit: %d min", FlugMinutenGesamt); // Note: this won't waste flash memory, if #DEBUG is not active
//printf("\n\rEE_Parameter size:%i\n\r", PARAMSET_STRUCT_LEN);
 
DebugOut.Status[0] = 0x01 | 0x02;
JetiBeep = 0;
if(EE_Parameter.ExtraConfig & CFG_NO_RCOFF_BEEPING) DisableRcOffBeeping = 1;
DisableRcOffBeeping = 0;
 
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space
 
/*
{
static uint8_t i, buffer[512];
SD_Result_t res;
printf("\r\n Buffer: ");
for(i = 0; i<26 ; i++)
{
buffer[i] = 'a'+ i;
uart_putchar(buffer[i]);
}
res = SDC_PutSector(501, buffer);
printf("\r\n Put Sector = %d", res);
printf("\r\n Buffer: ");
for(i = 0; i<26 ; i++)
{
uart_putchar(buffer[i]);
buffer[i] = 0;
}
 
res = SDC_GetSector (501, buffer);
printf("\r\n Get Sector = %d", res);
printf("\r\n Buffer: ");
for(i = 0; i<26 ; i++)
{
uart_putchar(buffer[i]);
}
 
}
*/
TestFileWrite();
 
 
 
 
while(1)
{
 
if(SD_WatchDog)
{
if(SD_WatchDog)
{
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) printf("\n\rSD-Watchdog - Logging aborted\n\r");
}
}
 
 
if(ReceiverUpdateModeActive) while (1) PORTC &= ~(1<<7); // Beeper off
//GRN_ON;
if(UpdateMotor && AdReady) // ReglerIntervall
{
//GRN_OFF;
cli();
UpdateMotor--;
sei();
MotorRegler();
if(UpdateMotor && AdReady) // ReglerIntervall
{
CountUpdateMotorIn5Sec++;
//GRN_OFF;
cli();
UpdateMotor = 0;
sei();
 
MotorRegler();
 
FC_StatusFlags |= FC_STATUS_FLY;
 
SendMotorData();
ROT_OFF;
if(SenderOkay) { SenderOkay--; /*VersionInfo.HardwareError[1] &= ~FC_ERROR1_PPM;*/ }
RED_OFF;
if(SenderOkay)
{
SenderOkay--;
}
else
{
TIMSK1 |= _BV(ICIE1); // enable PPM-Input
PPM_in[0] = 0; // set RSSI to zero on data timeout
VersionInfo.HardwareError[1] |= FC_ERROR1_PPM;
UART_VersionInfo.HardwareError[1] |= FC_ERROR1_PPM;
}
 
if (CheckDelay(timer1000ms))
if (CheckDelay(timer1000ms))
{
if(++count5sec == 5)
{
count5sec = 0;
FreqGpsProcessedIn5Sec = CountGpsProcessedIn5Sec * 2;
FreqNewGpsDataIn5Sec = CountNewGpsDataIn5Sec * 2;
CountGpsProcessedIn5Sec = 0;
CountNewGpsDataIn5Sec = 0;
}
timer1000ms = SetDelay(1000);
if(++count5sec == 5)
{
count5sec = 0;
FreqGpsProcessedIn5Sec = CountGpsProcessedIn5Sec * 2;
FreqNewGpsDataIn5Sec = CountNewGpsDataIn5Sec * 2;
FreqUpdateMotorIn5Sec = CountUpdateMotorIn5Sec * 2;
CountGpsProcessedIn5Sec = 0;
CountNewGpsDataIn5Sec = 0;
CountUpdateMotorIn5Sec = 0;
}
timer1000ms = SetDelay(1000);
}
 
 
if(!--I2CTimeout || MissingMotor)
{
if(!I2CTimeout)
{
I2C_Reset();
I2CTimeout = 5;
if(!--I2CTimeout || MissingMotor)
{
if(!I2CTimeout)
{
I2C_Reset();
I2CTimeout = 5;
DebugOut.Analog[28]++; // I2C-Error
VersionInfo.HardwareError[1] |= FC_ERROR1_I2C;
UART_VersionInfo.HardwareError[1] |= FC_ERROR1_I2C;
DebugOut.Status[1] |= 0x02; // BL-Error-Status
}
if((BeepMuster == 0xffff) && MotorenEin)
{
beeptime = 25000;
BeepMuster = 0x0080;
}
}
else
{
ROT_OFF;
}
LIBTEL_Polling();
}
if((BeepMuster == 0xffff) && MotorenEin)
{
beeptime = 25000;
BeepMuster = 0x0080;
}
}
else
{
RED_OFF;
}
LIBTEL_Polling();
 
if(!UpdateMotor)
{
if(NewSBusData) ProcessSBus();
else
{
if(CalculateServoSignals) CalculateServo();
DatenUebertragung();
BearbeiteRxDaten();
if(CheckDelay(timer))
if(!UpdateMotor)
{
static unsigned char second;
timer += 20; // 20 ms interval
 
CalcNickServoValue();
 
if(EE_Parameter.Receiver == RECEIVER_HOTT) HoTT_Menu();
if(NewSBusData)
{
ProcessSBus();
}
else
if(EE_Parameter.Receiver == RECEIVER_JETI) BuildJeti_Vario();
 
if(MissingMotor)
{
VersionInfo.HardwareError[1] |= FC_ERROR1_BL_MISSING;
DebugOut.Status[1] |= 0x02; // BL-Error-Status
}
else
{
if(!beeptime)
{
if(I2CTimeout > 6) DebugOut.Status[1] &= ~0x02; // BL-Error-Status
}
}
if(DisableRcOffBeeping) if(SenderOkay > 150) { DisableRcOffBeeping = 0; beeptime = 5000;};
if(PcZugriff) PcZugriff--;
else
{
ExternControl.Config = 0;
ExternStickNick = 0;
ExternStickRoll = 0;
ExternStickGier = 0;
if(!SenderOkay)
USART0_TransmitTxData();
USART0_ProcessRxData();
if(CheckDelay(timer))
{
if(BeepMuster == 0xffff && DisableRcOffBeeping != 2)
{
beeptime = 15000;
BeepMuster = 0x0c00;
if(DisableRcOffBeeping) DisableRcOffBeeping = 2;
}
}
}
static unsigned char second;
timer += 20; // 20 ms interval
 
if(UBat < BattLowVoltageWarning)
{
FC_StatusFlags |= FC_STATUS_LOWBAT;
if(BeepMuster == 0xffff && UBat > 10) // Do not beep, if the voltage reading is below 1V (Supplied via MKUSB)
{
beeptime = 6000;
BeepMuster = 0x0300;
if(Receiver == RECEIVER_HOTT) HoTT_Menu();
else
if(Receiver == RECEIVER_JETI) BuildJeti_Vario();
 
if(MissingMotor)
{
UART_VersionInfo.HardwareError[1] |= FC_ERROR1_BL_MISSING;
DebugOut.Status[1] |= 0x02; // BL-Error-Status
}
else
{
if(!beeptime)
{
if(I2CTimeout > 6) DebugOut.Status[1] &= ~0x02; // BL-Error-Status
}
}
if(DisableRcOffBeeping) if(SenderOkay > 150) { DisableRcOffBeeping = 0; beeptime = 5000;};
if(PcAccess) PcAccess--;
else
{
if(!SenderOkay)
{
if(BeepMuster == 0xffff && DisableRcOffBeeping != 2)
{
beeptime = 15000;
BeepMuster = 0x0c00;
if(DisableRcOffBeeping) DisableRcOffBeeping = 2;
}
}
}
 
if(U_Bat < BattLowVoltageWarning)
{
FC_StatusFlags |= FC_STATUS_LOWBAT;
if(BeepMuster == 0xffff && U_Bat > 10) // Do not beep, if the voltage reading is below 1V (Supplied via MKUSB)
{
beeptime = 6000;
BeepMuster = 0x0300;
}
}
else if(!beeptime) FC_StatusFlags &= ~FC_STATUS_LOWBAT;
// SendSPI = SPI_BYTEGAP;
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space
// +++++++++++++++++++++++++++++++++
// Sekundentakt
if(++second == 49)
{
second = 0;
if(ShowSettingNameTime) ShowSettingNameTime--;
if(FC_StatusFlags & FC_STATUS_FLY) FlugSekunden++;
else timer2 = 1450; // 0,5 Minuten aufrunden
 
if(modell_fliegt < 1024)
{
if(StartLuftdruck < Luftdruck) StartLuftdruck += 5;
else
if(StartLuftdruck > Luftdruck) StartLuftdruck -= 5;
}
}
// +++++++++++++++++++++++++++++++++
if(++timer2 == 2930) // eine Minute
{
timer2 = 0;
FlugMinuten++;
FlugMinutenGesamt++;
SetParamByte(PID_FLIGHT_MINUTES,FlugMinuten / 256);
SetParamByte(PID_FLIGHT_MINUTES+1,FlugMinuten % 256);
SetParamByte(PID_FLIGHT_MINUTES_TOTAL,FlugMinutenGesamt / 256);
SetParamByte(PID_FLIGHT_MINUTES_TOTAL+1,FlugMinutenGesamt % 256);
timer = SetDelay(20); // falls "timer += 20;" mal nicht geht
}
}
Capacity_Update();
}
else if(!beeptime) FC_StatusFlags &= ~FC_STATUS_LOWBAT;
// SendSPI = SPI_BYTEGAP;
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space
// +++++++++++++++++++++++++++++++++
// Sekundentakt
if(++second == 49)
{
second = 0;
if(ShowSettingNameTime) ShowSettingNameTime--;
if(FC_StatusFlags & FC_STATUS_FLY) FlugSekunden++;
else timer2 = 1450; // 0,5 Minuten aufrunden
 
if(modell_fliegt < 1024)
{
if(StartLuftdruck < Luftdruck) StartLuftdruck += 5;
else
if(StartLuftdruck > Luftdruck) StartLuftdruck -= 5;
}
}
// +++++++++++++++++++++++++++++++++
if(++timer2 == 2930) // eine Minute
{
timer2 = 0;
FlugMinuten++;
FlugMinutenGesamt++;
SetParamByte(PID_FLIGHT_MINUTES,FlugMinuten / 256);
SetParamByte(PID_FLIGHT_MINUTES+1,FlugMinuten % 256);
SetParamByte(PID_FLIGHT_MINUTES_TOTAL,FlugMinutenGesamt / 256);
SetParamByte(PID_FLIGHT_MINUTES_TOTAL+1,FlugMinutenGesamt % 256);
timer = SetDelay(20); // falls "timer += 20;" mal nicht geht
}
}
LED_Update();
Capacity_Update();
}
} //else DebugOut.Analog[18]++;
if(update_spi) update_spi--;
} // 500Hz
/*if(update_spi == 0) // 41Hz
{
if(SPI_StartTransmitPacket()) update_spi = 12;
else
if(BytegapSPI == 0) SPI_TransmitByte();
}
else if(BytegapSPI == 0) SPI_TransmitByte(); */
}
} // EOF if(!UpdateMotors)
} // EOF if(UpdateMotor && AdReady) ca. 488Hz
} //EOF while(1)
}
//DebugOut.Analog[16]
 
/I2C_Telemetry/trunk/main.h
1,12 → 1,6
#ifndef _MAIN_H
#define _MAIN_H
 
#define FC_ADDRESS 2
#define NC_ADDRESS 2
#define MK3MAG_ADDRESS 3
#define BL_CTRL_ADDRESS 5
 
 
//#define DEBUG // use to activate debug output to MK-Tool: use Debug(text);
//#define ACT_S3D_SUMMENSIGNAL
//#define UserParameter8_FAILSAFE
13,45 → 7,46
//#define RECEIVER_SPEKTRUM_DX7EXP
//#define RECEIVER_SPEKTRUM_DX8EXP
 
// neue Hardware
#define ROT_OFF {if((PlatinenVersion == 10)||(PlatinenVersion >= 20)) PORTB &=~0x01; else PORTB |= 0x01;}
#define ROT_ON {if((PlatinenVersion == 10)||(PlatinenVersion >= 20)) PORTB |= 0x01; else PORTB &=~0x01;}
#define ROT_FLASH PORTB ^= 0x01
#define GRN_OFF {if((PlatinenVersion < 12) || PlatinenVersion == 25) PORTB &=~0x02; else PORTB |= 0x02;}
#define GRN_ON {if((PlatinenVersion < 12) || PlatinenVersion == 25) PORTB |= 0x02; else PORTB &=~0x02;}
#define GRN_FLASH PORTB ^= 0x02
#define RED_OFF {PORTB &=~0x01;}
#define RED_ON {PORTB |= 0x01;}
 
#define GRN_OFF {PORTB &=~0x02;}
#define GRN_ON {PORTB |= 0x02;}
 
 
#define SYSCLK F_CPU
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#define J3High PORTD |= 0x20
#define J3Low PORTD &= ~0x20
#define J4High PORTD |= 0x10
#define J4Low PORTD &= ~0x10
#define J5High PORTD |= 0x08
#define J5Low PORTD &= ~0x08
extern unsigned int BattLowVoltageWarning;
 
extern volatile unsigned char SenderOkay;
extern unsigned char BattLowVoltageWarning;
extern unsigned char CosinusNickWinkel, CosinusRollWinkel;
extern unsigned char PlatinenVersion;
extern unsigned char FoundMotors,DisableRcOffBeeping;
 
// defines for the receiver selection
#define RECEIVER_PPM 0
#define RECEIVER_SPEKTRUM 1
#define RECEIVER_SPEKTRUM_HI_RES 2
#define RECEIVER_SPEKTRUM_LOW_RES 3
#define RECEIVER_JETI 4
#define RECEIVER_ACT_DSL 5
#define RECEIVER_HOTT 6
#define RECEIVER_SBUS 7
#define RECEIVER_USER 8
#define RECEIVER_UNKNOWN 0xFF
extern unsigned int Receiver;
 
extern unsigned char BoardRelease;
extern unsigned char FoundMotors, DisableRcOffBeeping;
extern unsigned char JetiBeep;
void LipoDetection(unsigned char print);
extern unsigned int FlugMinuten,FlugMinutenGesamt,FlugSekunden;
extern void PrintLine(void); // "================================="
extern unsigned char ActiveParamSet;
extern unsigned int BL3_Current(unsigned char who); // in 0,1A
extern unsigned int CountGpsProcessedIn5Sec ,CountNewGpsDataIn5Sec , FreqGpsProcessedIn5Sec , FreqNewGpsDataIn5Sec;
extern unsigned int CountGpsProcessedIn5Sec ,CountNewGpsDataIn5Sec, CountUpdateMotorIn5Sec, FreqUpdateMotorIn5Sec, FreqGpsProcessedIn5Sec , FreqNewGpsDataIn5Sec;
 
 
#include <avr/pgmspace.h>
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 
#endif
 
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
/I2C_Telemetry/trunk/makefile
1,7 → 1,6
#--------------------------------------------------------------------
# MCU name
MCU = atmega1284p
#MCU = atmega644p
F_CPU = 20000000
#-------------------------------------------------------------------
VERSION_MAJOR = 2
9,7 → 8,6
VERSION_PATCH = 3
VERSION_SERIAL_MAJOR = 11 # Serial Protocol
VERSION_SERIAL_MINOR = 0 # Serial Protocol
NC_SPI_COMPATIBLE = 57 # Navi-Kompatibilität
LIB_TEL_COMPATIBLE = 5 # Library
#-------------------------------------------------------------------
# ATMEGA644: 63487 is maximum
/I2C_Telemetry/trunk/menu.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
56,7 → 56,7
char DisplayBuff[80];
unsigned char DispPtr = 0;
 
unsigned char MaxMenue = 17;
unsigned char MaxMenue = 18;
unsigned char MenuePunkt = 0;
unsigned char RemoteKeys = 0;
 
81,8 → 81,8
{
unsigned char i, sign;
int i1,i2,i3;
 
 
if(RemoteKeys & KEY1) { if(MenuePunkt) MenuePunkt--; else MenuePunkt = MaxMenue;}
if(RemoteKeys & KEY2) { if(MenuePunkt == MaxMenue) MenuePunkt = 0; else MenuePunkt++;}
if((RemoteKeys & KEY1) && (RemoteKeys & KEY2)) MenuePunkt = 0;
94,13 → 94,12
{
case 0:
LCD_printfxy(0,0,"-I2C-Telemetry-");
LCD_printfxy(0,1,"HW:V%d.%d SW:%d.%02d%c ",PlatinenVersion/10,PlatinenVersion%10, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH +'a');
LCD_printfxy(0,2,"Setting:%d %s", ActiveParamSet,Mixer.Name);
LCD_printfxy(0,1,"HW:V%d.%d SW:%d.%02d%c ",BoardRelease/10,BoardRelease%10, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH +'a');
 
if(VersionInfo.HardwareError[1] & FC_ERROR1_MIXER) LCD_printfxy(0,3,"Mixer Error!")
else
if(VersionInfo.HardwareError[0]) LCD_printfxy(0,3,"Hardware Error 1:%d !!",VersionInfo.HardwareError[0])
if(UART_VersionInfo.HardwareError[1] & FC_ERROR1_MIXER) LCD_printfxy(0,3,"Mixer Error!")
else
if(UART_VersionInfo.HardwareError[0]) LCD_printfxy(0,3,"Hardware Error 1:%d !!",UART_VersionInfo.HardwareError[0])
else
if(MissingMotor) LCD_printfxy(0,3,"Missing BL-Ctrl:%d !!",MissingMotor)
else
if(I2CTimeout < 6) LCD_printfxy(0,3,"I2C ERROR!!!")
110,14 → 109,8
break;
case 1:
LCD_printfxy(0,0,"Height: %5i",(int)(HoehenWert/5));
LCD_printfxy(0,1,"Setpoint:%5i",(int)(SollHoehe/5));
LCD_printfxy(0,2,"Pressure:%5i",MessLuftdruck);
LCD_printfxy(0,3,"Offset: %5i",OCR0A);
if(ACC_AltitudeControl)
{
LCD_printfxy(17,2,"(A)");
LCD_printfxy(17,3,"%i",CalAthmospheare);
}
break;
case 2:
if (GPSData.Status == INVALID)
162,17 → 155,15
i2 = abs((int16_t)(GPSData.Position.Altitude%1000L));
LCD_printfxy(0,3,"Alt: %c%04d.%.03d m",sign, i1, i2);
}
 
break;
case 3:
for(i=1;i<9;i+=2) LCD_printfxy(0,i/2,"K%i:%4i K%i:%4i ",i,PPM_in[i],i+1,PPM_in[i+1]);
break;
case 4:
LCD_printfxy(0,0,"Ni:%4i Ro:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_NICK]],PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]);
LCD_printfxy(0,1,"Gs:%4i Gi:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_GAS]]+127,PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]);
LCD_printfxy(0,2,"P1:%4i P2:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]]+127,PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]]+127);
LCD_printfxy(0,3,"P3:%4i P4:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]]+127,PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]]+127);
break;
 
break;
 
case 5:
LCD_printfxy(0,0,"GPS UTC Time");
if (!SystemTime.Valid)
192,78 → 183,67
LCD_printfxy(0,0,"SD-Card Logs");
LCD_printfxy(0,1,"GPX:%4u (%3ims) ",Logged_GPX_Counter,LogCfg.GPX_Interval);
LCD_printfxy(0,2,"KML:%4u (%3ims) ", Logged_KML_Counter, LogCfg.KML_Interval);
LCD_printfxy(0,3,"Test: (%3ims) ", LogCfg.KML_Interval);
break;
case 7:
LCD_printfxy(0,0,"Voltage: %3i.%1iV",UBat/10, UBat%10);
LCD_printfxy(0,1,"Current: %3i.%1iA",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10);
LCD_printfxy(0,2,"Power: %4iW",Capacity.ActualPower);
LCD_printfxy(0,3,"Discharge: %5imAh", Capacity.UsedCapacity);
LCD_printfxy(0,0,"Voltage: %3i.%02iV",U_Bat/100, U_Bat%100);
LCD_printfxy(0,1,"Current: %3i.%1iA",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10);
LCD_printfxy(0,2,"Power: %4iW",Capacity.ActualPower);
LCD_printfxy(0,3,"Discharge:%5imAh", Capacity.UsedCapacity);
break;
case 8:
LCD_printfxy(0,0,"Receiver");
// LCD_printfxy(0,1,"RC-RSSI: %4i", PPM_in[0]);
LCD_printfxy(0,0,"Receiver:");
LCD_printfxy(0,1,"Voltage: %3i.%02iV", U_recv/100, U_recv%100);
LCD_printfxy(0,2,"RC-Quality: %4i", SenderOkay);
LCD_printfxy(0,3,"RC-Channels:%4i", Channels-1);
break;
case 9:
LCD_printfxy(0,0,"CPU Processing ");
LCD_printfxy(0,2,"GPS-Data: %2i.%iHz ",FreqNewGpsDataIn5Sec/10, FreqNewGpsDataIn5Sec%10);
LCD_printfxy(0,0,"ADC");
LCD_printfxy(0,1,"Voltage: %3i.%02iV", U_mess/100, U_mess%100);
LCD_printfxy(0,2,"Res4: %4i", Res4);
LCD_printfxy(0,3,"Res5: %4i", Res5);
break;
 
case 10:
LCD_printfxy(0,0,"CPU Processing ");
LCD_printfxy(0,1,"Update: %3i.%iHz ",FreqUpdateMotorIn5Sec/10, FreqUpdateMotorIn5Sec%10);
LCD_printfxy(0,2,"GPS-Data:%2i.%iHz ",FreqNewGpsDataIn5Sec/10, FreqNewGpsDataIn5Sec%10);
if(FreqNewGpsDataIn5Sec >= 48 && FreqNewGpsDataIn5Sec <= 52) LCD_printfxy(18,2,"OK") else LCD_printfxy(18,2,"!!");
break;
case 10:
case 11:
for(i=0;i<4;i++) LCD_printfxy(0,i,"Poti%i: %3i",i+1,Poti[i]);
break;
case 11:
case 12:
for(i=0;i<4;i++) LCD_printfxy(0,i,"Poti%i: %3i",i+5,Poti[i+4]);
break;
case 12:
//#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
case 13:
LCD_printfxy(0,0,"Servo " );
LCD_printfxy(0,1,"Setpoint %3i",Parameter_ServoNickControl);
LCD_printfxy(0,2,"Position: %3i",ServoNickValue/4);
LCD_printfxy(0,3,"Range:%3i-%3i",EE_Parameter.ServoNickMin,EE_Parameter.ServoNickMax);
LCD_printfxy(0,1,"Setpoint %3i",ServoNickValue);
break;
/* case 13:
LCD_printfxy(0,0,"ExternControl " );
LCD_printfxy(0,1,"Ni:%4i Ro:%4i ",ExternControl.Nick,ExternControl.Roll);
LCD_printfxy(0,2,"Gs:%4i Gi:%4i ",ExternControl.Gas,ExternControl.Gier);
LCD_printfxy(0,3,"Hi:%4i Cf:%4i ",ExternControl.Hight,ExternControl.Config);
break;
*/
//#endif
case 13:
case 14:
LCD_printfxy(0,0,"BL-Ctrl Errors " );
for(i=0;i<3;i++)
for(i=0;i<3;i++)
{
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+1].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+2].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+3].State & MOTOR_STATE_ERROR_MASK);
// if(i*4 >= RequiredMotors) break;
}
}
break;
case 14:
case 15:
LCD_printfxy(0,0,"BL Temperature" );
for(i=0;i<3;i++)
for(i=0;i<3;i++)
{
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].Temperature,Motor[i*4+1].Temperature,Motor[i*4+2].Temperature,Motor[i*4+3].Temperature);
// if(4 + i * 4 >= RequiredMotors) break;
}
}
break;
//#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
case 15:
case 16:
LCD_printfxy(0,0,"BL Current" );
LCD_printfxy(11,3,"(in 0.1A)" );
for(i=0;i<3;i++)
for(i=0;i<3;i++)
{
// LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].Current,Motor[i*4+1].Current,Motor[i*4+2].Current,Motor[i*4+3].Current);
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",BL3_Current(i*4),BL3_Current(i*4+1),BL3_Current(i*4+2),BL3_Current(i*4+3));
// LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].MaxPWM,Motor[i*4+1].MaxPWM,Motor[i*4+2].MaxPWM,Motor[i*4+3].MaxPWM);
if(4 + i * 4 >= RequiredMotors) break;
}
}
break;
//#endif
case 16:
case 17:
LCD_printfxy(0,0,"BL-Ctrl found " );
LCD_printfxy(0,1," %c %c %c %c ",'-' + 4 * (Motor[0].State>>7),'-' + 5 * (Motor[1].State>>7),'-' + 6 * (Motor[2].State>>7),'-' + 7 * (Motor[3].State>>7));
LCD_printfxy(0,2," %c %c %c %c ",'-' + 8 * (Motor[4].State>>7),'-' + 9 * (Motor[5].State>>7),'-' + 10 * (Motor[6].State>>7),'-' + 11 * (Motor[7].State>>7));
272,7 → 252,7
if(Motor[10].State>>7) LCD_printfxy(8,3,"11");
if(Motor[11].State>>7) LCD_printfxy(12,3,"12");
break;
case 17:
case 18:
LCD_printfxy(0,0,"Flight-Time " );
LCD_printfxy(0,1,"Total:%5umin",FlugMinutenGesamt);
LCD_printfxy(0,2,"Act: %5umin",FlugMinuten);
/I2C_Telemetry/trunk/mkprotocol.c
0,0 → 1,275
/*#######################################################################################*/
/* !!! THIS IS NOT FREE SOFTWARE !!! */
/*#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt.
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software.
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####'
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
// + agreement shall be the property of the Licensor.
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other
// + features that can be used to identify the program may not be altered or defaced by the customer.
// + The customer shall be responsible for taking reasonable precautions
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence.
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test
// + the software for his purpose before any operational usage. The customer will backup his data before using the software.
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations.
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
// + #### END OF LICENSING TERMS ####
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdarg.h>
#include <stdio.h>
#include <avr/boot.h>
#include <avr/wdt.h>
#include "mkprotocol.h"
 
 
/**************************************************************/
/* Create serial output frame */
/**************************************************************/
uint8_t AddSerialData(Buffer_t* pTxBuff, uint8_t *buffer, uint16_t size) //uint8_t *data, uint8_t len, ....
{
unsigned int i;
if(pTxBuff->Locked == 1) return(0);
// tx-buffer is not in use
// lock the buffer
pTxBuff->Locked = 1;
pTxBuff->Position = 0;
for(i=0; i<size; i++) pTxBuff->pData[pTxBuff->Position++] = buffer[i];
pTxBuff->DataBytes = pTxBuff->Position;
pTxBuff->Position = 0; // reset buffer position for transmision
return(pTxBuff->Locked);
}
 
/**************************************************************/
/* Create serial output frame */
/**************************************************************/
uint8_t MKProtocol_CreateSerialFrame(Buffer_t* pTxBuff, uint8_t CmdID, uint8_t Address, uint8_t numofbuffers , ...) //uint8_t *data, uint8_t len, ....
{
va_list ap;
 
uint8_t a,b,c;
uint16_t ptr = 0;
uint16_t tmpCRC = 0, i;
 
uint8_t* pdata = NULL;
int len = 0;
 
if(pTxBuff->Locked == 1) return(0);
 
// tx-buffer is not in use
// lock the buffer
pTxBuff->Locked = 1;
pTxBuff->Position = 0;
pTxBuff->pData[pTxBuff->Position++] = '#'; // Start character
pTxBuff->pData[pTxBuff->Position++] = 'a' + Address; // Address (a=0; b=1,...)
pTxBuff->pData[pTxBuff->Position++] = CmdID; // Command
 
va_start(ap, numofbuffers);
if(numofbuffers)
{
pdata = va_arg(ap, uint8_t*);
len = va_arg(ap, int);
ptr = 0;
numofbuffers--;
}
while(len)
{
if(len)
{
a = pdata[ptr++];
len--;
if((!len) && numofbuffers) // try to jump to next buffer
{
pdata = va_arg(ap, uint8_t*);
len = va_arg(ap, int);
ptr = 0;
numofbuffers--;
}
}
else a = 0;
if(len)
{
b = pdata[ptr++];
len--;
if((!len) && numofbuffers) // try to jump to next buffer
{
pdata = va_arg(ap, uint8_t*);
len = va_arg(ap, int);
ptr = 0;
numofbuffers--;
}
}
else b = 0;
if(len)
{
c = pdata[ptr++];
len--;
if((!len) && numofbuffers) // try to jump to next buffer
{
pdata = va_arg(ap, uint8_t*);
len = va_arg(ap, int);
ptr = 0;
numofbuffers--;
}
}
else c = 0;
pTxBuff->pData[pTxBuff->Position++] = '=' + (a >> 2);
pTxBuff->pData[pTxBuff->Position++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
pTxBuff->pData[pTxBuff->Position++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
pTxBuff->pData[pTxBuff->Position++] = '=' + ( c & 0x3f);
}
va_end(ap);
// add crc
for(i = 0; i < pTxBuff->Position; i++)
{
tmpCRC += pTxBuff->pData[i];
}
tmpCRC %= 4096;
pTxBuff->pData[pTxBuff->Position++] = '=' + tmpCRC / 64;
pTxBuff->pData[pTxBuff->Position++] = '=' + tmpCRC % 64;
pTxBuff->pData[pTxBuff->Position++] = '\r';
pTxBuff->DataBytes = pTxBuff->Position;
pTxBuff->Position = 0; // reset buffer position for transmision
return(pTxBuff->Locked);
}
 
// typical called in an UART Rx ISR
/**************************************************************/
/* Collect serial frame */
/**************************************************************/
uint8_t MKProtocol_CollectSerialFrame(Buffer_t* pRxBuff, uint8_t c)
{
if(pRxBuff->Locked == 0)
{ // rx buffer not locked
if(c == '#') // if syncronisation character is received
{
pRxBuff->Position = 0; // reset buffer
pRxBuff->pData[pRxBuff->Position++] = c; // copy 1st byte to buffer
pRxBuff->DataBytes = 1;
}
else if (pRxBuff->Position < pRxBuff->Size) // rx buffer not full
{
pRxBuff->pData[pRxBuff->Position++] = c; // copy byte to rxd buffer
pRxBuff->DataBytes++;
// termination character received and sync has been established
if ((c == '\r') && (pRxBuff->pData[0]== '#'))
{
// calculate checksum from transmitted data
uint16_t crc = 0, i;
uint8_t crc1, crc2;
for(i = 0; i < (pRxBuff->Position-3); i++)
{
crc += pRxBuff->pData[i];
}
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
// compare checksum to transmitted checksum bytes
if((crc1 == pRxBuff->pData[pRxBuff->Position-3]) && (crc2 == pRxBuff->pData[pRxBuff->Position-2]))
{
// checksum is valid
pRxBuff->Position = 0;
pRxBuff->Locked = 1; // lock the rxd buffer
// if 2nd byte is an 'R' start bootloader
if(pRxBuff->pData[2] == 'R') // not if the motors are running)
{
//LcdClear();
wdt_enable(WDTO_250MS); // Reset-Commando
}
} // eof checksum valid
else
{ // checksum is invalid
Buffer_Clear(pRxBuff);
} // eof checksum invalid
} // eof termination character received
} // rxd buffer not full
else // rxd buffer overrun
{
Buffer_Clear(pRxBuff);
} // eof rxd buffer overrun
}
return(pRxBuff->Locked);
}
 
/**************************************************************/
/* Decode detination address */
/**************************************************************/
void MKProtocol_DecodeSerialFrameHeader(Buffer_t* pRxBuff, SerialMsg_t* pSerialMsg)
{
if(pRxBuff->Locked)
{
pSerialMsg->Address = pRxBuff->pData[1] - 'a';
pSerialMsg->CmdID = pRxBuff->pData[2];
}
else
{
pSerialMsg->Address = 0;
pSerialMsg->CmdID = ' ';
}
}
 
/**************************************************************/
/* Decode data */
/**************************************************************/
void MKProtocol_DecodeSerialFrameData(Buffer_t* pRxBuff, SerialMsg_t* pSerialMsg)
{
uint8_t a,b,c,d;
uint16_t ptrIn = 3; // start with first data byte in rx buffer
uint16_t ptrOut = 3;
uint16_t len = pRxBuff->DataBytes - 6; // must be a multiple of 4 (3 bytes at begin and 3 bytes at end are no payload )
 
len/=4; // number of 4 byte blocks
while(len--)
{
a = pRxBuff->pData[ptrIn++] - '=';
b = pRxBuff->pData[ptrIn++] - '=';
c = pRxBuff->pData[ptrIn++] - '=';
d = pRxBuff->pData[ptrIn++] - '=';
 
pRxBuff->pData[ptrOut++] = (a << 2) | (b >> 4);
pRxBuff->pData[ptrOut++] = ((b & 0x0f) << 4) | (c >> 2);
pRxBuff->pData[ptrOut++] = ((c & 0x03) << 6) | d;
}
pSerialMsg->pData = &(pRxBuff->pData[3]);
pSerialMsg->DataLen = ptrOut - 3; // return number of data in bytes
pRxBuff->Position = 0;
pRxBuff->DataBytes = ptrOut;
}
 
/I2C_Telemetry/trunk/mkprotocol.h
0,0 → 1,27
#ifndef _MKPROTOCOL_H
#define _MKPROTOCOL_H
#include "buffer.h"
 
// slave addresses
#define ANY_ADDRESS 0
#define FC_ADDRESS 1
#define NC_ADDRESS 2
#define MK3MAG_ADDRESS 3
#define MKOSD_ADDRESS 4
#define BL_ADDRESS 5
 
typedef struct
{
uint8_t Address;
uint8_t CmdID;
uint8_t* pData;
uint16_t DataLen;
} __attribute__((packed)) SerialMsg_t;
 
uint8_t MKProtocol_CollectSerialFrame(Buffer_t* pRxBuff, uint8_t c);
uint8_t MKProtocol_CreateSerialFrame(Buffer_t* pTxBuff, uint8_t CmdID, uint8_t Address, uint8_t numofbuffers , ...); //uint8_t *data, uint8_t len, ....;
uint8_t AddSerialData(Buffer_t* pTxBuff, uint8_t *buffer, uint16_t size);
void MKProtocol_DecodeSerialFrameHeader(Buffer_t* pRxBuff, SerialMsg_t* pSerialMsg);
void MKProtocol_DecodeSerialFrameData(Buffer_t* pRxBuff, SerialMsg_t* pSerialMsg);
 
#endif // _MKPROTOCOL_H
/I2C_Telemetry/trunk/rc.c
7,7 → 7,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18,7 → 18,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
32,7 → 32,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
53,44 → 53,32
// + #### END OF LICENSING TERMS ####
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdlib.h>
#include <avr/interrupt.h>
#include "rc.h"
 
#include "rc.h"
#include "main.h"
// Achtung: ACT_S3D_SUMMENSIGNAL wird in der Main.h gesetzt
#define MAX_RC_IN 16+12+3+4 // 16ch + 12ser + 3stages + 4 reserved
volatile int PPM_in[MAX_RC_IN];
volatile int PPM_diff[MAX_RC_IN]; // das differnzierte Stick-Signal
volatile char Channels,tmpChannels = 0;
#define MAX_RC_IN 16 // 16ch
volatile int PPM_in[MAX_RC_IN+1];
 
volatile char Channels;
volatile unsigned char NewPpmData = 1;
unsigned int PPM_Neutral = 466;
volatile unsigned char SenderOkay = 0;
 
//############################################################################
// Clear the values
void rc_sum_init(void)
//############################################################################
 
void RC_Init(void)
{
unsigned char i;
for(i=0;i<MAX_RC_IN;i++)
{
if(i < 5) PPM_in[i] = 0; else PPM_in[i] = -127;
PPM_diff[i] = 0;
}
PPM_in[PPM_IN_MAX] = +127;
PPM_in[PPM_IN_OFF] = -127;
PPM_in[PPM_IN_MID] = 0;
return;
unsigned char i;
 
for(i = 0; i <= MAX_RC_IN; i++)
{
PPM_in[i] = 0;
}
}
 
#ifndef ACT_S3D_SUMMENSIGNAL
//############################################################################
// Interrupt function for the PPM-Input
 
ISR(TIMER1_CAPT_vect)
//############################################################################
{
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(!(EE_Parameter.ExtraConfig & CFG_SENSITIVE_RC))
#endif
{
static unsigned int AltICR=0;
signed int signal = 0,tmp;
static int index;
99,182 → 87,35
AltICR = ICR1;
//Syncronisationspause? (3.52 ms < signal < 25.6 ms)
if((signal > 1100) && (signal < 8000))
{
Channels = index;
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten
index = 1;
}
{
Channels = index;
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten
index = 1;
}
else
{
if(index < 13+4)
{
if(index < 13+4)
{
if((signal > 250) && (signal < 687))
{
signal -= PPM_Neutral;
// Stabiles Signal
if(EE_Parameter.FailsafeChannel == 0 || PPM_in[EE_Parameter.FailsafeChannel] < 100) // forces Failsafe if the receiver doesn't have 'signal loss' on Failsafe
{
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10; else SenderOkay = 200;}
}
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
else PPM_diff[index] = 0;
PPM_in[index] = tmp;
}
{
signal -= PPM_Neutral;
// Stabiles Signal
if(abs(signal - PPM_in[index]) < 6)
{
if(SenderOkay < 200) SenderOkay += 10;
else SenderOkay = 200;
}
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
PPM_in[index] = tmp;
}
index++;
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
#else
if(PlatinenVersion < 20)
{
if(index == 5) J3High; else J3Low; // Servosignal an J3 anlegen
if(index == 6) J4High; else J4Low; // Servosignal an J4 anlegen
if(index == 7) J5High; else J5Low; // Servosignal an J5 anlegen
}
#endif
}
}
}
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
else
{
static unsigned int AltICR=0;
static int ppm_in[13+4];
static int ppm_diff[13+4];
static int old_ppm_in[13+4];
static int old_ppm_diff[13+4];
signed int signal = 0,tmp;
static unsigned char index, okay_cnt = 0;
signal = (unsigned int) ICR1 - AltICR;
AltICR = ICR1;
//Syncronisationspause? (3.52 ms < signal < 25.6 ms)
if((signal > 1100) && (signal < 8000))
{
tmpChannels = index;
if(tmpChannels >= 4 && Channels == tmpChannels)
{
if(okay_cnt > 10)
{
NewPpmData = 0; // Null bedeutet: Neue Daten
for(index = 0; index < 13+4; index++)
{
if(okay_cnt > 30)
{
old_ppm_in[index] = PPM_in[index];
old_ppm_diff[index] = PPM_diff[index];
}
PPM_in[index] = ppm_in[index];
PPM_diff[index] = ppm_diff[index];
}
}
if(okay_cnt < 255) okay_cnt++;
}
else
{
if(okay_cnt > 100) okay_cnt = 10; else okay_cnt = 0;
ROT_ON;
}
index = 1;
if(!MotorenEin) Channels = tmpChannels;
}
else
{
if(index < 13+4)
{
if((signal > 250) && (signal < 687))
{
signal -= PPM_Neutral;
// Stabiles Signal
if((abs(signal - ppm_in[index]) < 6))
{
if(EE_Parameter.FailsafeChannel == 0 || PPM_in[EE_Parameter.FailsafeChannel] < 100) // forces Failsafe if the receiver doesn't have 'signal loss' on Failsafe
{
if(okay_cnt > 25) SenderOkay += 10;
else
if(okay_cnt > 10) SenderOkay += 2;
if(SenderOkay > 200) SenderOkay = 200;
}
}
tmp = (3 * (ppm_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
if(SenderOkay >= 190) ppm_diff[index] = ((tmp - ppm_in[index]) / 3) * 3;
else ppm_diff[index] = 0;
ppm_in[index] = tmp;
}
else ROT_ON;
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
#else
if(PlatinenVersion < 20)
{
if(index == 5) J3High; else J3Low; // Servosignal an J3 anlegen
if(index == 6) J4High; else J4Low; // Servosignal an J4 anlegen
if(index == 7) J5High; else J5Low; // Servosignal an J5 anlegen
}
#endif
}
if(index < 20) index++;
else
if(index == 20)
{
unsigned char i;
ROT_ON;
index = 30;
for(i=0;i<13+4;i++) // restore from older data
{
PPM_in[i] = old_ppm_in[i];
PPM_diff[i] = 0;
// okay_cnt /= 2;
}
}
}
}
#endif
 
}
 
#else
//############################################################################
// Interrupt function for the PPM-Input
ISR(TIMER1_CAPT_vect)
//############################################################################
 
{
static unsigned int AltICR=0;
signed int signal = 0,tmp;
static int index;
 
signal = (unsigned int) ICR1 - AltICR;
signal /= 2;
AltICR = ICR1;
//Syncronisationspause?
if((signal > 1100*2) && (signal < 8000*2))
{
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten
index = 1;
}
else
{
if(index < 13)
{
if((signal > 250) && (signal < 687*2))
{
signal -= 962;
// Stabiles Signal
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;}
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
else PPM_diff[index] = 0;
PPM_in[index] = tmp;
}
index++;
}
}
}
#endif
 
 
 
/I2C_Telemetry/trunk/rc.h
1,42 → 1,19
/*#######################################################################################
Derkodieren eines RC Summen Signals
Derkodieren eines RC Summen Signals
#######################################################################################*/
 
#ifndef _RC_H
#define _RC_H
 
#if defined (__AVR_ATmega644__)
#define TIMER_RELOAD_VALUE 250
#endif
#define MAX_RC_IN 16 // 16ch
 
#if defined (__AVR_ATmega644P__)
#define TIMER_RELOAD_VALUE 250
#endif
extern void RC_Init(void);
 
#define MAX_RC_IN 16+12+3+4 // 16ch + 12ser + 3stages + 4 reserved
 
extern void rc_sum_init (void);
 
extern volatile int PPM_in[MAX_RC_IN];
extern volatile int PPM_diff[MAX_RC_IN]; // das diffenzierte Stick-Signal
extern volatile int PPM_in[MAX_RC_IN+1];
extern unsigned int PPM_Neutral;
extern volatile unsigned char NewPpmData;
extern volatile char Channels,tmpChannels;
extern unsigned int PPM_Neutral;
extern volatile char Channels;
extern volatile unsigned char SenderOkay;
 
// 0 -> frei bzw. ACT rssi
// 1 - 16 -> 1-16
// 17 - 28 -> 12 Serial channels
// 29 -> WP-Event kanal
// 30 -> -127
// 31 -> 0
// 32 -> 128
 
#define SERIAL_POTI_START 17
#define WP_EVENT_PPM_IN 29
#define PPM_IN_OFF 30
#define PPM_IN_MAX 31
#define PPM_IN_MID 32
 
#define FromNC_WP_EventChannel PPM_in[WP_EVENT_PPM_IN] // WP_EVENT-Channel-Value
 
#endif //_RC_H
/I2C_Telemetry/trunk/sbus.c
7,7 → 7,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18,7 → 18,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
32,7 → 32,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
57,7 → 57,6
#include "sbus.h"
#include "main.h"
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
unsigned char NewSBusData = 0, sBusBuffer[25];
 
//############################################################################
68,9 → 67,9
// -- Start of USART1 initialisation for Spekturm seriell-mode
// USART1 Control and Status Register A, B, C and baud rate register
uint8_t sreg = SREG;
 
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * 100000) - 1);
 
// disable all interrupts before reconfiguration
cli();
// disable RX-Interrupt
87,7 → 86,7
// set TXD1 (PD3) as an output pin
PORTD |= (1 << PORTD3);
DDRD |= (1 << DDD3);
*/
*/
// USART0 Baud Rate Register
// set clock divider
UBRR1H = (uint8_t)(ubrr>>8);
133,18 → 132,18
static unsigned char ptr = 0;
if(!SpektrumTimer && udr == 0x0f) // wait for the start
{
ptr = 0;
ptr = 0;
SpektrumTimer = 80; // 8ms gap
}
else
else
{
if(++ptr == 24) // last byte
{
NewSBusData = 1;
}
else
else
if(ptr > 24) ptr = 25;
else
else
{
sBusBuffer[ptr] = udr; // collect all bytes
}
157,20 → 156,20
unsigned char bitmask8 = 1, sbyte = 2, i, index = 1, process;
unsigned int bitmask11 = 256;
signed int signal = 0,tmp;
 
if(!(sBusBuffer[23] & 4)) // This Bit contains the 'Signal loss'
{
TIMSK1 &= ~_BV(ICIE1); // disable PPM-Input
if(EE_Parameter.FailsafeChannel == 0 || PPM_in[EE_Parameter.FailsafeChannel] < 100) // forces Failsafe if the receiver doesn't have 'signal loss' on Failsafe
{
if(SenderOkay < 200) SenderOkay += 20; else SenderOkay = 200;
}
 
 
if(SenderOkay < 200) SenderOkay += 20; else SenderOkay = 200;
 
signal = sBusBuffer[1];
if(!load--) { process = (12*11 - 8); load = 2;} else process = (4*11 - 8); // lowers the processor load
if(!load--) { process = (12*11 - 8); load = 2;} else process = (4*11 - 8); // lowers the processor load
for(i = 0; i < process; i++) // collect the single bits
{
if(sBusBuffer[sbyte] & bitmask8) signal |= bitmask11;
bitmask8 *= 2;
bitmask8 *= 2;
if(!bitmask8)
{
bitmask8 = 1;
181,11 → 180,9
{
bitmask11 = 1;
signal = (signal-1024) / 5; // the resolution is higher than required
tmp = (3 * (PPM_in[index]) + signal) / 4;
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
else PPM_diff[index] = 0;
PPM_in[index] = tmp;
signal = 0;
index++; // next channel
196,4 → 193,3
NewSBusData = 0;
}
 
#endif
/I2C_Telemetry/trunk/sbus.h
1,11 → 1,10
#ifndef _SBUS_H
#define _SBUS_H
 
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
extern unsigned char NewSBusData, sBusBuffer[25];
extern void SbusParser(unsigned char);
extern void SbusUartInit(void);
extern void ProcessSBus(void);
 
 
#endif
#endif
/I2C_Telemetry/trunk/settings.c
60,9 → 60,9
#include "fat16.h"
#include "settings.h"
#include "main.h"
unsigned int WaypointAccelerationSetting = 100; // acceleration for flying waypoints in percent (0-100) or Poti -> 255 = Poti1, 254 = Poti2...
unsigned int WaypointAcceleration = 100; // the real value
 
unsigned char GPS_RC_Channel = 0;
 
typedef struct
{
ParamId_t ParamId;
94,16 → 94,9
{PID_RECEIVER , "RECEIVER \0" ,"0=PPM,1=Spek,2=SpekHi,3=SpekLo,4=Jeti,5=ACT,6=HoTT,7=SBus ", 1, 1, 6, 0, 8},
{PID_KML_LOGGING , "KMLLOGGING \0" ,"KML logging interval in ms (0 = disabled) ", 1, 200, 500, 0, 60000}, // the log interval for KML logging, 0 = off
{PID_GPX_LOGGING , "GPXLOGGING \0" ,"GPX logging interval in ms (0 = disabled) ", 1, 500, 500, 0, 60000}, // the log interval for GPX logging, 0 = off
{PID_ABSOLUTE_FLYING_ALT , "MAX_FLYING_ALT \0" ,"max. altitude in m ", 1, 0, 0, 0, 30000}, // in [m]
{PID_ABSOLUTE_FLYING_RANGE , "MAX_FLYING_RANGE\0" ,"max. range in m ", 1, 0, 0, 0, 60000}, // in [m]
{PID_AUTO_DESCEND_RANGE , "DESCEND_RANGE \0" ,"Auto-descend range in m (0 = disabled) (only comm. License) ", 1, 0, 0, 0, 60000}, // in [m]
{PID_GPS_SBAS_CONFIG , "GPS_SBAS_DGPS_ON\0" ,"GPS SBAS mode (0 = off, 1 = on) ", 1, 1, 1, 0, 1},
{PID_MIN_EVENT_TIME , "MIN_EVENT_TIME \0" ,"minimum time of the Waypoint-Event value (seconds) ", 1, 2, 2, 0, 600}, // in seconds
{PID_WP_ACCELERATE , "WAYPOINT DYNAMIC\0" ,"dynamic for flying waypoints in percent (0-200) ", 1, 100, 100, 0, 255}, // in percent or Poti
{PID_WP_WAIT_FOR_LED , "WAIT_FOR_OUT1 \0" ,"Wait on Waypoint until Out-Pattern is finished (1=on 0=off) ", 1, 1, 1, 0, 1},
{PID_SEND_NMEA , "NMEA_INTERVAL \0" ,"NMEA Output interval in ms (0 = disabled) ", 1, 0, 0, 0, 60000}, // the log interval for GPX logging, 0 = off
{PID_GPS_AUTOCONFIG , "GPSAUTOCONFIG \0" ,"GPS configmode (0 = off, 1 = on) ", 1, 1, 1, 0, 1}
 
{PID_GPS_AUTOCONFIG , "GPSAUTOCONFIG \0" ,"GPS configmode (0 = off, 1 = on) ", 1, 1, 1, 0, 1},
{PID_GPS_RC_CANNEL , "GPS_RC_CHANNEL \0" ,"GPS rc channel (0 = off ", 1, 0, 0, 0, 16}
};
 
 
143,7 → 136,7
if((CFG_Parameter[i].Value < CFG_Parameter[i].Min) || (CFG_Parameter[i].Value > CFG_Parameter[i].Max))
{ // print a warning
printf("\r\n%s <-- %d is out of range [%d...%d]", string, CFG_Parameter[i].Value, CFG_Parameter[i].Min, CFG_Parameter[i].Max);
 
CFG_Parameter[i].Value = CFG_Parameter[i].Default; // fallback to default
}
retval = 1; // value in range
153,7 → 146,7
if(!retval)
{
printf("\r\n%s <-- unknown parameter\r\n", string);
 
}
return(retval);
}
174,7 → 167,7
Settings_SetDefaultValues();
if(Fat16_IsValid())
{ // check if settings file is existing
 
if(fexist_(filename))
{
fp = fopen_(filename, 'r'); // try to open the file
187,7 → 180,7
printf(".reading...");
while(fgets_(settingsline, LINE_MAX, fp) != 0 && (SD_WatchDog))
{
 
if ( // ignorelines starting with \r,\n,' ',';','#'
(settingsline[0] != '\n') &&
(settingsline[0] != '\r') &&
196,10 → 189,10
(settingsline[0] != '#' )
)
{
 
name = strtok(settingsline, "="); // get name
value = strtok(NULL, "="); // get value
 
if ((name != NULL) && (value != NULL))
{
unsigned char i;
/I2C_Telemetry/trunk/settings.h
8,21 → 8,16
PID_KML_LOGGING,
PID_GPX_LOGGING,
PID_GPS_AUTOCONFIG,
PID_ABSOLUTE_FLYING_RANGE,
PID_ABSOLUTE_FLYING_ALT,
PID_GPS_SBAS_CONFIG,
PID_AUTO_DESCEND_RANGE,
PID_MIN_EVENT_TIME,
PID_WP_WAIT_FOR_LED,
PID_WP_ACCELERATE,
PID_SEND_NMEA
PID_GPS_RC_CANNEL
} ParamId_t;
 
void Settings_Init(void);
void Settings_SetDefaultValues(void);
unsigned char Settings_GetParamValue(ParamId_t Pid, unsigned int* pValue);
extern unsigned int WaypointAccelerationSetting; // acceleration for flying waypoints in percent (0-100) or Poti -> 255 = Poti1, 254 = Poti2...
extern unsigned int WaypointAcceleration; // the real value
 
unsigned char GPS_RC_Channel;
 
#endif // _SETTINGS_H
 
 
/I2C_Telemetry/trunk/timer0.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
57,19 → 57,13
volatile unsigned int CountMilliseconds = 0;
volatile unsigned int tim_main;
volatile unsigned char UpdateMotor = 0;
volatile unsigned int cntKompass = 0;
volatile unsigned int beeptime = 0;
volatile unsigned char BytegapSPI = 0, ServoActive = 0, CalculateServoSignals = 1;
unsigned char JustMK3MagConnected = 0;
 
uint16_t RemainingPulse = 0;
volatile int16_t ServoNickOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon
volatile int16_t ServoRollOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon
 
unsigned int BeepMuster = 0xffff;
signed int NickServoValue = 128 * MULTIPLYER * 16;
 
volatile int16_t ServoNickValue = 0;
volatile int16_t ServoRollValue = 0;
signed int ServoNickValue = 0;
 
DateTime_t SystemTime;
 
90,7 → 84,6
{
static unsigned char cnt_1ms = 1,cnt = 0;
unsigned char pieper_ein = 0;
if(BytegapSPI) BytegapSPI--;
if(SpektrumTimer) SpektrumTimer--;
if(!cnt--)
{
101,8 → 94,8
cnt_1ms %= 2;
 
if(!cnt_1ms) if(UpdateMotor < 4) UpdateMotor++;
 
 
if(beeptime)
{
if(beeptime > 10) beeptime -= 10; else beeptime = 0;
120,7 → 113,7
if(pieper_ein) PORTC |= (1<<7); // Speaker an PORTC.7
else PORTC &= ~(1<<7);
}
 
}
 
 
127,40 → 120,36
// -----------------------------------------------------------------------
unsigned int SetDelay(unsigned int t)
{
// TIMSK0 &= ~_BV(TOIE0);
return(CountMilliseconds + t + 1);
// TIMSK0 |= _BV(TOIE0);
return(CountMilliseconds + t + 1);
}
 
// -----------------------------------------------------------------------
char CheckDelay(unsigned int t)
{
// TIMSK0 &= ~_BV(TOIE0);
return(((t - CountMilliseconds) & 0x8000) >> 9);
// TIMSK0 |= _BV(TOIE0);
return(((t - CountMilliseconds) & 0x8000) >> 9);
}
 
// -----------------------------------------------------------------------
void Delay_ms(unsigned int w)
{
unsigned int akt;
akt = SetDelay(w);
while (!CheckDelay(akt));
unsigned int akt;
akt = SetDelay(w);
while (!CheckDelay(akt));
}
 
void Delay_ms_Mess(unsigned int w)
{
unsigned int akt;
akt = SetDelay(w);
while (!CheckDelay(akt)) if(AdReady) {AdReady = 0; ANALOG_ON;}
unsigned int akt;
akt = SetDelay(w);
while (!CheckDelay(akt)) if(AdReady) {AdReady = 0; ANALOG_ON;}
}
 
/*****************************************************/
/* Initialize Timer 2 */
/*****************************************************/
// The timer 2 is used to generate the PWM at PD7 (J7)
// to control a camera servo for nick compensation.
void TIMER2_Init(void)
// The timer 2 is used to generate the PWM at PD7 (SERVO_C)
// to control a servo
void Timer2_Init(void)
{
uint8_t sreg = SREG;
 
169,8 → 158,6
 
PORTD &= ~(1<<PORTD7); // set PD7 to low
 
DDRC |= (1<<DDC6); // set PC6 as output (Reset for HEF4017)
HEF4017Reset_ON;
// Timer/Counter 2 Control Register A
 
// Timer Mode is FastPWM with timer reload at OCR2A (Bits: WGM22 = 1, WGM21 = 1, WGM20 = 1)
204,105 → 191,64
SREG = sreg;
}
 
//----------------------------
void Timer_Init(void)
{
tim_main = SetDelay(10);
TCCR0B = CK8;
// TCCR0A = (1<<COM0A1)|(1<<COM0B1)|3;//fast PWM
TCCR0A = (1<<COM0A1)|(1<<COM0B1)|(1<<COM0B0)|3;//fast PWM
OCR0B = 255;
OCR0A = 180;
TCNT0 = (unsigned char)-TIMER_RELOAD_VALUE; // reload
//OCR1 = 0x00;
TIMSK0 |= _BV(TOIE0);
}
 
 
/*****************************************************/
/* Control Servo Position */
/* Initialize Timer 0 */
/*****************************************************/
void CalcNickServoValue(void)
// timer 0 is used for the PWM generation to control the offset voltage at the air pressure sensor
// Its overflow interrupt routine is used to generate the beep signal and the flight control motor update rate
void Timer0_Init(void)
{
signed int max, min;
uint8_t sreg = SREG;
 
if(EE_Parameter.ServoCompInvert & SERVO_RELATIVE) // relative moving of the servo value
{
max = ((unsigned int) EE_Parameter.ServoNickMax * MULTIPLYER * 15);
min = ((unsigned int) EE_Parameter.ServoNickMin * MULTIPLYER * 20);
NickServoValue -= ((signed char) (Parameter_ServoNickControl - 128) / 4) * 6;
LIMIT_MIN_MAX(NickServoValue,min, max);
}
else NickServoValue = (int16_t)Parameter_ServoNickControl * (MULTIPLYER*16); // direct poti control
}
// disable all interrupts before reconfiguration
cli();
 
void CalculateServo(void)
{
signed char cosinus, sinus;
signed long nick, roll;
// configure speaker port as output
// Speaker at PC7
DDRC |= (1<<DDC7);
PORTC &= ~(1<<PORTC7);
 
cosinus = sintab[EE_Parameter.CamOrientation + 6];
sinus = sintab[EE_Parameter.CamOrientation];
 
if(CalculateServoSignals == 1)
{
nick = 0;
nick = ((long)Parameter_ServoNickComp * nick) / 512L;
// offset (Range from 0 to 255 * 3 = 765)
if(EE_Parameter.ServoCompInvert & SERVO_RELATIVE) ServoNickOffset = NickServoValue;
else ServoNickOffset += (NickServoValue - ServoNickOffset) / EE_Parameter.ServoManualControlSpeed;
// set PB3 and PB4 as output for the PWM used as offset for the pressure sensor
DDRB |= (1<<DDB4)|(1<<DDB3);
PORTB &= ~((1<<PORTB4)|(1<<PORTB3));
 
if(EE_Parameter.ServoCompInvert & SERVO_NICK_INV) // inverting movement of servo
{
nick = ServoNickOffset / 16 + nick;
}
else
{ // inverting movement of servo
nick = ServoNickOffset / 16 - nick;
}
if(EE_Parameter.ServoFilterNick) ServoNickValue = ((ServoNickValue * EE_Parameter.ServoFilterNick) + nick) / (EE_Parameter.ServoFilterNick + 1);
else ServoNickValue = nick;
// limit servo value to its parameter range definition
if(ServoNickValue < ((int16_t)EE_Parameter.ServoNickMin * MULTIPLYER))
{
ServoNickValue = (int16_t)EE_Parameter.ServoNickMin * MULTIPLYER;
}
else
if(ServoNickValue > ((int16_t)EE_Parameter.ServoNickMax * MULTIPLYER))
{
ServoNickValue = (int16_t)EE_Parameter.ServoNickMax * MULTIPLYER;
}
if(PlatinenVersion < 20) CalculateServoSignals = 0; else CalculateServoSignals++;
}
else
{
roll = ((long)Parameter_ServoRollComp * roll) / 512L;
ServoRollOffset += ((int16_t)Parameter_ServoRollControl * (MULTIPLYER*16) - ServoRollOffset) / EE_Parameter.ServoManualControlSpeed;
if(EE_Parameter.ServoCompInvert & SERVO_ROLL_INV)
{ // inverting movement of servo
roll = ServoRollOffset / 16 + roll;
}
else
{ // inverting movement of servo
roll = ServoRollOffset / 16 - roll;
}
if(EE_Parameter.ServoFilterRoll) ServoRollValue = ((ServoRollValue * EE_Parameter.ServoFilterRoll) + roll) / (EE_Parameter.ServoFilterRoll + 1);
else ServoRollValue = roll;
// limit servo value to its parameter range definition
if(ServoRollValue < ((int16_t)EE_Parameter.ServoRollMin * MULTIPLYER))
{
ServoRollValue = (int16_t)EE_Parameter.ServoRollMin * MULTIPLYER;
}
else
if(ServoRollValue > ((int16_t)EE_Parameter.ServoRollMax * MULTIPLYER))
{
ServoRollValue = (int16_t)EE_Parameter.ServoRollMax * MULTIPLYER;
}
CalculateServoSignals = 0;
}
// Timer/Counter 0 Control Register A
 
// Waveform Generation Mode is Fast PWM (Bits WGM02 = 0, WGM01 = 1, WGM00 = 1)
// Clear OC0A on Compare Match, set OC0A at BOTTOM, noninverting PWM (Bits COM0A1 = 1, COM0A0 = 0)
// Clear OC0B on Compare Match, set OC0B at BOTTOM, (Bits COM0B1 = 1, COM0B0 = 0)
TCCR0A &= ~((1<<COM0A0)|(1<<COM0B0));
TCCR0A |= (1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
 
// Timer/Counter 0 Control Register B
 
// set clock divider for timer 0 to SYSCLOCK/8 = 20MHz / 8 = 2.5MHz
// i.e. the timer increments from 0x00 to 0xFF with an update rate of 2.5 MHz
// hence the timer overflow interrupt frequency is 2.5 MHz / 256 = 9.765 kHz
 
// divider 8 (Bits CS02 = 0, CS01 = 1, CS00 = 0)
TCCR0B &= ~((1<<FOC0A)|(1<<FOC0B)|(1<<WGM02));
TCCR0B = (TCCR0B & 0xF8)|(0<<CS02)|(1<<CS01)|(0<<CS00);
 
// initialize the Output Compare Register A & B used for PWM generation on port PB3 & PB4
OCR0A = 0; // for PB3
OCR0B = 180; // for PB4
 
// init Timer/Counter 0 Register
TCNT0 = 0;
 
// Timer/Counter 0 Interrupt Mask Register
// enable timer overflow interrupt only
TIMSK0 &= ~((1<<OCIE0B)|(1<<OCIE0A));
TIMSK0 |= (1<<TOIE0);
 
SREG = sreg;
}
 
 
ISR(TIMER2_COMPA_vect)
{
// frame len 22.5 ms = 14063 * 1.6 us
313,7 → 259,7
 
#define IRS_RUNTIME 127
#define PPM_STOPPULSE 188
#define PPM_FRAMELEN (1757 * EE_Parameter.ServoNickRefresh)
#define PPM_FRAMELEN (1757 * 4)
#define MINSERVOPULSE 375
#define MAXSERVOPULSE 1500
#define SERVORANGE (MAXSERVOPULSE - MINSERVOPULSE)
320,111 → 266,31
 
static uint8_t PulseOutput = 0;
static uint16_t ServoFrameTime = 0;
static uint8_t ServoIndex = 0;
 
 
if(PlatinenVersion < 20)
//---------------------------
// Nick servo state machine
//---------------------------
if(!PulseOutput) // pulse output complete
{
//---------------------------
// Nick servo state machine
//---------------------------
if(!PulseOutput) // pulse output complete
if(TCCR2A & (1<<COM2A0)) // we had a low pulse
{
if(TCCR2A & (1<<COM2A0)) // we had a low pulse
{
TCCR2A &= ~(1<<COM2A0);// make a high pulse
RemainingPulse = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms
RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
// range servo pulse width
if(RemainingPulse > MAXSERVOPULSE ) RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit
else if(RemainingPulse < MINSERVOPULSE ) RemainingPulse = MINSERVOPULSE; // lower servo pulse limit
// accumulate time for correct update rate
ServoFrameTime = RemainingPulse;
}
else // we had a high pulse
{
TCCR2A |= (1<<COM2A0); // make a low pulse
RemainingPulse = PPM_FRAMELEN - ServoFrameTime;
CalculateServoSignals = 1;
}
// set pulse output active
PulseOutput = 1;
TCCR2A &= ~(1<<COM2A0);// make a high pulse
RemainingPulse = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms
RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
// range servo pulse width
if(RemainingPulse > MAXSERVOPULSE ) RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit
else if(RemainingPulse < MINSERVOPULSE ) RemainingPulse = MINSERVOPULSE; // lower servo pulse limit
// accumulate time for correct update rate
ServoFrameTime = RemainingPulse;
}
} // EOF Nick servo state machine
else
{
//-----------------------------------------------------
// PPM state machine, onboard demultiplexed by HEF4017
//-----------------------------------------------------
if(!PulseOutput) // pulse output complete
else // we had a high pulse
{
if(TCCR2A & (1<<COM2A0)) // we had a low pulse
{
TCCR2A &= ~(1<<COM2A0);// make a high pulse
if(ServoIndex == 0) // if we are at the sync gap
{
RemainingPulse = PPM_FRAMELEN - ServoFrameTime; // generate sync gap by filling time to full frame time
ServoFrameTime = 0; // reset servo frame time
HEF4017Reset_ON; // enable HEF4017 reset
}
else // servo channels
if(ServoIndex > EE_Parameter.ServoNickRefresh)
{
RemainingPulse = 10; // end it here
}
else
{
RemainingPulse = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms
switch(ServoIndex) // map servo channels
{
case 1: // Nick Compensation Servo
RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
break;
case 2: // Roll Compensation Servo
RemainingPulse += ServoRollValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
break;
case 3:
RemainingPulse += ((int16_t)Parameter_Servo3 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
break;
case 4:
RemainingPulse += ((int16_t)Parameter_Servo4 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
break;
case 5:
RemainingPulse += ((int16_t)Parameter_Servo5 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
break;
default: // other servo channels
RemainingPulse += 2 * PPM_in[ServoIndex]; // add channel value, factor of 2 because timer 1 increments 3.2µs
break;
}
// range servo pulse width
if(RemainingPulse > MAXSERVOPULSE) RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit
else if(RemainingPulse < MINSERVOPULSE) RemainingPulse = MINSERVOPULSE; // lower servo pulse limit
// substract stop pulse width
RemainingPulse -= PPM_STOPPULSE;
// accumulate time for correct sync gap
ServoFrameTime += RemainingPulse;
}
}
else // we had a high pulse
{
TCCR2A |= (1<<COM2A0); // make a low pulse
// set pulsewidth to stop pulse width
RemainingPulse = PPM_STOPPULSE;
// accumulate time for correct sync gap
ServoFrameTime += RemainingPulse;
if((ServoActive && SenderOkay) || ServoActive == 2) HEF4017Reset_OFF; // disable HEF4017 reset
else HEF4017Reset_ON;
ServoIndex++;
if(ServoIndex > EE_Parameter.ServoNickRefresh+1)
{
CalculateServoSignals = 1;
ServoIndex = 0; // reset to the sync gap
}
}
// set pulse output active
PulseOutput = 1;
TCCR2A |= (1<<COM2A0); // make a low pulse
RemainingPulse = PPM_FRAMELEN - ServoFrameTime;
}
} // EOF PPM state machine
// set pulse output active
PulseOutput = 1;
}
 
// General pulse output generator
if(RemainingPulse > (255 + IRS_RUNTIME))
/I2C_Telemetry/trunk/timer0.h
3,8 → 3,6
 
#define TIMER_TEILER CK8
#define TIMER_RELOAD_VALUE 250
#define HEF4017Reset_ON PORTC |= (1<<PORTC6)
#define HEF4017Reset_OFF PORTC &= ~(1<<PORTC6)
 
typedef struct{
uint16_t Year;
20,24 → 18,17
extern DateTime_t SystemTime;
 
 
void Timer_Init(void);
void TIMER2_Init(void);
void Timer0_Init(void);
void Timer2_Init(void);
void Delay_ms(unsigned int);
void Delay_ms_Mess(unsigned int);
unsigned int SetDelay (unsigned int t);
char CheckDelay (unsigned int t);
void CalculateServo(void);
void CalcNickServoValue(void);
 
extern volatile unsigned int CountMilliseconds;
extern volatile unsigned char UpdateMotor;
extern volatile unsigned int beeptime;
extern volatile unsigned int cntKompass;
extern unsigned int BeepMuster;
extern volatile unsigned char BytegapSPI, ServoActive, CalculateServoSignals;
extern volatile int16_t ServoNickValue;
extern volatile int16_t ServoRollValue;
extern signed int NickServoValue;
extern unsigned char JustMK3MagConnected;
extern signed int ServoNickValue;
 
#endif
/I2C_Telemetry/trunk/twimaster.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
70,6 → 70,7
volatile uint16_t I2CTimeout = 100;
 
uint8_t MissingMotor = 0;
unsigned char RequiredMotors = 12;
 
volatile uint8_t BLFlags = 0;
 
164,7 → 165,7
case 0: // TWI_STATE_MOTOR_TX
I2C_TransferActive = 1;
// skip motor if not used in mixer
while((Mixer.Motor[motor_write][MIX_GAS] <= 0) && (motor_write < MAX_MOTORS)) motor_write++;
while(motor_write < MAX_MOTORS) motor_write++;
if(motor_write >= MAX_MOTORS) // writing finished, read now
{
BLConfig_WriteMask = 0; // reset configuration bitmask
301,13 → 302,13
// if(!(FC_StatusFlags & FC_STATUS_MOTOR_RUN) && ((Motor[motor_read].MaxPWM & 252) == 248)) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
// else Motor[motor_read].Version = 0;
if(!(FC_StatusFlags & FC_STATUS_MOTOR_RUN))
{
{
if((Motor[motor_read].MaxPWM & 252) == 248) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
else Motor[motor_read].Version = 0;
if(Motor[motor_read].MaxPWM == 248) Motor[motor_read].Version |= (MOTOR_STATE_FAST_MODE | MOTOR_STATE_BL30);
else
if(Motor[motor_read].MaxPWM == 249) Motor[motor_read].Version |= MOTOR_STATE_BL30;
}
}
}
if(++motor_read >= MAX_MOTORS)
{
337,39 → 338,11
break;
 
case 20:
switch(dac_channel)
{
case 0:
I2C_WriteByte(AnalogOffsetNick); // 1st byte for Channel A
break;
case 1:
I2C_WriteByte(AnalogOffsetRoll); // 1st byte for Channel B
break;
case 2:
I2C_WriteByte(AnalogOffsetGier); // 1st byte for Channel C
break;
}
break;
 
case 21:
I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80
break;
 
case 22:
I2C_Stop(TWI_STATE_MOTOR_TX);
I2C_TransferActive = 0;
I2CTimeout = 10;
// repeat case 18...22 until all DAC Channels are updated
if(dac_channel < 2)
{
dac_channel ++; // jump to next channel
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // start transmission for next channel
}
else
{
dac_channel = 0; // reset dac channel counter
BLFlags |= BLFLAG_TX_COMPLETE;
}
BLFlags |= BLFLAG_TX_COMPLETE;
 
break;
default:
I2C_Stop(TWI_STATE_MOTOR_TX);
383,13 → 356,24
 
}
 
uint8_t RAM_Checksum(uint8_t* pBuffer, uint16_t len)
{
uint8_t crc = 0xAA;
uint16_t i;
 
for(i=0; i<len; i++)
{
crc += pBuffer[i];
}
return crc;
}
 
uint8_t I2C_WriteBLConfig(uint8_t motor)
{
uint8_t i;
uint16_t timer;
 
if(MotorenEin || PC_MotortestActive) return(BLCONFIG_ERR_MOTOR_RUNNING); // not when motors are running!
if(MotorenEin || MotorTest_Active) return(BLCONFIG_ERR_MOTOR_RUNNING); // not when motors are running!
if(motor > MAX_MOTORS) return (BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist!
if(motor)
{
438,7 → 422,7
uint8_t i;
uint16_t timer;
 
if(MotorenEin || PC_MotortestActive) return(BLCONFIG_ERR_MOTOR_RUNNING); // not when motors are running!
if(MotorenEin || MotorTest_Active) return(BLCONFIG_ERR_MOTOR_RUNNING); // not when motors are running!
if(motor > MAX_MOTORS) return (BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist!
if(motor == 0) return (BLCONFIG_ERR_READ_NOT_POSSIBLE);
if(!(Motor[motor-1].State & MOTOR_STATE_PRESENT_MASK)) return(BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist!
/I2C_Telemetry/trunk/twimaster.h
6,7 → 6,6
 
#define TWI_STATE_MOTOR_TX 0
#define TWI_STATE_MOTOR_RX 5
#define TWI_STATE_GYRO_OFFSET_TX 18
 
extern volatile uint8_t twi_state;
extern volatile uint8_t motor_write;
14,6 → 13,7
extern volatile uint8_t I2C_TransferActive;
 
extern uint8_t MissingMotor;
unsigned char RequiredMotors;
 
#define MAX_MOTORS 12
#define MOTOR_STATE_PRESENT_MASK 0x80
/I2C_Telemetry/trunk/uart.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
53,16 → 53,17
#include <stdarg.h>
#include <string.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "main.h"
#include "uart.h"
#include "libtel.h"
#include "eeprom.h"
#include "ftphelper.h"
#include "mkprotocol.h"
 
#define ABO_TIMEOUT 4000 // disable abo after 4 seconds
#define MAX_SENDE_BUFF 1220
#define MAX_EMPFANGS_BUFF 1220
 
 
#define BLPARAM_REVISION 1
#define MASK_SET_PWM_SCALING 0x01
#define MASK_SET_CURRENT_LIMIT 0x02
73,38 → 74,45
#define MASK_SET_DEFAULT_PARAMS 0x40
#define MASK_SET_SAVE_EEPROM 0x80
 
unsigned char GetExternalControl = 0,DebugDisplayAnforderung1 = 0, DebugDisplayAnforderung = 0,DebugDataAnforderung = 0,GetVersionAnforderung = 0, GetPPMChannelAnforderung = 0;
unsigned char DisplayLine = 0;
unsigned volatile char SioTmp = 0;
unsigned volatile char NeuerDatensatzEmpfangen = 0;
unsigned volatile char NeueKoordinateEmpfangen = 0;
unsigned volatile char UebertragungAbgeschlossen = 1;
unsigned volatile char CntCrcError = 0;
unsigned volatile char AnzahlEmpfangsBytes = 0;
unsigned volatile char TxdBuffer[MAX_SENDE_BUFF];
unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF];
unsigned char UART_Request_FTP = 0;
// the tx buffer
#define UART0_TX_BUFFER_LEN 1220
uint8_t UART0_tbuffer[UART0_TX_BUFFER_LEN];
Buffer_t UART0_tx_buffer;
 
unsigned char *pRxData = 0;
unsigned char RxDataLen = 0;
unsigned volatile char PC_DebugTimeout = 0;
unsigned volatile char PC_MotortestActive = 0;
unsigned char DebugTextAnforderung = 255;
// the rx buffer
#define UART0_RX_BUFFER_LEN 1220
uint8_t UART0_rbuffer[UART0_RX_BUFFER_LEN];
Buffer_t UART0_rx_buffer;
 
unsigned char PcZugriff = 100;
unsigned char MotorTest[16];
unsigned char MeineSlaveAdresse = 1; // Flight-Ctrl
unsigned char ConfirmFrame;
 
uint8_t Request_FTP = 0;
uint8_t Request_VerInfo = 0;
uint8_t Request_Display = 0;
uint8_t Request_Display1 = 0;
uint8_t Request_DebugData = 0;
uint8_t Request_DebugLabel = 255;
uint8_t Request_PPMChannels = 0;
uint8_t Request_MotorTest = 0;
uint8_t DisplayLine = 0;
uint8_t DisplayKeys = 0;
 
uint8_t PcAccess = 100;
uint16_t AboTimeOut = 0;
 
uint8_t MotorTest_Active = 0;
uint8_t MotorTest[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
uint8_t Address = FC_ADDRESS; // Flight-Ctrl
 
struct str_DebugOut DebugOut;
struct str_ExternControl ExternControl;
struct str_VersionInfo VersionInfo;
struct str_WinkelOut WinkelOut;
struct str_Data3D Data3D;
struct str_VersionInfo UART_VersionInfo;
 
int Display_Timer, Debug_Timer,Kompass_Timer,Timer3D;
unsigned int DebugDataIntervall = 0, Intervall3D = 0, Display_Interval = 0;
unsigned int AboTimeOut = 0;
unsigned volatile char ReceiverUpdateModeActive = 0; // 1 = Update 2 = JetiBox-Simulation
uint16_t DebugData_Timer;
uint16_t Data3D_Timer;
uint16_t Display_Timer;
uint16_t DebugData_Interval = 0; // in 1ms
uint16_t Data3D_Interval = 0; // in 1ms
uint16_t Display_Interval = 0;
 
const unsigned char ANALOG_TEXT[32][16] PROGMEM =
{
114,7 → 122,7
"2 ",
"3 ",
"4 ",
"Altitude [0.1m] ", //5
"Altitude ", //5
"NumberOfSats ",
"Gas ",
"8 ",
142,520 → 150,268
"30 ", //30
"31 "
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Sende-Part der Datenübertragung
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
/****************************************************************/
/* USART0 TX Interrupt Routine */
/****************************************************************/
ISR(USART0_TX_vect)
{
static unsigned int ptr = 0;
unsigned char tmp_tx;
uint8_t tmp_tx;
 
if(!UebertragungAbgeschlossen)
{
ptr++; // die [0] wurde schon gesendet
tmp_tx = TxdBuffer[ptr];
if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
{
ptr = 0;
UebertragungAbgeschlossen = 1;
}
UDR0 = tmp_tx;
}
else ptr = 0;
if(UART0_tx_buffer.Locked)
{
tmp_tx = UART0_tx_buffer.pData[UART0_tx_buffer.Position++]; // read next byte from txd buffer
UDR0 = tmp_tx;
// if terminating character or end of txd buffer reached
if((tmp_tx == '\0') || (UART0_tx_buffer.Position >= UART0_tx_buffer.DataBytes))
{
Buffer_Clear(&UART0_tx_buffer); // clear txd buffer, that unlocks it.
}
}
}
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Empfangs-Part der Datenübertragung, incl. CRC-Auswertung
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/****************************************************************/
/* USART0 RX Interrupt Routine */
/****************************************************************/
ISR(USART0_RX_vect)
{
static unsigned int crc;
static unsigned char crc1,crc2;
static unsigned int buf_ptr;
static unsigned char UartState = 0;
unsigned char CrcOkay = 0;
uint8_t c;
 
if (ReceiverUpdateModeActive == 1) { UDR1 = UDR0; return; } // 1 = Update
if (ReceiverUpdateModeActive == 2) { RxdBuffer[0] = UDR0; return; } // 2 = JetiBox-Simulation
c = UDR0;
 
SioTmp = UDR0;
UBX_Parser(SioTmp); // and put it into the ubx protocol parser
 
if(buf_ptr >= MAX_SENDE_BUFF) UartState = 0;
if(SioTmp == '\r' && UartState == 2)
{
UartState = 0;
crc -= RxdBuffer[buf_ptr-2];
crc -= RxdBuffer[buf_ptr-1];
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
CrcOkay = 0;
if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1])) CrcOkay = 1; else { CrcOkay = 0; CntCrcError++;};
if(!NeuerDatensatzEmpfangen && CrcOkay) // Datensatz schon verarbeitet
{
NeuerDatensatzEmpfangen = 1;
AnzahlEmpfangsBytes = buf_ptr + 1;
RxdBuffer[buf_ptr] = '\r';
if(RxdBuffer[2] == 'R' && !MotorenEin)
{
LcdClear();
wdt_enable(WDTO_250MS); // Reset-Commando
ServoActive = 0;
}
}
}
else
switch(UartState)
{
case 0:
if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1; // Startzeichen und Daten schon verarbeitet
buf_ptr = 0;
RxdBuffer[buf_ptr++] = SioTmp;
crc = SioTmp;
break;
case 1: // Adresse auswerten
UartState++;
RxdBuffer[buf_ptr++] = SioTmp;
crc += SioTmp;
break;
case 2: // Eingangsdaten sammeln
RxdBuffer[buf_ptr] = SioTmp;
if(buf_ptr < MAX_EMPFANGS_BUFF) buf_ptr++;
else UartState = 0;
crc += SioTmp;
break;
default:
UartState = 0;
break;
}
MKProtocol_CollectSerialFrame(&UART0_rx_buffer, c); // ckeck for MK-Frame
UBX_Parser(c); // and check ubx protocol parser for gpx data
}
 
 
// --------------------------------------------------------------------------
void AddCRC(unsigned int wieviele)
//---------------------------------------------------------------------------------------------
void USART0_TransmitTxData(void)
{
unsigned int tmpCRC = 0,i;
for(i = 0; i < wieviele;i++)
{
tmpCRC += TxdBuffer[i];
}
// if(i > MAX_SENDE_BUFF - 3) tmpCRC += 11;
tmpCRC %= 4096;
TxdBuffer[i++] = '=' + tmpCRC / 64;
TxdBuffer[i++] = '=' + tmpCRC % 64;
TxdBuffer[i++] = '\r';
UebertragungAbgeschlossen = 0;
UDR0 = TxdBuffer[0];
//if(DebugOut.Analog[] < i) DebugOut.Analog[] = i;
}
 
 
// --------------------------------------------------------------------------
void SendOutData(unsigned char cmd,unsigned char address, unsigned char BufferAnzahl, ...) //unsigned char *snd, unsigned char len)
{
va_list ap;
unsigned int pt = 0;
unsigned char a,b,c;
unsigned int ptr = 0;
 
unsigned char *snd = 0;
int len = 0;
 
TxdBuffer[pt++] = '#'; // Startzeichen
TxdBuffer[pt++] = 'a' + address; // Adresse (a=0; b=1,...)
TxdBuffer[pt++] = cmd; // Commando
 
va_start(ap, BufferAnzahl);
if(BufferAnzahl)
{
snd = va_arg(ap, unsigned char*);
len = va_arg(ap, int);
ptr = 0;
BufferAnzahl--;
}
while(len)
{
if(len)
if(UART0_tx_buffer.Locked)
{
a = snd[ptr++];
len--;
if((!len) && BufferAnzahl)
{
snd = va_arg(ap, unsigned char*);
len = va_arg(ap, int);
ptr = 0;
BufferAnzahl--;
if(UART0_tx_buffer.Position == 0)
{
UDR0 = UART0_tx_buffer.pData[UART0_tx_buffer.Position++]; // initiates the transmittion (continued in the TX ISR)
}
}
else a = 0;
if(len)
{
b = snd[ptr++];
len--;
if((!len) && BufferAnzahl)
else
{
snd = va_arg(ap, unsigned char*);
len = va_arg(ap, int);
ptr = 0;
BufferAnzahl--;
return;
}
}
else b = 0;
if(len)
else // not locked
{
c = snd[ptr++];
len--;
if((!len) && BufferAnzahl)
if(CheckDelay(AboTimeOut))
{
snd = va_arg(ap, unsigned char*);
len = va_arg(ap, int);
ptr = 0;
BufferAnzahl--;
Display_Interval = 0;
DebugData_Interval = 0;
}
}
else c = 0;
TxdBuffer[pt++] = '=' + (a >> 2);
TxdBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
TxdBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
TxdBuffer[pt++] = '=' + ( c & 0x3f);
}
va_end(ap);
AddCRC(pt);
}
 
// --------------------------------------------------------------------------
void Decode64(void) // die daten werden im rx buffer dekodiert, das geht nur, weil aus 4 byte immer 3 gemacht werden.
{
unsigned char a,b,c,d;
unsigned char x,y,z;
unsigned int ptrIn = 3; // start at begin of data block
unsigned int ptrOut = 3;
unsigned int len = AnzahlEmpfangsBytes - 6; // von der Gesamtbytezahl eines Frames gehen 3 Bytes des Headers ('#',Addr, Cmd) und 3 Bytes des Footers (CRC1, CRC2, '\r') ab.
if(((Display_Interval > 0 && CheckDelay(Display_Timer)) || Request_Display))
{
if(DisplayLine > 3)// new format
{
Menu();
MKProtocol_CreateSerialFrame(&UART0_tx_buffer, 'H', FC_ADDRESS, 1, (uint8_t *)DisplayBuff, 80);
}
else // old format
{
LCD_printfxy(0,0,"!!! INCOMPATIBLE !!!");
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), (uint8_t *)DisplayBuff, 20);
if(DisplayLine++ > 3) DisplayLine = 0;
}
Display_Timer = SetDelay(Display_Interval);
Request_Display = 0;
}
else if(Request_Display1)
{
Menu();
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'L', FC_ADDRESS, 3, &MenuePunkt, sizeof(MenuePunkt), &MaxMenue, sizeof(MaxMenue), DisplayBuff, sizeof(DisplayBuff));
Request_Display1 = 0;
}
else if(Request_VerInfo)
{
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'V', FC_ADDRESS, 1, (unsigned char *) &UART_VersionInfo, sizeof(UART_VersionInfo));
Request_VerInfo = 0;
Debug_OK("Version gesendet");
}
else if(((DebugData_Interval>0 && CheckDelay(DebugData_Timer)) || Request_DebugData))
{
CopyDebugValues();
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'D', FC_ADDRESS, 1, (unsigned char *) &DebugOut,sizeof(DebugOut));
Request_DebugData = 0;
if(DebugData_Interval>0) DebugData_Timer = SetDelay(DebugData_Interval);
}
else if(Request_DebugLabel != 255) // Texte für die Analogdaten
{
uint8_t label[16]; // local sram buffer
memcpy_P(label, ANALOG_TEXT[Request_DebugLabel], 16); // read lable from flash to sra
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'A', FC_ADDRESS, 2, (unsigned char *)&Request_DebugLabel, sizeof(Request_DebugLabel),label, 16);
Request_DebugLabel = 255;
}
else if(Request_PPMChannels)
{
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'P', FC_ADDRESS, 1, (unsigned char *) &PPM_in, sizeof(PPM_in));
Request_PPMChannels = 0;
}
else if(Request_FTP)
{
uint8_t errorcode = FTP_ERROR_NONE;
 
while(len)
{
a = RxdBuffer[ptrIn++] - '=';
b = RxdBuffer[ptrIn++] - '=';
c = RxdBuffer[ptrIn++] - '=';
d = RxdBuffer[ptrIn++] - '=';
if (!Partition.IsValid) errorcode = FTP_ERROR_NO_SDCARD;
 
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
if (!errorcode) CheckFTPCommand(Request_FTP, &UART0_tx_buffer);
else
{
uint8_t cmd = FTP_CMD_ERROR;
MKProtocol_CreateSerialFrame(&UART0_tx_buffer, 'F', NC_ADDRESS, 2, &cmd, 1, &errorcode, 1);
}
Request_FTP = 0;
}
#ifdef DEBUG // only include functions if DEBUG is defined
else if(Request_DebugOutput)
{
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'0', FC_ADDRESS, 1, (unsigned char *) &tDebug, sizeof(tDebug));
Request_DebugOutput = 0;
}
#endif
else if(Request_MotorTest)
{
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'T', Address, 0);
Request_MotorTest = 0;
}
}
// if a new frame has been created, initiate transmission
if(UART0_tx_buffer.Locked) UDR0 = UART0_tx_buffer.pData[UART0_tx_buffer.Position++]; // initiates the transmittion (continued in the TX ISR)
}
 
if(len--) RxdBuffer[ptrOut++] = x; else break;
if(len--) RxdBuffer[ptrOut++] = y; else break;
if(len--) RxdBuffer[ptrOut++] = z; else break;
}
pRxData = (unsigned char*)&RxdBuffer[3]; // decodierte Daten beginnen beim 4. Byte
RxDataLen = ptrOut - 3; // wie viele Bytes wurden dekodiert?
 
}
 
// --------------------------------------------------------------------------
void BearbeiteRxDaten(void)
/****************************************************************/
/* Check for incomming mk frame data */
/****************************************************************/
void USART0_ProcessRxData(void)
{
if(!NeuerDatensatzEmpfangen) return;
 
unsigned char tempchar1, tempchar2;
Decode64(); // dekodiere datenblock im Empfangsbuffer
switch(RxdBuffer[1]-'a') // check for Slave Address
// check for new data frame
if(UART0_rx_buffer.Locked)
{
case FC_ADDRESS: // FC special commands
// case NC_ADDRESS:
switch(RxdBuffer[2])
SerialMsg_t SerialMsg;
 
MKProtocol_DecodeSerialFrameHeader(&UART0_rx_buffer, &SerialMsg); // decode serial frame header in rxd buffer
MKProtocol_DecodeSerialFrameData(&UART0_rx_buffer, &SerialMsg); // decode serial frame data in rxd buffer
 
if( SerialMsg.Address == FC_ADDRESS )
{
case 'f': // ftp command
UART_Request_FTP = pRxData[0];
memcpy(&FTP_data, &pRxData[1], sizeof(FTP_data)); // copy ftp parameter
break;
case 'K':// Kompasswert
switch(SerialMsg.CmdID)
{
case 'f': // ftp command
Request_FTP = SerialMsg.pData[0];
memcpy(&FTP_data, &SerialMsg.pData[1], sizeof(FTP_data)); // copy ftp parameter
break;
case 't':// Motortest
if(AnzahlEmpfangsBytes > 20) memcpy(&MotorTest[0], (unsigned char *)pRxData, sizeof(MotorTest));
else memcpy(&MotorTest[0], (unsigned char *)pRxData, 4);
PC_MotortestActive = 240;
//while(!UebertragungAbgeschlossen);
//SendOutData('T', MeineSlaveAdresse, 0);
PcZugriff = 255;
break;
 
case 'n':// "Get Mixer
while(!UebertragungAbgeschlossen);
SendOutData('N', FC_ADDRESS, 1, (unsigned char *) &Mixer, sizeof(Mixer) - 1);
Debug("Mixer lesen");
case 't':// Motortest
if(SerialMsg.DataLen > 20) memcpy(&MotorTest[0], SerialMsg.pData, sizeof(MotorTest));
else memcpy(&MotorTest[0], SerialMsg.pData, 4);
Request_MotorTest = 1;
MotorTest_Active = 240;
PcAccess = 255;
AboTimeOut = SetDelay(ABO_TIMEOUT);
break;
 
case 'm':// "Write Mixer
if(pRxData[0] == EEMIXER_REVISION)
{
memcpy(&Mixer, (unsigned char *)pRxData, sizeof(Mixer) - 1);
MixerTable_WriteToEEProm();
tempchar1 = 1;
VersionInfo.HardwareError[1] &= ~FC_ERROR1_MIXER;
}
else
{
tempchar1 = 0;
}
while(!UebertragungAbgeschlossen);
SendOutData('M', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1));
case 'u': // request BL parameter
Debug("Reading BL %d", SerialMsg.pData[0]);
// try to read BL configuration
tempchar2 = I2C_ReadBLConfig(SerialMsg.pData[0]);
if(tempchar2 == BLCONFIG_SUCCESS) tempchar1 = 1;
else tempchar1 = 0;
while(UART0_tx_buffer.Locked); // wait for previous frame to be sent
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'U', FC_ADDRESS, 4, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2), &SerialMsg.pData[0], 1, &BLConfig, sizeof(BLConfig_t));
break;
 
case 'p': // get PPM Channels
GetPPMChannelAnforderung = 1;
PcZugriff = 255;
break;
 
case 'q':// "Get"-Anforderung für Settings
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
if(MotorenEin) break;
if((10 <= pRxData[0]) && (pRxData[0] < 20))
case 'w': // write BL parameter
Debug("Writing BL %d", SerialMsg.pData[0]);
if(SerialMsg.DataLen >= 1+sizeof(BLConfig_t))
{
tempchar1 = pRxData[0] - 10;
if(tempchar1< 1) tempchar1 = 1; // limit to 1
else if(tempchar1 > 5) tempchar1 = 5; // limit to 5
SetDefaultParameter(tempchar1, 1);
memcpy(&BLConfig, (uint8_t*)(&SerialMsg.pData[1]), sizeof(BLConfig_t));
tempchar2 = I2C_WriteBLConfig(SerialMsg.pData[0]);
if(tempchar2 == BLCONFIG_SUCCESS) tempchar1 = 1;
else tempchar1 = 0; // indicate error
while(UART0_tx_buffer.Locked); // wait for previous frame to be sent
MKProtocol_CreateSerialFrame(&UART0_tx_buffer,'W', FC_ADDRESS,2, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2));
}
else if((20 <= pRxData[0]) && (pRxData[0] < 30))
{
tempchar1 = pRxData[0] - 20;
if(tempchar1< 1) tempchar1 = 1; // limit to 1
else if(tempchar1 > 5) tempchar1 = 5; // limit to 5
SetDefaultParameter(tempchar1, 0);
}
else
{
tempchar1 = pRxData[0];
if(tempchar1 == 0xFF)
{
tempchar1 = GetActiveParamSet();
}
if(tempchar1< 1) tempchar1 = 1; // limit to 1
else if(tempchar1 > 5) tempchar1 = 5; // limit to 5
// load requested parameter set
ParamSet_ReadFromEEProm(tempchar1);
}
while(!UebertragungAbgeschlossen);
SendOutData('Q', FC_ADDRESS, 2, &tempchar1, sizeof(tempchar1), (unsigned char *) &EE_Parameter, sizeof(EE_Parameter) - 1);
Debug("Lese Setting %d", tempchar1);
break;
 
case 's': // Parametersatz speichern
if((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EEPARAM_REVISION) && MotorenEin == 0) // check for setting to be in range
{
memcpy(&EE_Parameter, (uint8_t*)&pRxData[1], sizeof(EE_Parameter) - 1);
ParamSet_WriteToEEProm(pRxData[0]);
tempchar1 = GetActiveParamSet();
}
else
{
tempchar1 = 0; // mark in response an invlid setting
}
while(!UebertragungAbgeschlossen);
SendOutData('S', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1));
if(!MotorenEin) Piep(tempchar1,110);
LipoDetection(0);
LIBTEL_ReceiverInit(EE_Parameter.Receiver);
default:
//unsupported command received
break;
#warning : "TODO: case 'f'"
/*case 'f': // auf anderen Parametersatz umschalten
if(MotorenEin) break;
if((1 <= pRxData[0]) && (pRxData[0] <= 5)) ParamSet_ReadFromEEProm(pRxData[0]);
tempchar1 = GetActiveParamSet();
while(!UebertragungAbgeschlossen);
SendOutData('F', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1));
Piep(tempchar1,110);
LipoDetection(0);
LIBTEL_ReceiverInit(EE_Parameter.Receiver);
break;*/
case 'y':// serial Potis
for(tempchar1 = 0; tempchar1 < 12; tempchar1++) PPM_in[SERIAL_POTI_START + tempchar1] = (signed char) pRxData[tempchar1];
break;
case 'u': // request BL parameter
Debug("Reading BL %d", pRxData[0]);
// try to read BL configuration
tempchar2 = I2C_ReadBLConfig(pRxData[0]);
if(tempchar2 == BLCONFIG_SUCCESS) tempchar1 = 1;
else tempchar1 = 0;
while(!UebertragungAbgeschlossen); // wait for previous frame to be sent
SendOutData('U', FC_ADDRESS, 4, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2), &pRxData[0], 1, &BLConfig, sizeof(BLConfig_t));
break;
case 'w': // write BL parameter
Debug("Writing BL %d", pRxData[0]);
if(RxDataLen >= 1+sizeof(BLConfig_t))
{
memcpy(&BLConfig, (uint8_t*)(&pRxData[1]), sizeof(BLConfig_t));
tempchar2 = I2C_WriteBLConfig(pRxData[0]);
if(tempchar2 == BLCONFIG_SUCCESS) tempchar1 = 1;
else tempchar1 = 0; // indicate error
while(!UebertragungAbgeschlossen); // wait for previous frame to be sent
SendOutData('W', FC_ADDRESS,2, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2));
}
break;
case 'j':
if(MotorenEin) break;
tempchar1 = LIBTEL_GetCPUType();
if((tempchar1 == CPU_ATMEGA644P) || (tempchar1 == CPU_ATMEGA1284P))
{
uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/ (8 * 38400L) - 1);
} // EOF cmd id
 
cli();
}
else // any other address
{
switch(SerialMsg.CmdID)
{
case 't':// Motortest
if(SerialMsg.DataLen >= sizeof(MotorTest)) memcpy(&MotorTest[0], SerialMsg.pData, sizeof(MotorTest));
else memcpy(&MotorTest[0], SerialMsg.pData, 4);
Request_MotorTest = 1;
MotorTest_Active = 250;
PcAccess = 255;
AboTimeOut = SetDelay(ABO_TIMEOUT);
break;
 
// UART0 & UART1 disable RX and TX-Interrupt
UCSR0B &= ~((1 << RXCIE0)|(1 << TXCIE0));
UCSR1B &= ~((1 << RXCIE1)|(1 << TXCIE1));
case 'a':// Texte der Analogwerte
Request_DebugLabel = SerialMsg.pData[0];
if (Request_DebugLabel > 31) Request_DebugLabel = 31;
PcAccess = 255;
break;
 
// UART0 & UART1 disable receiver and transmitter
UCSR0B &= ~((1 << TXEN0) | (1 << RXEN0));
UCSR1B &= ~((1 << TXEN1) | (1 << RXEN1));
case 'd': // Poll the debug data
PcAccess = 255;
DebugData_Interval = (unsigned int)SerialMsg.pData[0] * 10;
if(DebugData_Interval > 0) Request_DebugData = 1;
AboTimeOut = SetDelay(ABO_TIMEOUT);
break;
 
// UART0 & UART1 flush receive buffer explicit
while ( UCSR1A & (1<<RXC1) ) UDR1;
while ( UCSR0A & (1<<RXC0) ) UDR0;
case 'h':// x-1 Displayzeilen
PcAccess = 255;
if((SerialMsg.pData[0] & 0x80) == 0x00) // old format
{
DisplayLine = 2;
Display_Interval = 0;
}
else // new format
{
RemoteKeys |= ~SerialMsg.pData[0];
Display_Interval = (unsigned int)SerialMsg.pData[1] * 10;
DisplayLine = 4;
AboTimeOut = SetDelay(ABO_TIMEOUT);
}
Request_Display = 1;
break;
 
case 'l':// x-1 Displayzeilen
PcAccess = 255;
MenuePunkt = SerialMsg.pData[0];
Request_Display1 = 1;
break;
case 'v': // Version-Anforderung und Ausbaustufe
Request_VerInfo = 1;
break;
 
if(pRxData[0] == 1) ReceiverUpdateModeActive = 2;
else
{ // Jeti or HoTT update
//#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
if(pRxData[0] == 100) ubrr = (uint16_t) ((uint32_t) F_CPU/ (8 * 19200L) - 1); // HoTT
//#endif
ReceiverUpdateModeActive = 1;
// UART0 & UART1 set baudrate
UBRR1H = (uint8_t)(ubrr>>8);
UBRR1L = (uint8_t)ubrr;
UBRR0H = UBRR1H;
UBRR0L = UBRR1L;
// UART1 no parity
UCSR1C &= ~(1 << UPM11);
UCSR1C &= ~(1 << UPM10);
// UART1 8-bit
UCSR1B &= ~(1 << UCSZ12);
UCSR1C |= (1 << UCSZ11);
UCSR1C |= (1 << UCSZ10);
}
// UART0 & UART1 1 stop bit
UCSR1C &= ~(1 << USBS1);
UCSR0C &= ~(1 << USBS0);
// UART1 clear 9th bit
UCSR1B &= ~(1<<TXB81);
// enable receiver and transmitter for UART0 and UART1
UCSR0B |= (1 << TXEN0) | (1 << RXEN0);
UCSR1B |= (1 << TXEN1) | (1 << RXEN1);
// enable RX-Interrupt for UART0 and UART1
UCSR0B |= (1 << RXCIE0);
UCSR1B |= (1 << RXCIE1);
// disable other Interrupts
TIMSK0 = 0;
TIMSK1 = 0;
TIMSK2 = 0;
 
sei();
}
break;
 
} // case FC_ADDRESS:
 
default: // any Slave Address
 
switch(RxdBuffer[2])
{
// 't' comand placed here only for compatibility to BL
case 't':// Motortest
if(AnzahlEmpfangsBytes >= sizeof(MotorTest)) memcpy(&MotorTest[0], (unsigned char *)pRxData, sizeof(MotorTest));
else memcpy(&MotorTest[0], (unsigned char *)pRxData, 4);
while(!UebertragungAbgeschlossen);
SendOutData('T', MeineSlaveAdresse, 0);
PC_MotortestActive = 250;
PcZugriff = 255;
AboTimeOut = SetDelay(ABO_TIMEOUT);
default:
//unsupported command received
break;
// 'K' comand placed here only for compatibility to old MK3MAG software, that does not send the right Slave Address
case 'K':// Kompasswert
break;
case 'a':// Texte der Analogwerte
DebugTextAnforderung = pRxData[0];
if (DebugTextAnforderung > 31) DebugTextAnforderung = 31;
PcZugriff = 255;
break;
case 'b':
memcpy((unsigned char *)&ExternControl, (unsigned char *)pRxData, sizeof(ExternControl));
ConfirmFrame = ExternControl.Frame;
PcZugriff = 255;
break;
case 'c': // Poll the 3D-Data
if(!Intervall3D) { if(pRxData[0]) Timer3D = SetDelay(pRxData[0] * 10);}
Intervall3D = pRxData[0] * 10;
AboTimeOut = SetDelay(ABO_TIMEOUT);
break;
case 'd': // Poll the debug data
PcZugriff = 255;
DebugDataIntervall = (unsigned int)pRxData[0] * 10;
if(DebugDataIntervall > 0) DebugDataAnforderung = 1;
AboTimeOut = SetDelay(ABO_TIMEOUT);
break;
 
case 'h':// x-1 Displayzeilen
PcZugriff = 255;
if((pRxData[0] & 0x80) == 0x00) // old format
{
DisplayLine = 2;
Display_Interval = 0;
}
else // new format
{
RemoteKeys |= ~pRxData[0];
Display_Interval = (unsigned int)pRxData[1] * 10;
DisplayLine = 4;
AboTimeOut = SetDelay(ABO_TIMEOUT);
}
DebugDisplayAnforderung = 1;
break;
 
case 'l':// x-1 Displayzeilen
PcZugriff = 255;
MenuePunkt = pRxData[0];
DebugDisplayAnforderung1 = 1;
break;
case 'v': // Version-Anforderung und Ausbaustufe
GetVersionAnforderung = 1;
break;
 
case 'g'://
GetExternalControl = 1;
break;
 
default:
//unsupported command received
break;
}
break; // default:
}
NeuerDatensatzEmpfangen = 0;
pRxData = 0;
RxDataLen = 0;
} // EOF cmd id
} // EOF any other address
Buffer_Clear(&UART0_rx_buffer); // free the buffer
} // EOF UART0_rx_buffer.Locked
}
 
//############################################################################
//Routine für die Serielle Ausgabe
void uart_putchar (char c)
//############################################################################
/****************************************************************/
/* Send Character */
/****************************************************************/
void USART0_PutChar (char c)
{
//Warten solange bis Zeichen gesendet wurde
loop_until_bit_is_set(UCSR0A, UDRE0);
664,136 → 420,115
}
 
 
//############################################################################
//INstallation der Seriellen Schnittstelle
void UART_Init (void)
//############################################################################
/****************************************************************/
/* Set Baudrate of the USART0 */
/****************************************************************/
void USART0_SetBaudrate(uint32_t baudrate)
{
unsigned int ubrr = (unsigned int) ((unsigned long) F_CPU/(8 * USART0_BAUD) - 1);
uint16_t ubrr;
 
//Enable TXEN im Register UCR TX-Data Enable & RX Enable
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
// UART Double Speed (U2X)
UCSR0A |= (1 << U2X0);
// RX-Interrupt Freigabe
UCSR0B |= (1 << RXCIE0);
// TX-Interrupt Freigabe
UCSR0B |= (1 << TXCIE0);
// disable RX-Interrupt
UCSR0B &= ~(1 << RXCIE0);
// disable TX-Interrupt
UCSR0B &= ~(1 << TXCIE0);
 
ubrr = (uint16_t) ((uint32_t) F_CPU/(8 * baudrate) - 1);
 
// USART0 Baud Rate Register
// set clock divider
UBRR0H = (uint8_t)(ubrr >> 8);
UBRR0L = (uint8_t)ubrr;
 
// clear rxd_buffer
Buffer_Clear(&UART0_rx_buffer);
// clear rxd_buffer
Buffer_Clear(&UART0_tx_buffer);
 
Debug_Timer = SetDelay(DebugDataIntervall);
Kompass_Timer = SetDelay(220);
 
VersionInfo.SWMajor = VERSION_MAJOR;
VersionInfo.SWMinor = VERSION_MINOR;
VersionInfo.SWPatch = VERSION_PATCH;
VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR;
VersionInfo.reserved1 = 0;
VersionInfo.reserved2 = 0;
VersionInfo.HWMajor = PlatinenVersion;
VersionInfo.Flags |= FC_VERSION_FLAG_NC_PRESENT;
pRxData = 0;
RxDataLen = 0;
// flush receive buffer
while ( UCSR0A & (1<<RXC0) ) UDR0;
 
// enable interrupts at the end
// enable RX-Interrupt
UCSR0B |= (1 << RXCIE0);
// enable TX-Interrupt
UCSR0B |= (1 << TXCIE0);
 
}
 
//---------------------------------------------------------------------------------------------
void DatenUebertragung(void)
 
/****************************************************************/
/* Initialization of the USART0 */
/****************************************************************/
void USART0_Init (void)
{
if(!UebertragungAbgeschlossen) return;
uint8_t sreg = SREG;
 
if(CheckDelay(AboTimeOut))
{
Display_Interval = 0;
DebugDataIntervall = 0;
Intervall3D = 0;
}
// disable all interrupts before configuration
cli();
 
if(((Display_Interval>0 && CheckDelay(Display_Timer)) || DebugDisplayAnforderung) && UebertragungAbgeschlossen)
{
if(DisplayLine > 3)// new format
{
Menu();
SendOutData('H', FC_ADDRESS, 1, (uint8_t *)DisplayBuff, 80);
}
else // old format
{
LCD_printfxy(0,0,"!!! INCOMPATIBLE !!!");
SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), (uint8_t *)DisplayBuff, 20);
if(DisplayLine++ > 3) DisplayLine = 0;
}
Display_Timer = SetDelay(Display_Interval);
DebugDisplayAnforderung = 0;
}
if(DebugDisplayAnforderung1 && UebertragungAbgeschlossen)
{
Menu();
SendOutData('L', FC_ADDRESS, 3, &MenuePunkt, sizeof(MenuePunkt), &MaxMenue, sizeof(MaxMenue), DisplayBuff, sizeof(DisplayBuff));
DebugDisplayAnforderung1 = 0;
}
if(GetVersionAnforderung && UebertragungAbgeschlossen)
{
SendOutData('V', FC_ADDRESS, 1, (unsigned char *) &VersionInfo, sizeof(VersionInfo));
GetVersionAnforderung = 0;
Debug_OK("Version gesendet");
}
// disable RX-Interrupt
UCSR0B &= ~(1 << RXCIE0);
// disable TX-Interrupt
UCSR0B &= ~(1 << TXCIE0);
 
if(GetExternalControl && UebertragungAbgeschlossen) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
{
SendOutData('G',MeineSlaveAdresse, 1, (unsigned char *) &ExternControl, sizeof(ExternControl));
GetExternalControl = 0;
}
if(((DebugDataIntervall>0 && CheckDelay(Debug_Timer)) || DebugDataAnforderung) && UebertragungAbgeschlossen)
{
CopyDebugValues();
SendOutData('D', FC_ADDRESS, 1, (unsigned char *) &DebugOut,sizeof(DebugOut));
DebugDataAnforderung = 0;
if(DebugDataIntervall>0) Debug_Timer = SetDelay(DebugDataIntervall);
}
if(DebugTextAnforderung != 255) // Texte für die Analogdaten
{
unsigned char label[16]; // local sram buffer
memcpy_P(label, ANALOG_TEXT[DebugTextAnforderung], 16); // read lable from flash to sra
SendOutData('A', FC_ADDRESS, 2, (unsigned char *)&DebugTextAnforderung, sizeof(DebugTextAnforderung),label, 16);
DebugTextAnforderung = 255;
}
if(ConfirmFrame && UebertragungAbgeschlossen) // Datensatz bestätigen
{
SendOutData('B', FC_ADDRESS, 1, (uint8_t*)&ConfirmFrame, sizeof(ConfirmFrame));
ConfirmFrame = 0;
}
if(GetPPMChannelAnforderung && UebertragungAbgeschlossen)
{
SendOutData('P', FC_ADDRESS, 1, (unsigned char *) &PPM_in, sizeof(PPM_in));
GetPPMChannelAnforderung = 0;
}
if(UART_Request_FTP && (UebertragungAbgeschlossen))
{
unsigned char errorcode = FTP_ERROR_NONE;
if(FC_StatusFlags & FC_STATUS_MOTOR_RUN) errorcode = FTP_ERROR_MOTOR_RUN;
else if (!Partition.IsValid) errorcode = FTP_ERROR_NO_SDCARD;
// initialize txd buffer
Buffer_Init(&UART0_tx_buffer, UART0_tbuffer, UART0_TX_BUFFER_LEN);
 
if (!errorcode) CheckFTPCommand(UART_Request_FTP);
else
{
unsigned char cmd = FTP_CMD_ERROR;
SendOutData('F', NC_ADDRESS, 2, &cmd, 1, &errorcode, 1);
}
// initialize rxd buffer
Buffer_Init(&UART0_rx_buffer, UART0_rbuffer, UART0_RX_BUFFER_LEN);
 
UART_Request_FTP = 0;
}
#ifdef DEBUG // only include functions if DEBUG is defined
if(SendDebugOutput && UebertragungAbgeschlossen)
{
SendOutData('0', FC_ADDRESS, 1, (unsigned char *) &tDebug, sizeof(tDebug));
SendDebugOutput = 0;
}
#endif
}
 
// set direction of RXD0 and TXD0 pins
// set RXD0 (PD0) as an input pin
PORTD |= (1 << PORTD0);
DDRD &= ~(1 << DDD0);
// set TXD0 (PD1) as an output pin
PORTD |= (1 << PORTD1);
DDRD |= (1 << DDD1);
 
// USART0 Baud Rate Register
USART0_SetBaudrate(USART0_BAUD);
 
// USART0 Control and Status Register A, B, C
 
// enable double speed operation
UCSR0A |= (1 << U2X0);
// enable receiver and transmitter
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
// set asynchronous mode
UCSR0C &= ~(1 << UMSEL01);
UCSR0C &= ~(1 << UMSEL00);
// no parity
UCSR0C &= ~(1 << UPM01);
UCSR0C &= ~(1 << UPM00);
// 1 stop bit
UCSR0C &= ~(1 << USBS0);
// 8-bit
UCSR0B &= ~(1 << UCSZ02);
UCSR0C |= (1 << UCSZ01);
UCSR0C |= (1 << UCSZ00);
 
 
// initialize the debug timer
DebugData_Timer = SetDelay(DebugData_Interval);
 
// flush receive buffer
while ( UCSR0A & (1<<RXC0) ) UDR0;
 
// enable interrupts at the end
// enable RX-Interrupt
UCSR0B |= (1 << RXCIE0);
// enable TX-Interrupt
UCSR0B |= (1 << TXCIE0);
 
 
UART_VersionInfo.SWMajor = VERSION_MAJOR;
UART_VersionInfo.SWMinor = VERSION_MINOR;
UART_VersionInfo.SWPatch = VERSION_PATCH;
UART_VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR;
UART_VersionInfo.ProtoMinor = VERSION_SERIAL_MINOR;
 
// restore global interrupt flags
SREG = sreg;
}
/I2C_Telemetry/trunk/uart.h
1,73 → 1,10
#ifndef _UART_H
#define _UART_H
#ifndef _UART0_H
#define _UART0_H
 
#define printf_P(format, args...) _printf_P(&uart_putchar, format , ## args)
#define printf(format, args...) _printf_P(&uart_putchar, PSTR(format) , ## args)
//Baud rate of the USART
#define USART0_BAUD 57600L
 
void BearbeiteRxDaten(void);
 
extern unsigned char DebugGetAnforderung;
extern void SendOutData(unsigned char cmd,unsigned char address, unsigned char BufferAnzahl, ...);
extern unsigned volatile char ReceiverUpdateModeActive;
extern unsigned volatile char UebertragungAbgeschlossen;
extern unsigned volatile char PC_DebugTimeout;
extern unsigned volatile char NeueKoordinateEmpfangen;
extern unsigned volatile char PC_MotortestActive;
extern unsigned char MeineSlaveAdresse;
extern unsigned char PcZugriff;
extern unsigned char RemotePollDisplayLine;
extern unsigned volatile char RxdBuffer[];
extern int Debug_Timer,Kompass_Timer;
extern void UART_Init (void);
extern void uart_putchar (char c);
//extern void boot_program_page (uint32_t page, uint8_t *buf);
extern void DatenUebertragung(void);
extern void Uart1Init(void);
extern void BearbeiteRxDaten(void);
extern unsigned char MotorTest[16];
 
struct str_DebugOut
{
unsigned char Status[2];
signed int Analog[32]; // Debugwerte
};
 
extern struct str_DebugOut DebugOut;
 
struct str_WinkelOut
{
signed int Winkel[2];
unsigned char UserParameter[2];
unsigned char CalcState;
unsigned char Orientation;
};
extern struct str_WinkelOut WinkelOut;
 
struct str_Data3D
{
signed int Winkel[3]; // nick, roll, compass in 0,1°
signed char Centroid[3];
signed char reserve[5];
};
extern struct str_Data3D Data3D;
 
struct str_ExternControl
{
unsigned char Digital[2];
unsigned char RemoteTasten;
signed char Nick;
signed char Roll;
signed char Gier;
unsigned char Gas;
signed char Hight;
unsigned char free;
unsigned char Frame;
unsigned char Config;
};
extern struct str_ExternControl ExternControl;
 
// FC hardware errors
 
// bitmask for UART_VersionInfo_t.HardwareError[0]
#define FC_ERROR0_GYRO_NICK 0x01
#define FC_ERROR0_GYRO_ROLL 0x02
87,33 → 24,45
#define FC_ERROR1_RES2 0x40
#define FC_ERROR1_RES3 0x80
 
#define printf_P(format, args...) _printf_P(&USART0_PutChar, format , ## args)
#define printf(format, args...) _printf_P(&USART0_PutChar, PSTR(format) , ## args)
 
// for FlightCtrl
//VersionInfo.Flags
#define FC_VERSION_FLAG_NC_PRESENT 0x01
// for NaviCtrl
#define NC_VERSION_FLAG_MK3MAG_PRESENT 0x01
 
extern unsigned char MotorTest_Active;
extern unsigned char Adresse;
extern unsigned char PcAccess;
 
extern void USART0_Init(void);
extern void USART0_SetBaudrate(uint32_t baudrate);
extern void USART0_PutChar(char c);
extern void USART0_TransmitTxData(void);
extern void USART0_ProcessRxData(void);
 
 
extern unsigned char MotorTest[16];
 
struct str_DebugOut
{
unsigned char Status[2];
signed int Analog[32]; // Debugwerte
};
 
extern struct str_DebugOut DebugOut;
 
struct str_VersionInfo
{
unsigned char SWMajor;
unsigned char SWMinor;
unsigned char ProtoMajor;
unsigned char reserved1;
unsigned char ProtoMinor;
unsigned char SWPatch;
unsigned char HardwareError[2];
unsigned char HWMajor;
unsigned char reserved2;
unsigned char reserved2;
unsigned char Flags;
};
 
extern struct str_VersionInfo VersionInfo;
extern struct str_VersionInfo UART_VersionInfo;
 
//#define USART0_BAUD 9600
//#define USART0_BAUD 14400
//#define USART0_BAUD 28800
//#define USART0_BAUD 38400
#define USART0_BAUD 57600
 
 
#endif //_UART_H
#endif //_UART0_H
/I2C_Telemetry/trunk/ubx.h
52,6 → 52,31
extern gps_data_t GPSData;
extern uint16_t CheckGPSOkay;
 
#define UBX_CLASS_CFG 0x06
#define UBX_CLASS_ACK 0x05
 
typedef struct
{
uint8_t Class;
uint8_t Id;
uint16_t Length;
} __attribute__((packed)) ubxmsghdr_t;
 
#define UBX_MSG_DATA_SIZE 200
typedef struct
{
uint8_t ClassMask;
uint8_t IdMask;
ubxmsghdr_t Hdr;
uint8_t Data[UBX_MSG_DATA_SIZE];
uint8_t Status;
} __attribute__((packed)) ubxmsg_t;
// msg obj to reveive
// set Class and Id and correspoinding masks of a message that should be received
extern ubxmsg_t UbxMsg;
 
 
 
void UBX_Init(void);
void UBX_Parser(uint8_t c);