Subversion Repositories Projects

Rev

Rev 1307 | 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                  *
 *   Copyright (C) 2010 Sebastian Boehm, seb@exse.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 "mk-data-structs.h"
#include "parameter.h"
#include "menu.h"
#include "eeprom.h"
#include "parameter_names.h"



#define TIMEOUT 500     // 5 sec

uint8_t display_settings_menu (void);
uint8_t display_param_menu (uint8_t);
uint8_t load_setting (uint8_t);
uint8_t write_setting (uint8_t);
uint8_t display_section_menu(void);
void edit_param(uint8_t);
void copy_setting(void);





mk_param_struct_t *mk_param_struct;

uint8_t ii;
volatile uint8_t offset = 0;
volatile uint8_t dmode = 0;
volatile uint8_t target_pos = 1;

volatile uint8_t offset2 = 0;
volatile uint8_t pmode = 0;
volatile uint8_t target_pos2 = 1;

uint8_t changes = 0;

#define OFFSETOF(type, field)    ((unsigned int) &(((type *) 0)->field))

#define MKOSO(field) (uint8_t)OFFSETOF(mk_param_struct_t, field)

// Typ(1=mit Poti,0=ohne Poti,2=bitfield,3=serCh,4=LEDmask,5 Angle,6 Empfaenger ),
// min,
// max,
// struct-name,
// default1,
// default2,
// default3+4+5
prog_uchar  param_config[8*PARAM_COUNT]=
{
         // group 0 (kanaele) 15
         0,0,1,12  ,MKOSO(Kanalbelegung)+2,1,1,1, //   gas
         0,0,1,12  ,MKOSO(Kanalbelegung)+3,2,2,2, //   gier
         0,0,1,12  ,MKOSO(Kanalbelegung),3,3,3,   //   nick
         0,0,1,12  ,MKOSO(Kanalbelegung)+1,4,4,4, //   roll
         0,3,1,25  ,MKOSO(Kanalbelegung)+4,5,5,5, //   poti1
         0,3,1,25  ,MKOSO(Kanalbelegung)+5,6,6,6, //   poti2
         0,3,1,25  ,MKOSO(Kanalbelegung)+6,7,7,7, //   poti3
         0,3,1,25  ,MKOSO(Kanalbelegung)+7,8,8,8, //   poti4
         0,3,1,25  ,MKOSO(Kanalbelegung)+8,9,9,9, //   poti5
         0,3,1,25  ,MKOSO(Kanalbelegung)+9,10,10,10, //   poti6
         0,3,1,25  ,MKOSO(Kanalbelegung)+10,11,11,11, //   poti7
         0,3,1,25  ,MKOSO(Kanalbelegung)+11,12,12,12, //   poti8
         //26.3.2011 0.82 CB
         0,0,0,12  ,MKOSO(MotorSafetySwitch),0,0,0, //   Motor Sicherungsswitch
         //
         0,2,0,0x04,MKOSO(ExtraConfig),0,0,0, //erweiterte signal pruefung
         0,6,0,5   ,MKOSO(Receiver),1,1,1,

         // group 1 (main) 8
         
         1,2,0,0x01,MKOSO(GlobalConfig),0,0,1, //hoehenregler
         1,2,0,0x20,MKOSO(GlobalConfig),1,1,1, //gps
         1,2,0,0x08,MKOSO(GlobalConfig),1,1,1, //kompass
         1,2,0,0x10,MKOSO(GlobalConfig),0,0,0, //feste ausrichtung
         1,2,0,0x04,MKOSO(ExtraConfig),0,0,0, //erweiterte signal pruefung
         1,2,0,0x40,MKOSO(GlobalConfig),1,1,1, //achsentkopplung
         1,2,0,0x80,MKOSO(GlobalConfig),0,0,0, //drehratenbregrenzung
         1,2,0,0x04,MKOSO(GlobalConfig),0,0,0, //heading hold

         // group 2 (stick) 4
         2,0,0,20  ,MKOSO(Stick_P),8,8,8,
         2,0,0,20  ,MKOSO(Stick_D),16,16,16,
         2,1,0,247 ,MKOSO(Gier_P),6,6,6,
         2,1,0,247 ,MKOSO(ExternalControl),0,0,0,
         


         // group3 : looping 9
       
         3,2,0,0x01,MKOSO(BitConfig),0,0,0, //oben
         3,2,0,0x02,MKOSO(BitConfig),0,0,0, //unten
         3,2,0,0x04,MKOSO(BitConfig),0,0,0, //links
         3,2,0,0x08,MKOSO(BitConfig),0,0,0, //rechts
         3,1,0,247 ,MKOSO(LoopGasLimit),50,50,50,
         3,0,0,247 ,MKOSO(LoopThreshold),90,90,90,
         3,0,0,247 ,MKOSO(LoopHysterese),50,50,50,
         3,0,0,247 ,MKOSO(WinkelUmschlagNick),78,78,78,
         3,0,0,247 ,MKOSO(WinkelUmschlagRoll),78,78,78,


         
         
         // group 4 (hoehe) 13
         
         4,2,0,0x01,MKOSO(GlobalConfig),1,1,1, //hoehenrelger
         4,2,0,0x01,MKOSO(ExtraConfig),0,0,0, //vario oder hoeenbergenzung
         4,2,0,0x02,MKOSO(GlobalConfig),1,1,1, //hoehenschalter
         4,2,0,0x02,MKOSO(ExtraConfig),1,1,1, //variobeep
         4,1,0,247 ,MKOSO(MaxHoehe),255,255,255,
         4,0,0,247 ,MKOSO(Hoehe_MinGas),30,30,30,        
         4,1,0,247 ,MKOSO(Hoehe_P),15,15,15,    
         4,1,0,247 ,MKOSO(Luftdruck_D),30,30,30,        
         4,1,0,247 ,MKOSO(Hoehe_ACC_Wirkung),0,0,0,      
         4,0,0,247 ,MKOSO(Hoehe_Verstaerkung),15,15,15,          
         4,0,0,247 ,MKOSO(Hoehe_HoverBand),8,8,8,        
         4,1,0,247 ,MKOSO(Hoehe_GPS_Z),64,64,64,        
         4,0,0,247 ,MKOSO(Hoehe_StickNeutralPoint),0,0,0,
         
         // Typ(1=mit Poti,0=ohne Poti,2=bitfield,3=serCh,4=LEDmask,5 Angle,6 Empfaenger),
         // min,
         // max,
         // struct-name,
         // default1,
         // default2,
         // default3+4+5
         
         // group 5 : kamera 16
         
         5,1,0,247,MKOSO(ServoNickControl),100,100,100,
         5,0,0,247,MKOSO(ServoNickComp),40,40,40,
         5,2,0,0x01,MKOSO(ServoCompInvert),1,1,1,
         5,0,0,247,MKOSO(ServoNickMin),0,0,0,
         5,0,0,247,MKOSO(ServoNickMax),247,247,247,

         5,1,0,247,MKOSO(ServoRollControl),100,100,100,
         5,0,0,247,MKOSO(ServoRollComp),40,40,40,
         5,2,0,0x01,MKOSO(ServoCompInvert),0,0,0,
         5,0,0,247,MKOSO(ServoRollMin),0,0,0,
         5,0,0,247,MKOSO(ServoRollMax),247,247,247,


         5,0,2,8  ,MKOSO(ServoNickRefresh),6,6,6,
         //26.3.2011 0.82 CB
         5,0,0,247 ,MKOSO(ServoManualControlSpeed),40,40,40,
         5,5,0,247 ,MKOSO(CamOrientation),0,0,0,
         //
         5,1,0,247,MKOSO(Servo3),125,125,125,
         5,1,0,247,MKOSO(Servo4),125,125,125,
         5,1,0,247,MKOSO(Servo5),125,125,125,
         
         
         // group 6 : navictrl 17

    6,2,0,0x20,MKOSO(GlobalConfig),1,1,1, //gps
        6,1,0,247,MKOSO(NaviGpsModeControl),254,254,254,
        6,1,0,247,MKOSO(NaviGpsGain),100,100,100,
        6,0,0,247,MKOSO(NaviStickThreshold),8,8,8,
        6,0,0,247,MKOSO(NaviGpsMinSat),6,6,6,
        6,1,0,247,MKOSO(NaviGpsP),90,90,90,
        6,1,0,247,MKOSO(NaviGpsI),90,90,90,
        6,1,0,247,MKOSO(NaviGpsD),90,90,90,
        6,1,0,247,MKOSO(NaviGpsPLimit),75,75,75,
        6,1,0,247,MKOSO(NaviGpsILimit),75,75,75,
        6,1,0,247,MKOSO(NaviGpsDLimit),75,75,75,
        6,1,0,247,MKOSO(NaviGpsACC),0,0,0,
//
        6,1,0,247,MKOSO(NaviWindCorrection),90,90,90,
        6,1,0,247,MKOSO(NaviSpeedCompensation),30,30,30,
        6,1,0,247,MKOSO(NaviOperatingRadius),100,100,100,
        6,1,0,247,MKOSO(NaviAngleLimitation),100,100,100,
        6,0,0,247,MKOSO(NaviPH_LoginTime),2,2,2,
       


         // group 7 : ausgaenge 9
         
     7,4,0,255,MKOSO(J16Bitmask),95,95,95,
     7,1,0,247,MKOSO(J16Timing),30,30,30,
     7,4,0,255,MKOSO(J17Bitmask),243,243,243,
     7,1,0,247,MKOSO(J17Timing),30,30,30,
     7,2,0,0x10,MKOSO(BitConfig),0,0,0,//CFG_MOTOR_BLINK
     7,4,0,255,MKOSO(WARN_J16_Bitmask),170,170,170,
     7,2,0,0x20,MKOSO(BitConfig),1,1,1,//CFG_MOTOR_OFF_LED1
     7,4,0,255,MKOSO(WARN_J17_Bitmask),170,170,170,
     7,2,0,0x40,MKOSO(BitConfig),1,1,1,//CFG_MOTOR_OFF_LED2
       
                 
         
         // group 8 : versch. 7
         
     8,0,0,247,MKOSO(Gas_Min),8,8,8,
     8,0,0,247,MKOSO(Gas_Max),230,230,230,
     8,1,0,247,MKOSO(KompassWirkung),128,128,128,
     8,1,0,247,MKOSO(OrientationModeControl),0,0,0,
     8,0,0,247,MKOSO(UnterspannungsWarnung),33,33,33,
     8,0,0,247,MKOSO(NotGasZeit),90,90,90,
     8,0,0,247,MKOSO(NotGas),45,45,45,


         // group 9 : gyro 12
         
         9,1,0,247,MKOSO(Gyro_P),100,100,100,
         9,1,0,247,MKOSO(Gyro_I),120,120,120,
         9,1,0,247,MKOSO(Gyro_D),10,10,10,
         9,1,0,247,MKOSO(Gyro_Gier_P),100,100,100,
         9,1,0,247,MKOSO(Gyro_Gier_I),120,120,120,
         9,1,0,247,MKOSO(DynamicStability),70,70,70,
         9,2,0,0x80,MKOSO(GlobalConfig),0,0,0, //drehratenbregrenzung
         9,0,0,247,MKOSO(GyroAccFaktor),27,27,27,
         9,0,0,247,MKOSO(GyroAccAbgleich),32,32,32,
         9,1,0,247,MKOSO(I_Faktor),16,16,16,
         9,0,0,247,MKOSO(Driftkomp),0,0,0,
         9,0,0,8,MKOSO(Gyro_Stability),100,100,100,
         
         
         // group 10: benutzer 8
         
         10,1,0,247,MKOSO(UserParam1),0,0,0,
         10,1,0,247,MKOSO(UserParam2),0,0,0,
         10,1,0,247,MKOSO(UserParam3),0,0,0,
         10,1,0,247,MKOSO(UserParam4),0,0,0,
         10,1,0,247,MKOSO(UserParam5),0,0,0,
         10,1,0,247,MKOSO(UserParam6),0,0,0,
         10,1,0,247,MKOSO(UserParam7),0,0,0,
         10,1,0,247,MKOSO(UserParam8),0,0,0,


         // group 11: achskoppl 4
         
         11,2,0,0x40,MKOSO(GlobalConfig),0,0,0, //achsentkopplung
         11,1,0,247,MKOSO(AchsKopplung1),90,90,90,
         11,1,0,247,MKOSO(AchsKopplung2),80,80,80,
         11,1,0,247,MKOSO(CouplingYawCorrection),70,70,70,
         
         
         
         // group 12: mixer
         
         12,5,0,23,MKOSO(OrientationAngle),0,0,0,
         
};






void edit_parameter (void)
{
        SwitchToFC();


        uint8_t setting;

       
        setting = display_settings_menu();
       
        if(setting == 6)
        {
                copy_setting();
                return;
        }
       
               
                if(setting == 255) return;
                uint8_t setting_loaded =  load_setting(setting);
                if(setting_loaded == 255) return;

                offset = 0;
                dmode = 0;
                target_pos = 1;
                changes =0;


                        uint8_t group =0;
                        do
                        {
                       
                                group = display_section_menu();
                       
                                if(group != 255)
                                {
                                        offset2 = 0;
                                        pmode = 0;
                                        target_pos2 = 1;
                                        uint8_t param;
                                        do
                                        {
                                                param = display_param_menu(group);
                                               
                                                if(param != 255)
                                                {
                                                        edit_param(param);
                                                }
                                       
                                        }
                                        while(param != 255);
                                }
                       
                               
                        }
                        while(group != 255);
                       
                if(changes == 1)
                {
                        lcd_cls();
                        lcd_printp_at (0, 0, PSTR("Save Setting x?"), 0);
                        write_ndigit_number_u(13,0,setting, 1,0);
                        lcd_printp_at (3, 1, PSTR("yes"), 0);
                        lcd_printp_at (3, 2, PSTR("no"), 0);
                        lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Exit   \x0c"), 0);
                       
                        uint8_t val = menu_choose2 (1, 2, 2,0,0);
                       
                        if(val == 1)
                        {
                                uint8_t setting_written = write_setting(setting);
       
                                if(setting_written == setting)
                                {
                                        lcd_printp_at (0, 4, PSTR("saved and"), 0);
                                        lcd_printp_at (0, 5, PSTR("activated"), 0);
                                }
                                else
                                {
                                        lcd_printp_at (0, 4, PSTR("ERROR"), 0);
                                }
                                timer = 100;
                                while (timer > 0);

                        }
                       
                }
               
               
       
       
}


void copy_setting(void)
{
        uint8_t fromsetting = 3;
        uint8_t tosetting = 5;
       
        lcd_cls();
       
        lcd_printp_at (0, 0, PSTR("Copy Setting:"), 0);
        lcd_printp_at (3, 2, PSTR("From Setting:"), 0);
        lcd_printp_at (3, 3, PSTR("  To Setting:"), 0);
       
        //                           123456789012345678901
        //                               x     x    x
        lcd_printpns_at (0, 7, PSTR("From   To  Back   Do"), 0);
       
       
        do
        {
                write_ndigit_number_u(17,2,fromsetting, 1,0);
                write_ndigit_number_u(17,3,tosetting, 1,0);
       
                if(get_key_press (1 << KEY_MINUS))
                {
                        fromsetting++;
                        if(fromsetting == 6) fromsetting = 1;
                }
                if(get_key_press (1 << KEY_PLUS))
                {
                        tosetting++;
                        if(tosetting == 6) tosetting = 1;
                }
                if(get_key_press (1 << KEY_ENTER))
                {                                                          
                        lcd_printp_at (0, 5, PSTR("Really want to copy?"), 0);
                        do
                        {
                       
                        if(get_key_press (1 << KEY_ENTER))
                        {
                                uint8_t loaded = load_setting(fromsetting);
                                if(loaded == fromsetting)
                                {
                                        uint8_t written = write_setting(tosetting);
                                        if(written == tosetting)
                                        {
                                                lcd_printp_at (0, 5, PSTR("written and activated"), 0);
                                                       
                                        }
                                        else
                                        {
                                                lcd_printp_at (0, 5, PSTR("ERROR               "), 0);
                                        }
                                }
                                else
                                {
                                        lcd_printp_at (0, 5, PSTR("ERROR               "), 0);
                                }
                                timer = 100;
                                while (timer > 0);
                                return;
                        }
                       
                       
                        }while (!get_key_short (1 << KEY_ESC));
                        lcd_printp_at (0, 5, PSTR("                    "), 0);
                       
                }
               
       
       
        }
        while (!get_key_short (1 << KEY_ESC));
}


//      write_ndigit_number_u (0,0, *(((uint8_t*)mk_param_struct) + OFFSETOF(mk_param_struct_t, GlobalConfig)) , 6, 0);//evtl. den cast auf uint16_t machen

  //  lcd_printp_at (pos, before, PSTR(" "), 0);
  //
  // oben  \x1a   unten \x1b
   //      lcd_printp_at (pos, line, PSTR("\x1D"), 0);


void edit_param(uint8_t param)
{
        lcd_cls();
        uint8_t type = pgm_read_byte(param_config+(8*param)+1);
        lcd_printp_at (0, 0, PSTR("Edit Setting:"), 0);
        if (type != 6) lcd_printp_at(0,2,param_names[param][DisplayLanguage], 0);
       

       
        if(type == 2)// ja/nein
        {
                lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Back   \x0c"), 0);
                lcd_printp_at (3, 4, PSTR("Y"), 0);
                lcd_printp_at (3, 5, PSTR("N"), 0);

                uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4));
                uint8_t defaultvalue =  pgm_read_byte(param_config+(8*param)+5);
                uint8_t bitmap = pgm_read_byte(param_config+(8*param)+3);
                uint8_t newvalue = value;

                if(defaultvalue == 1) lcd_printp_at (4, 4, PSTR("*"), 0);
                if(defaultvalue == 0) lcd_printp_at (4, 5, PSTR("*"), 0);
               
                do
                {
               
                        if(newvalue & bitmap)
                        {
                                lcd_printp_at (1, 4, PSTR("\x1D"), 0);
                        lcd_printp_at (1, 5, PSTR(" "), 0);
                        }
                        else
                        {
                        lcd_printp_at (1, 4, PSTR(" "), 0);
                                lcd_printp_at (1, 5, PSTR("\x1D"), 0);
                        }
                       
                       
                        if(get_key_press (1 << KEY_MINUS))
                        {
                                newvalue ^= bitmap;
                        }
                       
                        if(get_key_press (1 << KEY_PLUS))
                        {
                                newvalue ^= bitmap;
                        }

                        if(get_key_press (1 << KEY_ENTER))
                        {
                                if(newvalue != value)
                                {
                                        *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4)) = newvalue;
                                        changes=1;
                                }
                                break;
                               
                        }
                       
                        if(get_key_long (1 << KEY_ESC))
                        {
                                if(defaultvalue == 1)
                                {
                                        newvalue |= bitmap;
                                }
                                else
                                {
                                        newvalue &= ~bitmap;
                                }
                        }
                       
                       
                }while (!get_key_short (1 << KEY_ESC));
        }
        if(type == 0)// ohne poti
        {
                lcd_printpns_at (0, 7, PSTR(" \x18    \x19     Back   \x0c"), 0);
                uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4));
                uint8_t min   =pgm_read_byte(param_config+(8*param)+2);
                uint8_t max   = pgm_read_byte(param_config+(8*param)+3);
                uint8_t defaultvalue   = pgm_read_byte(param_config+(8*param)+5);
                lcd_printpns_at (4, 4, PSTR("(   -   ) (d:   )"), 0);
                write_ndigit_number_u (5, 4, min, 3, 0);
                write_ndigit_number_u (9, 4, max, 3, 0);
                write_ndigit_number_u (17, 4, defaultvalue, 3, 0);


                uint8_t newvalue = value;
               
                do
                {
                        write_ndigit_number_u (0, 4, newvalue, 3, 0);
                        lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
               
               
                        if(get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS))
                        {
                                if((newvalue+1) <= max)
                                {
                                        newvalue++;
                                        //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                                }
                        }

                        if(get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS))
                        {
                                if((newvalue-1)>=min)
                                {
                                        lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 0);
                                        newvalue--;
                                        //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                                }
                        }


                        if(get_key_press (1 << KEY_ENTER))
                        {
                                if(newvalue != value)
                                {
                                        *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4)) = newvalue;
                                        changes=1;
                                }
                                break;
                               
                        }
                        if(get_key_long (1 << KEY_ESC))
                        {
                                lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 0);
                                newvalue = defaultvalue;
                                //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                               
                        }
                       
                }while (!get_key_short (1 << KEY_ESC));
        }

        if(type == 1)// mit poti
        {
                lcd_printpns_at (0, 7, PSTR(" \x18    \x19     Back  \x0c\x0c"), 0);
                uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4));
                uint8_t min   =pgm_read_byte(param_config+(8*param)+2);
                uint8_t max   = pgm_read_byte(param_config+(8*param)+3);
                uint8_t defaultvalue   = pgm_read_byte(param_config+(8*param)+5);
                lcd_printpns_at (4, 4, PSTR("(   -   ) (d:Po )"), 0);
                write_ndigit_number_u (5, 4, min, 3, 0);
                write_ndigit_number_u (9, 4, max, 3, 0);
                if(defaultvalue > 247)
                {
                        write_ndigit_number_u (19, 4, 256-defaultvalue, 1, 0);
                }
                else
                {
                        write_ndigit_number_u (17, 4, defaultvalue, 3, 0);
                }


                uint8_t newvalue = value;
               
                uint8_t mode = 0;
                if(value > 247)
                {
                        mode=1;
                }
                else
                {
                }
               
                uint8_t tempv = 255;
               
                do
                {
                       
                        if(get_key_long (1 << KEY_ENTER))
                        {
                                if(mode == 0)
                                {
                                        mode = 1;
                                        lcd_frect ((8*0), (8*5), 128, 6, 0);
                                        tempv = newvalue;
                                        newvalue = 255;
                                }
                                else
                                {
                                        mode = 0;
                                        if(tempv == 255)
                                        {
                                                if (defaultvalue > 247)
                                                {
                                                        newvalue = min;
                                                }
                                                else
                                                {
                                                        newvalue = defaultvalue;
                                                }
                                        }
                                        else
                                        {
                                                newvalue = tempv;
                                        }
                                }
                        }
                       
                       
                        if(mode==0)
                        {
               
                                write_ndigit_number_u (0, 4, newvalue, 3, 0);
                                lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
               
               

                                if(get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS))
                                {
                                        if((newvalue+1) <= max)
                                        {
                                                newvalue++;
                                                //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                                        }
                                }
       
                                if(get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS))
                                {
                                        if((newvalue-1)>=min)
                                        {
                                                lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 0);
                                                newvalue--;
                                                //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                                        }
                                }
                        }
                        else
                        {
                                lcd_printpns_at (0, 4, PSTR("Po"), 0);
                                write_ndigit_number_u (2, 4, 256-newvalue, 1, 0);
                                if(get_key_press (1 << KEY_PLUS))
                                {
                                        if(newvalue > 248)
                                        {
                                                newvalue--;
                                        }
                                }
       
                                if(get_key_press (1 << KEY_MINUS))
                                {
                                        if(newvalue < 255)
                                        {
                                                newvalue++;
                                        }
                                }
                        }


                        if(get_key_short (1 << KEY_ENTER))
                        {
                                if(newvalue != value)
                                {
                                        *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4)) = newvalue;
                                        changes=1;
                                }
                                break;
                               
                        }
                        if(get_key_long (1 << KEY_ESC))
                        {
                                lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 0);
                                newvalue = defaultvalue;
                                if(newvalue > 247)
                                {
                                        mode =1;
                                }
                                else
                                {
                                        //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                                        mode =0;
                                }
                       
                               
                        }
                       
                }while (!get_key_short (1 << KEY_ESC));
        }

        if(type == 3)// serCH
        {
                lcd_printpns_at (0, 7, PSTR(" \x18    \x19     Back   \x0c"), 0);
                uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4));
                uint8_t min   =pgm_read_byte(param_config+(8*param)+2);
                uint8_t max   = pgm_read_byte(param_config+(8*param)+3);
                uint8_t defaultvalue   = pgm_read_byte(param_config+(8*param)+5);
                lcd_printpns_at (4, 4, PSTR("(1-S12/W) (d:   )"), 0);
//              write_ndigit_number_u (5, 4, min, 3, 0);
//              write_ndigit_number_u (9, 4, max, 3, 0);
                write_ndigit_number_u (17, 4, defaultvalue, 3, 0);


                uint8_t newvalue = value;

                do
                {
                        if (newvalue<=(max-13))
                        {
                        write_ndigit_number_u (0, 4, newvalue, 3, 0);
                        }
                else
                    if (newvalue<=(max-1))
                         {
                          lcd_printpns_at (0, 4, PSTR("S"), 0);
                          write_ndigit_number_u (1, 4, (newvalue-12), 2, 0);
                         }
                   if (newvalue==max)
                   {
                          lcd_printpns_at (0, 4, PSTR("WPE"), 0);
                   }

                          lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);


                        if(get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS))
                        {
                                if((newvalue+1) <= max)
                                {
                                        newvalue++;
                                        //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                                }
                        }

                        if(get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS))
                        {
                                if((newvalue-1)>=min)
                                {
                                        lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 0);
                                        newvalue--;
                                        //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);
                                }
                        }


                        if(get_key_press (1 << KEY_ENTER))
                        {
                                if(newvalue != value)
                                {
                                        *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4)) = newvalue;
                                        changes=1;
                                }
                                break;

                        }
                        if(get_key_long (1 << KEY_ESC))
                        {
                                lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 0);
                                newvalue = defaultvalue;
                                //lcd_frect ((8*0), (8*5), (newvalue * (16*8)) / max, 6, 1);

                        }

                }while (!get_key_short (1 << KEY_ESC));
        }


        if(type == 4) // led bitfeld
        {
                lcd_printpns_at (0, 7, PSTR(" \x19   Set    Back   \x0c"), 0);
                uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4));
                uint8_t defaultvalue   = pgm_read_byte(param_config+(8*param)+5);



                uint8_t pos = 0;
                uint8_t newvalue = value;
                do
                {

                        for(ii=0;ii<8;ii++)
                        {
                                if(newvalue & (1 << ii))
                                {
                                        lcd_printpns_at (8-ii, 4,PSTR("X"),0);
                                }
                                else
                                {
                                        lcd_printpns_at (8-ii, 4,PSTR("O"),0);
                                }
                        }
                        lcd_printpns_at (pos+1, 5,PSTR("\x1a"),0);
                        if(get_key_press (1 << KEY_MINUS))
                        {
                                lcd_printpns_at (pos+1, 5,PSTR(" "),0);
                                pos++;
                                if(pos == 8) pos = 0;
                        }
                        if(get_key_press (1 << KEY_PLUS))
                        {
                                newvalue ^= (1<<(7-pos));
                        }
                        if(get_key_press (1 << KEY_ENTER))
                        {
                                if(newvalue != value)
                                {
                                        *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4)) = newvalue;
                                        changes=1;
                                }
                                break;
                        }

                        if(get_key_long (1 << KEY_ESC))
                        {
                                newvalue = defaultvalue;
                        }

                       
                }while (!get_key_short (1 << KEY_ESC));
        }

        if(type == 6) // receiver
        {
                lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Back   \x0c"), 0);
                uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4));
                uint8_t defaultvalue   = pgm_read_byte(param_config+(8*param)+5);

                lcd_printpns_at (3, 1,PSTR("PPM"),0);
                lcd_printpns_at (3, 2,PSTR("Spektrum"),0);
                lcd_printpns_at (3, 3,PSTR("Spektrum HiRes"),0);
                lcd_printpns_at (3, 4,PSTR("Spektrum LoRes"),0);
                lcd_printpns_at (3, 5,PSTR("Jeti"),0);
                lcd_printpns_at (3, 6,PSTR("ACT DSL"),0);

                uint8_t newvalue = value;
                do
                {

                        for(ii=0;ii<6;ii++)
                        {
                                if(newvalue == ii)
                                {
                                        lcd_printpns_at (1, ii+1,PSTR(">"),0);
                                }
                                else
                                {
                                        lcd_printpns_at (1, ii+1,PSTR(" "),0);
                                }
                               
                               
                        }

                        if(get_key_press (1 << KEY_PLUS))
                        {
                                newvalue++;
                                if(newvalue == 6) newvalue = 0;
                        }
                        if(get_key_press (1 << KEY_MINUS))
                        {
                                if(newvalue == 0) newvalue = 6;
                                newvalue--;
                        }
                        if(get_key_press (1 << KEY_ENTER))
                        {
                                if(newvalue != value)
                                {
                                        *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4)) = newvalue;
                                        changes=1;
                                }
                                break;
                        }

                        if(get_key_long (1 << KEY_ESC))
                        {
                                newvalue = defaultvalue;
                        }

                       
                }while (!get_key_short (1 << KEY_ESC));
        }

        if(type == 5) // Angle
        {
                lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Back   \x0c"), 0);
                uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4));
                uint8_t defaultvalue   = pgm_read_byte(param_config+(8*param)+5);

                lcd_ecircle(102, 35, 16, 1);

                uint8_t newvalue = value;
                uint8_t oldvalue = newvalue;
                do
                {
               
                        if(oldvalue != newvalue) lcd_ecirc_line (102, 35, 15, oldvalue*15, 0);
                        oldvalue = newvalue;
                        lcd_ecirc_line (102, 35, 15, newvalue*15, 1);


                        if(get_key_press (1 << KEY_PLUS))
                        {
                                newvalue++;
                                if(newvalue == 24) newvalue = 0;
                        }
                        if(get_key_press (1 << KEY_MINUS))
                        {
                                if(newvalue == 0) newvalue = 24;
                                newvalue--;
                        }
                        if(get_key_press (1 << KEY_ENTER))
                        {
                                if(newvalue != value)
                                {
                                        *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*param)+4)) = newvalue;
                                        changes=1;
                                }
                                break;
                        }

                        if(get_key_long (1 << KEY_ESC))
                        {
                                newvalue = defaultvalue;
                        }

                       
                }while (!get_key_short (1 << KEY_ESC));
        }
       



//      while (!get_key_press (1 << KEY_ESC));
}      
       


       
uint8_t display_param_menu(uint8_t group)
{
        uint8_t items[20];
       
        uint8_t size=0;
        for(ii = 0;ii < PARAM_COUNT; ii++)
        {
                if(pgm_read_byte(param_config+(8*ii)) == (group-1))
                {
                        items[size] = ii;
                        size++;
                }
        }


//      offset2=0;
//      target_pos2=1;
//      pmode =0;
       
        uint8_t val =0 ;



        while(1)
        {
                lcd_cls ();
                lcd_printp_at (0, 0, PSTR("Choose Parameter:"), 0);
                lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Back   \x0c"), 0);
               
                ii = 0;
                if(offset2 > 0)
                {
                        lcd_printp_at(1,1, PSTR("\x1a"), 0);
                }
                for(ii = 0;ii < 6 ; ii++)
                {
                        if((ii+offset2) < size)
                        {
                                lcd_printp_at(3,ii+1,param_names[items[ii+offset2]][DisplayLanguage], 0);
                                // this reads the the offset in the struct from the pgm configuration table and then reads the value from the struct
                               
                                uint8_t type = pgm_read_byte(param_config+(8*items[ii+offset2])+1);

                                if(type == 0)
                                {
                                        write_ndigit_number_u (18, ii+1, *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4)), 3, 0);
                                }
                                if(type == 1)
                                {
                                        uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4));
                                       
                                        if(value < 248)
                                                write_ndigit_number_u (18, ii+1, value, 3, 0);
                                        if(value >= 248)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR(" P"), 0);
                                                write_ndigit_number_u (20, ii+1, 256-value, 1, 0);
                                        }
                                }
                                if(type == 2)
                                {

                                        uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4));
                                        uint8_t bitmap = pgm_read_byte(param_config+(8*items[ii+offset2])+3);
                                        if(value & bitmap)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR("  Y"), 0);
                                        }
                                        else
                                        {
                                                lcd_printp_at (18, ii+1, PSTR("  N"), 0);
                                        }
                                }
                                if(type == 3)
                                {
                                        uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4));
                                        if (value<=12)
//                                      write_ndigit_number_u (18, ii+1, *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4)), 3, 0);
                                        write_ndigit_number_u (18, ii+1, value, 3, 0);
                                else
                                    if (value<=(24))
                                         {
                                          lcd_printpns_at (18, ii+1, PSTR("S"), 0);
                                          write_ndigit_number_u (19, ii+1, (value-12), 2, 0);
                                         }
                           if (value==25)
                                   lcd_printpns_at (18, ii+1, PSTR("WPE"), 0);
                                }



                                if(type == 4)
                                {
                                        write_ndigit_number_u (18, ii+1, *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4)), 3, 0);
                                }
                                if(type == 5)
                                {
                                        write_ndigit_number_u (18, ii+1, (*(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4)))*15, 3, 0);
                                }
                                if(type == 6)
                                {
                                        uint8_t value = *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4));
                                        if(value == 0)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR("PPM"), 0);
                                        }
                                        else if(value == 1)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR(" SP"), 0);
                                        }
                                        else if(value == 2)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR("SPh"), 0);
                                        }
                                        else if(value == 3)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR("SPl"), 0);
                                        }
                                        else if(value == 4)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR("Jet"), 0);
                                        }
                                        else if(value == 5)
                                        {
                                                lcd_printp_at (18, ii+1, PSTR("ACT"), 0);
                                        }
                                        else
                                        {
                                                write_ndigit_number_u (18, ii+1, *(((uint8_t*)mk_param_struct) + pgm_read_byte(param_config+(8*items[ii+offset2])+4)), 3, 0);
                                        }
                                }
                                       
                        }
                        if((ii == 5)&&(ii+offset2 < (size-1)))
                        {
                                lcd_printp_at(1,6, PSTR("\x1b"), 0);
                        }
               
                }

/*              write_ndigit_number_u (0, 0,offset2, 3, 0);
                write_ndigit_number_u (4, 0,target_pos2, 3, 0);
                write_ndigit_number_u (7, 0,pmode, 3, 0);
                write_ndigit_number_u (10, 0,size, 3, 0);
                write_ndigit_number_u (14, 0,val, 3, 0);
                write_ndigit_number_u (17, 0,group, 3, 0);
*/

               
                if(pmode == 0)
                {
                        if(offset2 == 0)
                        {
                                if(size > 6)
                                {
                                        val = menu_choose2 (1, 5, target_pos2,0,1);
                                }
                                else
                                {
                                        val = menu_choose2 (1, size, target_pos2,0,0);
                                }

                        }
                        else
                        {
                                val = menu_choose2 (2, 5, target_pos2,1,1);
                        }
                }
                if(pmode == 1)
                {
                        if(offset2+7 > size)
                        {
                                val = menu_choose2 (2, 6, target_pos2,1,0);
                        }
                        else
                        {
                                val = menu_choose2 (2, 5, target_pos2,1,1);
                        }
                }
       
                if(val == 254)
                {
                        offset2++;
                        pmode = 1;
                        target_pos2 = 5;
                }else if(val == 253)
                {
                        offset2--;
                        pmode = 0;
                        target_pos2 = 2;
                }
                else
                {
                        break;
                }
        }
       
        if(val != 255)
        {
                target_pos2=val;       
                return items[val+offset2-1];
        }
        else
        {
                return val;
        }

}


uint8_t display_section_menu(void)
{
        uint8_t size = PAGES;
       
        uint8_t val =0;
       

        while(1)
        {
                lcd_cls ();
                lcd_printp_at (0, 0, PSTR("Choose Section:"), 0);
                lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Back   \x0c"), 0);
//              write_ndigit_number_u(0,0,dmode,2,0);
//              write_ndigit_number_u(2,0,offset,2,0);
//              write_ndigit_number_u(4,0,target_pos,2,0);
               
                ii = 0;
                if(offset > 0)
                {
                        lcd_printp_at(1,1, PSTR("\x1a"), 0);
                }
                for(ii = 0;ii < 6 ; ii++)
                {
                        if((ii+offset) < size)
                        {
                                lcd_printp_at(3,ii+1,param_pages[ii+offset][DisplayLanguage], 0);
                        }
                        if((ii == 5)&&(ii+offset < (size-1)))
                        {
                                lcd_printp_at(1,6, PSTR("\x1b"), 0);
                        }
               
                }


               
                if(dmode == 0)
                {
                        if(offset == 0)
                        {
                                if(size > 6)
                                {
                                        val = menu_choose2 (1, 5, target_pos,0,1);
                                }
                                else
                                {
                                        val = menu_choose2 (1, size, target_pos,0,0);
                                }
                        }
                        else
                        {
                                val = menu_choose2 (2, 5, target_pos,1,1);
                        }
                }
                if(dmode == 1)
                {
                        if(offset+7 > size)
                        {
                                val = menu_choose2 (2, 6, target_pos,1,0);
                        }
                        else
                        {
                                val = menu_choose2 (2, 5, target_pos,1,1);
                        }
                }
       
       
       
                if(val == 254)
                {
                        offset++;
                        dmode = 1;
                        target_pos = 5;
                }else if(val == 253)
                {
                        offset--;
                        dmode = 0;
                        target_pos = 2;
                }
                else
                {
                        break;
                }
        }

//      write_ndigit_number_u(0,0,val,2,0);
//       menu_choose2 (2, 5, target_pos,1,1);
        if(val != 255)
        {
                target_pos=val;
                return val+offset;
        }
        else
        {
                return val;
        }

}


uint8_t display_settings_menu (void)
{
    uint8_t status;

        lcd_cls ();

        uint8_t setting = 0;
        lcd_printp_at (0, 0, PSTR("Edit Setting:"), 0);
        lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Back   \x0c"), 0);
       

        for(setting=1;setting<6;setting++)
        {          
                status = load_setting(setting);
                if(status == 255) return 255;

        write_ndigit_number_u (3, setting, status, 1, 0);
        lcd_print_at (5,setting,(uint8_t*)mk_param_struct->Name, 0);
        }
        lcd_printp_at (3, 6, PSTR("Copy Setting"), 0);


        status = load_setting(0xff);
        if(status == 255) return 255;

        setting = menu_choose (1, 6, 1,status);

        return setting;
}



uint8_t load_setting(uint8_t setting)
{
        mode = 'Q';     // Settings
        uint8_t timeout = 50;
        rxd_buffer_locked = FALSE;
       
        while (!rxd_buffer_locked && timeout)
        {
                SendOutData ('q', ADDRESS_FC, 1, &setting, 1);
        //      _delay_ms(50);
                timer = 20;
            while (timer > 0);
            timeout--;
        }
       
        if (timeout != 0)
        {
                Decode64 ();
                setting = *pRxData;
            mk_param_struct = (mk_param_struct_t *) (pRxData + 1) ;
        }
        else
        {       // timeout occured
                lcd_printp_at (0, 2, PSTR("ERROR: no data"), 0);
               
                timer = 100;
                while (timer > 0);
                setting = 255;
        }

        return setting;
}

uint8_t write_setting(uint8_t setting)
{
        mode = 'S';     // Settings
        uint8_t timeout = 50;
        rxd_buffer_locked = FALSE;
       
        while (!rxd_buffer_locked && timeout)
        {
                SendOutData ('s', ADDRESS_FC, 2, &setting, 1, mk_param_struct, sizeof(mk_param_struct_t));
        //      _delay_ms(50);
                timer = 20;
            while (timer > 0);
            timeout--;
        }
       
        if (timeout != 0)
        {
                Decode64 ();
                setting = *pRxData;
        }
        else
        {       // timeout occured
                lcd_printp_at (0, 2, PSTR("ERROR: no data"), 0);
               
                timer = 100;
                while (timer > 0);
                setting = 255;
        }

        return setting;
}