Subversion Repositories FlightCtrl

Rev

Rev 976 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ingob 1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
// + Copyright (c) 04.2007 Holger Buss
3
// + only for non-profit use
4
// + www.MikroKopter.com
5
// + see the File "License.txt" for further Informations
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
 
8
#include "main.h"
9
#include "uart.h"
10
 
11
unsigned char DebugGetAnforderung = 0,DebugDisplayAnforderung = 0,DebugDataAnforderung = 0,GetVersionAnforderung = 0;
12
unsigned volatile char SioTmp = 0;
13
unsigned volatile char SendeBuffer[MAX_SENDE_BUFF];
14
unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF];
15
unsigned volatile char NMEABuffer[MAX_EMPFANGS_BUFF];
16
unsigned volatile char NeuerDatensatzEmpfangen = 0;
17
unsigned volatile char NeueKoordinateEmpfangen = 0;
18
unsigned volatile char UebertragungAbgeschlossen = 1;
19
unsigned volatile char CntCrcError = 0;
20
unsigned volatile char AnzahlEmpfangsBytes = 0;
21
unsigned volatile char PC_DebugTimeout = 0;
499 hbuss 22
unsigned char RemotePollDisplayLine = 0;
395 hbuss 23
unsigned char NurKanalAnforderung = 0;
499 hbuss 24
unsigned char DebugTextAnforderung = 255;
1 ingob 25
unsigned char PcZugriff = 100;
26
unsigned char MotorTest[4] = {0,0,0,0};
595 hbuss 27
unsigned char DubWiseKeys[4] = {0,0,0,0};
1 ingob 28
unsigned char MeineSlaveAdresse;
595 hbuss 29
unsigned char ConfirmFrame;
1 ingob 30
struct str_DebugOut    DebugOut;
595 hbuss 31
struct str_ExternControl  ExternControl;
1 ingob 32
struct str_VersionInfo VersionInfo;
693 hbuss 33
struct str_WinkelOut WinkelOut;
1 ingob 34
 
693 hbuss 35
int Debug_Timer,Kompass_Timer;
36
 
499 hbuss 37
const unsigned char ANALOG_TEXT[32][16] =
38
{
39
   //1234567890123456 
40
    "IntegralNick    ", //0
41
    "IntegralRoll    ",
42
    "AccNick         ",
43
    "AccRoll         ",
44
    "GyroGier        ",
45
    "HoehenWert      ", //5
46
    "AccZ            ",
47
    "Gas             ",
48
    "KompassValue    ",
513 hbuss 49
    "Spannung        ",
977 pangu 50
#ifdef HEXAKOPTER
51
    "Motor VL        ", //10
52
    "Motor VR        ",
53
    "Motor HL        ",
54
    "Motor HR        ",
55
    "Motor Links     ",
56
    "Motor Rechts    ", //15
57
#else
58
    "                ", //10
929 hbuss 59
    "                ",
977 pangu 60
    "Motor Vorne     ",
61
    "Motor Hinten    ",
62
    "Motor Links     ",
63
    "Motor Rechts    ", //15
64
#endif
65
    "                ",
744 hbuss 66
    "Distance        ",
67
    "OsdBar          ",
819 hbuss 68
    "MK3Mag CalState ",
854 hbuss 69
    "Servo           ", //20
70
    "Nick            ",
71
    "Roll            ",
720 ingob 72
    "                ",
73
    "                ",
74
    "                ", //25
75
    "                ",
76
    "                ",
977 pangu 77
    "Ersatzkompass   ",
78
    "Empfang         ",
720 ingob 79
    "GPS_Nick        ", //30
80
    "GPS_Roll        "
499 hbuss 81
};
82
 
83
 
84
 
1 ingob 85
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
86
//++ Sende-Part der Datenübertragung
87
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
88
SIGNAL(INT_VEC_TX)
89
{
90
 static unsigned int ptr = 0;
91
 unsigned char tmp_tx;
92
 if(!UebertragungAbgeschlossen)  
93
  {
94
   ptr++;                    // die [0] wurde schon gesendet
95
   tmp_tx = SendeBuffer[ptr];  
96
   if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
97
    {
98
     ptr = 0;
99
     UebertragungAbgeschlossen = 1;
100
    }
101
   UDR = tmp_tx;
102
  }
103
  else ptr = 0;
104
}
105
 
106
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
107
//++ Empfangs-Part der Datenübertragung, incl. CRC-Auswertung
108
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
109
SIGNAL(INT_VEC_RX)
110
{
111
 static unsigned int crc;
112
 static unsigned char crc1,crc2,buf_ptr;
113
 static unsigned char UartState = 0;
114
 unsigned char CrcOkay = 0;
115
 
116
 SioTmp = UDR;
117
 if(buf_ptr >= MAX_EMPFANGS_BUFF)    UartState = 0;
118
 if(SioTmp == '\r' && UartState == 2)
119
  {
120
   UartState = 0;
121
   crc -= RxdBuffer[buf_ptr-2];
122
   crc -= RxdBuffer[buf_ptr-1];
123
   crc %= 4096;
124
   crc1 = '=' + crc / 64;
125
   crc2 = '=' + crc % 64;
126
   CrcOkay = 0;
127
   if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1])) CrcOkay = 1; else { CrcOkay = 0; CntCrcError++;};
128
   if(!NeuerDatensatzEmpfangen && CrcOkay) // Datensatz schon verarbeitet
129
    {
130
     NeuerDatensatzEmpfangen = 1;
131
         AnzahlEmpfangsBytes = buf_ptr;
132
     RxdBuffer[buf_ptr] = '\r';
173 holgerb 133
         if(RxdBuffer[2] == 'R') wdt_enable(WDTO_250MS); // Reset-Commando
1 ingob 134
        }                                
135
  }
136
  else
137
  switch(UartState)
138
  {
139
   case 0:
140
          if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1;  // Startzeichen und Daten schon verarbeitet
141
                  buf_ptr = 0;
142
                  RxdBuffer[buf_ptr++] = SioTmp;
143
                  crc = SioTmp;
144
          break;
145
   case 1: // Adresse auswerten
146
                  UartState++;
147
                  RxdBuffer[buf_ptr++] = SioTmp;
148
                  crc += SioTmp;
149
                  break;
150
   case 2: //  Eingangsdaten sammeln
151
                  RxdBuffer[buf_ptr] = SioTmp;
152
                  if(buf_ptr < MAX_EMPFANGS_BUFF) buf_ptr++;
153
                  else UartState = 0;
154
                  crc += SioTmp;
155
                  break;
156
   default:
157
          UartState = 0;
158
          break;
159
  }
160
}
161
 
162
 
163
// --------------------------------------------------------------------------
164
void AddCRC(unsigned int wieviele)
165
{
166
 unsigned int tmpCRC = 0,i;
167
 for(i = 0; i < wieviele;i++)
168
  {
169
   tmpCRC += SendeBuffer[i];
170
  }
171
   tmpCRC %= 4096;
172
   SendeBuffer[i++] = '=' + tmpCRC / 64;
173
   SendeBuffer[i++] = '=' + tmpCRC % 64;
174
   SendeBuffer[i++] = '\r';
175
  UebertragungAbgeschlossen = 0;
176
  UDR = SendeBuffer[0];
177
}
178
 
179
 
180
 
181
// --------------------------------------------------------------------------
182
void SendOutData(unsigned char cmd,unsigned char modul, unsigned char *snd, unsigned char len)
183
{
184
 unsigned int pt = 0;
185
 unsigned char a,b,c;
186
 unsigned char ptr = 0;
187
 
188
 SendeBuffer[pt++] = '#';               // Startzeichen
189
 SendeBuffer[pt++] = modul;             // Adresse (a=0; b=1,...)
190
 SendeBuffer[pt++] = cmd;                       // Commando
191
 
192
 while(len)
193
  {
194
   if(len) { a = snd[ptr++]; len--;} else a = 0;
195
   if(len) { b = snd[ptr++]; len--;} else b = 0;
196
   if(len) { c = snd[ptr++]; len--;} else c = 0;
197
   SendeBuffer[pt++] = '=' + (a >> 2);
198
   SendeBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
199
   SendeBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
200
   SendeBuffer[pt++] = '=' + ( c & 0x3f);
201
  }
202
 AddCRC(pt);
203
}
204
 
205
 
206
// --------------------------------------------------------------------------
207
void Decode64(unsigned char *ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max)  // Wohin mit den Daten; Wie lang; Wo im RxdBuffer
208
{
209
 unsigned char a,b,c,d;
210
 unsigned char ptr = 0;
211
 unsigned char x,y,z;
212
 while(len)
213
  {
214
   a = RxdBuffer[ptrIn++] - '=';
215
   b = RxdBuffer[ptrIn++] - '=';
216
   c = RxdBuffer[ptrIn++] - '=';
217
   d = RxdBuffer[ptrIn++] - '=';
218
   if(ptrIn > max - 2) break;     // nicht mehr Daten verarbeiten, als empfangen wurden
219
 
220
   x = (a << 2) | (b >> 4);
221
   y = ((b & 0x0f) << 4) | (c >> 2);
222
   z = ((c & 0x03) << 6) | d;
223
 
224
   if(len--) ptrOut[ptr++] = x; else break;
225
   if(len--) ptrOut[ptr++] = y; else break;
226
   if(len--) ptrOut[ptr++] = z; else break;
227
  }
228
 
229
}
230
 
231
// --------------------------------------------------------------------------
232
void BearbeiteRxDaten(void)
233
{
234
 if(!NeuerDatensatzEmpfangen) return;
235
 
693 hbuss 236
 unsigned int tmp_int_arr1[1];
304 ingob 237
// unsigned int tmp_int_arr2[2];
238
// unsigned int tmp_int_arr3[3];
1 ingob 239
 unsigned char tmp_char_arr2[2];
304 ingob 240
// unsigned char tmp_char_arr3[3];
241
// unsigned char tmp_char_arr4[4];
1 ingob 242
 //if(!MotorenEin) 
243
  switch(RxdBuffer[2])
244
  {
693 hbuss 245
   case 'K':// Kompasswert
246
            Decode64((unsigned char *) &tmp_int_arr1[0],sizeof(tmp_int_arr1),3,AnzahlEmpfangsBytes);
247
            KompassValue = tmp_int_arr1[0];
248
            KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
249
                        break;
499 hbuss 250
   case 'a':// Texte der Analogwerte
251
            Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
252
            DebugTextAnforderung = tmp_char_arr2[0];
693 hbuss 253
            PcZugriff = 255;
499 hbuss 254
                        break;
595 hbuss 255
   case 'b':
256
                        Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
257
                        RemoteTasten |= ExternControl.RemoteTasten;
258
            ConfirmFrame = ExternControl.Frame;
918 hbuss 259
            PcZugriff = 255;
595 hbuss 260
            break;
261
   case 'c':
262
                        Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
263
                        RemoteTasten |= ExternControl.RemoteTasten;
264
            ConfirmFrame = ExternControl.Frame;
1 ingob 265
            DebugDataAnforderung = 1;
693 hbuss 266
            PcZugriff = 255;
1 ingob 267
            break;
268
   case 'h':// x-1 Displayzeilen
269
            Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
270
            RemoteTasten |= tmp_char_arr2[0];
395 hbuss 271
                        if(tmp_char_arr2[1] == 255) NurKanalAnforderung = 1; else NurKanalAnforderung = 0; // keine Displaydaten
1 ingob 272
                        DebugDisplayAnforderung = 1;
273
                        break;
274
   case 't':// Motortest
275
            Decode64((unsigned char *) &MotorTest[0],sizeof(MotorTest),3,AnzahlEmpfangsBytes);
693 hbuss 276
            PcZugriff = 255;
1 ingob 277
                        break;
492 hbuss 278
   case 'k':// Keys von DubWise
279
            Decode64((unsigned char *) &DubWiseKeys[0],sizeof(DubWiseKeys),3,AnzahlEmpfangsBytes);
595 hbuss 280
                        ConfirmFrame = DubWiseKeys[3];
693 hbuss 281
            PcZugriff = 255;
492 hbuss 282
                        break;
1 ingob 283
   case 'v': // Version-Anforderung     und Ausbaustufe
284
            GetVersionAnforderung = 1;
285
            break;                                                               
286
   case 'g':// "Get"-Anforderung für Debug-Daten 
287
            // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
288
            DebugGetAnforderung = 1;
289
            break;
290
   case 'q':// "Get"-Anforderung für Settings
291
            // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
292
            Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
846 hbuss 293
            while(!UebertragungAbgeschlossen);
1 ingob 294
            if(tmp_char_arr2[0] != 0xff)
295
             {
296
                          if(tmp_char_arr2[0] > 5) tmp_char_arr2[0] = 5;
297
                  ReadParameterSet(tmp_char_arr2[0], (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);                   
298
                  SendOutData('L' + tmp_char_arr2[0] -1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
299
             }
300
             else
301
                  SendOutData('L' + GetActiveParamSetNumber()-1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
302
 
303
            break;
304
 
305
   case 'l':
306
   case 'm':
307
   case 'n':
308
   case 'o':
309
   case 'p': // Parametersatz speichern
310
            Decode64((unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE,3,AnzahlEmpfangsBytes);
311
                        WriteParameterSet(RxdBuffer[2] - 'l' + 1, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
312
            eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], RxdBuffer[2] - 'l' + 1);  // aktiven Datensatz merken
395 hbuss 313
            Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L;
314
            Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L;
1 ingob 315
            Piep(GetActiveParamSetNumber());
316
         break;
317
 
318
 
319
  }
320
// DebugOut.AnzahlZyklen =  Debug_Timer_Intervall;
321
 NeuerDatensatzEmpfangen = 0;
322
}
323
 
324
//############################################################################
325
//Routine für die Serielle Ausgabe
326
int uart_putchar (char c)
327
//############################################################################
328
{
329
        if (c == '\n')
330
                uart_putchar('\r');
331
        //Warten solange bis Zeichen gesendet wurde
332
        loop_until_bit_is_set(USR, UDRE);
333
        //Ausgabe des Zeichens
334
        UDR = c;
335
 
336
        return (0);
337
}
338
 
339
// --------------------------------------------------------------------------
340
void WriteProgramData(unsigned int pos, unsigned char wert)
341
{
342
  //if (ProgramLocation == IN_RAM) Buffer[pos] = wert;
343
  // else eeprom_write_byte(&EE_Buffer[pos], wert);
344
  // Buffer[pos] = wert;
345
}
346
 
347
//############################################################################
348
//INstallation der Seriellen Schnittstelle
349
void UART_Init (void)
350
//############################################################################
351
{
352
        //Enable TXEN im Register UCR TX-Data Enable & RX Enable
353
 
354
        UCR=(1 << TXEN) | (1 << RXEN);
355
    // UART Double Speed (U2X)
356
        USR   |= (1<<U2X);          
357
        // RX-Interrupt Freigabe
358
        UCSRB |= (1<<RXCIE);          
359
        // TX-Interrupt Freigabe
360
        UCSRB |= (1<<TXCIE);          
361
 
362
        //Teiler wird gesetzt 
363
        UBRR=(SYSCLK / (BAUD_RATE * 8L) - 1);
364
        //UBRR = 33;
365
        //öffnet einen Kanal für printf (STDOUT)
366
        //fdevopen (uart_putchar, 0);
367
        //sbi(PORTD,4);
368
  Debug_Timer = SetDelay(200);  
693 hbuss 369
  Kompass_Timer = SetDelay(220);  
1 ingob 370
}
371
 
372
//---------------------------------------------------------------------------------------------
373
void DatenUebertragung(void)  
374
{
375
 if(!UebertragungAbgeschlossen) return;
376
 
377
   if(DebugGetAnforderung && UebertragungAbgeschlossen)               // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
378
   {
595 hbuss 379
      SendOutData('G',MeineSlaveAdresse,(unsigned char *) &ExternControl,sizeof(ExternControl));
1 ingob 380
          DebugGetAnforderung = 0;
381
   }
382
 
693 hbuss 383
    if((CheckDelay(Kompass_Timer)) && UebertragungAbgeschlossen)        
384
         {
846 hbuss 385
                  WinkelOut.Winkel[0] = (int) (IntegralNick / 108);  // etwa in 0,1 Grad
386
                  WinkelOut.Winkel[1] = (int) (IntegralRoll / 108);  // etwa in 0,1 Grad
717 hbuss 387
                  WinkelOut.UserParameter[0] = Parameter_UserParam1;
388
                  WinkelOut.UserParameter[1] = Parameter_UserParam2;
693 hbuss 389
          SendOutData('w',MeineSlaveAdresse,(unsigned char *) &WinkelOut,sizeof(WinkelOut));
855 hbuss 390
          if(WinkelOut.CalcState > 4)  WinkelOut.CalcState = 6; // wird dann in SPI auf Null gesetzt
693 hbuss 391
          Kompass_Timer = SetDelay(99);  
392
         }
393
 
1 ingob 394
    if((CheckDelay(Debug_Timer) || DebugDataAnforderung) && UebertragungAbgeschlossen)  
395
         {
396
          SendOutData('D',MeineSlaveAdresse,(unsigned char *) &DebugOut,sizeof(DebugOut));
397
          DebugDataAnforderung = 0;
398
          Debug_Timer = SetDelay(MIN_DEBUG_INTERVALL);  
399
         }
499 hbuss 400
    if(DebugTextAnforderung != 255) // Texte für die Analogdaten
401
     {
402
      SendOutData('A',DebugTextAnforderung + '0',(unsigned char *) ANALOG_TEXT[DebugTextAnforderung],16);
403
      DebugTextAnforderung = 255;
404
         }
595 hbuss 405
     if(ConfirmFrame && UebertragungAbgeschlossen)   // Datensatz ohne CRC bestätigen 
406
         {
407
      SendeBuffer[0] = '#';
408
      SendeBuffer[1] = ConfirmFrame;
409
      SendeBuffer[2] = '\r';
410
      UebertragungAbgeschlossen = 0;
411
      ConfirmFrame = 0;
412
      UDR = SendeBuffer[0];
413
     }
1 ingob 414
     if(DebugDisplayAnforderung && UebertragungAbgeschlossen)
415
         {
416
      Menu();
417
          DebugDisplayAnforderung = 0;
499 hbuss 418
      if(++RemotePollDisplayLine == 4 || NurKanalAnforderung)
173 holgerb 419
      {
304 ingob 420
       SendOutData('4',0,(unsigned char *)&PPM_in,sizeof(PPM_in));   // DisplayZeile übertragen
499 hbuss 421
       RemotePollDisplayLine = -1;
173 holgerb 422
      }
499 hbuss 423
      else  SendOutData('0' + RemotePollDisplayLine,0,(unsigned char *)&DisplayBuff[20 * RemotePollDisplayLine],20);   // DisplayZeile übertragen
1 ingob 424
         }
425
    if(GetVersionAnforderung && UebertragungAbgeschlossen)
426
     {
427
      SendOutData('V',MeineSlaveAdresse,(unsigned char *) &VersionInfo,sizeof(VersionInfo));
428
          GetVersionAnforderung = 0;
429
     }
430
 
431
}
432