Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1465 - 1
 
2
/****************************************************************/
3
/*                                                                                                                                                                                                                                                      */
4
/*                                                                       NG-Video 5,8GHz                                                                                                                */
5
/*                                                                                                                                                                                                                                                      */
6
/*                                                      Copyright (C) 2011 - gebad                                                                                      */
7
/*                                                                                                                                                                                                                                                      */
8
/*      This code is distributed under the GNU Public License                           */
9
/*      which can be found at http://www.gnu.org/licenses/gpl.txt               */
10
/*                                                                                                                                                                                                                                                      */
11
/****************************************************************/
12
 
13
#include <avr/interrupt.h>
14
#include <avr/eeprom.h>
15
#include <util/delay.h>
16
#include <stdlib.h>
17
#include <string.h>
18
 
19
#include "config.h"
20
#include "ngvideo.h"
21
#include "keys.h"
22
#include "menue.h"
23
#include "servo.h"
24
#include "tracking.h"
25
#include "messages.c"
26
#include "dogm.h"
27
#include "tools.h"
28
#include "usart.h"
29
#include "ngvideo.h"
30
 
31
typedef uint8_t scr_menu_t[SCROLL_MAIN_MAX];
32
char pmenu[6] = {"0"};                  // Zuordnung Menü Programmgliederung zu hinterlegten Funktionen
33
uint8_t m_pkt;                                                  // um bei Rücksprung auf ursprünglichen Arrayeintrag(Menüpunkt), Scroll_Menu zeigen
34
uint8_t servo_nr;                                               // zwischen Servo 1 und 2 wird nur mit global servo_nr unterschieden
35
uint8_t chrxs;                                                  // zum Laden lcdSpecialChrLs oder lcdSpecialChrRs
36
uint8_t exit_while = 0;                 // unabhängige Task (z.B: Menu_MK_BatteryChangeNr() - Aufruf) kann Eingabe while-Schleife beenden, wenn 1
37
 
38
// Menügliederung im Flash belassen
39
const char cmdStr0[]                            PROGMEM = "0";
40
const char cmdStr01[]                           PROGMEM = "01";
41
const char cmdStr02[]                           PROGMEM = "02";
42
const char cmdStr03[]                           PROGMEM = "03";
43
const char cmdStr031[]                  PROGMEM = "031";
44
const char cmdStr032[]                  PROGMEM = "032";               
45
const char cmdStr033[]                  PROGMEM = "033";               
46
const char cmdStr04[]                           PROGMEM = "04";
47
const char cmdStr05[]                           PROGMEM = "05";
48
const char cmdStr051[]                  PROGMEM = "051";
49
const char cmdStr052[]                  PROGMEM = "052";        // zwischen Servo 1 und 2 wird danach 
50
const char cmdStr0521[]                 PROGMEM = "0521";       // mit global servo_nr unterschieden
51
const char cmdStr0522[]                 PROGMEM = "0522";              
52
const char cmdStr0523[]                 PROGMEM = "0523";
53
const char cmdStr0524[]                 PROGMEM = "0524";
54
const char cmdStr053[]                  PROGMEM = "053";
55
const char cmdStr0531[]                 PROGMEM = "0531";
56
const char cmdStr0532[]                 PROGMEM = "0532";
57
const char cmdStr0533[]                 PROGMEM = "0533";
58
const char cmdStr0534[]                 PROGMEM = "0534";
59
const char cmdStr06[]                           PROGMEM = "06";
60
const char cmdStr061[]                  PROGMEM = "061";
61
const char cmdStr062[]                  PROGMEM = "062";
62
const char cmdStr0621[]                 PROGMEM = "0621";
63
const char cmdStr0622[]                 PROGMEM = "0622";
64
const char cmdStr0623[]                 PROGMEM = "0623";
65
const char cmdStr0624[]                 PROGMEM = "0624";
66
const char cmdStr0625[]                 PROGMEM = "0625";
67
const char cmdStr063[]                  PROGMEM = "063";
68
const char cmdStr064[]                  PROGMEM = "064";
69
const char cmdStr07[]                           PROGMEM = "07";
70
const char cmdStr071[]                  PROGMEM = "071";
71
const char cmdStr072[]                  PROGMEM = "072";
72
const char cmdStr08[]                           PROGMEM = "08";
73
const char cmdStr081[]                  PROGMEM = "081";
74
const char cmdStr082[]                  PROGMEM = "082";
75
const char cmdStr083[]                  PROGMEM = "083";
76
const char cmdStr0831[]                 PROGMEM = "0831";
77
const char cmdStr0832[]                 PROGMEM = "0832";
78
const char cmdStr0833[]                 PROGMEM = "0833";
79
const char cmdStr0834[]                 PROGMEM = "0834";
80
const char cmdStr0835[]                 PROGMEM = "0835";
81
const char cmdStr09[]                           PROGMEM = "09";
82
const char cmdStr0d[]                           PROGMEM = "0:";         // wird nur bei Tracking RSSI oder GPS eingeblendet - SCROLL_MAIN_MAX wird geändert
83
const char cmdStr0e[]                           PROGMEM = "0;";         // wird nur bei Tracking GPS eingeblendet                                        - SCROLL_MAIN_MAX wird geändert
84
const char cmdStr0e1[]                  PROGMEM = "0;1";        // nach '9' (0x39) folgt ':' (0x3a) ';' (0x3b)
85
const char cmdStr0e2[]                  PROGMEM = "0;2";       
86
const char cmdStr0e3[]                  PROGMEM = "0;3";
87
const char cmdStr0e4[]                  PROGMEM = "0;4";
88
const char cmdStr0e5[]                  PROGMEM = RXTimeStr;
89
 
90
command_table_t command_table[] PROGMEM =                       // Befehls-Tabelle
91
{
92
        {cmdStr0,               Menu_Main},
93
        {cmdStr01,              Menu_AV_Source},
94
        {cmdStr02,              Menu_RX_Channel},
95
        {cmdStr03,              Menu_RSSI_Calibr},
96
        {cmdStr031,             Menu_RSSI_min},
97
        {cmdStr032,             Menu_RSSI_min_all},            
98
        {cmdStr033,             Menu_RSSI_max},        
99
        {cmdStr04,              Menu_Language},
100
        {cmdStr05,              Menu_Servo_Calibr},
101
        {cmdStr051,             Menu_Servo_Steps},
102
        {cmdStr052,             Menu_Servo1},                                           // zwischen Servo 1 und 2 wird danach 
103
        {cmdStr0521,    Menu_Servo1_rev},                               // mit global servo_nr unterschieden
104
        {cmdStr0522,    Menu_Servo1_left},             
105
        {cmdStr0523,    Menu_Servo1_right},
106
        {cmdStr0524,    Menu_Servo1_middle},
107
        {cmdStr053,             Menu_Servo2},
108
        {cmdStr0531,    Menu_Servo2_rev},
109
        {cmdStr0532,    Menu_Servo2_left},
110
        {cmdStr0533,    Menu_Servo2_right},
111
        {cmdStr0534,    Menu_Servo2_middle},
112
        {cmdStr06,              Menu_Servo_Test},
113
        {cmdStr061,             Menu_Test_PulseWidth},
114
        {cmdStr062,             Menu_Test_Continuous},
115
        {cmdStr0621,    Menu_Test_Start},
116
        {cmdStr0622,    Menu_Test_SingleStep},
117
        {cmdStr0623,    Menu_Test_Repeat},
118
        {cmdStr0624,    Menu_Test_Pause},
119
        {cmdStr0625,    Menu_Test_Pause_Step},
120
        {cmdStr063,             Menu_Test_ServoNr},
121
        {cmdStr064,             Menu_Test_Frame},
122
        {cmdStr07,              Menu_lcd},
123
        {cmdStr071,             Menu_lcd_Contrast},
124
        {cmdStr072,             Menu_lcd_Backgr_Light},
125
        {cmdStr08,              Menu_Battery},
126
        {cmdStr081,             Menu_Low_U_Setup},
127
        {cmdStr082,             Menu_U_Offset},
128
        {cmdStr083,             Menu_MK_Battery},
129
        {cmdStr0831,    Menu_MK_BatteryNr},
130
        {cmdStr0832,    Menu_MK_BatteryCapacity},
131
        {cmdStr0833,    Menu_MK_I_Offset},
132
        {cmdStr0834,    Menu_MK_I_Faktor},
133
        {cmdStr0835,    Menu_MK_W_Faktor},
134
        {cmdStr09,              Menu_Tracking_Ant},
135
        {cmdStr0d,              Menu_Tracking_Option},  // wird nur bei Tracking RSSI oder GPS eingeblendet - SCROLL_MAIN_MAX wird geändert
136
        {cmdStr0e,              Menu_GPS_Display},                      // wird nur bei Tracking GPS oder NMEA eingeblendet - SCROLL_MAIN_MAX wird geändert
137
        {cmdStr0e1,             Menu_GPS_Display_FLAG}, // nach '9' (0x39) folgt ':' (0x3a)
138
        {cmdStr0e2,             Menu_GPS_Display_FLAG},
139
        {cmdStr0e3,             Menu_GPS_Display_FLAG},
140
        {cmdStr0e4,             Menu_GPS_Display_FLAG},
141
        {cmdStr0e5,             Menu_GPS_Displ_RX_Time} // bei NMEA wird dieser Menüpunkt um 1 vorgezogen (anstelle GPS_MISC)
142
};
143
 
144
 
145
uint8_t Change_Value(uint16_t *val, uint16_t min_val, uint16_t max_val, uint8_t fl_pos, Displ_Fnct_t Displ_Fnct);
146
 
147
 
148
/**************************************************************/
149
/*                                                                                                                                                                                                                                              */
150
/*                                                                              Steuerung der Menüs                                                                                     */
151
/*                                                                                                                                                                                                                                              */
152
/**************************************************************/
153
 
154
/************************************************************************************/
155
/*      sucht nach übergebenen String in der Kommandotabelle und springt zum daneben            */
156
/*      stehenden Menü-Programm                                                                                                                                                                                                                                 */
157
/*      Parameter:                                                                                                                                                                                                                                                                                      */
158
/*      char *pmenu             :zu suchender String in Kommandotabelle                                                                                                         */
159
/*                                                                                                                                                                                                                                                                                                                                      */
160
/************************************************************************************/
161
void Jump_Menu(char *pmenu)
162
{ uint8_t i;
163
        void (*func)(void);
164
 
165
        if (pmenu[0] != '\0'){
166
                for (i=0; i < sizeof(command_table) / sizeof(command_table_t); i++) {
167
                        // Ist das der gesuchte String? 
168
                        if (!(strcmp_P(pmenu, (char*)pgm_read_word(&(command_table[i].menu_nr))))) {
169
                                func = (void(*)(void))pgm_read_word(&(command_table[i].fp));
170
                                func();
171
                                break;
172
                        }
173
                }
174
        }
175
}
176
 
177
/************************************************************************************/
178
/*                                                                                                                                                                                                                                                                                                                                      */
179
/*                                                                                      Abfrage Short- oder Long-Enter                                                                                                                  */
180
/*              verbleibt in Abfrage bis Enter betätigt; Rückgabe => Short-Enter True/False             */
181
/*                                                                                                                                                                                                                                                                                                                                      */
182
/************************************************************************************/
183
uint8_t Long_Enter(void)
184
{
185
        Tasks_invisible();      // Dadurch ist Doppelaufruf von MK-GPS möglich!!! Nur bei Menu_MK_BatteryChangeNr()
186
        // falls Akku leer ==> Menü verlassen und Anzeige __ACCU_LOW
187
        U_Messen_cmp(DISABLE_BTIMER);
188
        if (Get_Key_Long( 1<<SW_ENTER ) || bat_low) {
189
                pmenu[0] ='\0';         // direkt in das Hauptprogramm
190
                return 1;
191
        }
192
        else return 0;
193
}
194
 
195
uint8_t Short_Enter(void)
196
{ uint8_t ret;
197
 
198
        // bis Short- oder Long-Enter, auch Akku leer
199
        while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && !exit_while);
200
        lcdClear();
201
        if (pmenu[0] == '\0') Displ_Main_Disp(); else Beep(BEEPENTER); // bei ShortEnter Beep
202
        ret = (pmenu[0] != '\0') && !exit_while;
203
        exit_while = 0;
204
        return(ret); // ShortEnter bringt 1 zurück
205
}
206
 
207
/************************************************************************************/
208
/*                                                                                                                                                                                                                                                                                                                                      */
209
/*      Unterprogramm vom Scroll_Menu(...) stellt Menüpunkte dar                                                                                                */
210
/*      Parameter:                                                                                                                                                                                                                                                                                      */
211
/*      scr_menu_t scr_menu             : Array mit Strings der Menüanzeige                                                                                             */
212
/*      uint8_t         scr_idx                 : ausgewählter Menüpunkt                                                                                                                                        */
213
/*      uint8_t         scroll_max      : scrollen bis Wert                                                                                                                                                             */
214
/*                                                                                                                                                                                                                                                                                                                                      */
215
/************************************************************************************/
216
void Displ_Scroll_Menu(scr_menu_t scr_menu, uint8_t scr_idx)
217
{       uint8_t i;
218
 
219
        if (scr_idx > 0) scr_idx--; else scr_idx = scr_menu[0];
220
        for (i = 0; i < LCD_LINES; i++) {
221
                lcdGotoXY(2, i);                                // LCD Beginn x-Position, 2 Zeichen rechts eingerückt
222
                lcdPuts(Msg(scr_menu[scr_idx + 1]));
223
                lcdClearEOL();                                  // ab Stringende bis zum Zeilenende löschen; LCD löschen flackert sonst zu sehr
224
                if (scr_idx < scr_menu[0]) scr_idx++; else scr_idx = 0;
225
        }
226
}
227
 
228
/************************************************************************************/
229
/*                                                                                                                                                                                                                                                                                                                                      */
230
/*      Unterprogramm vom Scroll_Menu(...) und Change_Value(...)                                                                                                */
231
/*      bei Rücksprung auf ursprünglichen Menüpunkt zeigen                                                                                                                      */
232
/*      Parameter:                                                                                                                                                                                                                                                                                      */
233
/*      uint8_t l               : Strinlänge von pmenue                                                                                                                                                                                 */
234
/*                                                                                                                                                                                                                                                                                                                                      */
235
/************************************************************************************/
236
void return_m_pkt(uint8_t l)
237
{
238
        if (l > 1) {            // bei l=1 und Subtraktion 1 wird sowieso Displ_Main_Disp() ausgeführt und dort pmenu[0] = '\0' gesetzt
239
                l--;
240
                m_pkt = pmenu[l] - '0'; // um bei Rücksprung auf ursprünglichen Arrayeintrag(Menüpunkt) zeigen
241
                pmenu[l] ='\0';                                 // auf letztes Zeichen Stringende schreiben
242
        }
243
        else Displ_Main_Disp();
244
}
245
 
246
/************************************************************************************/
247
/*                                                                                                                                                                                                                                                                                                                                      */
248
/*      scrollt Menü über Mehrzeilige LCD                                                                                                                                                                                               */
249
/*                                                                                                                                                                                                                                                                                                                                      */
250
/*      Taste<Enter> lang springt in Hauptanzeige, kurz geht in den angewälten Menüpunkt*/
251
/*      Taste<+>                eine Zeile nach oben                                                                                                                                                                                            */
252
/*      Taste<->                eine Zeile nach unten                                                                                                                                                                                           */
253
/*      Parameter:                                                                                                                                                                                                                                                                                      */
254
/*      scr_menu_t scr_menu             : Array mit Strings der Menüanzeige                                                                                             */
255
/*      uint8_t         scroll_max      : scrollen bis Wert                                                                                                                                                             */
256
/*      uint8_t         scr_idx                 : Index für array von Displ_Scroll_Menu(...)                                                    */
257
/*                                                                                                                                                                                                                                                                                                                                      */
258
/************************************************************************************/
259
void Scroll_Menu(scr_menu_t scr_menu, uint8_t scr_idx)
260
{ uint8_t l;
261
 
262
        lcdClear();
263
        lcdGotoXY(0, 1);
264
        lcdPutc(MARKER_SELECT);         // '>>'
265
        Displ_Scroll_Menu(scr_menu, scr_idx);
266
        // bis Menueeingabe bestätigt oder zum vorherigen Menue
267
        while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && !exit_while)
268
        {
269
                // >> Menueauswahl nach oben
270
                if( Get_Key_Press( 1<<SW_PLUS ) || Get_Key_Rpt( 1<<SW_PLUS ))           {
271
                        if (scr_idx > 0) scr_idx--; else scr_idx = scr_menu[0];
272
                        Displ_Scroll_Menu(scr_menu, scr_idx);
273
                }      
274
                // >> Menueauswahl nach unten
275
                if( Get_Key_Press( 1<<SW_MINUS ) || Get_Key_Rpt( 1<<SW_MINUS )) {
276
                        if (scr_idx < scr_menu[0]) scr_idx++; else scr_idx = 0;
277
                        Displ_Scroll_Menu(scr_menu, scr_idx);
278
                }
279
        }
280
 
281
        lcdClear();
282
        if (exit_while)                                                                                 // wegen Aufruf Menu_MK_BatteryChangeNr() in Task
283
                m_pkt = scr_idx;                                                                        // nach Task Menu_MK_BatteryChangeNr() wieder zum ursprünlichen Anzeigepunkt
284
        else {
285
                l = strlen(pmenu);
286
                if ((scr_idx == 0) || (l == 0)) // long Enter wird durch l == 0 brücksichtigt
287
                        return_m_pkt(l);                                                                // um bei Rücksprung auf ursprünglichen Menüpunkt zu zeigen oder Displ_Main_Disp()
288
                else {
289
                        m_pkt = 1;                                                                                      // 0 wäre "zurück", so aber ins Untermenü immer erster Menüpunkt
290
                        pmenu[l] = scr_idx + '0';                               // nächsten MenueIndex anhängen 1 oder 2 oder ...
291
                        pmenu[++l] ='\0';
292
                        Beep(BEEPENTER);
293
                }
294
        }
295
        exit_while = 0;
296
}
297
 
298
/************************************************************************************/
299
/*                                                                                                                                                                                                                                                                                                                                      */
300
/*      Ändern der Werte mit Tasten +,- und Anzeige                                                                                                                                                     */
301
/*      z.B. für U-Offset, Batterie leer Eingabe ...                                                                                                                                            */
302
/*                                                                                                                                                                                                                                                                                                                                      */
303
/*      Parameter:                                                                                                                                                                                                                                                                                      */
304
/*      uint16_t                        val                                     :zu ändernter Wert                                                                                                                                      */
305
/*      uint16_t min_val, max_val               :min, max Grenze Wert ändern darf                                                                               */
306
/*      uint8_t posX, posY                                      :Darstellung Wert xPos, YPos auf LCD                                                            */
307
/*      Displ_Fnct_t    Displ_Fnct              :Index um variable Display Funktion aufzurufen                  */
308
/*      uint8_t                         cycle                                   :0 begrenzt Anzeige bei man_val, bzw. max_val                           */
309
/*                                                                                                                      :1 springt nach max_val auf min_val und umgedreht               */
310
/*      uint8_t                         vrepeat                         :beschleunigte Repeat-Funktion aus/ein                                                  */
311
/*      uint16_t Change_Value_plmi(...)         :Rückgabe geänderter Wert                                                                                       */
312
/*                                                                                                                                                                                                                                                                                                                                      */
313
/************************************************************************************/
314
uint16_t Change_Value_plmi(uint16_t val, uint16_t min_val, uint16_t max_val, uint8_t posX, uint8_t posY, \
315
                                                                                                         Displ_Fnct_t Displ_Fnct, uint8_t cycle, uint8_t vrepeat)
316
{
317
        // >> Menueauswahl nach oben
318
        if( Get_Key_Press( 1<<SW_PLUS ) || Get_Key_Rpt( 1<<SW_PLUS )){
319
                if (val < max_val) {
320
                        val++;
321
                        Key_Speedup_rpt(vrepeat);               // beschleunigte Repeat-Funktion
322
                }
323
                else
324
                        if (cycle) val = min_val;
325
                lcdGotoXY(posX, posY);                          // lcd Position Wert
326
                Displ_Fnct(val);                                                        // geänderten Wert darstellen, je nach Menüpunkt
327
        }
328
        // >> Menueauswahl nach unten
329
        if( Get_Key_Press( 1<<SW_MINUS ) || Get_Key_Rpt( 1<<SW_MINUS )) {
330
                if (val > min_val) {
331
                        val--;
332
                        Key_Speedup_rpt(vrepeat);               // beschleunigte Repeat-Funktion
333
                }
334
                else
335
                        if (cycle) val = max_val;
336
                lcdGotoXY(posX, posY);                          // noch einmal lcd Position, sonst zum Teil + und - gleichzeitig, Anzeige verrutscht
337
                Displ_Fnct(val);                                                        // geänderten Wert darstellen, je nach Menüpunkt
338
        }
339
        return(val);
340
}
341
 
342
/************************************************************************************/
343
/*                                                                                                                                                                                                                                                                                                                                      */
344
/*      Ändern der Werte mit Tasten +,- repetierend; (long)Entertaste und Anzeige                               */
345
/*                                                      z.B. für U-Offset, Batterie leer Eingabe ...                                                                                            */
346
/*                                                                                                                                                                                                                                                                                                                                      */
347
/*      Parameter:                                                                                                                                                                                                                                                                                      */
348
/*      uint16_t *val                                           :zu ändernter Wert                                                                                                                                              */
349
/*      uint16_t min_val, max_val       :min, max Grenze Wert ändern darf                                                                                       */
350
/*      uint8_t fl_pos                                          :Bit 7 beschleunigte Repeat-Funktion aus/ein                                    */
351
/*                                                                                                               Bit 6 zyklische Werteänderung aus/ein                                                          */
352
/*                                                                                                               Bit 4-5  z.Z. ohne Funktion                                                                                                    */
353
/*                                                                                                               Bit 0-3 Wert xPos auf LCD                                                                                                              */
354
/*      Displ_Fnct_t Displ_Fnct         :Index um variable Display Funktion aufzurufen                          */
355
/*      uint8_t Change_Value(...)       :Rückgabe geändert ergibt TRUE                                                                                          */
356
/*                                                                                                                                                                                                                                                                                                                                      */
357
/************************************************************************************/
358
// Bei Bedarf könnte einfach innerhalp fl_pos auch noch pos_y (Bit 4-5) übergeben werden
359
uint8_t Change_Value(uint16_t *val, uint16_t min_val, uint16_t max_val, uint8_t fl_pos, Displ_Fnct_t Displ_Fnct)
360
{ uint16_t tmp_val;
361
 
362
        tmp_val = *val;
363
        lcdGotoXY(fl_pos & POSXMASK, ZLE_VAL);          // Position Wert
364
        Displ_Fnct(tmp_val);                                                                                    // initiale Wertdarstellung, je nach Menüpunkt
365
        if (pmenu[0] =='\0') strcpy(pmenu, "0");        // sonst wird eventuell nachfolgende while-Schleife nicht ausgeführt
366
        // bis Menueeingabe bestätigt oder zum vorherigen Menue
367
        while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && !exit_while)
368
                *val = Change_Value_plmi(*val, min_val, max_val, fl_pos & POSXMASK, ZLE_VAL, Displ_Fnct, fl_pos & (1<<CYCLE), fl_pos & (1<<V_REPEAT));
369
 
370
        lcdClear();
371
        if (exit_while) {
372
                exit_while = 0;
373
                *val = tmp_val;
374
        }
375
        else
376
                return_m_pkt(strlen(pmenu));            // um bei Rücksprung auf ursprünglichen Menüpunkt zeigen oder Displ_Main_Disp()
377
        return(tmp_val != *val);
378
}
379
 
380
/**************************************************************/
381
/*                                                                                                                                                                                                                                              */
382
/*                                               LCD-Darstellungen der Menüs                                                                            */
383
/*      Zur Unterstützung der Auswahl werden einige Einstellungen */
384
/*      sofort ausgeführt. Z.B.: Kontrast, Servo-Endausschlag                   */
385
/*                                                                                                                                                                                                                                              */
386
/**************************************************************/
387
 
388
/************************************************************************************/
389
/*      zeigt Menü-     * Überschrift * auf erste Zeile mittig auf Display an                                                           */
390
/*      Parameter:                                                                                                                                                                                                                                                                                      */
391
/*      uint8_t message         : index (MSG_) der darzustellenden Zeichenkette                                                         */
392
/*                                                                                                                                                                                                                                                                                                                                      */
393
/************************************************************************************/
394
void Displ_Title(uint8_t message)
395
{ uint8_t l;
396
        uint8_t x = 0;
397
 
398
        l = strlen(Msg(message));
399
        if ( LCD_COLS > l) x = (LCD_COLS - l)/2;
400
        if (x > 1) {
401
                lcdGotoXY(x - 2, 0);
402
                lcdPuts("* ");
403
                lcdPuts(Msg(message));
404
                lcdPutc(' ');
405
        }
406
        else {
407
                lcdGotoXY(0, 0);
408
                lcdPutc('*');
409
                lcdGotoXY(x, 0);
410
                lcdPuts(Msg(message));
411
                lcdGotoXY(LCD_COLS - 1, 0);
412
        }
413
        lcdPutc('*');
414
}
415
 
416
/************************************************************************************/
417
/*                              zeigt bei Programmstart Firmware- und DOGM-Version auf Display an                                       */
418
/*                                                                                                                                                                                                                                                                                                                                      */
419
/************************************************************************************/
420
void Displ_Version(void)
421
{
422
        lcdGotoXY(0, 0);
423
        lcdPuts(Msg(MSG_VERSION1));
424
        if (dogm_vers == DOGM3V)
425
                lcdPuts(Msg(MSG_UHW33V));
426
        else
427
                lcdPuts(Msg(MSG_UHW5V));
428
        lcdPuts(Msg(MSG_VERSION2));
429
        delay_ms100x(30);
430
        lcdClear();
431
}
432
 
433
/************************************************************************************/
434
/*      zeigt auszuwählenden/-gewählten Kanal und Frequenz auf Display an                                                               */
435
/*      Parameter:                                                                                                                                                                                                                                                                                      */
436
/*      uint16_t k                                              :Index anzuzeigender Wert = Kanal + 0x30 als Char,                              */
437
/*                                                                                               uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                   */
438
/*                                                                                                                                                                                                                                                                                                                                      */
439
/************************************************************************************/
440
void Displ_Channels(uint16_t k)
441
{ char *channels[] = {"5740", "5760","5780", "5800", "5820", "5840", "5860"};
442
 
443
        lcdPutc(k+0x30);
444
        lcdPuts(": ");
445
        lcdPuts(channels[k-1]);
446
        lcdPuts("MHz");
447
}
448
 
449
/************************************************************************************/
450
/*      zeigt Source AV1, AV2 oder Diversity zur Auswahl auf Display an                                                                 */
451
/*      Parameter:                                                                                                                                                                                                                                                                                      */
452
/*      uint16_t q                                              :Index anzuzeigender Wert,                                                                                                                              */
453
/*                                                                                               unint16_t wegen Vereinheitlichung f. Funktionsaufrauf          */
454
/*                                                                                                                                                                                                                                                                                                                                      */
455
/************************************************************************************/
456
void Displ_AV_Source(uint16_t q)
457
{ uint8_t av_src_table[] = {MSG_AV1, MSG_AV2, MSG_DIVERSITY};
458
 
459
        lcdPutStrMid(Msg(av_src_table[q]), ZLE_VAL);
460
}
461
 
462
/************************************************************************************/
463
/*      zeigt Tracking-Varianten zur Auswahl auf Display an                                                                                                                     */
464
/*      Parameter:                                                                                                                                                                                                                                                                                      */
465
/*      uint16_t q                                              :Index anzuzeigender Wert,                                                                                                                              */
466
/*                                                                                               uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                   */
467
/*                                                                                                                                                                                                                                                                                                                                      */
468
/************************************************************************************/
469
void Displ_sel_Tracking(uint16_t q)
470
{ uint8_t track_sel_table[] = {MSG_OFF, MSG_TRACK_RSSI, MSG_TRACK_GPS, MSG_TRACK_MKCOCKPIT, MSG_TRACK_NMEA};
471
 
472
        lcdPutStrMid(Msg(track_sel_table[q]), ZLE_VAL);
473
}
474
 
475
/************************************************************************************/
476
/*      zeigt Senden der OSD-Daten Anforderung zur Auswahl auf Display an                                                               */
477
/*      Parameter:                                                                                                                                                                                                                                                                                      */
478
/*      uint16_t q                                              :Index anzuzeigender Wert,                                                                                                                              */
479
/*                                                                                               uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                   */
480
/*                                                                                                                                                                                                                                                                                                                                      */
481
/************************************************************************************/
482
void Displ_track_TX(uint16_t q)
483
{ uint8_t track_TX_table[] = {MSG_OFF, MSG_TRACK_TX_ON};
484
 
485
        lcdPutStrMid(Msg(track_TX_table[q]), ZLE_VAL);
486
}
487
 
488
/************************************************************************************/
489
/*      zeigt einen max. 3-stelligen Integerwert auf Display an                                                                                                 */
490
/*      Parameter:                                                                                                                                                                                                                                                                                      */
491
/*      uint16_t val                            :anzuzeigender Wert,                                                                                                                                                            */
492
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
493
/*                                                                                                                                                                                                                                                                                                                                      */
494
/************************************************************************************/
495
void Displ_Format_Int(uint16_t val)
496
{
497
        lcdPuts(my_itoa(val, 3, 0, 0));
498
}
499
 
500
/************************************************************************************/
501
/*      zeigt den Kontrastwert auf Display an mit sofortiger Änderung                                                                           */
502
/*      Parameter:                                                                                                                                                                                                                                                                                      */
503
/*      uint16_t val                            :anzuzeigender Wert,                                                                                                                                                            */
504
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
505
/*                                                                                                                                                                                                                                                                                                                                      */
506
/************************************************************************************/
507
void Displ_Set_Contrast(uint16_t val)
508
{
509
        Displ_Format_Int(val);
510
        lcdContrast(dogm_vers, val);
511
}
512
 
513
/************************************************************************************/
514
/*      zeigt die Zeit zur Abschaltung der LCD-Hintergrundbeleuchtung an                                                                */
515
/*      Parameter:                                                                                                                                                                                                                                                                                      */
516
/*      uint16_t val                            :anzuzeigender Wert,                                                                                                                                                            */
517
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
518
/*                                                                                                                                                                                                                                                                                                                                      */
519
/************************************************************************************/
520
void Displ_Backgr_Light(uint16_t val)
521
{ char str[5];
522
 
523
        switch(val) {
524
                case BACKGR_LIGHT_MIN : lcdPuts(Msg(MSG_LIGHT_OFF));
525
                                                                                                                break;
526
                case BACKGR_LIGHT_MAX : lcdPuts(Msg(MSG_LIGHT_ON));
527
                                                                                                                break;
528
                default :                                                       itoa (val * 10, str, 10);
529
                                                                                                                lcdPutc(' ');
530
                                                                                                                lcdPuts(str);
531
                                                                                                                lcdPuts(Msg(MSG_SEC));
532
        }
533
        lcdClearEOL();
534
}
535
 
536
/************************************************************************************/
537
/*      zeigt ein oder aus zur Auswahl auf Display an                                                                                                                                           */
538
/*      Parameter:                                                                                                                                                                                                                                                                                      */
539
/*      uint16_t val                            :0 = aus oder 1 = ein,                                                                                                                                                  */
540
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
541
/*                                                                                                                                                                                                                                                                                                                                      */
542
/************************************************************************************/
543
void Displ_Off_On(uint16_t val)
544
{
545
        if (val == 0) lcdPuts(Msg(MSG_OFF)); else lcdPuts(Msg(MSG_ON));
546
}
547
 
548
/************************************************************************************/
549
/*      zeigt Servoschritte zur Auswahl auf Display an                                                                                                                                  */
550
/*      Parameter:                                                                                                                                                                                                                                                                                      */
551
/*      uint16_t val                            :0 = 255 oder 1 = 1023,                                                                                                                                                 */
552
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
553
/*                                                                                                                                                                                                                                                                                                                                      */
554
/************************************************************************************/
555
void Displ_Servo_Steps(uint16_t val)
556
{ uint8_t servo_step_table[] =          {MSG_STEPS_255, MSG_STEPS_1023};
557
 
558
        lcdPutStrMid(Msg(servo_step_table[val]), ZLE_VAL);
559
}
560
 
561
/************************************************************************************/
562
/*      zeigt Servo-Anschlagposition links auf Display an                                                                                                                       */
563
/*      mit sofortiger Wirkung auf Servo                                                                                                                                                                                                */
564
/*      Parameter:                                                                                                                                                                                                                                                                                      */
565
/*      uint16_t val                            :anzuzeigender Wert,                                                                                                                                                            */
566
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
567
/*                                                                                                                                                                                                                                                                                                                                      */
568
/************************************************************************************/
569
void Displ_Servo_Min(uint16_t val)
570
{ uint16_t steps = 0;
571
 
572
        Displ_Format_Int(val);
573
        servoSet_min(servo_nr, val);                                                                    // Wert setzen damit nachfolgend die
574
        if (servo[servo_nr].rev) steps = ServoSteps();
575
        servoSetPosition(servo_nr, steps);                                              // Änderung direkt am Servo sichtbar ist
576
}
577
 
578
/************************************************************************************/
579
/*      zeigt Servo-Anschlagposition rechts auf Display an                                                                                                                      */
580
/*      mit sofortiger Wirkung auf Servo                                                                                                                                                                                                */
581
/*      Parameter:                                                                                                                                                                                                                                                                                      */
582
/*      uint16_t val                            :anzuzeigender Wert,                                                                                                                                                            */
583
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
584
/*                                                                                                                                                                                                                                                                                                                                      */
585
/************************************************************************************/
586
void Displ_Servo_Max(uint16_t val)
587
{ uint16_t steps = ServoSteps();
588
 
589
        Displ_Format_Int(val);
590
        servoSet_max(servo_nr, val);                                                                    // Wert setzen damit nachfolgend die
591
        if (servo[servo_nr].rev) steps = 0;
592
        servoSetPosition(servo_nr, steps);                                              // Änderung direkt am Servo sichtbar ist
593
}
594
 
595
/************************************************************************************/
596
/*      zeigt Servo-Anschlagposition Mitte auf Display an                                                                                                                               */
597
/*      mit sofortiger Wirkung auf Servo                                                                                                                                                                                                */
598
/*      Parameter:                                                                                                                                                                                                                                                                                      */
599
/*      uint16_t val                            :anzuzeigender Wert,                                                                                                                                                            */
600
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
601
/*                                                                                                                                                                                                                                                                                                                                      */
602
/************************************************************************************/
603
void Displ_Servo_Mid(uint16_t val)
604
{ int16_t mid_val;
605
 
606
        mid_val = val - ServoSteps()/2;
607
        lcdPuts(my_itoa(mid_val, 4, 0, 0));
608
        servoSet_mid(servo_nr, val);                                                                    // Wert setzen damit nachfolgend die
609
        servoSetPosition(servo_nr, ServoSteps()/2);     // Änderung direkt am Servo sichtbar ist
610
}
611
 
612
/************************************************************************************/
613
/*      zeigt zu testende Servonummer zur Auswahl auf Display an                                                                                                */
614
/*      Parameter:                                                                                                                                                                                                                                                                                      */
615
/*      uint16_t val                            :0 = Servo 1 oder 1 = Servo 2,                                                                                                                  */
616
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
617
/*                                                                                                                                                                                                                                                                                                                                      */
618
/************************************************************************************/
619
void Displ_ServoNr(uint16_t val)
620
{
621
        if (val == 0) lcdPuts(Msg(MSG_SERVO1)); else lcdPuts(Msg(MSG_SERVO2));
622
}
623
 
624
 
625
/************************************************************************************/
626
/*      zeigt Servoausschlag in ms, in % und als Bargraph auf Display an                                                                */
627
/*      Parameter:                                                                                                                                                                                                                                                                                      */
628
/*      int16_t PosProzent      : aktuell eingestellte Position vom 0-Punkt (Mitte) aus                 */
629
/*      int16_t range                           : maximaler absoluter Ausschlag vom 0-Punkt aus                                                 */
630
/*                                                                                                                                                                                                                                                                                                                                      */
631
/************************************************************************************/
632
// leerer Rahmen für Bar
633
char* empty_Bar(void)
634
{ static char tmp_empty[LCD_COLS];
635
        uint8_t i;
636
 
637
        tmp_empty[0] = '\0';                    // '['
638
        for (i = 1; i < 15; i++)
639
                tmp_empty[i] = '\x07';
640
        tmp_empty[i] = '\x06';          // ']'
641
        return(tmp_empty);
642
}
643
 
644
void draw_bar(int16_t PosProzent, int16_t range, uint8_t zle)
645
{ int8_t i, sp_quad, sp_ch;
646
        int8_t lz = 8;
647
        char* bar;
648
 
649
        bar = empty_Bar();                                                                                              // leerer Rahmen für Bar
650
        sp_quad = abs(PosProzent) * 7 / range;          // Anzahl der vollen Kästchen
651
 
652
        sp_ch = (abs(PosProzent) -(range * sp_quad / 7)) * 35 / range; // Unterteilung Kästchen in 6 senkrechte Striche
653
        if (sp_ch > 4) sp_ch = 4; // bei 28 (7*4) wäre keine Korrektur erforderlich aber so kontinuierlicher
654
        if (PosProzent < 0){
655
                lz -=   sp_quad;                                                                                                        // Position für volles Kästchen bei Linksausschlag
656
                if (sp_ch > 0) bar[lz-1] = sp_ch;                       // vor erstes volles Kästchen Kästchenunterteilung schreiben
657
        }                                                                                                                                                                       // Unterteilung Kästchen der 4 senkrechte Striche nach Bar (0 und 5 entfallen)
658
        else
659
                if (sp_ch > 0) bar[lz+sp_quad] = sp_ch;// nach lezten vollen Kästchen Kästchenunterteilung schreiben
660
 
661
        for (i = 0; i < sp_quad; i++)
662
                bar[i+lz] = '\x05';                                                                                     // volle Kästchen schreiben
663
        lcdGotoXY(0,zle);
664
        for (uint8_t i = 0; i < LCD_COLS; i++) lcdPutc(bar[i]);// kpl. Bar zum Display
665
}
666
 
667
uint16_t calc_range(int16_t PosProzent, int16_t min, int16_t max, int16_t mid)
668
{ uint16_t range;
669
 
670
        if (PosProzent < 0) {
671
                range = mid - min;
672
                if (chrxs == CHRRS) {           // falls Richtung geändert, anderen Zeichensatz laden
673
                        chrxs = CHRLS;
674
                        lcdWriteCGRAM_Array(lcdSpecialChrLs, 5);// LCD-Char mit Rahmensymbole vom Graph
675
                }
676
        }
677
        else {
678
                range = max - mid;
679
                if (chrxs == CHRLS) {           // falls Richtung geändert, anderen Zeichensatz laden
680
                        lcdWriteCGRAM_Array(lcdSpecialChrRs, 5);// LCD-Char mit Rahmensymbole vom Graph
681
                        chrxs = CHRRS;
682
                }
683
        }
684
        return(range);
685
}
686
 
687
void Displ_PulseWidth(uint16_t val)
688
{ int16_t PosProzent, range;
689
        uint16_t Pos_us;
690
        char me[3] = {"ms"};
691
 
692
        servoSetPositionRaw(servo_nr, val);
693
 
694
        PosProzent = val - steps_pw[sIdxSteps].mid;
695
        range = calc_range(PosProzent, steps_pw[sIdxSteps].min, steps_pw[sIdxSteps].max, steps_pw[sIdxSteps].mid);
696
        draw_bar(PosProzent, range, 2); // auf 3. Display-Zeile
697
        PosProzent = (int32_t)1000 * PosProzent / range;
698
        lcdGotoXY(1, 1);
699
        Pos_us = pw_us(val);    // Zeit in µs bei x Servoschritte
700
        if (Pos_us < 1000) {
701
                me[0] = 'u';                            // soll 'µ' => programmierbarer Zeichensatz zu klein
702
                lcdPuts("  ");
703
                Displ_Format_Int(Pos_us);
704
        }
705
        else {
706
                lcdPuts(my_itoa(Pos_us, 5, 3, 3));
707
        }
708
        lcdPuts(me);
709
        lcdGotoXY(8, 1);
710
        lcdPuts(my_itoa(PosProzent, 6, 1, 1));
711
        lcdPutc('%');
712
}
713
 
714
/************************************************************************************/
715
/*      zeigt Pausenlänge der Links-, Mittel- und Rechtsposition auf Display an                                 */
716
/*      Parameter:                                                                                                                                                                                                                                                                                      */
717
/*      uint16_t val            : Zeit in 1ms * 100                                                                                                                                                                                     */
718
/*                                                                                                                                                                                                                                                                                                                                      */
719
/************************************************************************************/
720
void Displ_Pause(uint16_t val)
721
{
722
        if (val > 9) {
723
                lcdPuts(my_itoa(val, 3, 1, 1));
724
                lcdPuts("s ");
725
        }
726
        else {
727
                Displ_Format_Int(val * 100);
728
                lcdPuts("ms");
729
        }
730
}
731
 
732
/************************************************************************************/
733
/*      zeigt aus oder Integerwert auf Display an                                                                                                                                                               */
734
/*      Parameter:                                                                                                                                                                                                                                                                                      */
735
/*      uint16_t val            : val = 0 ==> aus, sont Integerwert                                                                                                                     */
736
/*                                                                                                                                                                                                                                                                                                                                      */
737
/************************************************************************************/
738
void Displ_Off_Format_Int(uint16_t val)
739
{
740
        if (val == 0)
741
                lcdPutStrMid(Msg(MSG_OFF), ZLE_VAL);
742
        else {
743
                lcdGotoXY(5,ZLE_VAL);
744
                Displ_Format_Int(val);
745
                lcdPutc(' ');
746
        }
747
}
748
 
749
/************************************************************************************/
750
/*      zeigt aus oder Pausenzeit zwischen 2 Servoschritte auf Display an                                                               */
751
/*      Parameter:                                                                                                                                                                                                                                                                                      */
752
/*      uint16_t val            : val = 0 ==> aus, sont Integerwert                                                                                                                     */
753
/*                                                                                                                                                                                                                                                                                                                                      */
754
/************************************************************************************/
755
void Displ_Pause_Step(uint16_t val)
756
{
757
        Displ_Off_Format_Int(val);
758
        if (val > 0) {
759
                lcdGotoXY(8,ZLE_VAL);
760
                lcdPuts("ms");
761
        }
762
}
763
/************************************************************************************/
764
/*      zeigt Baudrate für COM bei MKCockpit zur Auswahl auf Display an                                                                 */
765
/*      Parameter:                                                                                                                                                                                                                                                                                      */
766
/*      uint16_t q                                              :Index anzuzeigender Wert,                                                                                                                              */
767
/*                                                                                               uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                   */
768
/*                                                                                                                                                                                                                                                                                                                                      */
769
/************************************************************************************/
770
void Displ_Baudrate(uint16_t q)
771
{ char str[7];
772
 
773
        ltoa(getBaud(q), str, 10);
774
        lcdPutStrMid(str, ZLE_VAL);
775
}
776
 
777
/************************************************************************************/
778
/*      zeigt aktive Empfängerzeiten auf Display an                                                                                                                                                     */
779
/*                                                                                                                                                                                                                                                                                                                                      */
780
/************************************************************************************/
781
void Displ_RX_Time(void)
782
{
783
        lcdGotoXY(6, 1);
784
        Displ_TimeHMS(rxcount0);
785
        lcdGotoXY(6, 2);
786
        Displ_TimeHMS(rxcount1);
787
}
788
 
789
/************************************************************************************/
790
/*      zeigt eingestellte Akku-Kapazität des MK auf Display an                                                                                                 */
791
/*      Parameter:                                                                                                                                                                                                                                                                                      */
792
/*      uint16_t val                            :Akku-Kapazität in 50mAh Schritte                                                                                                               */
793
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
794
/*                                                                                                                                                                                                                                                                                                                                      */
795
/************************************************************************************/
796
void Displ_MK_Capacity(uint16_t val)
797
{
798
        lcdPuts(my_itoa(val * 50, 4, 0, 0));
799
        lcdPuts("mAh");
800
}
801
 
802
/************************************************************************************/
803
/*      zeigt Offset (Korrektur Ruhestrom) für Strom des MK auf Display an                                                      */
804
/*      Parameter:                                                                                                                                                                                                                                                                                      */
805
/*      uint16_t val                            :Korrekturfaktor                                                                                                                                                                                */
806
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
807
/*                                                                                                                                                                                                                                                                                                                                      */
808
/************************************************************************************/
809
void Displ_I_Offset(uint16_t val)
810
{
811
        lcdPuts(my_itoa((int8_t)val - MK_I_OFFSET_5,4,1,1));
812
        lcdPutc('A');
813
}
814
 
815
 
816
/************************************************************************************/
817
/*      zeigt Korrekturfaktor für Strom und Arbeit des MK auf Display an                                                                */
818
/*      Parameter:                                                                                                                                                                                                                                                                                      */
819
/*      uint16_t val                            :Korrekturfaktor                                                                                                                                                                                */
820
/*                                                                                       uint16_t wegen Vereinheitlichung f. Funktionsaufrauf                           */
821
/*                                                                                                                                                                                                                                                                                                                                      */
822
/************************************************************************************/
823
void Displ_Faktor_2Nk(uint16_t val)
824
{
825
        lcdPuts(my_itoa(val,4,2,2));
826
}
827
 
828
/************************************************************************************/
829
/*      zeigt den Marker in Hauptdarstellung auf selektierten RX an                                                                                     */
830
/*      d Diversity, << fester RX                                                                                                                                                                                                                               */
831
/*      Parameter:                                                                                                                                                                                                                                                                                      */
832
/*      uint8_t p                               :x-Position des Markers                                                                                                                                                         */
833
/*      uint8_t marker          :Markerzeichen z.B.:'' oder 'd' oder 's'                                                                                        */
834
/*                                                                                                                                                                                                                                                                                                                                      */
835
/************************************************************************************/
836
void Displ_AV_Mark(uint8_t p, char marker)
837
{
838
        if (p < 2) {
839
                lcdGotoXY(15,2 - p);            // da p immer neue Position 0 oder 1
840
                lcdPutc(' ');                                           // bisherigen AVx-, Diversity-Marker löschen
841
                lcdGotoXY(15,p + 1);            // an neuer Positon
842
                lcdPutc(marker);                                // übergebenes Markerzeichen darstellen
843
        }
844
        else { // falls beim Einschalten Diversity auf aktiv, keine Marker
845
                lcdGotoXY(15,1);
846
                lcdPutc(' ');
847
                lcdGotoXY(15,2);
848
                lcdPutc(' ');
849
        }
850
}
851
 
852
/************************************************************************************/
853
/*                                                              Hauptanzeige unter Berücksichtigung von VBat                                                                                    */
854
/*                                                                                                                                                                                                                                                                                                                                      */
855
/************************************************************************************/
856
void SetAndDispl_AV_Mark(void)
857
{ char marker;
858
 
859
        marker = av_source < DIVERSITY? MARKER_AV : MARKER_RSSI;                // wird nur bei gesetzten Diversity überschrieben 
860
        Displ_AV_Mark(sw_avx, marker);
861
}
862
 
863
void Displ_Main_Disp(void)
864
{
865
        pmenu[0] ='\0';                                         // bei Direktansprung z.B. von Menu_RSSI_min() erforderlich
866
        lcdClear();
867
        if (!bat_low) {
868
                lcdClear();
869
                Displ_Channels(channel);
870
                lcdGotoXY(LCD_COLS - 1, 0);
871
                lcdPuts("V\n1\n2");
872
                SetAndDispl_AV_Mark();
873
                Displ_VBat();                                   // muss zuletzt stehen
874
        }
875
        else {
876
                lcdPutStrMid(Msg(MSG_ACCU_LOW), 0);
877
        }
878
}
879
 
880
 
881
 
882
/**************************************************************/
883
/*                                                                                                                                                                                                                                              */
884
/*                                                                                                      Menüs                                                                                                                   */
885
/*                                                                                                                                                                                                                                              */
886
/**************************************************************/
887
 
888
/**************************/
889
/*                                                                                              */
890
/*                               Haupmenü                               */
891
/*                                                                                              */
892
/**************************/
893
void Menu_Main(void)
894
{       scr_menu_t scr_main_menu = {SCROLL_MAIN_MAX-4, MSG_RETURN, MSG_AV_SOURCE, MSG_RX_CHANNEL, MSG_RSSI_CALIBR, MSG_LANGUAGE, \
895
                                                                                                                        MSG_SERVO_CALIBR, MSG_TEST_SERVO, MSG_LCD , MSG_BATTERY, MSG_TRACKING, 0, MSG_GPS_DISPLAY};
896
 
897
        switch(tracking) {
898
                case TRACKING_RSSI:                      scr_main_menu[11] = MSG_TRACK_SERVO_HYTERESE;
899
                                                                                                                 scr_main_menu[0]++;            // SCROLL_MAIN_MAX erhöhen
900
                                                                                                                 break;
901
                case TRACKING_GPS:                       scr_main_menu[11] = MSG_TRACK_TX_OSD_DATA;
902
                                                                                                                 scr_main_menu[0] += 2; // SCROLL_MAIN_MAX erhöhen, zusätzliche Anzeige zu GPS MSG_GPS_DISPLAY
903
                                                                                                                 break;
904
                case TRACKING_NMEA:                      scr_main_menu[0]++;            // SCROLL_MAIN_MAX erhöhen, zusätzliche Anzeige zu GPS 
905
                case TRACKING_MKCOCKPIT: scr_main_menu[0]++;            // SCROLL_MAIN_MAX erhöhen
906
                                                                                                                 scr_main_menu[11] = MSG_COM;
907
                                                                                                                 break;
908
        }
909
 
910
        strcpy(pmenu, "0");
911
        Scroll_Menu(scr_main_menu, m_pkt);      // pmenu global
912
        Jump_Menu(pmenu); //gewähltes Untermenü anspringen oder nur Return
913
}
914
 
915
/**************************/
916
/*                                                                                              */
917
/*                              AV-Quelle                               */
918
/*                                                                                              */
919
/**************************/
920
void Menu_AV_Source(void)
921
{ uint16_t tmp_val;
922
 
923
        Displ_Title(MSG_AV_SOURCE);
924
        tmp_val = av_source;
925
        if (Change_Value(&tmp_val, AV_SOURCE_MIN, AV_SOURCE_MAX, 3, Displ_AV_Source)) { // pmenu global
926
                cli();
927
                av_source = tmp_val;
928
                eeprom_write_byte(&ep_av_source, av_source);
929
                Double_Beep(DBEEPWR, DBEEPWRP);
930
                sw_avx = Set_AV_Source(av_source);
931
                if (pmenu[0] == '\0')                           // sonst ist AV-Source marker bei long Enter im Hauptdisplay nicht aktuallisiert
932
                        SetAndDispl_AV_Mark();
933
                sei();
934
        }
935
        Jump_Menu(pmenu);
936
}
937
 
938
/**************************/
939
/*                                                                                              */
940
/*                              Kanal                                           */
941
/*                                                                                              */
942
/**************************/
943
void Menu_RX_Channel(void)
944
{ uint16_t tmp_val;
945
 
946
        Displ_Title(MSG_RX_CHANNEL);
947
        tmp_val = channel;
948
        if (Change_Value(&tmp_val, CHANNEL_MIN, CHANNEL_MAX, 3, Displ_Channels) || (tmp_val != ch_stored)) {    // pmenu global
949
                channel = tmp_val;
950
                ch_stored = tmp_val;
951
                eeprom_write_byte(&ep_channel, channel);
952
                Double_Beep(DBEEPWR, DBEEPWRP);
953
                Set_Channel(channel);
954
                if (pmenu[0] == '\0') {                 // sonst ist channel im Hauptdisplay nicht aktuallisiert
955
                        lcdGotoXY(0,0);
956
                        Displ_Channels(channel);                // da erst jetzt die Variable für main_display geändert ist!
957
                }
958
        }
959
        Jump_Menu(pmenu);
960
}
961
 
962
/**************************/
963
/*                                                                                              */
964
/*                              RSSI                                            */
965
/*                                                                                              */
966
/**************************/
967
void Menu_RSSI_Calibr(void)
968
{ uint8_t scr_sub_menu[SCROLL_MAX_5]    = {SCROLL_MAX_5-2, MSG_RETURN, MSG_RSSI_MIN, MSG_RSSI_MIN_ALL, MSG_RSSI_MAX};
969
 
970
        Scroll_Menu(scr_sub_menu, m_pkt);       // pmenu global
971
        Jump_Menu(pmenu);
972
}
973
 
974
void AdviceTX(uint8_t msg)
975
{ char str[20];
976
 
977
        strcpy(str, Msg(MSG_TX));
978
        strcat(str, Msg(msg));
979
        lcdPutStrMid(str, 1);
980
        lcdPutStrMid(Msg(MSG_CONTINUE), 2);
981
}
982
 
983
void Menu_RSSI_min(void)
984
{
985
        Displ_Title(MSG_RSSI_MIN);
986
        AdviceTX(MSG_TX_OFF);
987
        if (Short_Enter()) {                                                    // pmenu global
988
                RSSI_Min_Calibrate(0, bar_udbm);
989
                Displ_Main_Disp();                                                      // da erst jetzt die Variable für main_display geändert ist!
990
        }
991
        else
992
                Jump_Menu(pmenu);
993
}
994
 
995
void Displ_RSSImin_allError(char *str_ch)
996
{ char str[LCD_COLS + 1];
997
 
998
        lcdClear();
999
        strcpy(str, Msg(MSG_CALIB));
1000
        strcat(str, "-");
1001
        strcat(str, Msg(MSG_ERROR));
1002
        lcdPutStrMid(str,0);
1003
        lcdPutStrMid(Msg(MSG_RX_CHANNEL),1);
1004
        lcdPutStrMid(str_ch, 2);
1005
        delay_ms100x(30);
1006
}
1007
 
1008
void Menu_RSSI_min_all(void)
1009
{ char not_cal[15];
1010
        uint8_t f = 0;
1011
 
1012
        Displ_Title(MSG_RSSI_MIN_ALL);
1013
        AdviceTX(MSG_TX_OFF);
1014
        if (Short_Enter()) {                                            // pmenu global
1015
                for ( uint8_t i = 1; i <= CHANNEL_MAX; i++) {
1016
                        Set_Channel(i);
1017
                        if (!RSSI_Min_Calibrate(i, bar_udbm)) {
1018
                                not_cal[f++] = i + 0x30;
1019
                                not_cal[f++] = ',';
1020
                        }
1021
                }
1022
                Set_Channel(channel);
1023
                Double_Beep(DBEEPWR, DBEEPWRP);
1024
                if (f > 0) {                                                            // Konnten einige Kanäle nicht auf RSSI-Min kalibiert werden?
1025
                        not_cal[--f] = '\0';                    // letzes Komma durch Stringende ersetzen
1026
                        Displ_RSSImin_allError(not_cal);
1027
                }
1028
                Displ_Main_Disp();
1029
        }
1030
        else
1031
                Jump_Menu(pmenu);
1032
}
1033
 
1034
void Menu_RSSI_max(void)
1035
{
1036
        Displ_Title(MSG_RSSI_MAX);
1037
        AdviceTX(MSG_TX_ON);
1038
        if (Short_Enter()) {                                    // pmenu global
1039
                RSSI_Max_Calibrate(bar_udbm);
1040
                Displ_Main_Disp();
1041
        }
1042
        else
1043
                Jump_Menu(pmenu);
1044
}
1045
 
1046
/**************************/
1047
/*                                                                                              */
1048
/*                              Sprache                                 */
1049
/*                                                                                              */
1050
/**************************/
1051
void Displ_Language(uint16_t i)
1052
{ uint8_t lanuage_table[3] = {MSG_GERMAN, MSG_ENGLISH, MSG_FRENCH};
1053
 
1054
        lcdPutStrMid(Msg(lanuage_table[i]), ZLE_VAL);
1055
}
1056
 
1057
void Menu_Language(void)
1058
{ uint16_t tmp_val;
1059
 
1060
        Displ_Title(MSG_LANGUAGE);
1061
        tmp_val = language;
1062
        language = eeprom_read_byte(&ep_language); // damit bei Erstinbetriebnahme Sprache gespeichert wird NO_LANGUAGE
1063
        Change_Value(&tmp_val, GERMAN, LAST_LANG, 3, Displ_Language); // pmenu global
1064
        if (tmp_val != language) {
1065
                language = tmp_val;
1066
                eeprom_write_byte(&ep_language, language);
1067
                Double_Beep(DBEEPWR, DBEEPWRP);
1068
        }
1069
        Jump_Menu(pmenu);
1070
}
1071
 
1072
/**************************/
1073
/*                                                                                              */
1074
/*      Servo-Einstellungen             */
1075
/*                                                                                              */
1076
/**************************/
1077
void Menu_Servo_Calibr(void)
1078
{ uint8_t scr_sub_menu[SCROLL_MAX_5] = {SCROLL_MAX_5 - 2, MSG_RETURN, MSG_SERVO_STEPS, MSG_SERVO1, MSG_SERVO2};
1079
 
1080
        Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
1081
        Jump_Menu(pmenu);
1082
}
1083
 
1084
void NoTracking_ServosOff(void)
1085
{
1086
        if (tracking == TRACKING_MIN) {
1087
                delay_ms100x(4);                                // sonst werden Impulse bereits vor erreichen der Servo-default-Stellung abgeschaltet
1088
                servoOff();                                                     // Servos sind nur zum Tracking oder bei Kalibrierung eingeschaltet
1089
        }
1090
}
1091
 
1092
void Servo_NewValues(uint8_t idx_presc)
1093
{
1094
        for (uint8_t i = 0; i < SERVO_NUM_CHANNELS; i++) {
1095
                if (idx_presc == STEPS_255) {                   // Werte umrechnen für Prescaler = 256
1096
                        servo[i].min /= 4;
1097
                        servo[i].max /= 4;
1098
                        servo[i].mid /= 4;
1099
                }
1100
                else {                                                                                                          // Werte umrechnen für Prescaler = 64
1101
                        servo[i].min *= 4;
1102
                        servo[i].max *= 4;
1103
                        servo[i].mid    = (servo[i].mid + 1) * 4 - 1;
1104
                }
1105
                servoSet_min(i, servo[i].min);
1106
                servoSet_max(i, servo[i].max);
1107
                servoSet_mid(i, servo[i].mid);
1108
                eeprom_write_block(&servo[i],&ep_servo[i],sizeof(servo_t));
1109
        }
1110
        // Vorberechnung von ServoChannels[channel].duty
1111
        servoSetDefaultPos();                                                           // Ausgangsstellung beider Servos
1112
}
1113
 
1114
void Menu_Servo_Steps(void)
1115
{ uint16_t tmp_val;
1116
 
1117
        Displ_Title(MSG_SERVO_STEPS);
1118
        lcdGotoXY(8, ZLE_VAL);
1119
        tmp_val = sIdxSteps;
1120
        if (Change_Value(&tmp_val, STEPS_255, STEPS_1023, 5, Displ_Servo_Steps)) { // pmenu global
1121
                cli();
1122
                sIdxSteps = tmp_val;
1123
                eeprom_write_byte(&ep_sIdxSteps, sIdxSteps);
1124
                Servo_NewValues(sIdxSteps);                             // hier ist der neue Index anzugeben!
1125
                servoInit(SERVO_PERIODE);
1126
                sei();
1127
                NoTracking_ServosOff();
1128
                Double_Beep(DBEEPWR, DBEEPWRP);
1129
        }
1130
        Jump_Menu(pmenu);
1131
}
1132
 
1133
void Menu_Servo1(void)
1134
{ uint8_t scr_servo_menu[SCROLL_MAX_6] = {SCROLL_MAX_6 - 2, MSG_RETURN, MSG_SERVO1_REVERSE, MSG_CALIB1_LEFT, MSG_CALIB1_RIGHT, MSG_CALIB1_MIDDLE};
1135
 
1136
        Scroll_Menu(scr_servo_menu, m_pkt); // pmenu global
1137
        servo_nr = 0;
1138
        Jump_Menu(pmenu);
1139
}
1140
 
1141
void Menu_Servo2(void)
1142
{ uint8_t scr_servo_menu[SCROLL_MAX_6] = {SCROLL_MAX_6 - 2, MSG_RETURN, MSG_SERVO2_REVERSE, MSG_CALIB2_LEFT, MSG_CALIB2_RIGHT, MSG_CALIB2_MIDDLE};
1143
 
1144
        Scroll_Menu(scr_servo_menu, m_pkt); // pmenu global
1145
        servo_nr = 1;
1146
        Jump_Menu(pmenu);
1147
}
1148
 
1149
uint8_t Servo_tmp_on(uint8_t servo_period)
1150
{ uint8_t tmp_tracking = tracking;
1151
 
1152
        tracking = 0;                                                                                           // Servopositionierung durch tracking abschalten
1153
        if (tracking == TRACKING_MIN) servoInit(servo_period); // falls aus, Servos einschalten
1154
        lcdGotoXY(0, 0);                                                                                // lcd Cursor vorpositionieren
1155
        return(tmp_tracking);
1156
}
1157
 
1158
void Servo_tmp_Original(uint8_t track)
1159
{
1160
        servoSetDefaultPos();
1161
        tracking = track;                                                                               // ursprünglicher Wert Tracking aus, RSSI oder GPS
1162
        NoTracking_ServosOff();                                                 // Servos sind nur zum Tracking oder bei Kalibrierung eingeschaltet
1163
        Jump_Menu(pmenu);
1164
}
1165
 
1166
void Menu_Servo_rev(void)
1167
{ uint16_t tmp_val;
1168
        uint8_t tmp_tracking;
1169
 
1170
        tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
1171
        tmp_val = servo[servo_nr].rev;
1172
        if (Change_Value(&tmp_val , 0, 1, 6, Displ_Off_On)) { // pmenu global; reverse gibt es nur 0=off, 1=on
1173
                servo[servo_nr].rev = tmp_val ;
1174
                servoSet_rev(servo_nr, tmp_val );
1175
                eeprom_write_block(&servo[servo_nr],&ep_servo[servo_nr],sizeof(servo_t));
1176
                Double_Beep(DBEEPWR, DBEEPWRP);
1177
        }
1178
        Servo_tmp_Original(tmp_tracking);
1179
}
1180
 
1181
void Menu_Servo1_rev(void)
1182
{
1183
        Displ_Title(MSG_SERVO1_REVERSE);
1184
        Menu_Servo_rev();
1185
}
1186
 
1187
void Menu_Servo2_rev(void)
1188
{
1189
        Displ_Title(MSG_SERVO2_REVERSE);
1190
        Menu_Servo_rev();
1191
}
1192
 
1193
void Menu_Servo_left(void)
1194
{ uint16_t tmp_val;
1195
        uint8_t tmp_tracking;
1196
 
1197
        tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
1198
        servoSetPosition(servo_nr, ServoSteps());                               // Linkssanschlag um Kalibrierung am Servo zu sehen
1199
        tmp_val = servo[servo_nr].max;
1200
        if (Change_Value(&tmp_val, servo_limit[sIdxSteps][LEFT].min, servo_limit[sIdxSteps][LEFT].max, 6|(1<<V_REPEAT), Displ_Servo_Max)) { // pmenu global
1201
                servo[servo_nr].max = tmp_val;
1202
                eeprom_write_block(&servo[servo_nr],&ep_servo[servo_nr],sizeof(servo_t));
1203
                servoSet_mid(servo_nr, servo[servo_nr].mid);            // Mittelposition muss sich bei Ausschlagsänderung verschieben
1204
                Double_Beep(DBEEPWR, DBEEPWRP);
1205
        }
1206
        Servo_tmp_Original(tmp_tracking);
1207
}
1208
 
1209
void Menu_Servo1_left(void)
1210
{
1211
        Displ_Title(MSG_CALIB1_LEFT);
1212
        Menu_Servo_left();
1213
}
1214
 
1215
void Menu_Servo2_left(void)
1216
{
1217
        Displ_Title(MSG_CALIB2_LEFT);
1218
        Menu_Servo_left();
1219
}
1220
 
1221
void Menu_Servo_right(void)
1222
{ uint16_t tmp_val;
1223
        uint8_t tmp_tracking;
1224
 
1225
        tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
1226
        servoSetPosition(servo_nr, 0);                                                                          // Rechtsanschlag um Kalibrierung am Servo zu sehen
1227
        tmp_val = servo[servo_nr].min;
1228
        if (Change_Value(&tmp_val, servo_limit[sIdxSteps][RIGHT].min, servo_limit[sIdxSteps][RIGHT].max, 6|(1<<V_REPEAT), Displ_Servo_Min)) { // pmenu global
1229
                servo[servo_nr].min = tmp_val;
1230
                eeprom_write_block(&servo[servo_nr],&ep_servo[servo_nr],sizeof(servo_t));
1231
                servoSet_mid(servo_nr, servo[servo_nr].mid);            // Mittelposition muss sich bei Ausschlagsänderung verschieben
1232
                Double_Beep(DBEEPWR, DBEEPWRP);
1233
        }
1234
         Servo_tmp_Original(tmp_tracking);
1235
}
1236
 
1237
void Menu_Servo1_right(void)
1238
{
1239
        Displ_Title(MSG_CALIB1_RIGHT);
1240
        Menu_Servo_right();
1241
}
1242
 
1243
void Menu_Servo2_right(void)
1244
{
1245
        Displ_Title(MSG_CALIB2_RIGHT);
1246
        Menu_Servo_right();
1247
}
1248
 
1249
void Menu_Servo_middle(void)
1250
{ uint16_t tmp_val;
1251
        uint8_t tmp_tracking;
1252
 
1253
        tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
1254
        servoSetPosition(servo_nr, ServoSteps()/2);                     // Mittelposition um Kalibrierung am Servo zu sehen
1255
        tmp_val = servo[servo_nr].mid;
1256
        if (Change_Value(&tmp_val, servo_limit[sIdxSteps][MIDDLE].min, servo_limit[sIdxSteps][MIDDLE].max, 5|(1<<V_REPEAT), Displ_Servo_Mid)) { // pmenu global
1257
                servo[servo_nr].mid = tmp_val;
1258
                eeprom_write_block(&servo[servo_nr], &ep_servo[servo_nr], sizeof(servo_t));
1259
                Double_Beep(DBEEPWR, DBEEPWRP);
1260
        }
1261
        Servo_tmp_Original(tmp_tracking);
1262
}
1263
 
1264
void Menu_Servo1_middle(void)
1265
{
1266
        Displ_Title(MSG_CALIB1_MIDDLE);
1267
        Menu_Servo_middle();
1268
}
1269
 
1270
void Menu_Servo2_middle(void)
1271
{
1272
        Displ_Title(MSG_CALIB2_MIDDLE);
1273
        Menu_Servo_middle();
1274
}
1275
 
1276
/**************************/
1277
/*                                                                                              */
1278
/*                      Servos-Tests                    */
1279
/*                                                                                              */
1280
/**************************/
1281
void Menu_Servo_Test(void)
1282
{ uint8_t scr_sub_menu[SCROLL_MAX_6]    = {SCROLL_MAX_6 - 2, MSG_RETURN, MSG_PULSE_WIDTH, MSG_CONTINOUS, MSG_SERVO, MSG_FRAME};
1283
 
1284
        Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
1285
        servo_nr = eeprom_read_byte(&ep_servo_nr);
1286
        Jump_Menu(pmenu);
1287
}
1288
 
1289
void Menu_Test_Frame(void)
1290
{ uint16_t tmp_val;
1291
 
1292
        Displ_Title(MSG_FRAME);
1293
        lcdGotoXY(8, ZLE_VAL);
1294
        lcdPuts("ms");
1295
        tmp_val = servo_frame;
1296
        if (Change_Value(&tmp_val, SERVO_PERIODE_MIN, SERVO_PERIODE_MAX, 5|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu global
1297
                servo_frame = tmp_val;
1298
                eeprom_write_byte(&ep_servo_frame, servo_frame);
1299
                Double_Beep(DBEEPWR, DBEEPWRP);
1300
        }
1301
        Jump_Menu(pmenu);
1302
}
1303
 
1304
void Menu_Test_ServoNr(void)
1305
{ uint16_t tmp_val;
1306
 
1307
        Displ_Title(MSG_SERVO);
1308
        tmp_val = servo_nr;
1309
        if (Change_Value(&tmp_val, 0, 1, 4, Displ_ServoNr)) { // pmenu global; es gibt nur 0=Servo1, 1=Servo2
1310
                servo_nr = tmp_val;
1311
                eeprom_write_byte(&ep_servo_nr, servo_nr);
1312
                Double_Beep(DBEEPWR, DBEEPWRP);
1313
        }
1314
        Jump_Menu(pmenu);
1315
}
1316
 
1317
// Dieser Test im raw-Modus ohne Anschlagkalibrierung (normiert) z.B.: für Modelleinstellungen ohne Empfänger
1318
void Menu_Test_PulseWidth(void)
1319
{ uint8_t tmp_tracking;
1320
        uint16_t tmp_val;
1321
 
1322
        tmp_tracking = Servo_tmp_on(servo_frame);
1323
        lcdWriteCGRAM_Array(lcdSpecialChrLs, 8);        // LCD-Char mit Rahmensymbole vom Graph
1324
        chrxs = CHRLS;                                                                                                          // verhindert wiederholtes Lesen bereits geladener LCD-Char
1325
        Displ_Title(MSG_PULSE_WIDTH);
1326
        tmp_val = steps_pw[sIdxSteps].mid;
1327
        Change_Value(&tmp_val, steps_pw[sIdxSteps].min, steps_pw[sIdxSteps].max, 4|(1<<V_REPEAT), Displ_PulseWidth); // pmenu global
1328
        lcdWriteCGRAM_Array(lcdSpecialChr, 7);          // LCD-Char für Bargraph zurückschreiben
1329
        cli();
1330
        servoInit(SERVO_PERIODE);
1331
        sei();
1332
        Servo_tmp_Original(tmp_tracking);
1333
}
1334
 
1335
void Menu_Test_Continuous(void)
1336
{ uint8_t scr_sub_menu[SCROLL_MAX_7]    = {SCROLL_MAX_7 - 2, MSG_RETURN, MSG_START, MSG_SINGLE_STEP, MSG_REPEAT, MSG_PAUSE, MSG_PAUSE_STEP};
1337
 
1338
        Scroll_Menu(scr_sub_menu, m_pkt);                               // pmenu global
1339
        Jump_Menu(pmenu);
1340
}
1341
 
1342
void Menu_Test_SingleStep(void)
1343
{uint16_t tmp_val;
1344
 
1345
        Displ_Title(MSG_SINGLE_STEP);
1346
        tmp_val = single_step;
1347
        if (Change_Value(&tmp_val, SINGLE_STEP_MIN, SINGLE_STEP_MAX, 5|(1<<V_REPEAT), Displ_Off_Format_Int)) { // pmenu global
1348
                single_step = tmp_val;
1349
                eeprom_write_byte(&ep_single_step, single_step);
1350
                Double_Beep(DBEEPWR, DBEEPWRP);
1351
        }
1352
        Jump_Menu(pmenu);
1353
}
1354
 
1355
void Menu_Test_Repeat(void)
1356
{uint16_t tmp_val;
1357
 
1358
        Displ_Title(MSG_REPEAT);
1359
        tmp_val = repeat;
1360
        if (Change_Value(&tmp_val, REPEAT_MIN, REPEAT_MAX, 5|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu global
1361
                repeat = tmp_val;
1362
                eeprom_write_byte(&ep_repeat, repeat);
1363
                Double_Beep(DBEEPWR, DBEEPWRP);
1364
        }
1365
        Jump_Menu(pmenu);
1366
}
1367
 
1368
void Menu_Test_Pause(void)
1369
{uint16_t tmp_val;
1370
 
1371
        Displ_Title(MSG_PAUSE);
1372
        tmp_val = pause;
1373
        if (Change_Value(&tmp_val, PAUSE_MIN, PAUSE_MAX, 5|(1<<V_REPEAT), Displ_Pause)) { // pmenu global
1374
                pause = tmp_val;
1375
                eeprom_write_byte(&ep_pause, pause);
1376
                Double_Beep(DBEEPWR, DBEEPWRP);
1377
        }
1378
        Jump_Menu(pmenu);
1379
}
1380
 
1381
void Menu_Test_Pause_Step(void)
1382
{uint16_t tmp_val;
1383
 
1384
        Displ_Title(MSG_PAUSE_STEP);
1385
        tmp_val = pause_step;
1386
        if (Change_Value(&tmp_val, PAUSE_STEP_MIN, PAUSE_STEP_MAX, 5|(1<<V_REPEAT), Displ_Pause_Step)) { // pmenu global
1387
                pause_step = tmp_val;
1388
                eeprom_write_byte(&ep_pause_step, pause_step);
1389
                Double_Beep(DBEEPWR, DBEEPWRP);
1390
        }
1391
        Jump_Menu(pmenu);
1392
}
1393
 
1394
int8_t calc_dir(uint8_t idx, int16_t *Position)
1395
{ uint8_t nextIdx;
1396
        int8_t nextDir = 1;
1397
 
1398
        nextIdx = idx;
1399
        if ((idx + 1) < POSIDX_MAX)
1400
                nextIdx++;
1401
        else
1402
                nextIdx = 0;
1403
        if (Position[PosIdx[idx]] > Position[PosIdx[nextIdx]]) nextDir = -1;
1404
        return(nextDir);
1405
}
1406
 
1407
void Displ_LoopCounter(uint8_t val)
1408
{
1409
        lcdGotoXY(2,2);
1410
        lcdPuts(Msg(MSG_COUNTER));
1411
        lcdPuts(my_itoa(val, 4, 0, 0));
1412
}
1413
 
1414
// Test über Scalierung der Servos mit Anschlagkalibrierung
1415
void Menu_Test_Start(void)
1416
{ uint8_t tmp_tracking, idx, rep;
1417
        int8_t dir;
1418
        int16_t sPos;
1419
        int16_t Position[3];   
1420
        int16_t range;
1421
 
1422
        tmp_tracking = Servo_tmp_on(servo_frame);
1423
        lcdWriteCGRAM_Array(lcdSpecialChrLs, 8);                // LCD-Char mit Rahmensymbole vom Graph
1424
        chrxs = CHRLS;                                                                                                                  // Flag, welche Kästchensymbole geladen
1425
        Displ_Title(MSG_CONTINOUS);
1426
        Displ_LoopCounter(repeat);
1427
        Position[0] = 0;                                                                                                                // skalierte Servoposition aber unterschiedliche Schrittanzahl möglich
1428
        Position[1] = ServoSteps()/2;
1429
        Position[2] = ServoSteps();
1430
        // init Einzelschritt
1431
        idx = 0;
1432
        dir = calc_dir(idx, Position);
1433
        sPos = Position[PosIdx[idx]];
1434
        idx++;
1435
        rep = repeat;
1436
 
1437
        // Test bis Ende der Wiederholungen oder irgendein Enter
1438
        while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && (rep > 0)) {  
1439
                range = calc_range(sPos - Position[1], Position[0], Position[2], Position[1]);
1440
                draw_bar(sPos - Position[1], range, 1); // eingerahmter Balkengraph auf 2. Display-Zeile
1441
                servoSetPosition(servo_nr, sPos);
1442
 
1443
                if ( sPos != Position[PosIdx[idx]]) {           // Links-, Mittel- oder Rechtsposotion erreicht?
1444
                        sPos += (single_step * dir);                                            // variable Schrittweite subtrahieren oder addieren
1445
                        if (((dir < 0) && (sPos < Position[PosIdx[idx]])) || ((dir > 0) && (sPos > Position[PosIdx[idx]])) || !(single_step))
1446
                                sPos = Position[PosIdx[idx]];                           // Überlauf bei variabler Schrittweite berücksichtigen oder Einzelschritt
1447
                        _delay_ms(servo_frame + 1 + pause_step);// Bei Schrittweite um 1 würden welche übersprungen, zusätzlich pro Servoschritt verzögert
1448
                }
1449
                else {
1450
                        dir = calc_dir(idx, Position);                                  // Richtungsänderung
1451
                        if (idx < (POSIDX_MAX - 1)) {
1452
                                if (idx == 0) {
1453
                                        rep--;                                                                                                                  // bei jeden vollen Durchlauf Wiederholzähler verringern
1454
                                        Displ_LoopCounter(rep);
1455
                                }
1456
                                idx++;                                                                                                                          // Index für nächsten Positionswert ==> Array PosIdx[] bestimmt Anschlagreihenfolge
1457
                        }
1458
                        else
1459
                                idx = 0;
1460
                        delay_ms100x(pause);                                                                            // variable Pause bei Links-, Mittel- und Rechtsposotion Mindestzeit 400ms (Servolauf)
1461
                }
1462
        }
1463
 
1464
        lcdClear();
1465
        if (pmenu[0] == '\0')
1466
                Displ_Main_Disp();
1467
        else
1468
                return_m_pkt(strlen(pmenu));                                                    // um bei Rücksprung auf ursprünglichen Menüpunkt zeigen oder Displ_Main_Disp()
1469
        lcdWriteCGRAM_Array(lcdSpecialChr, 7);                  // LCD-Char für Bargraph zurückschreiben
1470
        cli();
1471
        servoInit(SERVO_PERIODE);
1472
        sei();
1473
        Servo_tmp_Original(tmp_tracking);
1474
}
1475
 
1476
 
1477
/**************************/
1478
/*                                                                                              */
1479
/*                                      LCD                                             */
1480
/*                                                                                              */
1481
/**************************/
1482
void Menu_lcd(void)
1483
{ uint8_t scr_sub_menu[SCROLL_MAX_4] = {SCROLL_MAX_4 - 2, MSG_RETURN, MSG_CONTRAST, MSG_BACKGR_LIGHT};
1484
 
1485
        Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
1486
        Jump_Menu(pmenu);
1487
}
1488
 
1489
void Menu_lcd_Contrast(void)
1490
{ uint16_t tmp_val;
1491
 
1492
        Displ_Title(MSG_LCD);
1493
        lcdGotoXY(2, ZLE_VAL);
1494
        lcdPuts(Msg(MSG_CONTRAST));
1495
        lcdPuts(": ");
1496
        tmp_val = contrast;
1497
        if (Change_Value(&tmp_val, CONTRAST_MIN, CONTRAST_MAX, 11, Displ_Set_Contrast)) { // pmenu global
1498
                contrast = tmp_val;
1499
                eeprom_write_byte(&ep_contrast, contrast);
1500
                Double_Beep(DBEEPWR, DBEEPWRP);
1501
        }
1502
        Jump_Menu(pmenu);
1503
}
1504
 
1505
void Menu_lcd_Backgr_Light(void)
1506
{ uint16_t tmp_val;
1507
 
1508
        Displ_Title(MSG_BACKGR_LIGHT);
1509
        lcdGotoXY(0, ZLE_VAL);
1510
        lcdPuts(Msg(MSG_LIGHT));
1511
        tmp_val = light_time;
1512
        if (Change_Value(&tmp_val, BACKGR_LIGHT_MIN, BACKGR_LIGHT_MAX, 6|(1<<V_REPEAT), Displ_Backgr_Light)) { // pmenu global
1513
                light_time = tmp_val;
1514
                eeprom_write_byte(&ep_light_time, light_time);
1515
                Double_Beep(DBEEPWR, DBEEPWRP);
1516
                if (light_time == BACKGR_LIGHT_MIN) lcdSet_BackgrLight_Off(); // Hintergrundbeleuchtung immer aus ==> sofort schalten
1517
        }
1518
        Jump_Menu(pmenu);
1519
}
1520
 
1521
/**************************/
1522
/*                                                                                              */
1523
/*                              Batterie                                */
1524
/*                                                                                              */
1525
/**************************/
1526
void Menu_Battery(void)
1527
{ uint8_t scr_sub_menu[SCROLL_MAX_5] = {SCROLL_MAX_5 - 2, MSG_RETURN, MSG_U_SETUP, MSG_U_OFFSET, MSG_MK_BATTERY};
1528
 
1529
        Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
1530
        Jump_Menu(pmenu);
1531
}
1532
 
1533
/*****************/
1534
/* NG-Video Akku */
1535
/*****************/
1536
void Menu_Low_U_Setup(void)
1537
{ uint16_t tmp_val;
1538
 
1539
        Displ_Title(MSG_U_MIN);
1540
        tmp_val = u_min;
1541
        if (Change_Value(&tmp_val, U_MIN_MIN, U_MIN_MAX, 4|(1<<V_REPEAT), Displ_U_2Nk)) { // pmenu global
1542
                u_min = tmp_val;
1543
                eeprom_write_word(&ep_u_min, u_min);
1544
                hyst_u_min = u_min;
1545
                Double_Beep(DBEEPWR, DBEEPWRP);
1546
        }
1547
        Jump_Menu(pmenu);
1548
}
1549
 
1550
void Menu_U_Offset(void)
1551
{ uint16_t tmp_val;
1552
 
1553
        Displ_Title(MSG_U_OFFSET);
1554
        tmp_val = u_offset;
1555
        if (Change_Value(&tmp_val, U_OFFSET_MIN, U_OFFSET_MAX, 4|(1<<V_REPEAT), Displ_U_2Nk)) { // pmenu global
1556
                u_offset = tmp_val;
1557
                eeprom_write_byte(&ep_u_offset, u_offset);
1558
                Double_Beep(DBEEPWR, DBEEPWRP);
1559
        }
1560
        Jump_Menu(pmenu);
1561
}
1562
 
1563
/******************/
1564
/*       MK-Akku(s)             */
1565
/******************/
1566
void Menu_MK_Battery(void)
1567
{ uint8_t scr_sub_menu[SCROLL_MAX_7] = {SCROLL_MAX_7 - 2, MSG_RETURN, MSG_MK_BAT_NR, MSG_MK_BAT_CAPACITY, MSG_MK_I_OFFSET, MSG_MK_I_FAKTOR, MSG_MK_W_FAKTOR};
1568
 
1569
        Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
1570
        Jump_Menu(pmenu);
1571
}
1572
 
1573
// für Nutzung verschiedener Akku's unterschiedlicher Kapazität
1574
// könnte auch für Statistik Ladezyklen erweitert werden aber sinnlos bei Verwendung gleicher Akku's in anderen Modellen
1575
void Menu_MK_BatteryChangeNr(void)
1576
{ uint16_t tmp_val;
1577
 
1578
        Displ_Title(MSG_MK_BAT_NR);
1579
        tmp_val = mk_akku_nr+1;
1580
        if (Change_Value(&tmp_val, AKKU_NR_MIN+1, AKKU_NR_MAX+1, 5|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu global
1581
                mk_akku_nr = --tmp_val;
1582
                eeprom_write_byte(&ep_mk_akku_nr, mk_akku_nr);
1583
                eeprom_read_block(&mk_lipo,&ep_mk_lipo[mk_akku_nr],sizeof(mk_lipo_t));
1584
                mk_dUsedCapacity = mk_lipo.UsedCapacity;
1585
                Double_Beep(DBEEPWR, DBEEPWRP);
1586
        }
1587
}
1588
 
1589
void Menu_MK_BatteryNr(void)
1590
{
1591
        Menu_MK_BatteryChangeNr();
1592
        Jump_Menu(pmenu);
1593
}
1594
 
1595
void Menu_MK_BatteryCapacity(void)
1596
{ uint16_t tmp_val;
1597
 
1598
        Displ_Title(MSG_MK_BAT_CAPACITY);
1599
        tmp_val = mk_lipo.Capacity/50;
1600
        if (Change_Value(&tmp_val, AKKU_CAPACITY_MIN/50, AKKU_CAPACITY_MAX/50, 5|(1<<V_REPEAT), Displ_MK_Capacity)) { // pmenu global
1601
                mk_lipo.Capacity = tmp_val * 50;
1602
                eeprom_write_block(&mk_lipo,&ep_mk_lipo[mk_akku_nr],sizeof(mk_lipo_t));
1603
                Double_Beep(DBEEPWR, DBEEPWRP);
1604
        }
1605
        Jump_Menu(pmenu);
1606
}
1607
 
1608
void Menu_MK_I_Offset(void)
1609
{ uint16_t tmp_val;
1610
 
1611
        Displ_Title(MSG_MK_I_OFFSET);
1612
        tmp_val = mk_i_offset;
1613
        if (Change_Value(&tmp_val, MK_I_OFFSET_MIN, MK_I_OFFSET_MAX, 5|(1<<V_REPEAT), Displ_I_Offset)) { // pmenu global
1614
                mk_i_offset = tmp_val;
1615
                eeprom_write_byte(&ep_mk_i_offset, mk_i_offset);
1616
                Double_Beep(DBEEPWR, DBEEPWRP);
1617
        }
1618
        Jump_Menu(pmenu);
1619
}
1620
 
1621
void Menu_MK_I_Faktor(void)
1622
{ uint16_t tmp_val;
1623
 
1624
        Displ_Title(MSG_MK_I_FAKTOR);
1625
        tmp_val = mk_i_faktor;
1626
        if (Change_Value(&tmp_val, MK_I_FAKTOR_MIN, MK_I_FAKTOR_MAX, 6|(1<<V_REPEAT), Displ_Faktor_2Nk)) { // pmenu global
1627
                mk_i_faktor = tmp_val;
1628
                eeprom_write_byte(&ep_mk_i_faktor, mk_i_faktor);
1629
                Double_Beep(DBEEPWR, DBEEPWRP);
1630
        }
1631
        Jump_Menu(pmenu);
1632
}
1633
 
1634
void Menu_MK_W_Faktor(void)
1635
{ uint16_t tmp_val;
1636
 
1637
        Displ_Title(MSG_MK_W_FAKTOR);
1638
        tmp_val = mk_w_faktor;
1639
        if (Change_Value(&tmp_val, MK_W_FAKTOR_MIN, MK_W_FAKTOR_MAX, 6|(1<<V_REPEAT), Displ_Faktor_2Nk)) { // pmenu global
1640
                mk_w_faktor = tmp_val;
1641
                eeprom_write_byte(&ep_mk_w_faktor, mk_w_faktor);
1642
                Double_Beep(DBEEPWR, DBEEPWRP);
1643
        }
1644
        Jump_Menu(pmenu);
1645
}
1646
 
1647
 
1648
/**************************/
1649
/*                                                                                              */
1650
/*      Antennennachführung             */
1651
/*                                                                                              */
1652
/**************************/
1653
void Menu_Tracking_Ant(void)
1654
{ uint16_t tmp_val;
1655
 
1656
        Displ_Title(MSG_TRACKING);
1657
        tmp_val = tracking;
1658
        if (Change_Value(&tmp_val, TRACKING_MIN, TRACKING_MAX, 3, Displ_sel_Tracking)) { // pmenu global
1659
                cli();
1660
                tracking = tmp_val;
1661
                sei();
1662
                eeprom_write_byte(&ep_tracking, tracking);
1663
                Double_Beep(DBEEPWR, DBEEPWRP);
1664
                USART_RX_Mode(tracking);                // Unterschied Datenempfang GPS/MKCockpit/NMEA
1665
                coldstart = 1;
1666
                rxcount0 = 0;
1667
                rxcount1 = 0;
1668
                servoSetDefaultPos();                           // Ausgangsstellung beider Servos
1669
                if (tracking > TRACKING_MIN)
1670
                        servoInit(SERVO_PERIODE);
1671
                NoTracking_ServosOff();
1672
                USART_Init_Baudrate();
1673
        }
1674
        Jump_Menu(pmenu);
1675
}
1676
 
1677
/**************************/
1678
/*                       Optionen                                       */
1679
/*      Antennennachführung             */
1680
/*                                                                                              */
1681
/**************************/
1682
void Menu_Tracking_HYST(void)
1683
{ uint16_t tmp_val;
1684
 
1685
        Displ_Title(MSG_HYSTERESE);
1686
        tmp_val = track_hyst;
1687
        if (Change_Value(&tmp_val, TRACKING_HYST_MIN, TRACKING_HYST_MAX, 7|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu gloabal
1688
                track_hyst = tmp_val;
1689
                eeprom_write_byte(&ep_track_hyst, track_hyst);
1690
                Double_Beep(DBEEPWR, DBEEPWRP);
1691
        }
1692
        Jump_Menu(pmenu);
1693
}
1694
 
1695
void Menu_Tracking_TXOSD(void)
1696
{ uint16_t tmp_val;
1697
 
1698
        Displ_Title(MSG_TRACK_TX_OSD_DATA);
1699
        tmp_val = track_tx;
1700
        if (Change_Value(&tmp_val, 0, 1, 3, Displ_track_TX)) { // pmenu global; Senden gibt es nur 0=off, 1=on
1701
                track_tx = tmp_val;
1702
                eeprom_write_byte(&ep_track_tx, track_tx);
1703
                Double_Beep(DBEEPWR, DBEEPWRP);
1704
        }
1705
        Jump_Menu(pmenu);
1706
}
1707
 
1708
void Menu_Baudrate(void)
1709
{ uint16_t tmp_val;
1710
 
1711
        Displ_Title(MSG_BAUDRATE);
1712
        tmp_val = baudrate;
1713
        if (Change_Value(&tmp_val, BAUDRATE_MIN, BAUDRATE_MAX, 3, Displ_Baudrate)) { // pmenu global
1714
                baudrate = tmp_val;
1715
                eeprom_write_byte(&ep_baudrate, baudrate);
1716
                Double_Beep(DBEEPWR, DBEEPWRP);
1717
                USART_Init(getBaud(baudrate));
1718
        }
1719
        Jump_Menu(pmenu);
1720
}
1721
 
1722
void Menu_Tracking_Option(void)
1723
{ // im Menü ist dies der gleiche Gliederungspunkt aber mit geänderter Auswahl
1724
        switch(tracking) {
1725
                case TRACKING_RSSI:                             Menu_Tracking_HYST();
1726
                                                                                                                        break;
1727
                case TRACKING_GPS:                              Menu_Tracking_TXOSD();
1728
                                                                                                                        break;
1729
                case TRACKING_MKCOCKPIT:       
1730
                case TRACKING_NMEA:                             Menu_Baudrate();
1731
                                                                                                                        break;
1732
        }
1733
}
1734
 
1735
/**************************/
1736
/*                                                                                              */
1737
/*                      Anzeige GPS                             */
1738
/*                                                                                              */
1739
/**************************/
1740
void Menu_GPS_Display(void)
1741
{ uint8_t scr_sub_menu[SCROLL_MAX_7] = {SCROLL_MAX_7 - 2, MSG_RETURN, MSG_GPS_CALCULATE, MSG_GPS_CURRENT, MSG_GPS_HOME, \
1742
                                                                                                                                                                 MSG_GPS_MISC, MSG_RX_TIME};
1743
 
1744
        if (tracking == TRACKING_NMEA) {                // Manipulierung der Menüanzeige/-ausführung
1745
                scr_sub_menu[0] = SCROLL_MAX_7 - 3;
1746
                scr_sub_menu[5] = MSG_RX_TIME;
1747
        }
1748
        else
1749
                if (tracking != TRACKING_GPS)   scr_sub_menu[0] = SCROLL_MAX_7 - 4;             // Only show MISC in GPS mode, not NMEA
1750
        Scroll_Menu(scr_sub_menu, m_pkt);       // pmenu global
1751
        Jump_Menu(pmenu);
1752
}
1753
 
1754
void Menu_GPS_Display_FLAG(void)                        // ist Flag in tracking.c Tracking_GPS(void)
1755
{ uint8_t slen;
1756
 
1757
        slen = strlen(pmenu) - 1;
1758
        gps_display = pmenu[slen] - '0';                // char to byte 1 bis 3 im String enthalten
1759
        if ((tracking == TRACKING_NMEA) && (gps_display == GPS_MISC))
1760
                pmenu[slen] = RXTimeChr[0];                     // Manipulierung der Menüausführung
1761
        else {
1762
                m_pkt = gps_display;
1763
                gps_disp_clear = 1;                                                             // damit Text "...keine Daten empf..." nach Datenempfang gelöscht wird
1764
                if (gps_display != GPS_MISC)    lcdPuts(Msg(MSG_GPS_NO_DATA));
1765
                if (Short_Enter())                                                              // pmenu global
1766
                        pmenu[slen] = '\0';                                                     // Menüpunkt zurück
1767
                gps_display = GPS_DISP_NONE;                    // nach Tastaturabfrage keine Anzeige GPS, sondern normales Menü
1768
        }
1769
        Jump_Menu(pmenu);
1770
}
1771
 
1772
void Menu_GPS_Displ_RX_Time(void)
1773
{
1774
        Displ_Title(MSG_RX_TIME);
1775
        lcdGotoXY(0, 1);
1776
        lcdPuts(Msg(MSG_RX1));
1777
        lcdGotoXY(0, 2);
1778
        lcdPuts(Msg(MSG_RX2));
1779
        Displ_RX_Time();
1780
        // bei Menüpunktmanipulatin TRACKING_NMEA und vorgezogen Menu_GPS_Displ_RX_Time ist Rücksprung real GPS_MISC
1781
        m_pkt = ((tracking == TRACKING_NMEA) && (gps_display == GPS_MISC))? GPS_MISC: GPS_RX_COUNT;
1782
        gps_display = GPS_RX_COUNT;
1783
        if (Short_Enter())                                                               // pmenu global
1784
                pmenu[strlen(pmenu) - 1] = '\0';// Menüpunkt zurück
1785
        gps_display = GPS_DISP_NONE;                     // nach Tastaturabfrage keine Anzeige GPS, sondern normales Menü
1786
        Jump_Menu(pmenu);
1787
}