Subversion Repositories FlightCtrl

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/**************************************************************************************************************************************
* File:                 uart.c
*
* Purpose:              This program treats the RS232 USRAT interface
*
* Functions:    void UART_Init(void)
*                               ISR(USART0_TX_vect)
*                               ISR(USART0_RX_vect)
*                               void AddCRC(unsigned int wieviele)
*                               void SendOutData(unsigned char cmd,unsigned char address, unsigned char BufferAnzahl, ...)
*                               void Decode64(void)
*                               void BearbeiteRxDaten(void)
*                               int uart_putchar(char c)
*                               void DatenUebertragung(void)
*
******************************************************************************************************************************************/

#include "main.h"
#include "uart.h"

#include <stdarg.h>
#include <string.h>

//------------------------ Definitionen ---------
#define FC_ADDRESS 1
#define NC_ADDRESS 2
#define MK3MAG_ADDRESS 3

//---------------------------------------------Variables-------
unsigned char GetExternalControl = 0;
unsigned char DebugDisplayAnforderung1 = 0;
unsigned char DebugDisplayAnforderung = 0;
unsigned char DebugDataAnforderung = 0;
unsigned char GetVersionAnforderung = 0;
unsigned char GetPPMChannelAnforderung = 0;

unsigned char DisplayLine = 0;
unsigned volatile char SioTmp = 0;
unsigned volatile char SendeBuffer[MAX_SENDE_BUFF];
unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF];
unsigned volatile char NMEABuffer[MAX_EMPFANGS_BUFF];
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 char *pRxData = 0;
unsigned char RxDataLen = 0;
unsigned volatile char PC_DebugTimeout = 0;
unsigned volatile char PC_MotortestActive = 0;

unsigned char DebugTextAnforderung = 255;
unsigned char PcZugriff = 100;
unsigned char MotorTest[16];
unsigned char MeineSlaveAdresse = 1; // Flight-Ctrl
unsigned char ConfirmFrame;

int Debug_Timer,Kompass_Timer,Timer3D;
unsigned int DebugDataIntervall = 200, Intervall3D = 0;

//---------------------------------------structs----------
struct str_DebugOut    DebugOut;
struct str_ExternControl  ExternControl;
struct str_VersionInfo VersionInfo;
struct str_WinkelOut WinkelOut;
struct str_Data3D Data3D;


const unsigned char ANALOG_TEXT[32][16] =
{
        //1234567890123456      // -------------------------------------------------------------// siehe "Debugwerte zuordnen" in fc.c Zeile 1270
        "3D Nick-Winkel  ", // 0        = IntegralNick / (EE_Parameter.GyroAccFaktor * 4);              // = Winkel * 10
        "AccNick         ",     // 1    = Mittelwert_AccNick / 4;                                                               // = so um die Null
        "maxcontrollerDD ", // 2        =                                                                                                               // = so um die Null
        "mincontrollerDD ", // 3        =                                                                                                               // = so um die Null
        "MesswertNick    ", // 4        = MesswertGier;                                                                                 // = -450
        "HiResNick       ", // 5        = auf Null bezogener Gyro Nickwert                                              // = so um die Null
        "AdWertAccNick   ", // 6        =                                                                                                               // = 713
        "Gas = thrust    ", // 7        = Gas                                                                                                   // = min 72 max 840 entspricht der Gashebelstellung
        "                ", // 8        =                                                                                                               // = 0 bis 360 Grad jenachdem wie der MK steht
        "Spannung V      ", // 9        = UBat;                                                                                                 // = 120 bei 12V
        "Empfang         ", // 10       = SenderOkay;                                                                                   // = 0 wenn Sender aus und ca 200 wenn Sender an
        "controllerP     ",     // 11   = controllerP                                                                                   // = dreht sich im Kreis - Umlauf 40 sec
        "Motor vorne     ",     // 12   = Motor[0]                                                                                              // = 0          // wird in SendMotorData(void) hier in fc.c zugewiesen
        "Motor hinten    ",     // 13   = Motor[1]                                                                                              // = 0
        "controllerD     ",     // 14   =                                                                                                               // = 0
        "controllerDD    ", // 15       =                                                                                                               // = 0
        "PPM_in[3] Nick  ",     // 16   =                                                                                                               // = -120...+120        // ab hier beginjnt der zweite Teil der Anzeige ------------
        "ipk[0]          ",     // 17   =                                                                                               // =           
        "ipk[1]          ",     // 18   =                                                                                                               // =
        "ipk[2]          ",     // 19   =                                                                                                               // =
        "ucflg1          ", // 20       =                                                                                                               // =
        "Stick Kanal 5   ",     // 21   = PPM_in[5]                                                                                             // = ca -120 oder +120
        "MesswertNick    ",     // 22   = MesswertNick;                                                                                 // = 0
        "maxcontrollerD  ",     // 23   =                                                                                                               // = 0
        "mincontrollerD  ",     // 24   =                                                                                                               // = -560
        "AdWertNick      ", // 25       = AdWertNick;                                                                                   // = 1130
        "maxcontrollerP  ", // 26       =                                                                                                               //
        "mincontrollerP  ", // 27       =                                                                                                               //
        "PPM_in[4] Gier  ", // 28       = PPM_in[4];                                                                                    // = ca -120 bis +120
        "PPM_in[3] Nick  ", // 29       = PPM_in[3];                                                                                    // = ca -120 bis +120
        "PPM_in[2] Roll  ", // 30       = PPM_in[2];                                                                                    // = ca -120 bis +120          
        "PPM_in[1] Gas   "      // 31   = PPM_in[1];                                                                                    // = ca -120 bis +120          
};
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------



//------------------------------------------------------------------------------------------------------------------
// Installation of the USART COM Port
//------------------------------------------------------------------------------------------------------------------
void UART_Init(void)
{
        //------------------------------------------------------------------------------------------------------------
        // UCSR0B – USART Control and Status Register 0 B containing RXCIE0 TXCIE0 UDRIE0 RXEN0 TXEN0 UCSZ02 RXB80 TXB80
        //
        UCSR0B = (1 << TXEN0) | (1 << RXEN0);                           // Writing this bit to one enables the USART Transmitter
       
        //------------------------------------------------------------------------------------------------------------
        // UCSR0A – USART Control and Status Register A containing RXC0 TXC0 UDRE0 FE0 DORn UPEn U2X0 MPCM0
        //
        UCSR0A   |= (1<<U2X0);                                                          // Double the USART Transmission Speed
       
        //------------------------------------------------------------------------------------------------------------
        // UCSR0B – USART Control and Status Register 0 B containing RXCIE0 TXCIE0 UDRIE0 RXEN0 TXEN0 UCSZ02 RXB80 TXB80
        //
        UCSR0B |= (1<<RXCIE);                                                           // RX Complete Interrupt Enable
        UCSR0B |= (1<<TXCIE);                                                           // TX Complete Interrupt Enable
       
        //------------------------------------------------------------------------------------------------------------
        // UBRRnL and UBRRnH – USART Baud Rate Registers
        //
        UBRR0L = (SYSCLK / (BAUD_RATE * 8L) - 1);                       // set Baudrate to 57600

       
        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.ProtoMinor = VERSION_SERIAL_MINOR;
       
        pRxData = 0;
        RxDataLen = 0;
}
//------------------------------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------------
// Interrupt due to USART0 TX Complete
//-----------------------------------------------------------------------------------------------------
ISR(USART0_TX_vect)
{
        static unsigned int ptr = 0;
        unsigned char tmp_tx;
        if(!UebertragungAbgeschlossen)
        {
                ptr++;                                                                          // die [0] wurde schon gesendet
                tmp_tx = SendeBuffer[ptr];
                if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
                {
                        ptr = 0;
                        UebertragungAbgeschlossen = 1;
                }
                UDR = tmp_tx;
        }
        else ptr = 0;
}
//-----------------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------------
// Interrupt due to USART0 RX Complete
//-----------------------------------------------------------------------------------------------------
ISR(USART0_RX_vect)
{
        static unsigned int crc;
        static unsigned char crc1,crc2,buf_ptr;
        static unsigned char UartState = 0;
        unsigned char CrcOkay = 0;

        SioTmp = UDR;
        if(buf_ptr >= MAX_EMPFANGS_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')
                        {
                                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;
        }
}
//-----------------------------------------------------------------------------------------------------



// --------------------------------------------------------------------------
// checksum
// --------------------------------------------------------------------------
void AddCRC(unsigned int wieviele)
{
        unsigned int tmpCRC = 0,i;
        for(i = 0; i < wieviele;i++)
        {
                tmpCRC += SendeBuffer[i];
        }
        tmpCRC %= 4096;
        SendeBuffer[i++] = '=' + tmpCRC / 64;
        SendeBuffer[i++] = '=' + tmpCRC % 64;
        SendeBuffer[i++] = '\r';
        UebertragungAbgeschlossen = 0;
        UDR = SendeBuffer[0];
}
//-----------------------------------------------------------------------------------------------------



// ---------------------------------------------------------------------------------------------------------------------------
//unsigned char *snd, unsigned char len)
// ---------------------------------------------------------------------------------------------------------------------------
void SendOutData(unsigned char cmd,unsigned char address, unsigned char BufferAnzahl, ...)
{
        va_list ap;
        unsigned int pt = 0;
        unsigned char a,b,c;
        unsigned char ptr = 0;

        unsigned char *snd = 0;
        int len = 0;

        SendeBuffer[pt++] = '#';                                                                // Startzeichen
        SendeBuffer[pt++] = 'a' + address;                                              // Adresse (a=0; b=1,...)
        SendeBuffer[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)
                {
                        a = snd[ptr++];
                        len--;
                        if((!len) && BufferAnzahl)
                        {
                                snd = va_arg(ap, unsigned char*);
                                len = va_arg(ap, int);
                                ptr = 0;
                                BufferAnzahl--;
                        }
                }
                else a = 0;
                if(len)
                {
                        b = snd[ptr++];
                        len--;
                        if((!len) && BufferAnzahl)
                        {
                                snd = va_arg(ap, unsigned char*);
                                len = va_arg(ap, int);
                                ptr = 0;
                                BufferAnzahl--;
                        }
                }
                else b = 0;
                if(len)
                {
                        c = snd[ptr++];
                        len--;
                        if((!len) && BufferAnzahl)
                        {
                                snd = va_arg(ap, unsigned char*);
                                len = va_arg(ap, int);
                                ptr = 0;
                                BufferAnzahl--;
                        }
                }
                else c = 0;
                SendeBuffer[pt++] = '=' + (a >> 2);
                SendeBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
                SendeBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
                SendeBuffer[pt++] = '=' + ( c & 0x3f);
        }
        va_end(ap);
        AddCRC(pt);
}
// EOF : SendOutData() ----------------------------------------------------------------------------------------------------



// ----------------------------------------------------------------------------------------------------------------------
// die daten werden im rx buffer dekodiert, das geht nur, weil aus 4 byte immer 3 gemacht werden.
// ----------------------------------------------------------------------------------------------------------------------
void Decode64(void)    
{
        unsigned char a,b,c,d;
        unsigned char x,y,z;
        unsigned char ptrIn = 3;                                                        // start at begin of data block
        unsigned char ptrOut = 3;
        unsigned char len = AnzahlEmpfangsBytes - 6;            // von der Gesamtbytezahl eines Frames gehen 3 Bytes des Headers  ('#',Addr, Cmd) und 3 Bytes des Footers (CRC1, CRC2, '\r') ab.

        while(len)
        {
                a = RxdBuffer[ptrIn++] - '=';
                b = RxdBuffer[ptrIn++] - '=';
                c = RxdBuffer[ptrIn++] - '=';
                d = RxdBuffer[ptrIn++] - '=';
               
                x = (a << 2) | (b >> 4);
                y = ((b & 0x0f) << 4) | (c >> 2);
                z = ((c & 0x03) << 6) | d;
               
                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)
{
        if(!NeuerDatensatzEmpfangen) return;
       
        unsigned char tempchar1, tempchar2;
        Decode64();                                                                     // dekodiere datenblock im Empfangsbuffer
        switch(RxdBuffer[1]-'a')                                                // check for Slave Address
        {
                case FC_ADDRESS:                                                        // FC special commands
                       
                switch(RxdBuffer[2])
                {
                        case 'K':                                                               // Kompasswert
                                        memcpy((unsigned char *)&KompassValue , (unsigned char *)pRxData, sizeof(KompassValue));
                                        KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
                                        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));
                                        break;
                                       
                        case 'm':                                                                       // "Write Mixer
                                        while(!UebertragungAbgeschlossen);
                                        if(pRxData[0] == MIXER_REVISION)
                                        {
                                                memcpy(&Mixer, (unsigned char *)pRxData, sizeof(Mixer));
                                                eeprom_write_block(&Mixer, &EEPromArray[EEPROM_ADR_MIXER_TABLE], sizeof(Mixer));
                                                tempchar1 = 1;
                                        }
                                        else  tempchar1 = 0;
                                        SendOutData('M', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1));
                                        break;
                                       
                        case 'p':                                                                       // get PPM Channels
                                        GetPPMChannelAnforderung = 1;
                                        break;
                                       
                        case 'q':                                                                       // "Get"-Anforderung für Settings
                                        // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
                                        if(pRxData[0] == 0xFF)
                                        {
                                                pRxData[0] = GetActiveParamSetNumber();
                                        }
                                        // limit settings range
                                        if(pRxData[0] < 1) pRxData[0] = 1;              // limit to 5
                                        else if(pRxData[0] > 5) pRxData[0] = 5;         // limit to 5
                                        // load requested parameter set
                                        ReadParameterSet(pRxData[0], (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);    // #define  STRUCT_PARAM_LAENGE  sizeof(EE_Parameter)
                                       
                                        while(!UebertragungAbgeschlossen);
                                        tempchar1 = pRxData[0];
                                        tempchar2 = EE_DATENREVISION;           // #define EE_DATENREVISION 80  // Parameter fürs Koptertool; entspricht den EEPROM-Daten von FlightCtrl Version V0.76g
                                        SendOutData('Q', FC_ADDRESS, 3, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2), (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);   // #define  STRUCT_PARAM_LAENGE  sizeof(EE_Parameter)
                                        break;
                                       
                        case 's': // Parametersatz speichern
                                       
                                        if((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EE_DATENREVISION)) // check for setting to be in range
                                        {
                                                memcpy((unsigned char *) &EE_Parameter.Kanalbelegung[0], (unsigned char *)&pRxData[2], STRUCT_PARAM_LAENGE);            // #define  STRUCT_PARAM_LAENGE  sizeof(EE_Parameter)
                                                WriteParameterSet(pRxData[0], (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
                                                Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L;
                                                Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L;
                                                SetActiveParamSetNumber(pRxData[0]);
                                                tempchar1 = GetActiveParamSetNumber();
                                                LipoDetection(0);                                                       // jump tp main.c line 59
                                                Piep(tempchar1,110);
                                        }
                                        else
                                        {
                                                tempchar1 = 0;                                          // mark in response an invlid setting
                                        }
                                        while(!UebertragungAbgeschlossen);
                                        SendOutData('S', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1));
                                        break;
                                       
                } // EOF : case FC_ADDRESS
               
                default: // any Slave Address
               
                switch(RxdBuffer[2])
                {
                        // 't' comand placed here only for compatibility to BL
                        case 't':                                                                               // Motortest
                                        if(AnzahlEmpfangsBytes > 20) 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;
                                        break;
                                        // 'K' comand placed here only for compatibility to old MK3MAG software, that does not send the right Slave Address
                        case 'K':                                                                               // Kompasswert
                                        memcpy((unsigned char *)&KompassValue , (unsigned char *)pRxData, sizeof(KompassValue));
                                        KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
                                        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;
                                        break;
                        case 'd':                                                                               // Poll the debug data
                                        DebugDataIntervall = pRxData[0] * 10;
                                        if(DebugDataIntervall > 0) DebugDataAnforderung = 1;
                                        break;
                                       
                        case 'h':                                                                               // x-1 Displayzeilen
                                PcZugriff = 255;
                                        RemoteKeys |= pRxData[0];
                                        if(RemoteKeys) DisplayLine = 0;
                                        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;
                }
                break;                                                                                          // default:
        }
        NeuerDatensatzEmpfangen = 0;
        pRxData = 0;
        RxDataLen = 0;
}
//-----------------------------------------------------------------------------------------------------



// --------------------------------------------------------------------------
// function serial output
// --------------------------------------------------------------------------
int uart_putchar(char c)
{
        if (c == '\n')  uart_putchar('\r');
        loop_until_bit_is_set(USR, UDRE);                       // Warten solange bis Zeichen gesendet wurde
        UDR = c;                                                                        // Ausgabe des Zeichens
       
        return (0);
}
//-----------------------------------------------------------------------------------------------------



//---------------------------------------------------------------------------------------------
// Datenübertragung
//---------------------------------------------------------------------------------------------
void DatenUebertragung(void)
{
 if(!UebertragungAbgeschlossen) return;
       
        if(DebugDisplayAnforderung && UebertragungAbgeschlossen)
        {
                Menu();
                SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), &DisplayBuff[DisplayLine * 20], 20);
                DisplayLine++;
                if(DisplayLine >= 4) DisplayLine = 0;
                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;
        }
       
        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((CheckDelay(Kompass_Timer)) && UebertragungAbgeschlossen)
        {
                WinkelOut.Winkel[0] = (int) (IntegralNick / (EE_Parameter.GyroAccFaktor * 4));  // etwa in 0.1 Grad
                WinkelOut.Winkel[1] = (int) (IntegralRoll / (EE_Parameter.GyroAccFaktor * 4));  // etwa in 0.1 Grad
                WinkelOut.UserParameter[0] = Parameter_UserParam1;
                WinkelOut.UserParameter[1] = Parameter_UserParam2;
                SendOutData('w', MK3MAG_ADDRESS, 1, (unsigned char *) &WinkelOut,sizeof(WinkelOut));
                if(WinkelOut.CalcState > 4)  WinkelOut.CalcState = 6;                                                   // wird dann in SPI auf Null gesetzt
                Kompass_Timer = SetDelay(99);
        }
       
        if(((DebugDataIntervall>0 && CheckDelay(Debug_Timer)) || DebugDataAnforderung) && UebertragungAbgeschlossen)
        {
                //if(Poti3 > 64)         
                SendOutData('D', FC_ADDRESS, 1, (unsigned char *) &DebugOut,sizeof(DebugOut));
                DebugDataAnforderung = 0;
                if(DebugDataIntervall>0) Debug_Timer = SetDelay(DebugDataIntervall);
        }
       
        if(Intervall3D > 0 && CheckDelay(Timer3D) && UebertragungAbgeschlossen)
        {
                Data3D.Winkel[0] = (int) (IntegralNick / (EE_Parameter.GyroAccFaktor * 4));  // etwa in 0.1 Grad
                Data3D.Winkel[1] = (int) (IntegralRoll / (EE_Parameter.GyroAccFaktor * 4));  // etwa in 0.1 Grad
                Data3D.Winkel[2] = (int) ((10 * ErsatzKompass) / GIER_GRAD_FAKTOR);
                SendOutData('C', FC_ADDRESS, 1, (unsigned char *) &Data3D,sizeof(Data3D));
                Timer3D = SetDelay(Intervall3D);
        }
       
        if(DebugTextAnforderung != 255)                                                                                                         // Texte für die Analogdaten
        {
                SendOutData('A', FC_ADDRESS, 2, (unsigned char *)&DebugTextAnforderung, sizeof(DebugTextAnforderung),(unsigned char *) ANALOG_TEXT[DebugTextAnforderung], 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;
        }
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------