Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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