Subversion Repositories Projects

Rev

Blame | Last modification | View Log | RSS feed

/*****************************************************************************
 *   Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de                  *
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
 *                                                                           *
 *   This program is free software; you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation; either version 2 of the License.          *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program; if not, write to the                           *
 *   Free Software Foundation, Inc.,                                         *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
 *                                                                           *
 *****************************************************************************/


#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>

#include "main.h"
#include "lcd.h"
#include "timer.h"
#include "usart.h"
#include "parameter.h"
#include "menu.h"

#include "mk-data-structs.h"

#define TIMEOUT 500     // 5 sec

mk_param_struct_t *mk_param_struct;

uint8_t array[8];

prog_uchar p_menus[12][11]=
{
        "Config    ",
        "Channels  ",
        "Stick     ",
        "Hight     ",
        "Gyro      ",
        "Looping   ",
        "Camera    ",
        "Misc.     ",
        "User      ",
        "Coupling  ",
        "Config(2) ",
        "Loopingset"
};


// Diese Tabelle ordnet die eingelesenen Parameter den Menü-Seiten zu

prog_uchar p_menu_number[67]=
{
        2, 2, 2, 2, 2, 2, 2, 2,                         // Die ersten 8 Parameter werden auf Menüseite 2 angezeigt (=Kanalzuordnungen)
        0, 4, 4, 4, 4, 4, 4, 3,
        3, 3, 8, 8, 8, 8, 5, 5,
        8,8,8,0,5,9,9,9,
        9,7,7,7,7,7,7,6,
        6,6,10,10,6,6,5,5,
        5,9,9,9,9,0,7,11,
        11,11,11,12,12, 12,
        12,12,12,12,12

};

prog_uchar p_limits[199]=                                               // Limits f¸r die Parameter
{
        1,8,2,                  // 2:Nick                                       (3)
        1,8,2,                  // 2:Roll                                       (4)
        1,8,2,                  // 2:Gas                                        (2)    
        1,8,2,                  // 2:Gier                                       (1)
        1,8,2,                  // 2:Poti1                                      (6)
        1,8,2,                  // 2:Poti2                                      (6)
        1,8,2,                  // 2:Poti3                                      (7)
        1,8,2,                  // 2:Poti4                                      (5)
        0,0,0,                  // 1:Config                                    
        0,255,4,                // 4:Höhe MinGas                       (30)
        0,255,4,                // 4:Luftdruck_D                        (30)   
        0,255,4,                // 4:MaxHöhe (Setpoint?)       (Poti4)
        0,255,4,                // 4:Höhe_P                                    (10)
        0,50,4,                 // 4:Höhe Verst‰rkung                (3)
        0,255,4,                // 4:Höhe Z-acc                                (30)
        0,6,3,                  // 3:Nick/Roll P                        (3)
        0,64,3,                 // 3:Nick/Roll D                        (4)
        0,20,3,                 // 3:Gier_P                                     (6)
        0,32,8,                 // 8:Min.Gas                            (15)
        33,250,8,               // 8:Max.Gas                            (250)
        0,50,8,         // 5:Gyro-Acc Faktor                    (30)
        0,255,8,                // 8:Kompass-Wirkung            (128)
        0,0,5,                  // 5:Gyro-P                                     (80)
        0,0,5,                  // 5:Gyro-I                                     (120)
        0,250,8,                // 8:Unterspannung                      (94)
        0,250,8,                // 8:Not-Gas Zeit                       (20)
        0,250,8,                // 8:Not-Gas                            (35)
        0,1,0,                  // Ufo-Ausrichtung (X +)
        0,255,5,                // I-Faktor                                     (32)
        0,255,9,                // 9:User1                                      (80)
        0,255,9,                // 9:User2                                      (0)
        0,255,9,                // 9:User3
        0,255,9,                // 9:User4
        0,255,7,                // 7:Servo Nick Control         (100)
        0,250,7,                // 7:Servo Nick Compensation    (40)
        0,250,7,                // 7:Servo Nick min                     (50)
        0,250,7,                // 7:Servo Nick max                     (150)
        0,25,7,                 // 7:Servo Nick refrsh          (5)
        0,255,6,                // 6:Loop Gas Limit                     (50)
        0,250,6,                // 6:Loop Ansprechschwelle      (90)
        0,250,6,                // 6:Loop Hysterese                     (50)
        0,255,10,               // 10:Achskopplung                      (90)
        0,255,10,               // 10:Achsgegenkopplung         (5)
        0,250,6,                // 6:Turnover Nick                      (100)
        0,250,6,                // 6:Turnover Roll                      (100)
        0,250,5,                // 5: Gyro-Abgleich (Comp.)             (32)
        0,250,5,                // 5: Drift                                             (4)
        0,255,5,                // 5: Dynamic stability                 (75)
        0,255,9,                // 9:User5
        0,255,9,                // 9:User6
        0,255,9,                // 9:User7
        0,255,9,                // 9:User8                                      (0)

        0,0,1,                  // 6:Loop Config                        (0)
        0,1,7                   // 7:Servo Nick Compensation Invert (0)
       
};

prog_char bin_parameter[12][16] =                                                       // Die bin‰r kodierten Parametern werden getrennt behandelt.
{
        "Loop up        ",                     
        "Loop down          ",
        "Loop left      ",
        "Loop right     ",
        "Höhenregler    ",             // 8
        "Höhenschalter  ",
        "Headhold               ",
        "Kompass                ",
        "KompassFix             ",
        "GPS                    ",
        "Achsenkopplung ",
        "Drehrate               "
};

prog_char parameter[54][16]=
{
        "Nick           ",              // 0    (3)
        "Roll           ",              // 1    (4)
        "Gas            ",              //              (2)
        "Gier                   ",              //              (1)
        "Poti1                  ",              //              (6)
        "Poti2                  ",              //              (6)
        "Poti3                  ",              //              (7)
        "Poti4                  ",              //      7       (5)
        "Config                 ",              //      8
        "Höhe_MinGas   ",              // 9    (30)
        "Luftdruck_D    ",              // 10 Wert : 0-250              (30)
        "MaxHöhe       ",              // 11 Wert : 0-250   251 -> Poti1 (Poti4)
        "Höhe_P        ",              // 12 Wert : 0-32               (10)
        "Höhe_Verstaerk",              // 13 Wert : 0-50              
        "Höhe_ACC_Wirk.",              // 14 Wert : 0-250              (30)
        "Stick_P        ",              // 15 Wert : 1-6
        "Stick_D        ",              // 16 Wert : 0-64
        "Gier_P         ",              // 17 Wert : 1-20       POTI(?)
        "Gas_Min        ",              // 17 Wert : 0-32
        "Gas_Max        ",              // 18 Wert : 33-250
        "GyroAccFaktor  ",      // 19 Wert : 1-64
        "KompassWirkung ",              // 20 Wert : 0-250
        "Gyro_P                 ",              // 21 Wert : 0-250
        "Gyro_I                 ",              // 22 Wert : 0-250
        "Unterspannung  ",              // 23 Wert : 0-250
        "NotGas                 ",              // 24 Wert : 0-250     // Gaswert bei Empangsverlust
        "NotGasZeit     ",              // 25 Wert : 0-250     // Zeit bis auf NotGas geschaltet wird, wg. Rx-Problemen
        "UfoAusrichtung ",              // 26 X oder + Formation
        "I_Faktor       ",              // 27 = 32;
        "UserParam1             ",              // 28 = 32 * 4;             //zur freien Verwendung
        "UserParam2             ",      // 29 zur freien Verwendung
        "UserParam3             ",              // 30 zur freien Verwendung
        "UserParam4             ",              // 31 zur freien Verwendung
        "ServoNickCtrl  ",              // 32 Wert : 0-250     // Stellung des Servos
        "ServoNickComp  ",              // 33 Wert : 0-250     // Einfluss Gyro/Servo
        "ServoNickMin   ",              // 34 Wert : 0-250     // Anschlag
        "ServoNickMax   ",              // 35 Wert : 0-250     // Anschlag
        "ServoNickRefrsh",              // 36
        "LoopGasLimit   ",              // 37
        "LoopThreshold  ",              // 38 Wert: 0-250  Schwelle f¸r Stickausschlag
        "LoopHysterese  ",              // 39
        "AchsKopplung   ",              // 40
        "AchsGegenKoppl.",              // 41
        "WinklUmschlNick",              // 42
        "WinklUmschlRoll",              // 43
        "GyroAccAbgleich",      // 44  1/k
        "Driftkomp              ",              // 45
        "DynamicStabilit",              // 47
        "UserParam5             ",              // 48 zur freien Verwendung
        "UserParam6             ",              // 49 zur freien Verwendung
        "UserParam7             ",              // 50 zur freien Verwendung
        "UserParam8             ",              // 51 zur freien Verwendung
        "LoopConfig             ",              // 52  Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts / wird getrennt behandelt
        "ServoNickCompIn"               // 53 Wert : 0-250     // Richtung Einfluss Gyro/Servo
//      "Name           "               // 54
};




void binary (uint8_t data, uint8_t *feld)                       // Wandelt eine 8-Bit Zahl in eine Bin‰rzahl um (Array mit 8 Elementen)
{                                                                                                               // Wird f¸r die Flags (Loop + Grundkonfiguration) benˆtigt
        uint8_t i;
       
        i=0;
        for (i = 0; i < 8; i++)
        {
                if ((1 << i) & data)
                        feld[i] = 1;
                else
                        feld[i] = 0;
        }
}

uint8_t bindec (uint8_t *feld)                                          // wandelt eine Bin‰rzahl (im Array) in eine 8-Bit Zahl
{                                                                                                               // Wird f¸r die Flags (Loop + Grundkonfiguration) benˆtigt
        uint8_t i;
        uint8_t result;
       
        result = 0;
        for (i = 0; i < 8; i++)
        {
                if (feld[i] == 1)
                        result += 1 << i;
        }
        return result;
}




void decimal (uint8_t data, uint8_t *text)                      // wandelt Wert in rechtsbündigen Text um
{                                                                                                               // (schneller/kleiner als printf())
        text[0] = data/100;
        data -= (text[0] * 100);
        text[1] = data/10;
        data -= (text[1] *10);
        text[2] = data + 0x30;
        text[0] += 0x30;
        text[1] += 0x30;

        if (text[0] == 0x30)
        {
                text[0] = 0x20;
                if (text[1] == 0x30)
                        text[1] = 0x20;
        }
        text[3] = 0x00;
}

uint8_t show_parameter (uint8_t number)                                                 // Zeigt eine Parameter-Seite an und gibt die ausgew‰hlte Zeile zur¸ck
{
#if 0
        uint8_t i;
        uint8_t line;
        uint8_t text[25];
        uint8_t bin[8];
               
        line = 0;
       
        if (number > 1)
        {
                for (i = 0; i<66; i++)
                {
                        if (pgm_read_byte(p_limits+i*3+2) == number)
                        {
                                array[line] = i;
                                decimal(buffer[i],text);
                                lcd_print_at(0,line,text,0);
                                lcd_printp_at (5,line,parameter[i],0);
                                if (line <= 7)
                                        line++;
                        }
                }
        }
        else
        {                                                                                                                               // Sonderf‰lle: Bin‰re Eingabe
                if (number == 1)
                {
                        binary(buffer[52],bin);                                                         // Loop-Config
                        text[1] = 0x00;
                        for (i = 0; i < 4; i++)
                        {
                                text[0] = bin[i] + 0x30;
                                lcd_print_at (0, i, text, 0);
                                lcd_printp_at (5, i, bin_parameter[i], 0);
                        }
                       
                }
                if (number == 0)
                {
                        binary (buffer[8], bin);                                                                // Config
                        text[1] = 0x00;
                        for (i = 0; i < 8; i++)
                        {
                                text[0] = bin[i] + 0x30;
                                lcd_print_at (0, i, text, 0);
                                lcd_printp_at (5, i, bin_parameter[i + 4], 0);
                        }
                }
               

        }
        return line;
#endif
}

void edit_parameter2 (uint8_t page, uint8_t lines)                              // ƒndern der Parameter einer Seite
{
#if 0
        uint8_t line;
        uint8_t par;
        uint8_t min;
        uint8_t max;
        uint8_t text[10];
        uint8_t bin[8];
       
        if (page > 1)                                                                                                   // "normale" Parameter-Seiten
        {
                line = menu_choose(0,lines-1,4);
                if (line != 255)                                                                                // Wenn line == 255, wurde Escape gedr¸ckt
                {
                        par = buffer[array[line]];
                        min = pgm_read_byte(p_limits + par * 3);
                        max = pgm_read_byte(p_limits + par * 3 + 1);
                       
                        lcd_printp_at(4,line,PSTR("-"),0);
                       
                        while (key != key_nokey);
                       
                        do
                        {
                                if (key == key_minus)
                                {
                                        //if (par > min)                                                        // ‹berpr¸fung der Parameter auf Bereichs¸berschreitung derzeit deaktiviert
                                                par --;
                                }
                                if (key == key_plus)
                                {
                                        //if (par < max)
                                                par ++;
                                }
                               
                                decimal(par,text);
                                lcd_print_at(0,line,text,0);
                               
                                timer = 20;
                                while (timer > 0);
                        }
                        while ((key != 0x04) && (key != 0x08));
                       
                        if (key == 0x08)
                                buffer[array[line]] = par;
                }
        }
       
        if (page == 1)                                                                                  // Spezialfall:  Loop-Config (einzelne Bits setzen / lˆschen)
        {
                binary(buffer[52],bin);                                
                text[1] = 0x00;

                line = menu_choose(0,3,4);
                if (line != 255)                                                                        // Wenn line == 255, wurde Escape gedr¸ckt
                {
                        par = bin[line];
       
                        lcd_printp_at(4,line,PSTR("-"),0);
                       
                        do
                        {
                       
                                if (key == key_minus)
                                {
                                        par = 0x00;
                                }
                                if (key == key_plus)
                                {
                                        par = 0x01;
                                }
                               
                                text[0] = par+0x30;
                                lcd_print_at(0,line,text,0);
                                timer = 20;
                                while (timer > 0);
       
                       
                        }
                        while ((key != key_enter) && (key != key_esc));
       
                        if (key == key_enter)
                        {
                                bin[line] = par;
                                buffer[52] = bindec(bin);
                        }
       
                        lcd_cls();
                        decimal(buffer[52],text);
                        lcd_print(text,0);
                        timer = 200;
                        while(timer > 0);
                }
        }
        if (page == 0)                                                                                                  // Spezialfall: Allgemeine Konfiguration (einzelne Bits setzen/lˆschen)
        {
                binary(buffer[8],bin);                                 
                text[1] = 0x00;

                line = menu_choose(0,7,4);
                if (line != 255)                                                                                        // Wenn line == 255, wurde Escape gedr¸ckt
                {
                        par = bin[line];
       
                        lcd_printp_at(4,line,PSTR("-"),0);
                       
                        do
                        {
                       
                                if (key == key_minus)
                                {
                                        par = 0x00;
                                }
                                if (key == key_plus)
                                {
                                        par = 0x01;
                                }
                               
                                text[0] = par+0x30;
                                lcd_print_at(0,line,text,0);
                                timer = 20;
                                while (timer > 0);
       
                       
                        }
                        while ((key != key_enter) && (key != key_esc));
       
                        if (key == key_enter)
                        {
                                bin[line] = par;
                                buffer[8] = bindec(bin);
                        }
                       
                        lcd_cls();
                        decimal(buffer[8],text);
                        lcd_print(text,0);
                        timer = 200;
                        while(timer > 0);
                }
        }
#endif
}


void edit_parameter1 (void)
{
        uint8_t cmd;
        uint8_t setting = 0xff;
       
        mode = 'P';     // Settings

        lcd_cls ();

        //mode = 'Q';   // Settings
        _delay_ms (50);
        rxd_buffer_locked = FALSE;
        timer = TIMEOUT;
       
        LED2_ON;
        //SendOutData ('q', ADDRESS_FC, 1, &setting, 1);
        SendOutData ('p', ADDRESS_FC, 1);
        while (!rxd_buffer_locked && timer);
        if (timer)
        {
                LED3_ON;
                Decode64 ();
#if 0
                mk_param_struct = (mk_param_struct_t *) pRxData + 2;

                lcd_printp (PSTR("Current Setting: "), 0);
                lcd_write_number_u (*pRxData);
               
                lcd_printp (PSTR("Setting Version: "), 0);
                lcd_write_number_u (*pRxData+1);
#endif
                LED3_OFF;
        }
        else
        {       // timeout occured
                lcd_printp_at (0, 2, PSTR("ERROR: no data"), 0);
               
                timer = 100;
                while (timer > 0);
                return;
        }
        LED2_OFF;

        // after all work is done...
        rxd_buffer_locked = FALSE;

#if 0
        uint8_t page;                                                           // 12 Pages
        uint8_t text[15];
        uint8_t lines;
        uint8_t parameter;
       
        lcd_cls ();
       
        lcd_printp (PSTR("Load Setting\r\n"), 0);
        lcd_printp (PSTR(" 1:\r\n"), 0);
        lcd_printp (PSTR(" 2:\r\n"), 0);
        lcd_printp (PSTR(" 3:\r\n"), 0);
        lcd_printp (PSTR(" 4:\r\n"), 0);
        lcd_printp (PSTR(" 5:\r\n"), 0);
       
        parameter = menu_choose (1, 5, 0);

        page = 2;
        if (read_parameter (parameter) == 1)
        {
                lcd_printp_at (0, 6, PSTR("Timeout"), 0);
        }
        else
        {
                do
                {
                        lcd_cls ();
                        utoa (page, text, 10);
                        lcd_print (text, 0);
                        timer = 50;
                       
                        while (timer > 0);
                       
                        lcd_cls ();
                       
                        lines = show_parameter (page);
                       
                        while (key == key_nokey);
                        if (key == key_plus)
                                page++;
                        if (key == key_minus)
                                page--;
                               
                        if (page == 255)
                                page = 12;
                               
                        if (page > 12)
                                page = 0;
                       
                        if (key == key_enter)
                                edit_parameter2 (page, lines);
               
                }
                while (key != key_esc);
               
                lcd_cls ();
                lcd_printp (PSTR("Parameter speichern?\r\n  ja\r\n  nein"), 0);
               
                lines = menu_choose (1, 2, 0);
               
                if (lines == 1 )
                {
                        lcd_printp (PSTR("\r\n--->"), 0);
                        write_parameter (5);            // Sicherheitshalber wird derzeit ausschliefllich auf Parametersatz 5 gesichert.
                        lcd_printp (PSTR("\r\nParameter gespeichert"), 0);
                }
                else
                {
                        lcd_printp (PSTR("\r\nNicht gespeichert"), 0);
                }
        }
        timer = 100;
        while (timer > 0);
#endif
}

void display_page (uint8_t page)
{
        lcd_cls ();

        switch (page)
        {
                case 0:
                        lcd_printp (PSTR("Current Setting: "), 0);
                        lcd_write_number_u (*pRxData);
                       
                        lcd_printp (PSTR("\r\nSetting Version: "), 0);
                        lcd_write_number_u (*(pRxData + 1));
#if 0          
                        lcd_printp (PSTR("\r\nRxDataLen: "), 0);
                        lcd_write_number_u (RxDataLen);
                       
                        lcd_printp (PSTR("\r\nRxBytes: "), 0);
                        lcd_write_number_u (ReceivedBytes);
#endif
                        break;

                case 1:
                        lcd_printp (PSTR("Pitch: "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[0]);

                        lcd_printp (PSTR("Yaw  : "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[1]);
                       
                        lcd_printp (PSTR("Nick : "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[2]);
                       
                        lcd_printp (PSTR("Roll : "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[3]);
                       
                        lcd_printp (PSTR("Poti1: "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[4]);
                       
                        lcd_printp (PSTR("Poti2: "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[5]);
                       
                        lcd_printp (PSTR("Poti3: "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[6]);
                       
                        lcd_printp (PSTR("Poti4: "), 0);
                        lcd_write_number_u (mk_param_struct->Kanalbelegung[7]);
                        break;
        }
}


void edit_parameter (void)
{
        uint8_t cmd;
        uint8_t sett = 0xff;    // current active parameter set
        uint8_t page = 0;
       
        SwitchToFC();
       
        mode = 'Q';     // Settings
       
        lcd_cls ();

        _delay_ms (50);
        rxd_buffer_locked = FALSE;
        timer = TIMEOUT;
       
        SendOutData ('q', ADDRESS_FC, 1, &sett, 1);
        while (!rxd_buffer_locked && timer);
        if (timer)
        {
                Decode64 ();
                mk_param_struct = (mk_param_struct_t *) pRxData + 2;
               
                display_page (page);
               
                if (get_key_press (1 << KEY_MINUS))
                {
                        page--;
                }
                else if (get_key_press (1 << KEY_PLUS))
                {
                        page++;
                }

        }
        else
        {       // timeout occured
                lcd_printp_at (0, 2, PSTR("ERROR: no data"), 0);
               
                timer = 100;
                while (timer > 0);
                return;
        }
       
        // after all work is done...
        //rxd_buffer_locked = FALSE;
        while (!get_key_press (1 << KEY_ESC));  // ESC

        mode = 0;
        rxd_buffer_locked = FALSE;
}