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. |
- |