Subversion Repositories FlightCtrl

Rev

Rev 2097 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2097 Rev 2189
Line 1... Line 1...
1
#include <inttypes.h>
1
#include <inttypes.h>
2
#include <avr/io.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
3
#include <avr/interrupt.h>
4
#include "eeprom.h"
4
//#include "eeprom.h"
5
#include "analog.h"
5
#include "profiler.h"
6
#include "controlMixer.h"
6
#include "controlMixer.h"
7
 
-
 
-
 
7
#include "configuration.h"
-
 
8
#include "analog.h"
8
#include "timer0.h"
9
#include "timer0.h"
-
 
10
#include "debug.h"
-
 
11
#include "beeper.h"
9
#include "output.h"
12
#include "output.h"
-
 
13
#include "commands.h"
-
 
14
#include "flight.h"
-
 
15
#include "uart0.h"
-
 
16
#include "twimaster.h"
Line 10... Line 17...
10
 
17
 
11
#ifdef USE_MK3MAG
18
#ifdef USE_MK3MAG
12
#include "mk3mag.h"
19
#include "mk3mag.h"
Line -... Line 20...
-
 
20
#endif
-
 
21
 
-
 
22
#define MILLIS_DIVIDER 10
13
#endif
23
 
14
 
24
volatile uint32_t jiffiesClock;
15
volatile uint32_t globalMillisClock = 0;
25
volatile uint32_t millisClock;
16
volatile uint8_t  runFlightControl = 0;
26
volatile uint8_t  loopJiffiesClock;
Line 17... Line -...
17
volatile uint16_t beepTime = 0;
-
 
18
volatile uint16_t beepModulation = BEEP_MODULATION_NONE;
27
volatile uint16_t beepTime;
19
 
-
 
Line 20... Line 28...
20
#ifdef USE_NAVICTRL
28
volatile uint16_t beepModulation = BEEP_MODULATION_NONE;
21
volatile uint8_t SendSPI = 0;
29
 
22
#endif
30
volatile uint8_t flightControlStatus;
23
 
31
 
Line 55... Line 63...
55
 
63
 
56
  // Timer/Counter 0 Control Register B
64
        // Timer/Counter 0 Control Register B
57
  // set clock divider for timer 0 to SYSCLOCK/8 = 20MHz/8 = 2.5MHz
65
        // set clock divider for timer 0 to SYSCLOCK/8 = 20MHz/8 = 2.5MHz
58
  // i.e. the timer increments from 0x00 to 0xFF with an update rate of 2.5 MHz
66
        // i.e. the timer increments from 0x00 to 0xFF with an update rate of 2.5 MHz
59
  // hence the timer overflow interrupt frequency is 2.5 MHz/256 = 9.765 kHz
-
 
60
 
67
        // hence the timer overflow interrupt frequency is 2.5 MHz/256 = 9.765 kHz
61
  // divider 8 (Bits CS02 = 0, CS01 = 1, CS00 = 0)
68
        // divider 8 (Bits CS02 = 0, CS01 = 1, CS00 = 0)
62
  TCCR0B &= ~((1 << FOC0A) | (1 << FOC0B) | (1 << WGM02));
69
        TCCR0B &= ~((1 << FOC0A) | (1 << FOC0B) | (1 << WGM02));
Line 63... Line 70...
63
  TCCR0B = (TCCR0B & 0xF8) | (0 << CS02) | (1 << CS01) | (0 << CS00);
70
        TCCR0B = (TCCR0B & 0xF8) | (0 << CS02) | (1 << CS01) | (0 << CS00);
Line 75... Line 82...
75
  TIMSK0 |= (1 << TOIE0);
82
        TIMSK0 |= (1 << TOIE0);
Line 76... Line 83...
76
 
83
 
77
  SREG = sreg;
84
        SREG = sreg;
Line -... Line 85...
-
 
85
}
-
 
86
 
-
 
87
void runFlightControlTask(void) {
-
 
88
        if (flightControlStatus != NOT_RUNNING) {
-
 
89
                // Previous execution not completed! It is dangerous to start another.
-
 
90
                debugOut.digital[0] |= DEBUG_MAINLOOP_TIMER;
-
 
91
                return;
-
 
92
        }
-
 
93
 
-
 
94
        debugOut.digital[0] &= ~DEBUG_MAINLOOP_TIMER;
-
 
95
 
-
 
96
        controlMixer_periodicTask();
-
 
97
        commands_handleCommands();
-
 
98
        flightControlStatus = RUNNING;
-
 
99
 
-
 
100
    if (!--I2CTimeout || missingMotor) { // try to reset the i2c if motor is missing or timeout
-
 
101
         if (!I2CTimeout) {
-
 
102
             I2C_reset();
-
 
103
             I2CTimeout = 5;
-
 
104
         }
-
 
105
         beepI2CAlarm();
-
 
106
     }
-
 
107
       
-
 
108
        if (analog_controlDataStatus != CONTROL_SENSOR_DATA_READY) {
-
 
109
                // Analog data should have been ready but is not!!
-
 
110
                debugOut.digital[1] |= DEBUG_MAINLOOP_TIMER;
-
 
111
        } else {
-
 
112
                debugOut.digital[1] &= ~DEBUG_MAINLOOP_TIMER;
-
 
113
                J4HIGH;
-
 
114
                analog_sumAttitudeData();
-
 
115
                analog_updateControlData();
-
 
116
                flight_control();
-
 
117
                output_applyMulticopterMixer();
-
 
118
                I2C_start(TWI_STATE_MOTOR_TX);
-
 
119
                J4LOW;
-
 
120
        }
-
 
121
 
-
 
122
        flightControlStatus = NOT_RUNNING;
78
}
123
}
79
 
124
 
80
/*****************************************************/
125
/*****************************************************/
81
/*          Interrupt Routine of Timer 0             */
126
/*          Interrupt Routine of Timer 0             */
82
/*****************************************************/
127
/*****************************************************/
-
 
128
ISR (TIMER0_OVF_vect) { // 9765.625 Hz
-
 
129
        static uint8_t millisDivider = MILLIS_DIVIDER;
-
 
130
        static uint8_t controlLoopDivider = CONTROLLOOP_DIVIDER;
83
ISR(TIMER0_OVF_vect) { // 9765.625 Hz
131
        static uint8_t serialLoopDivider = SERIALLOOP_DIVIDER /2;
Line 84... Line 132...
84
  static uint8_t cnt_1ms = 1, cnt = 0;
132
    static uint8_t outputLoopDivider = OUTPUTLOOP_DIVIDER /3;
-
 
133
        uint8_t beeperOn = 0;
85
  uint8_t beeperOn = 0;
134
 
-
 
135
        jiffiesClock++;
86
 
136
        loopJiffiesClock++;
87
#ifdef USE_NAVICTRL
137
        // profiler_scoreTimerHit();
88
  if(SendSPI) SendSPI--; // if SendSPI is 0, the transmit of a byte via SPI bus to and from The Navicontrol is done
138
 
89
#endif
139
        sei();
-
 
140
 
-
 
141
        if (!--millisDivider) {
-
 
142
                millisClock++;
90
 
143
                millisDivider = MILLIS_DIVIDER;
91
  if (!cnt--) { // every 10th run (9.765625kHz/10 = 976.5625Hz)
144
        }
-
 
145
 
92
    cnt = 9;
146
        if (!--controlLoopDivider) {
-
 
147
            //sei();
-
 
148
                controlLoopDivider= CONTROLLOOP_DIVIDER;
-
 
149
                runFlightControlTask();
93
    cnt_1ms ^= 1;
150
                //cli();
94
    if (!cnt_1ms) {
151
        }
95
      if (runFlightControl == 1)
152
 
96
        debugOut.digital[1] |= DEBUG_MAINLOOP_TIMER;
153
    if (!--serialLoopDivider) {
-
 
154
        //sei();
-
 
155
        serialLoopDivider= SERIALLOOP_DIVIDER;
-
 
156
        // Allow serial data transmission if there is still time, or if we are not flying anyway.
97
      else
157
        usart0_transmitTxData();
-
 
158
        usart0_processRxData();
-
 
159
        //cli();
-
 
160
    }
98
        debugOut.digital[1] &= ~DEBUG_MAINLOOP_TIMER;
161
 
-
 
162
    if (!--outputLoopDivider) {
-
 
163
        //sei();
99
      runFlightControl = 1; // every 2nd run (976.5625 Hz/2 = 488.28125 Hz)
164
        outputLoopDivider= OUTPUTLOOP_DIVIDER;
Line 100... Line 165...
100
    }
165
        output_update();
101
    globalMillisClock++; // increment millisecond counter
166
        //cli();
102
  }
167
    }
Line 135... Line 200...
135
#endif
200
#endif
136
}
201
}
Line 137... Line 202...
137
 
202
 
138
// -----------------------------------------------------------------------
203
// -----------------------------------------------------------------------
139
uint16_t setDelay(uint16_t t) {
204
uint16_t setDelay(uint16_t t) {
140
  return (globalMillisClock + t - 1);
205
        return (millisClock + t - 1);
Line 141... Line 206...
141
}
206
}
142
 
207
 
143
// -----------------------------------------------------------------------
208
// -----------------------------------------------------------------------
144
int8_t checkDelay(uint16_t t) {
209
int8_t checkDelay(uint16_t t) {
Line 145... Line 210...
145
  return (((t - globalMillisClock) & 0x8000) >> 8); // check sign bit
210
        return (((t - millisClock) & 0x8000) >> 8); // check sign bit
146
}
211
}
147
 
212
 
148
// -----------------------------------------------------------------------
213
// -----------------------------------------------------------------------
149
void delay_ms(uint16_t w) {
214
void delay_ms(uint16_t w) {
150
  uint16_t t_stop = setDelay(w);
215
        uint16_t t_stop = setDelay(w);
151
  while (!checkDelay(t_stop))
-
 
152
    ;
-
 
153
}
-
 
154
 
-
 
155
// -----------------------------------------------------------------------
-
 
156
void delay_ms_with_adc_measurement(uint16_t w, uint8_t stop) {
-
 
157
  uint16_t t_stop;
-
 
158
  t_stop = setDelay(w);
-
 
159
  while (!checkDelay(t_stop)) {
-
 
160
        if (analogDataReady) {
-
 
161
          analog_update();
-
 
162
          startAnalogConversionCycle();
-
 
163
        }
-
 
164
  }
-
 
165
  if (stop) {
-
 
166
  // Wait for new samples to get prepared but do not restart AD conversion after that!
-
 
167
  // Caller MUST to that.
-