0,0 → 1,687 |
/***************************************************************************** |
* 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; |
} |