Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 1192 → Rev 1193

/Transportables_Koptertool/tags/V3.x/parameter.c
0,0 → 1,1388
/*****************************************************************************
* 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;
}