Subversion Repositories FlightCtrl

Rev

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

Rev Author Line No. Line
1910 - 1
#include <avr/boot.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
 
6
#include "timer0.h"
7
#include "timer2.h"
8
#include "uart0.h"
9
#include "output.h"
10
#include "attitude.h"
2099 - 11
#include "commands.h"
1910 - 12
#include "flight.h"
13
#include "rc.h"
14
#include "analog.h"
15
#include "configuration.h"
2099 - 16
#include "controlMixer.h"
1910 - 17
#include "eeprom.h"
2099 - 18
#include "printf_P.h"
1910 - 19
 
20
int16_t main(void) {
21
  uint16_t timer;
22
 
23
  // disable interrupts global
24
  cli();
25
 
26
  // analyze hardware environment
2099 - 27
  setCPUType();
28
  setBoardRelease();
1910 - 29
 
30
  // disable watchdog
31
  MCUSR &= ~(1 << WDRF);
32
  WDTCSR |= (1 << WDCE) | (1 << WDE);
33
  WDTCSR = 0;
34
 
2099 - 35
// This is strange: It should NOT be necessarty to do. But the call of the same,
36
// in channelMap_readOrDefault (if eeprom read fails) just sets all to 0,0,0,....
2122 - 37
// channelMap_default();
1910 - 38
 
39
  // initalize modules
40
  output_init();
41
  timer0_init();
2099 - 42
  timer2_init();
43
  usart0_init();
44
  //if (CPUType == ATMEGA644P);// usart1_Init();
1910 - 45
  RC_Init();
46
  analog_init();
47
 
2099 - 48
  // Parameter Set handling
49
  IMUConfig_readOrDefault();
50
  channelMap_readOrDefault();
2122 - 51
  rcTrim_readOrDefault();
2099 - 52
  paramSet_readOrDefault();
53
 
1910 - 54
  // enable interrupts global
55
  sei();
56
 
2099 - 57
  printf("\n\r===================================");
58
  printf("\n\rFlightControl");
59
  printf("\n\rHardware: Custom");
60
  printf("\n\r     CPU: Atmega644");
61
  if (CPUType == ATMEGA644P)
62
    printf("p");
63
  printf("\n\rSoftware: V%d.%d%c",VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 'a');
64
  printf("\n\r===================================");
1910 - 65
 
66
  // Wait for a short time (otherwise the RC channel check won't work below)
67
  // timer = SetDelay(500);
68
  // while(!CheckDelay(timer));
69
 
70
  // Instead, while away the time by flashing the 2 outputs:
71
  // First J16, then J17. Makes it easier to see which is which.
2099 - 72
  timer = setDelay(200);
73
  outputSet(0,1);
1910 - 74
  GRN_OFF;
75
  RED_ON;
76
  while (!checkDelay(timer))
77
    ;
78
 
2099 - 79
  timer = setDelay(200);
2110 - 80
  outputSet(0, 0);
81
  outputSet(1, 1);
1910 - 82
  RED_OFF;
83
  GRN_ON;
84
  while (!checkDelay(timer))
85
    ;
86
 
2099 - 87
  timer = setDelay(200);
1910 - 88
  while (!checkDelay(timer))
89
    ;
2099 - 90
  outputSet(1,0);
91
  GRN_OFF;
1910 - 92
 
2099 - 93
    printf("\n\r===================================");
1910 - 94
 
2099 - 95
#ifdef USE_NAVICTRL
96
  printf("\n\rSupport for NaviCtrl");
97
#endif
1910 - 98
 
2099 - 99
#ifdef USE_DIRECT_GPS
100
  printf("\n\rDirect (no NaviCtrl) navigation");
101
#endif
1910 - 102
 
103
  controlMixer_setNeutral();
2099 - 104
 
1910 - 105
  // Cal. attitude sensors and reset integrals.
106
  attitude_setNeutral();
2099 - 107
 
1910 - 108
  // Init flight parameters
2099 - 109
  // flight_setNeutral();
1910 - 110
 
2099 - 111
  beep(2000);
1910 - 112
 
2099 - 113
  printf("\n\n\r");
1910 - 114
 
2099 - 115
      while (1) {
1910 - 116
    if (runFlightControl) { // control interval
117
      runFlightControl = 0; // reset Flag, is enabled every 2 ms by ISR of timer0
118
      if (!analogDataReady) {
2099 - 119
        // Analog data should have been ready but is not!!
120
        debugOut.digital[0] |= DEBUG_MAINLOOP_TIMER;
1910 - 121
      } else {
2099 - 122
        debugOut.digital[0] &= ~DEBUG_MAINLOOP_TIMER;
2110 - 123
          }
2099 - 124
        // This is probably the correct order:
125
        // The attitude computation should not depend on anything from control (except maybe the estimation of control activity level)
126
        // The control may depend on attitude - for example, attitude control uses pitch and roll angles, compass control uses yaw angle etc.
127
        // Flight control uses results from both.
2124 - 128
#ifdef DO_PROFILE
129
      startProfileTimer(ATTITUDE);
130
#endif
131
      calculateFlightAttitude();
132
#ifdef DO_PROFILE
133
      stopProfileTimer(ATTITUDE);
134
#endif
135
 
136
#ifdef DO_PROFILE
137
      startProfileTimer(CONTROLMIXER);
138
#endif
139
      controlMixer_periodicTask();
140
#ifdef DO_PROFILE
141
      stopProfileTimer(CONTROLMIXER);
142
#endif
143
 
144
#ifdef DO_PROFILE
145
      startProfileTimer(COMMANDS);
146
#endif
147
      commands_handleCommands();
148
#ifdef DO_PROFILE
149
      stopProfileTimer(COMMANDS);
150
#endif
151
 
152
#ifdef DO_PROFILE
153
      startProfileTimer(FLIGHT);
154
#endif
155
      flight_control();
156
#ifdef DO_PROFILE
157
      stopProfileTimer(FLIGHT);
158
#endif
2099 - 159
 
1910 - 160
        // Allow Serial Data Transmit if motors must not updated or motors are not running
2108 - 161
        if (!runFlightControl || !isFlying) {
2099 - 162
          usart0_transmitTxData();
1910 - 163
        }
164
 
2099 - 165
        usart0_processRxData();
1910 - 166
 
2122 - 167
        static uint8_t aboveWarningLimitVoltageSeen = 0;
168
 
1910 - 169
        if (checkDelay(timer)) {
2122 - 170
          if (UBat >= staticParams.batteryWarningVoltage) {
171
            aboveWarningLimitVoltageSeen = 1;
172
          } else { // If we are above USB voltage, or if we have once been above warning voltage
173
            if (aboveWarningLimitVoltageSeen || UBat > UBAT_AT_5V) {
174
              beepBatteryAlarm();
175
            }
1910 - 176
          }
177
          timer = setDelay(20); // every 20 ms
178
        }
179
        output_update();
180
      }
181
 
2102 - 182
          calculateFeaturedServoValues();
2099 - 183
 
184
          if (runFlightControl) { // Time for the next iteration was up before the current finished. Signal error.
185
        debugOut.digital[1] |= DEBUG_MAINLOOP_TIMER;
186
      } else {
187
        debugOut.digital[1] &= ~DEBUG_MAINLOOP_TIMER;
2124 - 188
          }
189
 
190
#ifdef DO_PROFILE
191
          static uint8_t profileTimer;
192
          if (profileTimer++ == 0) {
193
                  debugProfileTimers(24);
194
          }
195
#endif
196
 
1910 - 197
  }
198
  return (1);
199
}