Subversion Repositories FlightCtrl

Rev

Rev 2130 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <avr/boot.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>

#include "timer0.h"
#include "timer2.h"
#include "uart0.h"
#include "output.h"
#include "attitude.h"
#include "commands.h"
#include "flight.h"
#include "rc.h"
#include "analog.h"
#include "configuration.h"
#include "controlMixer.h"
#include "eeprom.h"
#include "printf_P.h"

uint8_t resetFlag = 0;

void reset(void) {
        resetFlag = 1;
        wdt_enable(WDTO_15MS);
        while (1)
                ;
}

int16_t main(void) {
        uint16_t timer = 0;

#ifdef DO_PROFILE
        static uint8_t profileTimer;
#endif

        // disable interrupts global
        cli();

        wdt_enable(WDTO_120MS);

        // analyze hardware environment
        setCPUType();
        setBoardRelease();

        // initalize modules
        output_init();
        timer0_init();
        timer2_init();
        usart0_init();
        //if (CPUType == ATMEGA644P);// usart1_Init();
        RC_Init();
        analog_init();

        // Parameter Set handling
        IMUConfig_readOrDefault();
        channelMap_readOrDefault();
        rcTrim_readOrDefault();
        paramSet_readOrDefault();

        // enable interrupts global
        sei();

        controlMixer_setNeutral();

        // Cal. attitude sensors and reset integrals.
        attitude_setNeutral();

        // Init flight parameters
        // flight_setNeutral();

        // This is not a busy-wait operation and should be OK.
        beep(2000);

        while (1) {
                if (runFlightControl) { // control interval
                        runFlightControl = 0; // reset Flag, is enabled every 2 ms by ISR of timer0

                        if (!resetFlag) {
                                wdt_reset();
                        }

                        if (!analogDataReady) {
                                // Analog data should have been ready but is not!!
                                debugOut.digital[0] |= DEBUG_MAINLOOP_TIMER;
                        } else {
                                debugOut.digital[0] &= ~DEBUG_MAINLOOP_TIMER;
                        }
                        // This is probably the correct order:
                        // The attitude computation should not depend on anything from control (except maybe the estimation of control activity level)
                        // The control may depend on attitude - for example, attitude control uses pitch and roll angles, compass control uses yaw angle etc.
                        // Flight control uses results from both.
#ifdef DO_PROFILE
                        startProfileTimer(ATTITUDE);
#endif
                        calculateFlightAttitude();
#ifdef DO_PROFILE
                        stopProfileTimer(ATTITUDE);
#endif

#ifdef DO_PROFILE
                        startProfileTimer(CONTROLMIXER);
#endif
                        controlMixer_periodicTask();
#ifdef DO_PROFILE
                        stopProfileTimer(CONTROLMIXER);
#endif

#ifdef DO_PROFILE
                        startProfileTimer(COMMANDS);
#endif
                        commands_handleCommands();
#ifdef DO_PROFILE
                        stopProfileTimer(COMMANDS);
#endif

#ifdef DO_PROFILE
                        startProfileTimer(FLIGHT);
#endif
                        flight_control();
#ifdef DO_PROFILE
                        stopProfileTimer(FLIGHT);
#endif

                        // Allow Serial Data Transmit if motors must not updated or motors are not running
                        if (!runFlightControl || !isFlying) {
                                usart0_transmitTxData();
                        }

                        usart0_processRxData();

                        static uint8_t aboveWarningLimitVoltageSeen = 0;

                        if (checkDelay(timer)) {
                                if (UBat >= staticParams.batteryWarningVoltage) {
                                        aboveWarningLimitVoltageSeen = 1;
                                } else { // If we are above USB voltage, or if we have once been above warning voltage
                                        if (aboveWarningLimitVoltageSeen || UBat > UBAT_AT_5V) {
                                                beepBatteryAlarm();
                                        }
                                }
                                calculateFeaturedServoValues();
                                timer = setDelay(20); // every 20 ms
                        }

                        output_update();

                        if (runFlightControl) { // Time for the next iteration was up before the current finished. Signal error.
                                debugOut.digital[1] |= DEBUG_MAINLOOP_TIMER;
                        } else {
                                debugOut.digital[1] &= ~DEBUG_MAINLOOP_TIMER;
                        }
                }
        }
        return (1);
}