Subversion Repositories FlightCtrl

Rev

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

Rev Author Line No. Line
966 MikeW 1
/*
2
Copyright 2008, by Michael Walter
3
 
4
All functions written by Michael Walter are free software and can be redistributed and/or modified under the terms of the GNU Lesser
5
General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but
6
WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7
See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public
8
License along with this program. If not, see <http://www.gnu.org/licenses/>.
9
 
10
Please note: The software is based on the framework provided by H. Buss and I. Busker in their Mikrokopter projekt. All functions that
11
are not written by Michael Walter are under the license by H. Buss and I. Busker (license_buss.txt) published by www.mikrokopter.de
12
unless it is stated otherwise.
13
*/
14
 
15
/*****************************************************************************
16
  INCLUDES
17
**************************************************************************** */
838 MikeW 18
#include "main.h"
19
#include "kafi.h"
20
#include "mymath.h"
21
#include "mm3.h"
970 MikeW 22
#include "FlightControl.h"
966 MikeW 23
 
24
/*****************************************************************************
25
(SYMBOLIC) CONSTANTS
26
*****************************************************************************/
27
 
838 MikeW 28
#define sin45 -0.707106
29
#define cos45 0.707106
30
 
966 MikeW 31
/*****************************************************************************
32
  VARIABLES
33
*****************************************************************************/
34
extern int RCQuality;
35
int RemoteLinkLost;
36
extern unsigned long maxDistance;
838 MikeW 37
unsigned char EEPromArray[E2END+1] EEMEM;
966 MikeW 38
 
39
void TestRemote(void);
40
void IMU_Main(void);
41
void TestBattery(void);
42
void SendDebugData(void);
43
void InitPorts(void);
44
void GenerateDefaults(void);
45
void TestIC2Link(void);
46
void GetAirPressureOffset(void);
47
void DeployRescue(void);
48
 
838 MikeW 49
extern void InitOSD(void);
50
extern void InitGPS(void);
51
extern void SendOSD(void);
966 MikeW 52
extern void RemoteControl(void);  
838 MikeW 53
extern void SendMotorData(void);
966 MikeW 54
extern void GetMeasurements(void);
838 MikeW 55
extern void AttitudeEstimation(void);
966 MikeW 56
extern void PD_Regler(void);
838 MikeW 57
extern void SetNeutral(void);
58
 
59
/* ****************************************************************************
966 MikeW 60
Functionname:     main                      */ /*!
61
Description:      Hauptprogramm
62
 
63
  @return           void
64
  @pre              -
65
  @post             -
66
  @author           Michael Walter
67
**************************************************************************** */
68
int main (void)
69
{
70
  /* Controler Init */
71
  InitPorts();
72
  Kafi_Init();
73
  Timer_Init();
74
  UART_Init();
75
  InitGPS();
76
  rc_sum_init();
77
  ADC_Init();
78
  i2c_init();
79
#ifdef USE_COMPASS
80
  MM3_Init();
81
#endif
82
  /* Enable Interrupts */
83
  sei();
84
 
85
  /* Generate Default Values */
86
  GenerateDefaults ();
87
  /* Get Air Pressure Offset */
88
  GetAirPressureOffset();
89
  /* Determine Gyro / ACC Offsets */
90
  SetNeutral();
91
 
92
  DebugIn.Analog[1] = 1000;
93
  DebugIn.Digital[0] = 0x55;
94
 
95
#ifdef USE_COMPASS
96
  /* Calibrate the MM3 Compass? */
97
  if((PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] > 80) &&
98
    (PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] < -75) &&
99
    (MotorenEin == 0))
100
  {
101
    printf("\n\rCalibrating Compass");
102
    MM3_Calibrate();
103
  }
104
#endif 
105
 
106
#ifdef USE_OSD
107
  /* Init the Bob-4 OnScreen Display */
108
  InitOSD();
109
#endif
110
 
111
  /* Start the main Task */
112
  IMU_Main();
113
  return (1);
114
}
115
 
116
 
117
 
118
/* ****************************************************************************
119
  Functionname:     IMU_Main                      */ /*!
120
  Description:      
121
 
122
  @param[in]        
123
 
124
  @return           void
125
  @pre              -
126
  @post             -
127
  @author         Michael Walter  
128
**************************************************************************** */
129
void IMU_Main()
130
{
131
  ROT_ON
132
  I2CTimeout = 5000;
133
 
134
  while (1)
135
  {
972 MikeW 136
    static i32_t OldTime = 0;
966 MikeW 137
    if (UpdateMotor)
138
    {
139
      UpdateMotor=0;
140
 
141
#ifdef USE_OSD
142
      /* G e n e r a t e   O S D   D a t a */
143
      static char CntOSD = 0;
144
      if (CntOSD % 6 == 1)
145
      {
146
        SendOSD();
147
      }
148
      CntOSD++;
149
#endif
150
 
151
      /* Set the cycle Time to 120ms / 125ms */
152
      if (OldTime != 0)
153
      {
154
        while (((Count8Khz - OldTime) *10) / 8 < 120);
155
        DebugOut.Analog[14] = ((Count8Khz - OldTime) *10) / 8;
156
      }
157
      OldTime = Count8Khz;
158
 
159
      /*GetMeasurements()*/
160
      GetMeasurements();
161
      /*EstimateFlightAttitude */
162
      FlightAttitudeEstimation();
163
      /* Set Nominal Value */
164
      RemoteControl();  
165
      /* PID Control */
166
      PD_Regler();
167
      /* Send Motor Data */
168
      SendMotorData();
169
      /* TestRemote */
170
      TestRemote();
171
      /* Test IC2- / RC-Link */
172
      TestIC2Link();
173
    }
174
    /* Send Debug Data over RS232 */
175
    SendDebugData();
176
    /* Check the Batery for Undervoltage */
177
    TestBattery();
178
    /* DeployRescue */
179
    //DeployRescue();
180
  }
181
}
182
 
183
/* ****************************************************************************
184
Functionname:     DeployRescue                      */ /*!
185
Description:       Deploy a rescue parachute using a servo
186
 
187
  @return           void
188
  @pre              -
189
  @post             -
190
  @author           Michael Walter
191
**************************************************************************** */
192
void DeployRescue()
193
{
194
#if 0
195
  /* Yaw or pitch are greater than  60 Deg abs */
196
  if (((abs(status.iTheta10) > 600) || (abs(status.iPhi10) > 600)) &&
973 MikeW 197
            ((abs(AverageRoll) > Threshhold) ||
198
            (abs(AverageNick) > Threshhold) ||
199
            (abs(AverageGier) > Threshhold) ))
966 MikeW 200
  {
201
    MotorenEin = 0;
202
    Delay_ms(1000);
203
    ReleaseServo();
204
  }
205
#endif
206
}
207
 
208
/* ****************************************************************************
838 MikeW 209
Functionname:     ReadParameterSet                      */ /*!
210
Description:      -- Parametersatz aus EEPROM lesen ---
211
                  number [0..5]
212
 
213
  @return           void
214
  @pre              -
215
  @post             -
216
  @author           H. Buss / I. Busker
217
**************************************************************************** */
218
void ReadParameterSet(unsigned char number, unsigned char *buffer, unsigned char length)
219
{
966 MikeW 220
  if (number > 5)
221
  {
222
    number = 5;
223
  }
224
  eeprom_read_block(buffer, &EEPromArray[EEPROM_ADR_PARAM_BEGIN + length * number], length);
838 MikeW 225
}
226
 
227
/* ****************************************************************************
228
Functionname:     WriteParameterSet                      */ /*!
229
Description:      -- Parametersatz ins EEPROM schreiben ---
230
                  number [0..5]
231
 
232
  @return           void
233
  @pre              -
234
  @post             -
235
  @author           H. Buss / I. Busker
236
**************************************************************************** */
237
void WriteParameterSet(unsigned char number, unsigned char *buffer, unsigned char length)
238
{
966 MikeW 239
  if(number > 5)
240
  {
241
    number = 5;
242
  }
243
  eeprom_write_block(buffer, &EEPromArray[EEPROM_ADR_PARAM_BEGIN + length * number], length);
244
  eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], number);      // diesen Parametersatz als aktuell merken
838 MikeW 245
}
246
 
247
/* ****************************************************************************
248
Functionname:     GetActiveParamSetNumber                      */ /*!
249
Description:      
250
 
251
  @return           void
252
  @pre              -
253
  @post             -
254
  @author           H. Buss / I. Busker
255
**************************************************************************** */
256
unsigned char GetActiveParamSetNumber(void)
257
{
966 MikeW 258
  unsigned char set;
259
  set = eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET]);
260
  if(set > 5)
261
  {
262
    set = 2;  
263
    eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], set);      // diesen Parametersatz als aktuell merken
264
  }
265
  return(set);
838 MikeW 266
}
267
 
966 MikeW 268
/* ****************************************************************************
269
Functionname:     GetAirPressureOffset                      */ /*!
270
Description:      
838 MikeW 271
 
966 MikeW 272
  @return           void
273
  @pre              -
274
  @post             -
275
  @author           H. Buss / I. Busker
276
**************************************************************************** */
277
void GetAirPressureOffset(void)
278
{
279
 unsigned int timer;
280
 ReadParameterSet(GetActiveParamSetNumber(), (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
281
  printf("\n\rBenutze Parametersatz %d", GetActiveParamSetNumber());
282
  if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)
283
  {
284
    printf("\n\rAbgleich Luftdrucksensor..");
285
    timer = SetDelay(1000);  
286
    SucheLuftruckOffset();
287
    while (!CheckDelay(timer));
288
    printf("OK\n\r");
289
  }
290
}
291
 
838 MikeW 292
/* ****************************************************************************
966 MikeW 293
Functionname:     GenerateDefaults                      */ /*!
294
Description:      Generate the Default Paramter
838 MikeW 295
 
296
  @return           void
297
  @pre              -
298
  @post             -
299
  @author           H. Buss / I. Busker
300
**************************************************************************** */
966 MikeW 301
void  GenerateDefaults()
838 MikeW 302
{
966 MikeW 303
  VersionInfo.Hauptversion = VERSION_HAUPTVERSION;
304
  VersionInfo.Nebenversion = VERSION_NEBENVERSION;
305
  VersionInfo.PCKompatibel = VERSION_KOMPATIBEL;
306
 
307
#define EE_DATENREVISION 66 // wird angepasst, wenn sich die EEPROM-Daten geändert haben
308
  if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) != EE_DATENREVISION)
309
  {
310
    printf("\n\rInit. EEPROM: Generiere Default-Parameter...");
311
    DefaultKonstanten1();
312
    for (unsigned char i=0;i<6;i++)  
313
    {
314
      if(i==2) DefaultKonstanten2(); // Kamera
315
      if(i==3) DefaultKonstanten3(); // Beginner
316
      if(i>3)  DefaultKonstanten2(); // Kamera
317
      WriteParameterSet(i, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
318
    }
319
    eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], 3); // default-Setting
320
    eeprom_write_byte(&EEPromArray[EEPROM_ADR_VALID], EE_DATENREVISION);
321
  }
322
}
838 MikeW 323
 
324
 
966 MikeW 325
/* ****************************************************************************
326
Functionname:     InitPorts                      */ /*!
327
Description:      Init the IO Ports
838 MikeW 328
 
966 MikeW 329
  @return           void
330
  @pre              -
331
  @post             -
332
  @author           H. Buss / I. Busker
333
**************************************************************************** */
334
void  InitPorts()
335
{
336
  unsigned int timer = 0;
337
  DDRB  = 0x00;
338
  PORTB = 0x00;
339
  for(timer = 0; timer < 1000; timer++); // verzögern
340
  DDRC  = 0x81; // SCL
341
  PORTC = 0xff; // Pullup SDA
342
  DDRB  = 0x1B; // LEDs und Druckoffset
343
  PORTB = 0x01; // LED_Rot
344
  DDRD  = 0x3E; // Speaker & TXD & J3 J4 J5
345
  DDRD  |=0x80; // J7
346
  PORTD = 0xF7; // LED
347
 
348
  MCUSR &=~(1<<WDRF);
349
  WDTCSR |= (1<<WDCE)|(1<<WDE);
350
  WDTCSR = 0;
351
}
352
 
353
/* ****************************************************************************
354
Functionname:     TestIC2Link                      */ /*!
355
Description:      Test IC2- / RC-Link
356
 
357
  @return           void
358
  @pre              -
359
  @post             -
360
  @author           H. Buss / I. Busker
361
**************************************************************************** */
362
void TestIC2Link()
363
{
364
  if(PcZugriff)
365
  {
366
    PcZugriff--;
367
  }
368
 
369
  if(SenderOkay)  
370
  {
371
    SenderOkay--;
372
  }
373
 
374
  if(!I2CTimeout)
375
  {
376
    I2CTimeout = 5;
377
    i2c_reset();
378
    if((BeepMuster == 0xffff) && MotorenEin)
379
    {
380
      beeptime = 10000;
381
      BeepMuster = 0x0080;
382
    }
383
  }
384
  else
385
  {
386
    I2CTimeout--;
387
  }
388
}
389
 
390
 
391
/* ****************************************************************************
392
Functionname:     SendDebugData                      */ /*!
393
Description:      Send Debug Data over RS232
394
 
395
  @return           void
396
  @pre              -
397
  @post             -
398
  @author           H. Buss / I. Busker
399
**************************************************************************** */
400
void SendDebugData()
401
{
402
  if(SIO_DEBUG)
403
  {
404
    DatenUebertragung();
405
    BearbeiteRxDaten();
406
  }
407
  else
408
  {
409
    BearbeiteRxDaten();
410
  }
411
}
412
 
413
 
414
/* ****************************************************************************
415
Functionname:     TestBattery                      */ /*!
416
Description:      Check the Battery Voltage
417
 
418
  @return           void
419
  @pre              -
420
  @post             -
421
  @author           H. Buss / I. Busker
422
**************************************************************************** */
423
void  TestBattery()
424
{
425
  unsigned int timer = 0;
426
  if(CheckDelay(timer))
427
  {  /* Voltage is Below Threshhod ? */
428
    if(UBat < EE_Parameter.UnterspannungsWarnung)
429
    {    
430
      if(BeepMuster == 0xffff)
431
      {
432
        beeptime = 6000;
433
        BeepMuster = 0x0300;
434
      }
435
    }
436
    timer = SetDelay(100);  
437
  }
438
  DebugOut.Analog[15] =  UBat;
439
}
440
 
441
/* ****************************************************************************
442
  Functionname:     TestRemote                      */ /*!
443
  Description:      
444
 
445
  @param[in]        
446
 
447
  @return           void
448
  @pre              -
449
  @post             -
450
  @author         Michael Walter  
451
**************************************************************************** */
452
void TestRemote()
453
{
454
  /*--- (SYMBOLIC) CONSTANTS ---*/
455
 
456
  /*--- VARIABLES ---*/
457
  static unsigned int TimeSinceRC_BelowThreshhold = 0;
458
  static unsigned int TimeSinceRC_AboveThreshhold = 0;
459
 
460
  if (MotorenEin == 1)
461
  {
462
    if (RemoteLinkLost == 0)
463
    {
464
      if (RCQuality < 60)
465
      {
466
        if (TimeSinceRC_BelowThreshhold < 10000)
467
        {
468
          TimeSinceRC_BelowThreshhold++;
838 MikeW 469
        }
966 MikeW 470
      }
471
      else
472
      {
473
        TimeSinceRC_BelowThreshhold = 0;
474
      }
475
      if ((TimeSinceRC_BelowThreshhold > 500) || /* aprox. 5 seconds */
476
        (SenderOkay < 100))
477
      {
478
        RemoteLinkLost = 1;
479
        TimeSinceRC_AboveThreshhold = 0;
480
      }
481
    }
482
    else
483
    {
484
      if (RCQuality > 80)
485
      {
486
        if (TimeSinceRC_AboveThreshhold < 10000)
487
        {
488
          TimeSinceRC_AboveThreshhold++;
489
        }
490
      }
491
      else
492
      {
493
        TimeSinceRC_AboveThreshhold = 0;
494
      }
495
      if (TimeSinceRC_AboveThreshhold > 100) /* aprox. 1 seconds */
496
      {
497
        RemoteLinkLost = 0;
498
        TimeSinceRC_BelowThreshhold = 0;    
499
      }
500
    }
501
  }
502
  else
503
  {
504
    RemoteLinkLost = 0;
505
    TimeSinceRC_BelowThreshhold = 0;
506
    TimeSinceRC_AboveThreshhold = 0;
507
  }
508
  /*DebugOut.Analog[14] = TimeSinceRC_BelowThreshhold;*/
509
  /*DebugOut.Analog[15] = TimeSinceRC_AboveThreshhold;*/
838 MikeW 510
}