Subversion Repositories FlightCtrl

Rev

Rev 973 | Rev 980 | 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
 
974 MikeW 159
      /* GetMeasurements()*/
966 MikeW 160
      GetMeasurements();
974 MikeW 161
 
162
      /* EstimateFlightAttitude */
966 MikeW 163
      FlightAttitudeEstimation();
974 MikeW 164
 
966 MikeW 165
      /* Set Nominal Value */
166
      RemoteControl();  
974 MikeW 167
 
168
      /* PD Control */
966 MikeW 169
      PD_Regler();
974 MikeW 170
 
966 MikeW 171
      /* Send Motor Data */
172
      SendMotorData();
974 MikeW 173
 
966 MikeW 174
      /* TestRemote */
175
      TestRemote();
974 MikeW 176
 
966 MikeW 177
      /* Test IC2- / RC-Link */
178
      TestIC2Link();
179
    }
180
    /* Send Debug Data over RS232 */
181
    SendDebugData();
182
    /* Check the Batery for Undervoltage */
183
    TestBattery();
184
    /* DeployRescue */
974 MikeW 185
    /* DeployRescue(); */
966 MikeW 186
  }
187
}
188
 
189
/* ****************************************************************************
190
Functionname:     DeployRescue                      */ /*!
191
Description:       Deploy a rescue parachute using a servo
192
 
193
  @return           void
194
  @pre              -
195
  @post             -
196
  @author           Michael Walter
197
**************************************************************************** */
198
void DeployRescue()
199
{
200
#if 0
201
  /* Yaw or pitch are greater than  60 Deg abs */
202
  if (((abs(status.iTheta10) > 600) || (abs(status.iPhi10) > 600)) &&
973 MikeW 203
            ((abs(AverageRoll) > Threshhold) ||
204
            (abs(AverageNick) > Threshhold) ||
205
            (abs(AverageGier) > Threshhold) ))
966 MikeW 206
  {
207
    MotorenEin = 0;
208
    Delay_ms(1000);
209
    ReleaseServo();
210
  }
211
#endif
212
}
213
 
214
/* ****************************************************************************
838 MikeW 215
Functionname:     ReadParameterSet                      */ /*!
216
Description:      -- Parametersatz aus EEPROM lesen ---
217
                  number [0..5]
218
 
219
  @return           void
220
  @pre              -
221
  @post             -
222
  @author           H. Buss / I. Busker
223
**************************************************************************** */
224
void ReadParameterSet(unsigned char number, unsigned char *buffer, unsigned char length)
225
{
966 MikeW 226
  if (number > 5)
227
  {
228
    number = 5;
229
  }
230
  eeprom_read_block(buffer, &EEPromArray[EEPROM_ADR_PARAM_BEGIN + length * number], length);
838 MikeW 231
}
232
 
233
/* ****************************************************************************
234
Functionname:     WriteParameterSet                      */ /*!
235
Description:      -- Parametersatz ins EEPROM schreiben ---
236
                  number [0..5]
237
 
238
  @return           void
239
  @pre              -
240
  @post             -
241
  @author           H. Buss / I. Busker
242
**************************************************************************** */
243
void WriteParameterSet(unsigned char number, unsigned char *buffer, unsigned char length)
244
{
966 MikeW 245
  if(number > 5)
246
  {
247
    number = 5;
248
  }
249
  eeprom_write_block(buffer, &EEPromArray[EEPROM_ADR_PARAM_BEGIN + length * number], length);
250
  eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], number);      // diesen Parametersatz als aktuell merken
838 MikeW 251
}
252
 
253
/* ****************************************************************************
254
Functionname:     GetActiveParamSetNumber                      */ /*!
255
Description:      
256
 
257
  @return           void
258
  @pre              -
259
  @post             -
260
  @author           H. Buss / I. Busker
261
**************************************************************************** */
262
unsigned char GetActiveParamSetNumber(void)
263
{
966 MikeW 264
  unsigned char set;
265
  set = eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET]);
266
  if(set > 5)
267
  {
268
    set = 2;  
269
    eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], set);      // diesen Parametersatz als aktuell merken
270
  }
271
  return(set);
838 MikeW 272
}
273
 
966 MikeW 274
/* ****************************************************************************
275
Functionname:     GetAirPressureOffset                      */ /*!
276
Description:      
838 MikeW 277
 
966 MikeW 278
  @return           void
279
  @pre              -
280
  @post             -
281
  @author           H. Buss / I. Busker
282
**************************************************************************** */
283
void GetAirPressureOffset(void)
284
{
285
 unsigned int timer;
286
 ReadParameterSet(GetActiveParamSetNumber(), (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
287
  printf("\n\rBenutze Parametersatz %d", GetActiveParamSetNumber());
288
  if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)
289
  {
290
    printf("\n\rAbgleich Luftdrucksensor..");
291
    timer = SetDelay(1000);  
292
    SucheLuftruckOffset();
293
    while (!CheckDelay(timer));
294
    printf("OK\n\r");
295
  }
296
}
297
 
838 MikeW 298
/* ****************************************************************************
966 MikeW 299
Functionname:     GenerateDefaults                      */ /*!
300
Description:      Generate the Default Paramter
838 MikeW 301
 
302
  @return           void
303
  @pre              -
304
  @post             -
305
  @author           H. Buss / I. Busker
306
**************************************************************************** */
966 MikeW 307
void  GenerateDefaults()
838 MikeW 308
{
966 MikeW 309
  VersionInfo.Hauptversion = VERSION_HAUPTVERSION;
310
  VersionInfo.Nebenversion = VERSION_NEBENVERSION;
311
  VersionInfo.PCKompatibel = VERSION_KOMPATIBEL;
312
 
313
#define EE_DATENREVISION 66 // wird angepasst, wenn sich die EEPROM-Daten geändert haben
314
  if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) != EE_DATENREVISION)
315
  {
316
    printf("\n\rInit. EEPROM: Generiere Default-Parameter...");
317
    DefaultKonstanten1();
318
    for (unsigned char i=0;i<6;i++)  
319
    {
320
      if(i==2) DefaultKonstanten2(); // Kamera
321
      if(i==3) DefaultKonstanten3(); // Beginner
322
      if(i>3)  DefaultKonstanten2(); // Kamera
323
      WriteParameterSet(i, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
324
    }
325
    eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], 3); // default-Setting
326
    eeprom_write_byte(&EEPromArray[EEPROM_ADR_VALID], EE_DATENREVISION);
327
  }
328
}
838 MikeW 329
 
330
 
966 MikeW 331
/* ****************************************************************************
332
Functionname:     InitPorts                      */ /*!
333
Description:      Init the IO Ports
838 MikeW 334
 
966 MikeW 335
  @return           void
336
  @pre              -
337
  @post             -
338
  @author           H. Buss / I. Busker
339
**************************************************************************** */
340
void  InitPorts()
341
{
342
  unsigned int timer = 0;
343
  DDRB  = 0x00;
344
  PORTB = 0x00;
345
  for(timer = 0; timer < 1000; timer++); // verzögern
346
  DDRC  = 0x81; // SCL
347
  PORTC = 0xff; // Pullup SDA
348
  DDRB  = 0x1B; // LEDs und Druckoffset
349
  PORTB = 0x01; // LED_Rot
350
  DDRD  = 0x3E; // Speaker & TXD & J3 J4 J5
351
  DDRD  |=0x80; // J7
352
  PORTD = 0xF7; // LED
353
 
354
  MCUSR &=~(1<<WDRF);
355
  WDTCSR |= (1<<WDCE)|(1<<WDE);
356
  WDTCSR = 0;
357
}
358
 
359
/* ****************************************************************************
360
Functionname:     TestIC2Link                      */ /*!
361
Description:      Test IC2- / RC-Link
362
 
363
  @return           void
364
  @pre              -
365
  @post             -
366
  @author           H. Buss / I. Busker
367
**************************************************************************** */
368
void TestIC2Link()
369
{
370
  if(PcZugriff)
371
  {
372
    PcZugriff--;
373
  }
374
 
375
  if(SenderOkay)  
376
  {
377
    SenderOkay--;
378
  }
379
 
380
  if(!I2CTimeout)
381
  {
382
    I2CTimeout = 5;
383
    i2c_reset();
384
    if((BeepMuster == 0xffff) && MotorenEin)
385
    {
386
      beeptime = 10000;
387
      BeepMuster = 0x0080;
388
    }
389
  }
390
  else
391
  {
392
    I2CTimeout--;
393
  }
394
}
395
 
396
 
397
/* ****************************************************************************
398
Functionname:     SendDebugData                      */ /*!
399
Description:      Send Debug Data over RS232
400
 
401
  @return           void
402
  @pre              -
403
  @post             -
404
  @author           H. Buss / I. Busker
405
**************************************************************************** */
406
void SendDebugData()
407
{
408
  if(SIO_DEBUG)
409
  {
410
    DatenUebertragung();
411
    BearbeiteRxDaten();
412
  }
413
  else
414
  {
415
    BearbeiteRxDaten();
416
  }
417
}
418
 
419
 
420
/* ****************************************************************************
421
Functionname:     TestBattery                      */ /*!
422
Description:      Check the Battery Voltage
423
 
424
  @return           void
425
  @pre              -
426
  @post             -
427
  @author           H. Buss / I. Busker
428
**************************************************************************** */
429
void  TestBattery()
430
{
431
  unsigned int timer = 0;
432
  if(CheckDelay(timer))
433
  {  /* Voltage is Below Threshhod ? */
434
    if(UBat < EE_Parameter.UnterspannungsWarnung)
435
    {    
436
      if(BeepMuster == 0xffff)
437
      {
438
        beeptime = 6000;
439
        BeepMuster = 0x0300;
440
      }
441
    }
442
    timer = SetDelay(100);  
443
  }
444
  DebugOut.Analog[15] =  UBat;
445
}
446
 
447
/* ****************************************************************************
448
  Functionname:     TestRemote                      */ /*!
449
  Description:      
450
 
451
  @param[in]        
452
 
453
  @return           void
454
  @pre              -
455
  @post             -
456
  @author         Michael Walter  
457
**************************************************************************** */
458
void TestRemote()
459
{
460
  /*--- (SYMBOLIC) CONSTANTS ---*/
461
 
462
  /*--- VARIABLES ---*/
463
  static unsigned int TimeSinceRC_BelowThreshhold = 0;
464
  static unsigned int TimeSinceRC_AboveThreshhold = 0;
465
 
466
  if (MotorenEin == 1)
467
  {
468
    if (RemoteLinkLost == 0)
469
    {
470
      if (RCQuality < 60)
471
      {
472
        if (TimeSinceRC_BelowThreshhold < 10000)
473
        {
474
          TimeSinceRC_BelowThreshhold++;
838 MikeW 475
        }
966 MikeW 476
      }
477
      else
478
      {
479
        TimeSinceRC_BelowThreshhold = 0;
480
      }
481
      if ((TimeSinceRC_BelowThreshhold > 500) || /* aprox. 5 seconds */
482
        (SenderOkay < 100))
483
      {
484
        RemoteLinkLost = 1;
485
        TimeSinceRC_AboveThreshhold = 0;
486
      }
487
    }
488
    else
489
    {
490
      if (RCQuality > 80)
491
      {
492
        if (TimeSinceRC_AboveThreshhold < 10000)
493
        {
494
          TimeSinceRC_AboveThreshhold++;
495
        }
496
      }
497
      else
498
      {
499
        TimeSinceRC_AboveThreshhold = 0;
500
      }
501
      if (TimeSinceRC_AboveThreshhold > 100) /* aprox. 1 seconds */
502
      {
503
        RemoteLinkLost = 0;
504
        TimeSinceRC_BelowThreshhold = 0;    
505
      }
506
    }
507
  }
508
  else
509
  {
510
    RemoteLinkLost = 0;
511
    TimeSinceRC_BelowThreshhold = 0;
512
    TimeSinceRC_AboveThreshhold = 0;
513
  }
514
  /*DebugOut.Analog[14] = TimeSinceRC_BelowThreshhold;*/
515
  /*DebugOut.Analog[15] = TimeSinceRC_AboveThreshhold;*/
838 MikeW 516
}