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;
}