Subversion Repositories Projects

Rev

Rev 761 | Rev 783 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 761 Rev 762
1
/****************************************************************************
1
/****************************************************************************
2
 *   Copyright (C) 2009-2010 by Claas Anders "CaScAdE" Rathje               *
2
 *   Copyright (C) 2009-2010 by Claas Anders "CaScAdE" Rathje               *
3
 *   admiralcascade@gmail.com                                               *
3
 *   admiralcascade@gmail.com                                               *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
5
 *                                                                          *
5
 *                                                                          *
6
 *   This program is free software; you can redistribute it and/or modify   *
6
 *   This program is free software; you can redistribute it and/or modify   *
7
 *   it under the terms of the GNU General Public License as published by   *
7
 *   it under the terms of the GNU General Public License as published by   *
8
 *   the Free Software Foundation; either version 2 of the License.         *
8
 *   the Free Software Foundation; either version 2 of the License.         *
9
 *                                                                          *
9
 *                                                                          *
10
 *   This program is distributed in the hope that it will be useful,        *
10
 *   This program is distributed in the hope that it will be useful,        *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
13
 *   GNU General Public License for more details.                           *
13
 *   GNU General Public License for more details.                           *
14
 *                                                                          *
14
 *                                                                          *
15
 *   You should have received a copy of the GNU General Public License      *
15
 *   You should have received a copy of the GNU General Public License      *
16
 *   along with this program; if not, write to the                          *
16
 *   along with this program; if not, write to the                          *
17
 *   Free Software Foundation, Inc.,                                        *
17
 *   Free Software Foundation, Inc.,                                        *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
19
 ****************************************************************************/
19
 ****************************************************************************/
20
 
20
 
21
#include <avr/io.h>
21
#include <avr/io.h>
22
#include <avr/eeprom.h>
22
#include <avr/eeprom.h>
23
#include <avr/pgmspace.h>
23
#include <avr/pgmspace.h>
24
#include <avr/interrupt.h>
24
#include <avr/interrupt.h>
25
#include <util/delay.h>
25
#include <util/delay.h>
26
#include "max7456_software_spi.h"
26
#include "max7456_software_spi.h"
27
#include "config.h"
27
#include "config.h"
28
#include "main.h"
28
#include "main.h"
29
#include "buttons.h"
29
#include "buttons.h"
30
#include "usart1.h"
30
#include "usart1.h"
-
 
31
 
-
 
32
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
31
 
33
 
32
uint8_t EEMEM ee_checkbyte1 = CHECKBYTE1;
34
uint8_t EEMEM ee_checkbyte1 = CHECKBYTE1;
33
uint8_t EEMEM ee_checkbyte2 = CHECKBYTE2;
35
uint8_t EEMEM ee_checkbyte2 = CHECKBYTE2;
34
uint8_t EEMEM ee_COSD_FLAGS_MODES = 0;
36
uint8_t EEMEM ee_COSD_FLAGS_MODES = 0;
35
uint8_t EEMEM ee_COSD_FLAGS_CONFIG = 0;
37
uint8_t EEMEM ee_COSD_FLAGS_CONFIG = 0;
36
uint8_t EEMEM ee_COSD_DISPLAYMODE = 0;
38
uint8_t EEMEM ee_COSD_DISPLAYMODE = 0;
37
 
-
 
38
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
-
 
39
 
39
 
40
// video modes
40
// video modes
41
const char VM_PAL[] PROGMEM = "PAL ";
41
const char VM_PAL[] PROGMEM = "PAL ";
42
const char VM_NTSC[] PROGMEM = "NTSC";
42
const char VM_NTSC[] PROGMEM = "NTSC";
43
 
-
 
44
 
43
 
45
const displaymode_t * mode;
-
 
46
 
-
 
47
#endif
44
const displaymode_t * mode;
48
 
45
 
49
const char ee_message0[] PROGMEM = "Loading Data from EEPROM";
46
const char ee_message0[] PROGMEM = "Loading Data from EEPROM";
50
const char ee_message1[] PROGMEM = "No saved Data in EEPROM";
47
const char ee_message1[] PROGMEM = "No saved Data in EEPROM";
51
const char* ee_msg[] PROGMEM = {ee_message0, ee_message1};
48
const char* ee_msg[] PROGMEM = {ee_message0, ee_message1};
52
 
49
 
53
/**
50
/**
54
 * read data saved in eeprom, print out message if <verbose> is set
51
 * read data saved in eeprom, print out message if <verbose> is set
55
 */
52
 */
56
void get_eeprom(uint8_t verbose) {
53
void get_eeprom(uint8_t verbose) {
57
    if (eeprom_read_byte(&ee_checkbyte1) == CHECKBYTE1 && eeprom_read_byte(&ee_checkbyte2) == CHECKBYTE2) {
54
    if (eeprom_read_byte(&ee_checkbyte1) == CHECKBYTE1 && eeprom_read_byte(&ee_checkbyte2) == CHECKBYTE2) {
58
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
-
 
59
        if (verbose) write_ascii_string_pgm(2, 9, ee_msg[0]); // Loading data
55
        if (verbose) write_ascii_string_pgm(2, 9, ee_msg[0]); // Loading data
60
#endif
-
 
61
        COSD_FLAGS_MODES = eeprom_read_byte(&ee_COSD_FLAGS_MODES);
56
        COSD_FLAGS_MODES = eeprom_read_byte(&ee_COSD_FLAGS_MODES);
62
        COSD_FLAGS_CONFIG = eeprom_read_byte(&ee_COSD_FLAGS_CONFIG);
57
        COSD_FLAGS_CONFIG = eeprom_read_byte(&ee_COSD_FLAGS_CONFIG);
63
        COSD_DISPLAYMODE = eeprom_read_byte(&ee_COSD_DISPLAYMODE);
58
        COSD_DISPLAYMODE = eeprom_read_byte(&ee_COSD_DISPLAYMODE);
64
        //if (verbose) write_ndigit_number_u(23, 11, COSD_DISPLAYMODE, 2, 0);
59
        //if (verbose) write_ndigit_number_u(23, 11, COSD_DISPLAYMODE, 2, 0);
65
    } else {
60
    } else {
66
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
-
 
67
        if (verbose) write_ascii_string_pgm(2, 9, ee_msg[1]); // Loading data
61
        if (verbose) write_ascii_string_pgm(2, 9, ee_msg[1]); // Loading data
68
#endif
-
 
69
    }
62
    }
70
}
63
}
71
 
-
 
72
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
64
 
73
 
65
 
74
/**
66
/**
75
 * save data to eeprom
67
 * save data to eeprom
76
 */
68
 */
77
void save_eeprom() {
69
void save_eeprom() {
78
    eeprom_write_byte(&ee_checkbyte1, CHECKBYTE1);
70
    eeprom_write_byte(&ee_checkbyte1, CHECKBYTE1);
79
    eeprom_write_byte(&ee_checkbyte2, CHECKBYTE2);
71
    eeprom_write_byte(&ee_checkbyte2, CHECKBYTE2);
80
    eeprom_write_byte(&ee_COSD_FLAGS_MODES, COSD_FLAGS_MODES);
72
    eeprom_write_byte(&ee_COSD_FLAGS_MODES, COSD_FLAGS_MODES);
81
    eeprom_write_byte(&ee_COSD_FLAGS_CONFIG, COSD_FLAGS_CONFIG);
73
    eeprom_write_byte(&ee_COSD_FLAGS_CONFIG, COSD_FLAGS_CONFIG);
82
    eeprom_write_byte(&ee_COSD_DISPLAYMODE, COSD_DISPLAYMODE);
74
    eeprom_write_byte(&ee_COSD_DISPLAYMODE, COSD_DISPLAYMODE);
83
}
75
}
84
 
76
 
85
/**
77
/**
86
 * auto config some stuff on startup, currently only battery cells
78
 * auto config some stuff on startup, currently only battery cells
87
 */
79
 */
88
void init_cosd(uint8_t UBat) {
80
void init_cosd(uint8_t UBat) {
89
    clear();
81
    clear();
90
    write_ascii_string_pgm(2, 1, PSTR("C-OSD Initialisation")); // C-OSD Initialisation
82
    write_ascii_string_pgm(2, 1, PSTR("C-OSD Initialisation")); // C-OSD Initialisation
91
#if FCONLY
83
#if FCONLY
92
    write_ascii_string_pgm(2, 2, PSTR("FC only Mode")); // FC only mode
84
    write_ascii_string_pgm(2, 2, PSTR("FC only Mode")); // FC only mode
93
#else
85
#else
94
    write_ascii_string_pgm(2, 2, PSTR("NaviCtrl Mode")); // NaviCtrl Mode
86
    write_ascii_string_pgm(2, 2, PSTR("NaviCtrl Mode")); // NaviCtrl Mode
95
#endif
87
#endif
96
    write_ascii_string_pgm(2, 3, PSTR(BUILDDATE));
88
    write_ascii_string_pgm(2, 3, PSTR(BUILDDATE));
97
    uint8_t cellnum = 0;
89
    uint8_t cellnum = 0;
98
    if (CELL_NUM == -1) {
90
    if (CELL_NUM == -1) {
99
        write_ascii_string_pgm(2, 4, PSTR("Guessing Number of Cells")); // Guessing Number of Cells
91
        write_ascii_string_pgm(2, 4, PSTR("Guessing Number of Cells")); // Guessing Number of Cells
100
        do {
92
        do {
101
            cellnum++;
93
            cellnum++;
102
        } while (UBat > ((cellnum * CELL_VOLT_MAX) + 23));
94
        } while (UBat > ((cellnum * CELL_VOLT_MAX) + 23));
103
    } else {
95
    } else {
104
        cellnum = CELL_NUM;
96
        cellnum = CELL_NUM;
105
    }
97
    }
106
    min_voltage = cellnum * CELL_VOLT_MIN;
98
    min_voltage = cellnum * CELL_VOLT_MIN;
107
    max_voltage = cellnum * CELL_VOLT_MAX;
99
    max_voltage = cellnum * CELL_VOLT_MAX;
108
    write_ascii_string_pgm(2, 5, PSTR("Number of Cells:")); // Number of Cells
100
    write_ascii_string_pgm(2, 5, PSTR("Number of Cells:")); // Number of Cells
109
    write_ndigit_number_u(21, 5, cellnum, 1, 0);
101
    write_ndigit_number_u(21, 5, cellnum, 1, 0);
110
    write_ascii_string_pgm(2, 6, PSTR("Warn Voltage   :")); // Warn Voltage
102
    write_ascii_string_pgm(2, 6, PSTR("Warn Voltage   :")); // Warn Voltage
111
    write_ndigit_number_s_10th(20, 6, min_voltage, 3, 0);
103
    write_ndigit_number_s_10th(20, 6, min_voltage, 3, 0);
112
    write_ascii_string_pgm(2, 7, PSTR("Max Voltage    :")); // Max Voltage
104
    write_ascii_string_pgm(2, 7, PSTR("Max Voltage    :")); // Max Voltage
113
    write_ndigit_number_s_10th(20, 7, max_voltage, 3, 0);
105
    write_ndigit_number_s_10th(20, 7, max_voltage, 3, 0);
114
 
106
 
115
    get_eeprom(1);
107
    get_eeprom(1);
116
 
108
 
117
    //write_ascii_string_pgm(23, 2, vm[COSD_FLAGS & COSD_FLAG_NTSC]);
109
    //write_ascii_string_pgm(23, 2, vm[COSD_FLAGS & COSD_FLAG_NTSC]);
118
    if (COSD_FLAGS_CONFIG & COSD_FLAG_NTSC) {
110
    if (COSD_FLAGS_CONFIG & COSD_FLAG_NTSC) {
119
        write_ascii_string_pgm(23, 2, VM_NTSC);
111
        write_ascii_string_pgm(23, 2, VM_NTSC);
120
    } else {
112
    } else {
121
        write_ascii_string_pgm(23, 2, VM_PAL);
113
        write_ascii_string_pgm(23, 2, VM_PAL);
122
    }
114
    }
123
 
115
 
124
    // request version from board
116
    // request version from board
125
    rxd_buffer_locked = 0;
117
    rxd_buffer_locked = 0;
126
    usart1_EnableTXD();
118
    usart1_EnableTXD();
127
#if FCONLY
119
#if FCONLY
128
    //usart1_request_mk_data(0, 'v', 0);
120
    //usart1_request_mk_data(0, 'v', 0);
129
    write_ascii_string_pgm(2, 11, PSTR("FC VERSION: ........"));
121
    write_ascii_string_pgm(2, 11, PSTR("FC VERSION: ........"));
130
    usart1_puts_pgm(PSTR(REQUEST_FC_VERSION));
122
    usart1_puts_pgm(PSTR(REQUEST_FC_VERSION));
131
#else
123
#else
132
    //usart1_request_mk_data(1, 'v', 0);
124
    //usart1_request_mk_data(1, 'v', 0);
133
    usart1_puts_pgm(PSTR(REQUEST_NC_VERSION));
125
    usart1_puts_pgm(PSTR(REQUEST_NC_VERSION));
134
    write_ascii_string_pgm(2, 11, PSTR("NC VERSION: ........"));
126
    write_ascii_string_pgm(2, 11, PSTR("NC VERSION: ........"));
135
#endif
127
#endif
136
    usart1_DisableTXD();
128
    usart1_DisableTXD();
137
    // wait for response
129
    // wait for response
138
    while (rxd_buffer_locked == 0) {
130
    while (rxd_buffer_locked == 0) {
139
        asm("nop");
131
        asm("nop");
140
    }
132
    }
141
    Decode64();
133
    Decode64();
142
    str_VersionInfo VersionInfo;
134
    str_VersionInfo VersionInfo;
143
    VersionInfo = *((str_VersionInfo*)pRxData);
135
    VersionInfo = *((str_VersionInfo*)pRxData);
144
 
136
 
145
    write_ndigit_number_u(14, 11, VersionInfo.SWMajor, 3, 1);
137
    write_ndigit_number_u(14, 11, VersionInfo.SWMajor, 3, 1);
146
    write_ndigit_number_u(18, 11, VersionInfo.SWMinor, 3, 1);
138
    write_ndigit_number_u(18, 11, VersionInfo.SWMinor, 3, 1);
147
    write_ascii_char(22 + 11 * 30, 'a' + VersionInfo.SWPatch);
139
    write_ascii_char(22 + 11 * 30, 'a' + VersionInfo.SWPatch);
148
    // end version request
140
    // end version request
149
 
141
 
150
 
142
 
151
#if FCONLY
143
#if FCONLY
152
    COSD_DISPLAYMODE %= (sizeof (fcdisplaymodes) / sizeof (displaymode_t));
144
    COSD_DISPLAYMODE %= (sizeof (fcdisplaymodes) / sizeof (displaymode_t));
153
    mode = fcdisplaymodes;
145
    mode = fcdisplaymodes;
154
    mode += COSD_DISPLAYMODE;
146
    mode += COSD_DISPLAYMODE;
155
    osd_fcmode = (int(*)(void)) pgm_read_word(&mode->dfun);
147
    osd_fcmode = (int(*)(void)) pgm_read_word(&mode->dfun);
156
    // re-request data ever 100ms from FC;
148
    // re-request data ever 100ms from FC;
157
    //usart1_request_mk_data(0, 'd', 100);
149
    //usart1_request_mk_data(0, 'd', 100);
158
#else
150
#else
159
    COSD_DISPLAYMODE %= (sizeof (ncdisplaymodes) / sizeof (displaymode_t));
151
    COSD_DISPLAYMODE %= (sizeof (ncdisplaymodes) / sizeof (displaymode_t));
160
    mode = ncdisplaymodes;
152
    mode = ncdisplaymodes;
161
    mode += COSD_DISPLAYMODE;
153
    mode += COSD_DISPLAYMODE;
162
    osd_ncmode = (int(*)(void)) pgm_read_word(&mode->dfun);
154
    osd_ncmode = (int(*)(void)) pgm_read_word(&mode->dfun);
163
    // re-request OSD Data from NC every 100ms
155
    // re-request OSD Data from NC every 100ms
164
    //usart1_request_mk_data(1, 'o', 100);
156
    //usart1_request_mk_data(1, 'o', 100);
165
#endif
157
#endif
166
 
158
 
167
    _delay_ms(3000);
159
    _delay_ms(3000);
168
    clear();
160
    clear();
169
    // update flags to paint display again because of clear
161
    // update flags to paint display again because of clear
170
    COSD_FLAGS_RUNTIME &= ~COSD_ICONS_WRITTEN;
162
    COSD_FLAGS_RUNTIME &= ~COSD_ICONS_WRITTEN;
171
}
163
}
172
 
164
 
173
/* ##########################################################################
165
/* ##########################################################################
174
 * A simple config menu for the flags
166
 * A simple config menu for the flags
175
 * ##########################################################################*/
167
 * ##########################################################################*/
176
 
168
 
177
/**
169
/**
178
 * helper function for flag display
170
 * helper function for flag display
179
 */
171
 */
180
void onoff(uint8_t col, uint8_t line, uint8_t onoff) {
172
void onoff(uint8_t col, uint8_t line, uint8_t onoff) {
181
    if (onoff) {
173
    if (onoff) {
182
        write_ascii_string_pgm(col, line, PSTR("ON "));
174
        write_ascii_string_pgm(col, line, PSTR("ON "));
183
    } else {
175
    } else {
184
        write_ascii_string_pgm(col, line, PSTR("OFF"));
176
        write_ascii_string_pgm(col, line, PSTR("OFF"));
185
    }
177
    }
186
}
178
}
187
 
179
 
188
/**
180
/**
189
 * helper function for menu updating
181
 * helper function for menu updating
190
 */
182
 */
191
void config_menu_drawings(uint8_t chosen) {
183
void config_menu_drawings(uint8_t chosen) {
192
    static uint8_t old_y = 0;
184
    static uint8_t old_y = 0;
193
    uint8_t x = MENU_LEFT, y = MENU_TOP, line = MENU_TOP;
185
    uint8_t x = MENU_LEFT, y = MENU_TOP, line = MENU_TOP;
194
 
186
 
195
    if (chosen > 5 && chosen < 12) { // right
187
    if (chosen > 5 && chosen < 12) { // right
196
        x = MENU_MIDDLE;
188
        x = MENU_MIDDLE;
197
        y = chosen - 6 + MENU_TOP;
189
        y = chosen - 6 + MENU_TOP;
198
    } else if (chosen < 7) {
190
    } else if (chosen < 7) {
199
        y = chosen + MENU_TOP;
191
        y = chosen + MENU_TOP;
200
    } else {
192
    } else {
201
        y = chosen - 6 + MENU_TOP;
193
        y = chosen - 6 + MENU_TOP;
202
    }
194
    }
203
 
195
 
204
    // clear prevoius _cursor_ and draw current
196
    // clear prevoius _cursor_ and draw current
205
    for (uint8_t myx = MENU_LEFT; myx < 29; myx++) {
197
    for (uint8_t myx = MENU_LEFT; myx < 29; myx++) {
206
        write_char_att_xy(myx, old_y, 0);
198
        write_char_att_xy(myx, old_y, 0);
207
        if (myx > x - 1 && myx < x + 14) {
199
        if (myx > x - 1 && myx < x + 14) {
208
            write_char_att_xy(myx, y, BLACKBG | INVERT);
200
            write_char_att_xy(myx, y, BLACKBG | INVERT);
209
        }
201
        }
210
    };
202
    };
211
 
203
 
212
    write_ascii_string_pgm(MENU_LEFT, line, PSTR("Video"));
204
    write_ascii_string_pgm(MENU_LEFT, line, PSTR("Video"));
213
    if (COSD_FLAGS_CONFIG & COSD_FLAG_NTSC) {
205
    if (COSD_FLAGS_CONFIG & COSD_FLAG_NTSC) {
214
        write_ascii_string_pgm(MENU_LEFT + 10, line, VM_NTSC);
206
        write_ascii_string_pgm(MENU_LEFT + 10, line, VM_NTSC);
215
    } else {
207
    } else {
216
        write_ascii_string_pgm(MENU_LEFT + 10, line, VM_PAL);
208
        write_ascii_string_pgm(MENU_LEFT + 10, line, VM_PAL);
217
    }
209
    }
218
 
210
 
219
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Full HUD"));
211
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Full HUD"));
220
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_HUD);
212
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_HUD);
221
 
213
 
222
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Horizon"));
214
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Horizon"));
223
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_ARTHORIZON);
215
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_ARTHORIZON);
224
 
216
 
225
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Aggr.Hor."));
217
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Aggr.Hor."));
226
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_AGGRHORIZON);
218
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_AGGRHORIZON);
227
 
219
 
228
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Stats"));
220
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("Stats"));
229
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_STATS);
221
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_STATS);
230
 
222
 
231
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("A by FC"));
223
    write_ascii_string_pgm(MENU_LEFT, ++line, PSTR("A by FC"));
232
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_FCCURRENT);
224
    onoff(MENU_LEFT + 10, line, COSD_FLAGS_MODES & COSD_FLAG_FCCURRENT);
233
 
225
 
234
    // 2nd col
226
    // 2nd col
235
    line = 2;
227
    line = 2;
236
 
228
 
237
    write_ascii_string_pgm(MENU_MIDDLE, line, PSTR("V C-Strom"));
229
    write_ascii_string_pgm(MENU_MIDDLE, line, PSTR("V C-Strom"));
238
    onoff(MENU_MIDDLE + 10, line, COSD_FLAGS_MODES & COSD_FLAG_STROMVOLT);
230
    onoff(MENU_MIDDLE + 10, line, COSD_FLAGS_MODES & COSD_FLAG_STROMVOLT);
239
 
231
 
240
    write_ascii_string_pgm(MENU_MIDDLE, ++line, PSTR("Height by"));
232
    write_ascii_string_pgm(MENU_MIDDLE, ++line, PSTR("Height by"));
241
    if (COSD_FLAGS_CONFIG & COSD_FLAG_GPSHEIGHT) {
233
    if (COSD_FLAGS_CONFIG & COSD_FLAG_GPSHEIGHT) {
242
        write_ascii_string_pgm(MENU_MIDDLE + 10, line, PSTR(" GPS"));
234
        write_ascii_string_pgm(MENU_MIDDLE + 10, line, PSTR(" GPS"));
243
    } else {
235
    } else {
244
        write_ascii_string_pgm(MENU_MIDDLE + 10, line, PSTR("BARO"));
236
        write_ascii_string_pgm(MENU_MIDDLE + 10, line, PSTR("BARO"));
245
    }
237
    }
246
 
238
 
247
    write_ascii_string_pgm(MENU_MIDDLE, ++line, PSTR("Feet/mph"));
239
    write_ascii_string_pgm(MENU_MIDDLE, ++line, PSTR("Feet/mph"));
248
    onoff(MENU_MIDDLE + 10, line, COSD_FLAGS_CONFIG & COSD_FLAG_FEET);
240
    onoff(MENU_MIDDLE + 10, line, COSD_FLAGS_CONFIG & COSD_FLAG_FEET);
249
 
241
 
250
    write_ascii_string_pgm(MENU_MIDDLE, ++line, PSTR("Big Vario"));
242
    write_ascii_string_pgm(MENU_MIDDLE, ++line, PSTR("Big Vario"));
251
    onoff(MENU_MIDDLE + 10, line, COSD_FLAGS_MODES & COSD_FLAG_BIGVARIO);
243
    onoff(MENU_MIDDLE + 10, line, COSD_FLAGS_MODES & COSD_FLAG_BIGVARIO);
252
 
244
 
253
 
245
 
254
    // bottom
246
    // bottom
255
    write_ascii_string_pgm(MENU_LEFT, 9, PSTR("Reset uptime"));
247
    write_ascii_string_pgm(MENU_LEFT, 9, PSTR("Reset uptime"));
256
 
248
 
257
    write_ascii_string_pgm(MENU_LEFT, 10, PSTR("Display Mode"));
249
    write_ascii_string_pgm(MENU_LEFT, 10, PSTR("Display Mode"));
258
    write_ascii_string_pgm(18, 10, (const char *)(pgm_read_word(&(mode->desc))));
250
    write_ascii_string_pgm(18, 10, (const char *)(pgm_read_word(&(mode->desc))));
259
 
251
 
260
    write_ascii_string_pgm(MENU_LEFT, 11, PSTR("Save config"));
252
    write_ascii_string_pgm(MENU_LEFT, 11, PSTR("Save config"));
261
    write_ascii_string_pgm(MENU_LEFT, 12, PSTR("EXIT"));
253
    write_ascii_string_pgm(MENU_LEFT, 12, PSTR("EXIT"));
262
 
254
 
263
    old_y = y;
255
    old_y = y;
264
}
256
}
265
 
257
 
266
/**
258
/**
267
 * some sort of clicking response in the menu
259
 * some sort of clicking response in the menu
268
 */
260
 */
269
void config_menu_doclick(uint8_t chosen) {
261
void config_menu_doclick(uint8_t chosen) {
270
    write_ascii_string_pgm(MENU_LEFT, chosen + MENU_TOP - 6, PSTR("DONE              "));
262
    write_ascii_string_pgm(MENU_LEFT, chosen + MENU_TOP - 6, PSTR("DONE              "));
271
    _delay_ms(500);
263
    _delay_ms(500);
272
    config_menu_drawings(chosen);
264
    config_menu_drawings(chosen);
273
}
265
}
274
 
266
 
275
/**
267
/**
276
 * a simple config menu tryout
268
 * a simple config menu tryout
277
 */
269
 */
278
void config_menu(void) {
270
void config_menu(void) {
279
    // disable interrupts (makes the menu more smoothely)
271
    // disable interrupts (makes the menu more smoothely)
280
    cli();
272
    cli();
281
 
273
 
282
    // clear screen
274
    // clear screen
283
    clear();
275
    clear();
284
 
276
 
285
    uint8_t chosen = 0;
277
    uint8_t chosen = 0;
286
    uint8_t inmenu = 1;
278
    uint8_t inmenu = 1;
287
    write_ascii_string_pgm(6, 1, PSTR("C-OSD Config Menu"));
279
    write_ascii_string_pgm(6, 1, PSTR("C-OSD Config Menu"));
288
 
280
 
289
    // wait a bit before doing stuff so user has chance to release button
281
    // wait a bit before doing stuff so user has chance to release button
290
    _delay_ms(250);
282
    _delay_ms(250);
291
 
283
 
292
    config_menu_drawings(chosen);
284
    config_menu_drawings(chosen);
293
 
285
 
294
    while (inmenu) {
286
    while (inmenu) {
295
        if (s2_pressed()) {
287
        if (s2_pressed()) {
296
            chosen = (chosen + 1) % 17;
288
            chosen = (chosen + 1) % 17;
297
            if (chosen == 10) chosen = 13; // SKIP unused menu space for now
289
            if (chosen == 10) chosen = 13; // SKIP unused menu space for now
298
            config_menu_drawings(chosen);
290
            config_menu_drawings(chosen);
299
            _delay_ms(500);
291
            _delay_ms(500);
300
        } else if (s1_pressed()) {
292
        } else if (s1_pressed()) {
301
            switch (chosen) {
293
            switch (chosen) {
302
                case 0: // NTSC or PAL
294
                case 0: // NTSC or PAL
303
                    COSD_FLAGS_CONFIG ^= COSD_FLAG_NTSC;
295
                    COSD_FLAGS_CONFIG ^= COSD_FLAG_NTSC;
304
                    // Setup Video Mode
296
                    // Setup Video Mode
305
                    if (COSD_FLAGS_CONFIG & COSD_FLAG_NTSC) {
297
                    if (COSD_FLAGS_CONFIG & COSD_FLAG_NTSC) {
306
                        // NTSC + enable display immediately (VM0)
298
                        // NTSC + enable display immediately (VM0)
307
                        spi_send_byte(0x00, 0b00001000);
299
                        spi_send_byte(0x00, 0b00001000);
308
 
300
 
309
                        bottom_line = 12;
301
                        bottom_line = 12;
310
                    } else {
302
                    } else {
311
                        // PAL + enable display immediately (VM0)
303
                        // PAL + enable display immediately (VM0)
312
                        spi_send_byte(0x00, 0b01001000);
304
                        spi_send_byte(0x00, 0b01001000);
313
 
305
 
314
                        bottom_line = 14;
306
                        bottom_line = 14;
315
                    }
307
                    }
316
                    break;
308
                    break;
317
                case 1: // full HUD
309
                case 1: // full HUD
318
                    COSD_FLAGS_MODES ^= COSD_FLAG_HUD;
310
                    COSD_FLAGS_MODES ^= COSD_FLAG_HUD;
319
                    break;
311
                    break;
320
                case 2: // art horizon
312
                case 2: // art horizon
321
                    COSD_FLAGS_MODES ^= COSD_FLAG_ARTHORIZON;
313
                    COSD_FLAGS_MODES ^= COSD_FLAG_ARTHORIZON;
322
                    break;
314
                    break;
323
                case 3: // aggressiva horizon
315
                case 3: // aggressiva horizon
324
                    COSD_FLAGS_MODES ^= COSD_FLAG_AGGRHORIZON;
316
                    COSD_FLAGS_MODES ^= COSD_FLAG_AGGRHORIZON;
325
                    break;
317
                    break;
326
                case 4: // statistics
318
                case 4: // statistics
327
                    COSD_FLAGS_MODES ^= COSD_FLAG_STATS;
319
                    COSD_FLAGS_MODES ^= COSD_FLAG_STATS;
328
                    break;
320
                    break;
329
                case 5: // current by fc
321
                case 5: // current by fc
330
                    COSD_FLAGS_MODES ^= COSD_FLAG_FCCURRENT;
322
                    COSD_FLAGS_MODES ^= COSD_FLAG_FCCURRENT;
331
                    break;
323
                    break;
332
                case 6: // 2nd voltage by c-strom
324
                case 6: // 2nd voltage by c-strom
333
                    COSD_FLAGS_MODES ^= COSD_FLAG_STROMVOLT;
325
                    COSD_FLAGS_MODES ^= COSD_FLAG_STROMVOLT;
334
                    break;
326
                    break;
335
                case 7: // GPS or BARO height
327
                case 7: // GPS or BARO height
336
                    COSD_FLAGS_CONFIG ^= COSD_FLAG_GPSHEIGHT;
328
                    COSD_FLAGS_CONFIG ^= COSD_FLAG_GPSHEIGHT;
337
                    break;
329
                    break;
338
                case 8: // Feet and mph?
330
                case 8: // Feet and mph?
339
                    COSD_FLAGS_CONFIG ^= COSD_FLAG_FEET;
331
                    COSD_FLAGS_CONFIG ^= COSD_FLAG_FEET;
340
                    break;
332
                    break;
341
                case 9: // big vario
333
                case 9: // big vario
342
                    COSD_FLAGS_MODES ^= COSD_FLAG_BIGVARIO;
334
                    COSD_FLAGS_MODES ^= COSD_FLAG_BIGVARIO;
343
                    break;
335
                    break;
344
                case 13: // reset uptime
336
                case 13: // reset uptime
345
                    uptime = 0;
337
                    uptime = 0;
346
                    config_menu_doclick(chosen);
338
                    config_menu_doclick(chosen);
347
                    break;
339
                    break;
348
                case 14: // change mode
340
                case 14: // change mode
349
#if FCONLY
341
#if FCONLY
350
                    COSD_DISPLAYMODE = (COSD_DISPLAYMODE + 1) % (sizeof (fcdisplaymodes) / sizeof (displaymode_t));
342
                    COSD_DISPLAYMODE = (COSD_DISPLAYMODE + 1) % (sizeof (fcdisplaymodes) / sizeof (displaymode_t));
351
                    mode = fcdisplaymodes;
343
                    mode = fcdisplaymodes;
352
                    mode += COSD_DISPLAYMODE;
344
                    mode += COSD_DISPLAYMODE;
353
                    osd_fcmode = (int(*)(void)) pgm_read_word(&mode->dfun);
345
                    osd_fcmode = (int(*)(void)) pgm_read_word(&mode->dfun);
354
#else
346
#else
355
                    COSD_DISPLAYMODE = (COSD_DISPLAYMODE + 1) % (sizeof (ncdisplaymodes) / sizeof (displaymode_t));
347
                    COSD_DISPLAYMODE = (COSD_DISPLAYMODE + 1) % (sizeof (ncdisplaymodes) / sizeof (displaymode_t));
356
                    mode = ncdisplaymodes;
348
                    mode = ncdisplaymodes;
357
                    mode += COSD_DISPLAYMODE;
349
                    mode += COSD_DISPLAYMODE;
358
                    osd_ncmode = (int(*)(void)) pgm_read_word(&mode->dfun);
350
                    osd_ncmode = (int(*)(void)) pgm_read_word(&mode->dfun);
359
#endif
351
#endif
360
                    break;
352
                    break;
361
                case 15: // save
353
                case 15: // save
362
                    save_eeprom();
354
                    save_eeprom();
363
                    config_menu_doclick(chosen);
355
                    config_menu_doclick(chosen);
364
                    break;
356
                    break;
365
                case 16: // exit
357
                case 16: // exit
366
                    inmenu = 0;
358
                    inmenu = 0;
367
                    config_menu_doclick(chosen);
359
                    config_menu_doclick(chosen);
368
                    break;
360
                    break;
369
            }
361
            }
370
            config_menu_drawings(chosen);
362
            config_menu_drawings(chosen);
371
            _delay_ms(250);
363
            _delay_ms(250);
372
        }
364
        }
373
    }
365
    }
374
 
366
 
375
    // clear screen up again
367
    // clear screen up again
376
    clear();
368
    clear();
377
 
369
 
378
    // update flags to paint display again if needed
370
    // update flags to paint display again if needed
379
    COSD_FLAGS_RUNTIME &= ~COSD_ICONS_WRITTEN;
371
    COSD_FLAGS_RUNTIME &= ~COSD_ICONS_WRITTEN;
380
 
372
 
381
    // enable interrupts again
373
    // enable interrupts again
382
    sei();
374
    sei();
383
}
375
}
384
 
376
 
385
#endif
377
#endif
386
 
378