Subversion Repositories FlightCtrl

Rev

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