Subversion Repositories MK3Mag

Rev

Rev 5 | Rev 12 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ingob 1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 hbuss 2
// + MK3Mag 3D-Compass
3
// + ATMEGA168 mit 8MHz
4
// + (c) 05.2008 Holger Buss
1 ingob 5
// + Nur für den privaten Gebrauch
6
// + Keine Garantie auf Fehlerfreiheit
7
// + Kommerzielle Nutzung nur mit meiner Zustimmung
7 hbuss 8
// + Der Code ist für die Hardware MK3Mag entwickelt worden
9
// + www.mikrokopter.com
1 ingob 10
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11
 
12
#include "main.h"
13
#include "uart.h"
14
 
15
#define MAX_SENDE_BUFF     100
16
#define MAX_EMPFANGS_BUFF  100
17
 
18
unsigned volatile char SIO_Sollwert = 0;
19
unsigned volatile char SioTmp = 0;
20
unsigned volatile char SendeBuffer[MAX_SENDE_BUFF];
21
unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF];
22
unsigned volatile char NeuerDatensatzEmpfangen = 0;
23
unsigned volatile char UebertragungAbgeschlossen = 1;
24
unsigned char GetVersionAnforderung = 0,DebugTextAnforderung = 0,DebugGetAnforderung = 0, KompassAntwort = 0;
25
unsigned char MeineSlaveAdresse;
26
unsigned char MotorTest[4] = {0,0,0,0};
27
unsigned volatile char AnzahlEmpfangsBytes = 0;
28
unsigned char PcZugriff;
29
 
30
struct str_DebugOut       DebugOut;
7 hbuss 31
struct str_ExternData     ExternData;
1 ingob 32
struct str_ExternControl  ExternControl;
33
struct str_VersionInfo    VersionInfo;
34
 
35
 
3 ingob 36
 
1 ingob 37
int Debug_Timer;
38
 
39
const unsigned char ANALOG_TEXT[32][16] =
40
{
7 hbuss 41
   //1234567890123456
1 ingob 42
    "Magnet N        ", //0
43
    "Magnet R        ",
7 hbuss 44
    "Magnet Z        ",
45
    "Raw    N        ",
46
    "Raw    R        ",
47
    "Raw    Z        ", //5
1 ingob 48
    "Lage N          ",
49
    "Lage R          ",
7 hbuss 50
    "Xmin            ",
51
    "Xmax            ",
52
    "Ymin            ", //10
53
    "Ymax            ",
54
    "Zmin            ",
55
    "ZMax            ",
56
    "Calstate        ",
57
    "Kompass         ", //15
5 hbuss 58
    "User0           ",
59
    "User1           ",
7 hbuss 60
    "Analog18        ",
61
    "Analog19        ",
62
    "Analog20        ", //20
63
    "Analog21        ",
64
    "Analog22        ",
65
    "Analog23        ",
66
    "Analog24        ",
67
    "Analog25        ", //25
1 ingob 68
    "Analog26        ",
7 hbuss 69
    "Analog27        ",
70
    "Analog28        ",
71
    "Analog29        ",
72
    "Analog30        ", //30
73
    "Analog31        "
1 ingob 74
};
75
 
76
 
7 hbuss 77
 
1 ingob 78
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
79
//++ Sende-Part der Datenübertragung
80
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
81
SIGNAL(INT_VEC_TX)
82
{
83
 static unsigned int ptr = 0;
84
 unsigned char tmp_tx;
85
 if(!UebertragungAbgeschlossen)  
86
  {
87
   ptr++;                    // die [0] wurde schon gesendet
88
   tmp_tx = SendeBuffer[ptr];  
89
   if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
90
    {
91
     ptr = 0;
92
     UebertragungAbgeschlossen = 1;
93
    }
94
   UDR = tmp_tx;
95
  }
96
  else ptr = 0;
97
}
98
 
99
void SendUart(void)
100
{
101
 static unsigned int ptr = 0;
102
 unsigned char tmp_tx;
103
 if(!(USR & 0x40)) return;
104
 if(!UebertragungAbgeschlossen)  
105
  {
106
   ptr++;                    // die [0] wurde schon gesendet
107
   tmp_tx = SendeBuffer[ptr];  
108
   if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
109
    {
110
     ptr = 0;
111
     UebertragungAbgeschlossen = 1;
112
    }
113
   USR |= (1<TXC0);
114
   UDR = tmp_tx;
115
  }
116
  else ptr = 0;
117
}
118
 
119
// --------------------------------------------------------------------------
120
void Decode64(unsigned char *ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max)  // Wohin mit den Daten; Wie lang; Wo im RxdBuffer
121
{
122
 unsigned char a,b,c,d;
123
 unsigned char ptr = 0;
124
 unsigned char x,y,z;
125
 while(len)
126
  {
127
   a = RxdBuffer[ptrIn++] - '=';
128
   b = RxdBuffer[ptrIn++] - '=';
129
   c = RxdBuffer[ptrIn++] - '=';
130
   d = RxdBuffer[ptrIn++] - '=';
131
   if(ptrIn > max - 2) break;     // nicht mehr Daten verarbeiten, als empfangen wurden
132
 
133
   x = (a << 2) | (b >> 4);
134
   y = ((b & 0x0f) << 4) | (c >> 2);
135
   z = ((c & 0x03) << 6) | d;
136
 
137
   if(len--) ptrOut[ptr++] = x; else break;
138
   if(len--) ptrOut[ptr++] = y; else break;
139
   if(len--) ptrOut[ptr++] = z; else break;
140
  }
141
 
142
}
143
 
144
 
145
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
146
//++ Empfangs-Part der Datenübertragung
147
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
148
SIGNAL(INT_VEC_RX)
149
{
150
 static unsigned int crc;
151
 static unsigned char crc1,crc2,buf_ptr;
152
 static unsigned char UartState = 0;
153
 unsigned char CrcOkay = 0;
154
 
155
 SioTmp = UDR;
156
 if(buf_ptr >= MAX_EMPFANGS_BUFF)    UartState = 0;
157
 if(SioTmp == '\r' && UartState == 2)
158
  {
159
   UartState = 0;
160
   crc -= RxdBuffer[buf_ptr-2];
161
   crc -= RxdBuffer[buf_ptr-1];
162
   crc %= 4096;
163
   crc1 = '=' + crc / 64;
164
   crc2 = '=' + crc % 64;
165
   CrcOkay = 0;
166
   if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1])) CrcOkay = 1; else { CrcOkay = 0; };
167
   if(CrcOkay) // Datensatz schon verarbeitet
168
    {
169
     NeuerDatensatzEmpfangen = 1;
170
         AnzahlEmpfangsBytes = buf_ptr;
171
     RxdBuffer[buf_ptr] = '\r';
172
         if((RxdBuffer[2] == 'R')) wdt_enable(WDTO_250MS); // Reset-Commando
173
//     uart_putchar(RxdBuffer[2]);       
174
        }                                
175
  }
176
  else
177
  switch(UartState)
178
  {
179
   case 0:
180
          if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1;  // Startzeichen und Daten schon verarbeitet
181
                  buf_ptr = 0;
182
                  RxdBuffer[buf_ptr++] = SioTmp;
183
                  crc = SioTmp;
184
          break;
185
   case 1: // Adresse auswerten
186
                  UartState++;
187
                  RxdBuffer[buf_ptr++] = SioTmp;
188
                  crc += SioTmp;
189
                  break;
190
   case 2: //  Eingangsdaten sammeln
191
                  RxdBuffer[buf_ptr] = SioTmp;
192
                  if(buf_ptr < MAX_EMPFANGS_BUFF) buf_ptr++;
193
                  else UartState = 0;
194
                  crc += SioTmp;
195
                  break;
196
   default:
197
          UartState = 0;
198
          break;
199
  }
200
 
201
};
202
 
203
 
204
// --------------------------------------------------------------------------
205
void AddCRC(unsigned int wieviele)
206
{
207
 unsigned int tmpCRC = 0,i;
208
 for(i = 0; i < wieviele;i++)
209
  {
210
   tmpCRC += SendeBuffer[i];
211
  }
212
   tmpCRC %= 4096;
213
   SendeBuffer[i++] = '=' + tmpCRC / 64;
214
   SendeBuffer[i++] = '=' + tmpCRC % 64;
215
   SendeBuffer[i++] = '\r';
216
  UebertragungAbgeschlossen = 0;
217
  UDR = SendeBuffer[0];
218
}
219
 
220
 
221
// --------------------------------------------------------------------------
222
void SendOutData(unsigned char cmd,unsigned char modul, unsigned char *snd, unsigned char len)
223
{
224
 unsigned int pt = 0;
225
 unsigned char a,b,c;
226
 unsigned char ptr = 0;
227
 
228
 SendeBuffer[pt++] = '#';               // Startzeichen
229
 SendeBuffer[pt++] = modul;             // Adresse (a=0; b=1,...)
230
 SendeBuffer[pt++] = cmd;                       // Commando
231
 
232
 while(len)
233
  {
234
   if(len) { a = snd[ptr++]; len--;} else a = 0;
235
   if(len) { b = snd[ptr++]; len--;} else b = 0;
236
   if(len) { c = snd[ptr++]; len--;} else c = 0;
237
   SendeBuffer[pt++] = '=' + (a >> 2);
238
   SendeBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
239
   SendeBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
240
   SendeBuffer[pt++] = '=' + ( c & 0x3f);
241
  }
242
 AddCRC(pt);
243
}
244
 
245
 
246
 
247
//############################################################################
248
//Routine für die Serielle Ausgabe
249
int uart_putchar (char c)
250
//############################################################################
251
{
7 hbuss 252
    if(!(UCR & (1 << TXEN))) return (0);
1 ingob 253
        if (c == '\n')
254
                uart_putchar('\r');
255
        //Warten solange bis Zeichen gesendet wurde
256
        loop_until_bit_is_set(USR, UDRE);
257
        //Ausgabe des Zeichens
258
        UDR = c;
259
 
260
        return (0);
261
}
262
 
263
// --------------------------------------------------------------------------
264
void WriteProgramData(unsigned int pos, unsigned char wert)
265
{
266
}
267
 
268
//############################################################################
269
//INstallation der Seriellen Schnittstelle
270
void UART_Init (void)
271
//############################################################################
272
{
273
        //Enable TXEN im Register UCR TX-Data Enable & RX Enable
274
 
275
        UCR=(1 << TXEN) | (1 << RXEN);
276
    // UART Double Speed (U2X)
277
        USR   |= (1<<U2X);          
278
        // RX-Interrupt Freigabe
279
 
280
        UCSRB |= (1<<RXCIE);    // serieller Empfangsinterrupt       
281
 
282
        // TX-Interrupt Freigabe
283
        UCSRB |= (1<<TXCIE);          
284
 
285
        //Teiler wird gesetzt 
286
        UBRR= (SYSCLK / (BAUD_RATE * 8L) -1 );
287
        //öffnet einen Kanal für printf (STDOUT)
288
//      fdevopen (uart_putchar, NULL);
289
    Debug_Timer = SetDelay(200);  
290
    // Version beim Start ausgeben (nicht schön, aber geht... ) 
291
        uart_putchar ('\n');uart_putchar ('C');uart_putchar ('P');uart_putchar (':');
292
        uart_putchar ('V');uart_putchar (0x30 + VERSION_HAUPTVERSION);uart_putchar ('.');uart_putchar (0x30 + VERSION_NEBENVERSION/10); uart_putchar (0x30 + VERSION_NEBENVERSION%10);
293
    uart_putchar ('\n');
294
}
295
 
296
 
297
void BearbeiteRxDaten(void)
298
{
299
 if(!NeuerDatensatzEmpfangen) return;
300
// unsigned int tmp_int_arr1[1];
301
// unsigned int tmp_int_arr2[2];
302
// unsigned int tmp_int_arr3[3];
303
 unsigned char tmp_char_arr2[2];
304
// unsigned char tmp_char_arr3[3];
305
// unsigned char tmp_char_arr4[4];
306
 //if(!MotorenEin) 
307
 PcZugriff = 255;
308
 
309
  switch(RxdBuffer[2])
310
  {
311
   case 'w':// Lagewinkel
7 hbuss 312
            Decode64((unsigned char *) &ExternData,sizeof(ExternData),3,AnzahlEmpfangsBytes);
1 ingob 313
            DebugOut.Analog[15]++;
314
            KompassAntwort = 1;
315
            break;
316
   case 'c':
317
   case 'b':
318
                        Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
7 hbuss 319
            ExternData.Winkel[0] = ExternControl.Par1;
320
            ExternData.Winkel[1] = ExternControl.Par2;
1 ingob 321
            break;
322
   case 'v': // Version-Anforderung     und Ausbaustufe
323
            GetVersionAnforderung = 1;
324
            PC_Connected = 255;
325
            break;                                                               
326
 
327
   case 'a':// Texte der Analogwerte
328
            Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
329
            DebugTextAnforderung = tmp_char_arr2[0];
330
            PC_Connected = 255;
331
                        break;
332
   case 'g':// "Get"-Anforderung für Debug-Daten 
333
            // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
334
            PC_Connected = 255;
335
            DebugGetAnforderung = 1;
336
            break;
337
   case 'h':// x-1 Displayzeilen
338
            PC_Connected = 255;
339
            break;
340
/*
341
   case 'b':
342
                        Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
343
                        RemoteTasten |= ExternControl.RemoteTasten;
344
            ConfirmFrame = ExternControl.Frame;
345
            break;
346
   case 'c':
347
                        Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
348
                        RemoteTasten |= ExternControl.RemoteTasten;
349
            ConfirmFrame = ExternControl.Frame;
350
            DebugDataAnforderung = 1;
351
            break;
352
   case 'h':// x-1 Displayzeilen
353
            Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
354
            RemoteTasten |= tmp_char_arr2[0];
355
                        if(tmp_char_arr2[1] == 255) NurKanalAnforderung = 1; else NurKanalAnforderung = 0; // keine Displaydaten
356
                        DebugDisplayAnforderung = 1;
357
                        break;
358
   case 't':// Motortest
359
            Decode64((unsigned char *) &MotorTest[0],sizeof(MotorTest),3,AnzahlEmpfangsBytes);
360
                        break;
361
   case 'k':// Keys von DubWise
362
            Decode64((unsigned char *) &DubWiseKeys[0],sizeof(DubWiseKeys),3,AnzahlEmpfangsBytes);
363
                        ConfirmFrame = DubWiseKeys[3];
364
                        break;
365
   case 'q':// "Get"-Anforderung für Settings
366
            // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
367
            Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
368
            if(tmp_char_arr2[0] != 0xff)
369
             {
370
                          if(tmp_char_arr2[0] > 5) tmp_char_arr2[0] = 5;
371
                  ReadParameterSet(tmp_char_arr2[0], (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);                   
372
                  SendOutData('L' + tmp_char_arr2[0] -1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
373
             }
374
             else
375
                  SendOutData('L' + GetActiveParamSetNumber()-1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
376
 
377
            break;
378
 
379
   case 'l':
380
   case 'm':
381
   case 'n':
382
   case 'o':
383
   case 'p': // Parametersatz speichern
384
            Decode64((unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE,3,AnzahlEmpfangsBytes);
385
                        WriteParameterSet(RxdBuffer[2] - 'l' + 1, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
386
            eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], RxdBuffer[2] - 'l' + 1);  // aktiven Datensatz merken
387
            Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L;
388
            Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L;
389
            Piep(GetActiveParamSetNumber());
390
         break;
391
*/             
392
 
393
  }
394
// DebugOut.AnzahlZyklen =  Debug_Timer_Intervall;
395
 NeuerDatensatzEmpfangen = 0;
396
}
397
 
398
 
399
//---------------------------------------------------------------------------------------------
400
void DatenUebertragung(void)  
401
{
402
 if((CheckDelay(Debug_Timer) && UebertragungAbgeschlossen))      // im Singlestep-Betrieb in jedem Schtitt senden
403
         {
7 hbuss 404
         SetDebugValues();
1 ingob 405
          SendOutData('D',MeineSlaveAdresse,(unsigned char *) &DebugOut,sizeof(DebugOut));
406
          Debug_Timer = SetDelay(250);   // Sendeintervall
407
         }
408
    if(GetVersionAnforderung && UebertragungAbgeschlossen)
409
     {
410
      SendOutData('V',MeineSlaveAdresse,(unsigned char *) &VersionInfo,sizeof(VersionInfo));
411
          GetVersionAnforderung = 0;
412
     }
413
    if(DebugTextAnforderung != 255) // Texte für die Analogdaten
414
     {
415
      SendOutData('A',DebugTextAnforderung + '0',(unsigned char *) ANALOG_TEXT[DebugTextAnforderung],16);
416
      DebugTextAnforderung = 255;
417
         }
418
   if(DebugGetAnforderung && UebertragungAbgeschlossen)               // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
419
   {
420
      SendOutData('G',MeineSlaveAdresse,(unsigned char *) &ExternControl,sizeof(ExternControl));
421
          DebugGetAnforderung = 0;
422
   }
423
   if(KompassAntwort && UebertragungAbgeschlossen)            // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
424
   {
3 ingob 425
      SendOutData('K',MeineSlaveAdresse,(unsigned char *) &I2C_Heading,sizeof(I2C_Heading));
1 ingob 426
          KompassAntwort = 0;
427
   }
428
}
429