Subversion Repositories Projects

Rev

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

Rev 387 Rev 388
1
/****************************************************************************
1
/****************************************************************************
2
 *   Copyright (C) 2009 by Claas Anders "CaScAdE" Rathje                    *
2
 *   Copyright (C) 2009 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
 *   Credits to:                                                            *
21
 *   Credits to:                                                            *
22
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project       *
22
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project       *
23
 *   Gregor "killagreg" Stobrawa for making the MK code readable            *
23
 *   Gregor "killagreg" Stobrawa for making the MK code readable            *
24
 *   Klaus "akku" Buettner for the hardware                                 *
24
 *   Klaus "akku" Buettner for the hardware                                 *
25
 *   Manuel "KeyOz" Schrape for explaining the MK protocol to me            *
25
 *   Manuel "KeyOz" Schrape for explaining the MK protocol to me            *
26
 ****************************************************************************/
26
 ****************************************************************************/
27
 
27
 
28
#include <avr/io.h>
28
#include <avr/io.h>
29
#include <avr/interrupt.h>
29
#include <avr/interrupt.h>
30
#include <util/delay.h>
30
#include <util/delay.h>
31
#include <avr/pgmspace.h> 
31
#include <avr/pgmspace.h> 
32
#include "main.h"
32
#include "main.h"
33
#include "max7456_software_spi.h"
33
#include "max7456_software_spi.h"
34
#include "usart1.h"
34
#include "usart1.h"
35
 
35
 
36
/* TODO:
36
/* TODO:
37
 * - verifiy correctness of values
37
 * - verifiy correctness of values
38
 * - clean up code :)
38
 * - clean up code :)
39
 */
39
 */
40
 
40
 
41
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
41
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
42
// data structs not needed for character flashin
42
// data structs not needed for character flashin
43
#include "mk-data-structs.h"
43
#include "mk-data-structs.h"
44
 
44
 
45
/* ##########################################################################
45
/* ##########################################################################
46
 * global definitions and global vars
46
 * global definitions and global vars
47
 * ##########################################################################*/
47
 * ##########################################################################*/
48
 
48
 
49
volatile uint16_t setsReceived = 0;
49
volatile uint16_t setsReceived = 0;
50
 
50
 
51
volatile NaviData_t naviData;
51
volatile NaviData_t naviData;
52
volatile DebugOut_t debugData;
52
volatile DebugOut_t debugData;
53
 
53
 
54
// cache old vars for blinking attribute, checkup is faster than full
54
// cache old vars for blinking attribute, checkup is faster than full
55
// attribute write each time
55
// attribute write each time
56
volatile uint8_t last_UBat = 255;
56
volatile uint8_t last_UBat = 255;
57
volatile uint8_t last_RC_Quality = 255;
57
volatile uint8_t last_RC_Quality = 255;
58
 
58
 
59
// 16bit should be enough, normal LiPos don't last that long
59
// 16bit should be enough, normal LiPos don't last that long
60
volatile uint16_t uptime = 0;
60
volatile uint16_t uptime = 0;
61
volatile uint16_t timer = 0;
61
volatile uint16_t timer = 0;
62
 
62
 
63
// remember last time data was received
63
// remember last time data was received
64
volatile uint8_t seconds_since_last_data = 0;
64
volatile uint8_t seconds_since_last_data = 0;
65
 
65
 
66
// store stats description in progmem to save space
66
// store stats description in progmem to save space
67
char stats_item_0[] PROGMEM = "max Altitude:";
67
char stats_item_0[] PROGMEM = "max Altitude:";
68
char stats_item_1[] PROGMEM = "max Speed   :";
68
char stats_item_1[] PROGMEM = "max Speed   :";
69
char stats_item_2[] PROGMEM = "max Distance:";
69
char stats_item_2[] PROGMEM = "max Distance:";
70
char stats_item_3[] PROGMEM = "min voltage :";
70
char stats_item_3[] PROGMEM = "min voltage :";
71
char stats_item_4[] PROGMEM = "max time    :";
71
char stats_item_4[] PROGMEM = "max time    :";
72
char* stats_item_pointers[] PROGMEM = {stats_item_0, stats_item_1, stats_item_2,
72
char* stats_item_pointers[] PROGMEM = {stats_item_0, stats_item_1, stats_item_2,
73
                                        stats_item_3, stats_item_4};
73
                                        stats_item_3, stats_item_4};
74
 
74
 
75
// store more fixed strings in progmen
75
// store more fixed strings in progmen
76
char ON[] PROGMEM = "ON ";
76
char ON[] PROGMEM = "ON ";
77
char OFF[] PROGMEM = "OFF";
77
char OFF[] PROGMEM = "OFF";
78
 
78
 
79
// big vario arrays 
79
// big vario arrays 
80
char vario_00[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xff};
80
char vario_00[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xff};
81
char vario_01[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc0};
81
char vario_01[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc0};
82
char vario_02[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc1};
82
char vario_02[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc1};
83
char vario_03[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0x00};
83
char vario_03[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0x00};
84
char vario_04[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc0, 0x00};
84
char vario_04[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc0, 0x00};
85
char vario_05[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc1, 0x00};
85
char vario_05[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc1, 0x00};
86
char vario_06[5] PROGMEM = {0x00, 0x00, 0xc2, 0x00, 0x00};
86
char vario_06[5] PROGMEM = {0x00, 0x00, 0xc2, 0x00, 0x00};
87
char vario_07[5] PROGMEM = {0x00, 0x00, 0xbb, 0x00, 0x00};
87
char vario_07[5] PROGMEM = {0x00, 0x00, 0xbb, 0x00, 0x00};
88
char vario_08[5] PROGMEM = {0x00, 0x00, 0xc3, 0x00, 0x00};
88
char vario_08[5] PROGMEM = {0x00, 0x00, 0xc3, 0x00, 0x00};
89
char vario_09[5] PROGMEM = {0x00, 0xc4, 0xc3, 0x00, 0x00};
89
char vario_09[5] PROGMEM = {0x00, 0xc4, 0xc3, 0x00, 0x00};
90
char vario_10[5] PROGMEM = {0x00, 0xc5, 0xc3, 0x00, 0x00};
90
char vario_10[5] PROGMEM = {0x00, 0xc5, 0xc3, 0x00, 0x00};
91
char vario_11[5] PROGMEM = {0x00, 0xff, 0xc3, 0x00, 0x00};
91
char vario_11[5] PROGMEM = {0x00, 0xff, 0xc3, 0x00, 0x00};
92
char vario_12[5] PROGMEM = {0xc4, 0xff, 0xc3, 0x00, 0x00};
92
char vario_12[5] PROGMEM = {0xc4, 0xff, 0xc3, 0x00, 0x00};
93
char vario_13[5] PROGMEM = {0xc5, 0xff, 0xc3, 0x00, 0x00};
93
char vario_13[5] PROGMEM = {0xc5, 0xff, 0xc3, 0x00, 0x00};
94
char vario_14[5] PROGMEM = {0xff, 0xff, 0xc3, 0x00, 0x00};
94
char vario_14[5] PROGMEM = {0xff, 0xff, 0xc3, 0x00, 0x00};
95
char* vario_pnt[15] PROGMEM = {vario_00, vario_01, vario_02, vario_03, vario_04,
95
char* vario_pnt[15] PROGMEM = {vario_00, vario_01, vario_02, vario_03, vario_04,
96
                                vario_05, vario_06, vario_07, vario_08,
96
                                vario_05, vario_06, vario_07, vario_08,
97
                                vario_09, vario_10, vario_11, vario_12,
97
                                vario_09, vario_10, vario_11, vario_12,
98
                                vario_13, vario_14};
98
                                vario_13, vario_14};
99
 
99
 
100
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
100
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
101
 
101
 
102
// general PAL|NTSC distingiusch stuff
102
// general PAL|NTSC distingiusch stuff
103
uint8_t top_line = 1;
103
uint8_t top_line = 1;
104
uint8_t bottom_line = 14;
104
uint8_t bottom_line = 14;
105
 
105
 
106
// Flags
106
// Flags
107
uint8_t COSD_FLAGS = 0;
107
uint8_t COSD_FLAGS = 0;
108
 
108
 
109
/* ##########################################################################
109
/* ##########################################################################
110
 * debounce buttons
110
 * debounce buttons
111
 * ##########################################################################*/
111
 * ##########################################################################*/
112
int s1_pressed() {
112
int s1_pressed() {
113
        if (S1_PRESSED) {
113
        if (S1_PRESSED) {
114
                _delay_ms(25);
114
                _delay_ms(25);
115
                if (S1_PRESSED) return 1;
115
                if (S1_PRESSED) return 1;
116
        }
116
        }
117
        return 0;
117
        return 0;
118
}
118
}
119
 
119
 
120
int s2_pressed() {
120
int s2_pressed() {
121
        if (S2_PRESSED) {
121
        if (S2_PRESSED) {
122
                _delay_ms(25);
122
                _delay_ms(25);
123
                if (S2_PRESSED) return 1;
123
                if (S2_PRESSED) return 1;
124
        }
124
        }
125
        return 0;
125
        return 0;
126
}
126
}
127
 
127
 
128
 
128
 
129
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
129
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
130
 
130
 
131
/**
131
/**
132
 * serial support
132
 * serial support
133
 */
133
 */
134
//#include "usart1.c"
134
//#include "usart1.c"
135
 
135
 
136
 
136
 
137
/* ##########################################################################
137
/* ##########################################################################
138
 * timer stuff
138
 * timer stuff
139
 * ##########################################################################*/
139
 * ##########################################################################*/
140
 
140
 
141
/**
141
/**
142
 * timer kicks in every 1000uS ^= 1ms
142
 * timer kicks in every 1000uS ^= 1ms
143
 */
143
 */
144
ISR(TIMER0_OVF_vect) {
144
ISR(TIMER0_OVF_vect) {
145
    OCR0 = 15; // preload
145
    OCR0 = 15; // preload
146
    if (!timer--) {
146
    if (!timer--) {
147
        uptime++;
147
        uptime++;
148
        timer = 999;
148
        timer = 999;
149
                seconds_since_last_data++;
149
                seconds_since_last_data++;
150
    }
150
    }
151
}
151
}
152
 
152
 
153
/* ##########################################################################
153
/* ##########################################################################
154
 * compass stuff
154
 * compass stuff
155
 * ##########################################################################*/
155
 * ##########################################################################*/
156
 
156
 
157
/**
157
/**
158
 * convert the <heading> gotton from NC into an index
158
 * convert the <heading> gotton from NC into an index
159
 */
159
 */
160
uint8_t heading_conv(uint16_t heading) {
160
uint8_t heading_conv(uint16_t heading) {
161
    if (heading > 23 && heading < 68) {
161
    if (heading > 23 && heading < 68) {
162
        //direction = "NE";
162
        //direction = "NE";
163
        return 0;
163
        return 0;
164
    } else if (heading > 67 && heading < 113) {
164
    } else if (heading > 67 && heading < 113) {
165
        //direction = "E ";
165
        //direction = "E ";
166
        return 1;
166
        return 1;
167
    } else if (heading > 112 && heading < 158) {
167
    } else if (heading > 112 && heading < 158) {
168
        //direction = "SE";
168
        //direction = "SE";
169
        return 2;
169
        return 2;
170
    } else if (heading > 157 && heading < 203) {
170
    } else if (heading > 157 && heading < 203) {
171
        //direction = "S ";
171
        //direction = "S ";
172
        return 3;
172
        return 3;
173
    } else if (heading > 202 && heading < 248) {
173
    } else if (heading > 202 && heading < 248) {
174
        //direction = "SW";
174
        //direction = "SW";
175
        return 4;
175
        return 4;
176
    } else if (heading > 247 && heading < 293) {
176
    } else if (heading > 247 && heading < 293) {
177
        //direction = "W ";
177
        //direction = "W ";
178
        return 5;
178
        return 5;
179
    } else if (heading > 292 && heading < 338) {
179
    } else if (heading > 292 && heading < 338) {
180
        //direction = "NW";
180
        //direction = "NW";
181
        return 6;
181
        return 6;
182
    }
182
    }
183
    //direction = "N ";
183
    //direction = "N ";
184
    return 7;
184
    return 7;
185
}
185
}
186
 
186
 
187
/**
187
/**
188
 * convert the <heading> gotton from NC into a more
188
 * convert the <heading> gotton from NC into a more
189
 * precise index
189
 * precise index
190
 */
190
 */
191
uint8_t heading_fine_conv(uint16_t heading) {
191
uint8_t heading_fine_conv(uint16_t heading) {
192
        heading = ((heading * 10) + 113) % 3600;
192
        heading = ((heading * 10) + 113) % 3600;
193
        return (heading / 225);
193
        return (heading / 225);
194
}
194
}
195
 
195
 
196
/**
196
/**
197
 * draw a compass rose at <x>/<y> for <heading>
197
 * draw a compass rose at <x>/<y> for <heading>
198
 */
198
 */
199
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
199
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
200
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
200
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
201
    char rose[48] = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
201
    char rose[48] = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
202
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
202
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
203
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
203
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
204
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
204
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
205
        // the center is char 19 (north), we add the current heading in 8th
205
        // the center is char 19 (north), we add the current heading in 8th
206
        // which would be 22.5 degrees, but float would bloat up the code
206
        // which would be 22.5 degrees, but float would bloat up the code
207
        // and *10 / 225 would take ages... so we take the uncorrect way
207
        // and *10 / 225 would take ages... so we take the uncorrect way
208
    uint8_t front = 19 + (heading / 22);
208
    uint8_t front = 19 + (heading / 22);
209
    for (uint8_t i = 0; i < 9; i++) {
209
    for (uint8_t i = 0; i < 9; i++) {
210
                write_char_xy(x++, y, rose[front - 4 + i]);
210
                write_char_xy(x++, y, rose[front - 4 + i]);
211
    }
211
    }
212
}
212
}
213
 
213
 
214
/* ##########################################################################
214
/* ##########################################################################
215
 * battery index
215
 * battery index
216
 * ##########################################################################*/
216
 * ##########################################################################*/
217
/**
217
/**
218
 * draw a battery symbol at <x>/<y> according to <voltage>
218
 * draw a battery symbol at <x>/<y> according to <voltage>
219
 */
219
 */
220
void draw_battery(uint8_t x, uint8_t y, uint16_t voltage) {
220
void draw_battery(uint8_t x, uint8_t y, uint16_t voltage) {
221
        uint8_t percent = (100* (voltage - UBAT_WRN) / (UBAT_MAX - UBAT_WRN));
221
        uint8_t percent = (100* (voltage - UBAT_WRN) / (UBAT_MAX - UBAT_WRN));
222
        if (percent > 100) percent = 100;
222
        if (percent > 100) percent = 100;
223
        if (voltage < UBAT_WRN) percent = 0;
223
        if (voltage < UBAT_WRN) percent = 0;
224
        write_char_xy(x, y, 0x9d - (percent * 13 / 100));
224
        write_char_xy(x, y, 0x9d - (percent * 13 / 100));
225
        //write_ndigit_number_u(x, y-1, percent * 13 / 100, 100, 0);
225
        //write_ndigit_number_u(x, y-1, percent * 13 / 100, 100, 0);
226
}
226
}
227
 
227
 
228
/* ##########################################################################
228
/* ##########################################################################
229
 * variometer
229
 * variometer
230
 * ##########################################################################*/
230
 * ##########################################################################*/
231
/**
231
/**
232
 * draw variometer arrows at <x>/<y> according to <variometer>
232
 * draw variometer arrows at <x>/<y> according to <variometer>
233
 */
233
 */
234
void draw_variometer(uint8_t x, uint8_t y, int16_t variometer) {
234
void draw_variometer(uint8_t x, uint8_t y, int16_t variometer) {
235
        if (variometer == 0) {
235
        if (variometer == 0) {
236
                write_char_xy(x, y, 0xbb); // plain line
236
                write_char_xy(x, y, 0xbb); // plain line
237
        } else if (variometer > 0) { // gain height
237
        } else if (variometer > 0) { // gain height
238
                switch (variometer / 5){
238
                switch (variometer / 5){
239
                        case 0:
239
                        case 0:
240
                                //write_char_xy(x, y, 0xba); // smallest arrow up
240
                                //write_char_xy(x, y, 0xba); // smallest arrow up
241
                                write_char_xy(x, y, 0x70); // one arrow up
241
                                write_char_xy(x, y, 0x70); // one arrow up
242
                                break;
242
                                break;
243
                        case 1:
243
                        case 1:
244
                                //write_char_xy(x, y, 0xb9); // small arrow up
244
                                //write_char_xy(x, y, 0xb9); // small arrow up
245
                                write_char_xy(x, y, 0x71); // two arrows up
245
                                write_char_xy(x, y, 0x71); // two arrows up
246
                                break;
246
                                break;
247
                        case 2:
247
                        case 2:
248
                                //write_char_xy(x, y, 0xb8); // large arrow up
248
                                //write_char_xy(x, y, 0xb8); // large arrow up
249
                                write_char_xy(x, y, 0x72); // three arrows up
249
                                write_char_xy(x, y, 0x72); // three arrows up
250
                                break;
250
                                break;
251
                        default:
251
                        default:
252
                                //write_char_xy(x, y, 0xb7); // largest arrow up
252
                                //write_char_xy(x, y, 0xb7); // largest arrow up
253
                                write_char_xy(x, y, 0x73); // three black arrows up
253
                                write_char_xy(x, y, 0x73); // three black arrows up
254
                }
254
                }
255
        } else { // sink
255
        } else { // sink
256
                switch (variometer / -5){
256
                switch (variometer / -5){
257
                        case 0:
257
                        case 0:
258
                                //write_char_xy(x, y, 0xbc); // smallest arrow down
258
                                //write_char_xy(x, y, 0xbc); // smallest arrow down
259
                                write_char_xy(x, y, 0x77); // one arrow down
259
                                write_char_xy(x, y, 0x77); // one arrow down
260
                                break;
260
                                break;
261
                        case 1:
261
                        case 1:
262
                                //write_char_xy(x, y, 0xbd); // small arrow down
262
                                //write_char_xy(x, y, 0xbd); // small arrow down
263
                                write_char_xy(x, y, 0x76); // two arrows down
263
                                write_char_xy(x, y, 0x76); // two arrows down
264
                                break;
264
                                break;
265
                        case 2:
265
                        case 2:
266
                                //write_char_xy(x, y, 0xbe); // large arrow down
266
                                //write_char_xy(x, y, 0xbe); // large arrow down
267
                                write_char_xy(x, y, 0x75); // three arrows down
267
                                write_char_xy(x, y, 0x75); // three arrows down
268
                                break;
268
                                break;
269
                        default:
269
                        default:
270
                                //write_char_xy(x, y, 0xbf); // largest arrow down
270
                                //write_char_xy(x, y, 0xbf); // largest arrow down
271
                                write_char_xy(x, y, 0x74); // three black arrows down
271
                                write_char_xy(x, y, 0x74); // three black arrows down
272
                }
272
                }
273
        }
273
        }
274
}
274
}
275
 
275
 
276
/**
276
/**
277
 * draw a bigger vario with middle at <x>/<y> acording to <variometer>
277
 * draw a bigger vario with middle at <x>/<y> acording to <variometer>
278
 */
278
 */
279
void draw_big_variometer(uint8_t x, uint8_t y, int16_t variometer) {   
279
void draw_big_variometer(uint8_t x, uint8_t y, int16_t variometer) {   
280
        int16_t index = 7 + variometer;
280
        int16_t index = 7 + variometer;
281
        if (index > 14) index = 14;
281
        if (index > 14) index = 14;
282
        else if (index < 0) index = 0;
282
        else if (index < 0) index = 0;
283
       
283
       
284
        // TODO: why does write_string_pgm_down(x, y-2, vario_pnt[index], 5);
284
        // TODO: why does write_string_pgm_down(x, y-2, vario_pnt[index], 5);
285
        // not work??? WTF?!
285
        // not work??? WTF?!
286
        switch (index) {
286
        switch (index) {
287
                case 0: write_string_pgm_down(x, y-2, vario_pnt[0], 5);
287
                case 0: write_string_pgm_down(x, y-2, vario_pnt[0], 5);
288
                        break;
288
                        break;
289
                case 1: write_string_pgm_down(x, y-2, vario_pnt[1], 5);
289
                case 1: write_string_pgm_down(x, y-2, vario_pnt[1], 5);
290
                        break;
290
                        break;
291
                case 2: write_string_pgm_down(x, y-2, vario_pnt[2], 5);
291
                case 2: write_string_pgm_down(x, y-2, vario_pnt[2], 5);
292
                        break;
292
                        break;
293
                case 3: write_string_pgm_down(x, y-2, vario_pnt[3], 5);
293
                case 3: write_string_pgm_down(x, y-2, vario_pnt[3], 5);
294
                        break;
294
                        break;
295
                case 4: write_string_pgm_down(x, y-2, vario_pnt[4], 5);
295
                case 4: write_string_pgm_down(x, y-2, vario_pnt[4], 5);
296
                        break;
296
                        break;
297
                case 5: write_string_pgm_down(x, y-2, vario_pnt[5], 5);
297
                case 5: write_string_pgm_down(x, y-2, vario_pnt[5], 5);
298
                        break;
298
                        break;
299
                case 6: write_string_pgm_down(x, y-2, vario_pnt[6], 5);
299
                case 6: write_string_pgm_down(x, y-2, vario_pnt[6], 5);
300
                        break;
300
                        break;
301
                case 7: write_string_pgm_down(x, y-2, vario_pnt[7], 5);
301
                case 7: write_string_pgm_down(x, y-2, vario_pnt[7], 5);
302
                        break;
302
                        break;
303
                case 8: write_string_pgm_down(x, y-2, vario_pnt[8], 5);
303
                case 8: write_string_pgm_down(x, y-2, vario_pnt[8], 5);
304
                        break;
304
                        break;
305
                case 9: write_string_pgm_down(x, y-2, vario_pnt[9], 5);
305
                case 9: write_string_pgm_down(x, y-2, vario_pnt[9], 5);
306
                        break;
306
                        break;
307
                case 10: write_string_pgm_down(x, y-2, vario_pnt[10], 5);
307
                case 10: write_string_pgm_down(x, y-2, vario_pnt[10], 5);
308
                        break;
308
                        break;
309
                case 11: write_string_pgm_down(x, y-2, vario_pnt[11], 5);
309
                case 11: write_string_pgm_down(x, y-2, vario_pnt[11], 5);
310
                        break;
310
                        break;
311
                case 12: write_string_pgm_down(x, y-2, vario_pnt[12], 5);
311
                case 12: write_string_pgm_down(x, y-2, vario_pnt[12], 5);
312
                        break;
312
                        break;
313
                case 13: write_string_pgm_down(x, y-2, vario_pnt[13], 5);
313
                case 13: write_string_pgm_down(x, y-2, vario_pnt[13], 5);
314
                        break;
314
                        break;
315
                default: write_string_pgm_down(x, y-2, vario_pnt[14], 5);
315
                default: write_string_pgm_down(x, y-2, vario_pnt[14], 5);
316
        }              
316
        }              
317
}
317
}
318
 
318
 
319
/* ##########################################################################
319
/* ##########################################################################
320
 * artificial horizon
320
 * artificial horizon
321
 * ##########################################################################*/
321
 * ##########################################################################*/
322
// remember last time displayed values
322
// remember last time displayed values
323
int8_t old_af_x = -1, old_af_y = -1;
323
int8_t old_af_x = -1, old_af_y = -1;
324
 
324
 
325
/**
325
/**
326
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
326
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
327
 * from line <firstline> to <listlines> for given <nick> and <roll> values
327
 * from line <firstline> to <listlines> for given <nick> and <roll> values
328
 */
328
 */
329
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
329
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
330
        char noodle[5] = {225, 225, 226, 227, 227};
330
        char noodle[5] = {225, 225, 226, 227, 227};
331
        uint8_t center_x = 15;
331
        uint8_t center_x = 15;
332
        uint8_t center_y = lastline - firstline;
332
        uint8_t center_y = lastline - firstline;
333
        center_y = 7;
333
        center_y = 7;
334
        write_char_xy(center_x,center_y,228);
334
        write_char_xy(center_x,center_y,228);
335
        uint8_t cpos, nicky, rollx;
335
        uint8_t cpos, nicky, rollx;
336
       
336
       
337
        // which line
337
        // which line
338
        int8_t ypos =  nick / 20;
338
        int8_t ypos =  nick / 20;
339
        // which character from the array?
339
        // which character from the array?
340
        if (nick < 0) {
340
        if (nick < 0) {
341
                cpos = -1*((nick - (ypos * 20))/4);
341
                cpos = -1*((nick - (ypos * 20))/4);
342
                ypos--;
342
                ypos--;
343
        } else cpos = 4-((nick - (ypos * 20))/4);
343
        } else cpos = 4-((nick - (ypos * 20))/4);
344
        if (cpos > 4) cpos = 4;
344
        if (cpos > 4) cpos = 4;
345
 
345
 
346
        nicky = center_y - ypos;
346
        nicky = center_y - ypos;
347
        if (nicky > lastline) nicky = lastline;
347
        if (nicky > lastline) nicky = lastline;
348
        else if (nicky < firstline) nicky = firstline;
348
        else if (nicky < firstline) nicky = firstline;
349
 
349
 
350
        // ensure roll-borders
350
        // ensure roll-borders
351
        rollx = (roll / 8)+15;
351
        rollx = (roll / 8)+15;
352
        if (rollx < 2) rollx = 2;
352
        if (rollx < 2) rollx = 2;
353
        else if (rollx > 28) rollx = 28;
353
        else if (rollx > 28) rollx = 28;
354
 
354
 
355
 
355
 
356
        // clear roll
356
        // clear roll
357
        if (old_af_x != rollx && old_af_x >= 0) {
357
        if (old_af_x != rollx && old_af_x >= 0) {
358
                write_char_xy(old_af_x,13,0);
358
                write_char_xy(old_af_x,13,0);
359
        }
359
        }
360
 
360
 
361
        // clear nick
361
        // clear nick
362
        if (old_af_y != nicky && old_af_y >= 0) {
362
        if (old_af_y != nicky && old_af_y >= 0) {
363
                write_char_xy(center_x-1,old_af_y,0);
363
                write_char_xy(center_x-1,old_af_y,0);
364
                write_char_xy(center_x+1,old_af_y,0);
364
                write_char_xy(center_x+1,old_af_y,0);
365
        }
365
        }
366
 
366
 
367
 
367
 
368
        // draw nick
368
        // draw nick
369
        write_char_xy(center_x-1,nicky,noodle[cpos]);
369
        write_char_xy(center_x-1,nicky,noodle[cpos]);
370
        write_char_xy(center_x+1,nicky,noodle[cpos]);
370
        write_char_xy(center_x+1,nicky,noodle[cpos]);
371
 
371
 
372
        // draw roll
372
        // draw roll
373
        write_char_xy(rollx,lastline,229);
373
        write_char_xy(rollx,lastline,229);
374
 
374
 
375
        // update old vars
375
        // update old vars
376
        old_af_x = rollx;
376
        old_af_x = rollx;
377
        old_af_y = nicky;
377
        old_af_y = nicky;
378
 
378
 
379
        // debug numbers
379
        // debug numbers
380
        //write_3digit_number_u(20,6,cpos);
380
        //write_3digit_number_u(20,6,cpos);
381
        //write_number_s(20,7,ypos);    
381
        //write_number_s(20,7,ypos);    
382
        //write_number_s(0,7,nick);             
382
        //write_number_s(0,7,nick);             
383
        //write_number_s(18,11,roll);   
383
        //write_number_s(18,11,roll);   
384
}
384
}
385
 
385
 
386
/* ##########################################################################
386
/* ##########################################################################
387
 * A simple config menu for the flags
387
 * A simple config menu for the flags
388
 * ##########################################################################*/
388
 * ##########################################################################*/
389
 
389
 
390
/**
390
/**
391
 * helper function for menu updating
391
 * helper function for menu updating
392
 */
392
 */
393
void config_menu_drawings(uint8_t chosen) {
393
void config_menu_drawings(uint8_t chosen) {
394
    // clear prevoius _cursor_
394
    // clear prevoius _cursor_
395
    write_ascii_string(3, (chosen + 5) % 8, " ");
395
    write_ascii_string(3, (chosen + 5) % 8, " ");
396
    // draw current _cursor_
396
    // draw current _cursor_
397
    write_ascii_string(3, chosen + 5, ">");
397
    write_ascii_string(3, chosen + 5, ">");
398
    if (COSD_FLAGS & COSD_FLAG_HUD) {
398
    if (COSD_FLAGS & COSD_FLAG_HUD) {
399
        write_ascii_string_pgm(23, 5, ON);
399
        write_ascii_string_pgm(23, 5, ON);
400
    } else {
400
    } else {
401
                write_ascii_string_pgm(23, 5, OFF);
401
                write_ascii_string_pgm(23, 5, OFF);
402
    }
402
    }
403
    if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
403
    if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
404
        write_ascii_string_pgm(23, 6, ON);
404
        write_ascii_string_pgm(23, 6, ON);
405
    } else {
405
    } else {
406
        write_ascii_string_pgm(23, 6, OFF);
406
        write_ascii_string_pgm(23, 6, OFF);
407
    }
407
    }
408
        if (COSD_FLAGS & COSD_FLAG_BIGVARIO) {
408
        if (COSD_FLAGS & COSD_FLAG_BIGVARIO) {
409
        write_ascii_string_pgm(23, 7, ON);
409
        write_ascii_string_pgm(23, 7, ON);
410
    } else {
410
    } else {
411
                write_ascii_string_pgm(23, 7, OFF);
411
                write_ascii_string_pgm(23, 7, OFF);
412
    }
412
    }
413
        if (COSD_FLAGS & COSD_FLAG_STATS) {
413
        if (COSD_FLAGS & COSD_FLAG_STATS) {
414
        write_ascii_string_pgm(23, 8, ON);
414
        write_ascii_string_pgm(23, 8, ON);
415
    } else {
415
    } else {
416
        write_ascii_string_pgm(23, 8, OFF);
416
        write_ascii_string_pgm(23, 8, OFF);
417
    }
417
    }
418
    if (COSD_FLAGS & COSD_FLAG_WARNINGS) {
418
    if (COSD_FLAGS & COSD_FLAG_WARNINGS) {
419
        write_ascii_string_pgm(23, 9, ON);
419
        write_ascii_string_pgm(23, 9, ON);
420
    } else {
420
    } else {
421
        write_ascii_string_pgm(23, 9, OFF);
421
        write_ascii_string_pgm(23, 9, OFF);
422
    }
422
    }
423
}
423
}
424
 
424
 
425
/**
425
/**
426
 * some sort of clicking response in the menu
426
 * some sort of clicking response in the menu
427
 */
427
 */
428
void config_menu_doclick(uint8_t chosen, char** menu) {
428
void config_menu_doclick(uint8_t chosen, char** menu) {
429
        write_ascii_string(4, chosen + 5, "DONE              ");
429
        write_ascii_string(4, chosen + 5, "DONE              ");
430
        _delay_ms(1000);
430
        _delay_ms(1000);
431
        write_ascii_string(4, chosen + 5, menu[chosen]);
431
        write_ascii_string(4, chosen + 5, menu[chosen]);
432
}
432
}
433
 
433
 
434
/**
434
/**
435
 * a simple config menu tryout
435
 * a simple config menu tryout
436
 */
436
 */
437
void config_menu(void) {
437
void config_menu(void) {
438
        // disable interrupts (makes the menu more smoothely)
438
        // disable interrupts (makes the menu more smoothely)
439
        cli();
439
        cli();
440
 
440
 
441
        // clear screen
441
        // clear screen
442
        clear();
442
        clear();
443
       
443
       
444
        char* menu[9] = {"Full HUD",
444
        char* menu[9] = {"Full HUD",
445
                                         "Art.Horizon in HUD",
445
                                         "Art.Horizon in HUD",
446
                                         "Big Vario bar",
446
                                         "Big Vario bar",
447
                                         "Statistics",
447
                                         "Statistics",
448
                                         "Warnings",    // TODO: do it!
448
                                         "Warnings",    // TODO: do it!
449
                                         "Reset uptime",
449
                                         "Reset uptime",
450
                                         "Request OSD-data",
450
                                         "Request OSD-data",
451
                                         "Disable Debug-data",
451
                                         "Disable Debug-data",
452
                                         "EXIT"};
452
                                         "EXIT"};
453
 
453
 
454
        uint8_t inmenu = 1;
454
        uint8_t inmenu = 1;
455
        uint8_t chosen = 0;
455
        uint8_t chosen = 0;
456
        write_ascii_string(6,  2, "C-OSD Config Menu");
456
        write_ascii_string(6,  2, "C-OSD Config Menu");
457
 
457
 
458
        // wait a bit before doing stuff so user has chance to release button
458
        // wait a bit before doing stuff so user has chance to release button
459
        _delay_ms(250);
459
        _delay_ms(250);
460
 
460
 
461
        write_ascii_string(4,  5, menu[0]);
461
        write_ascii_string(4,  5, menu[0]);
462
        write_ascii_string(4,  6, menu[1]);
462
        write_ascii_string(4,  6, menu[1]);
463
        write_ascii_string(4,  7, menu[2]);
463
        write_ascii_string(4,  7, menu[2]);
464
        write_ascii_string(4,  8, menu[3]);
464
        write_ascii_string(4,  8, menu[3]);
465
        write_ascii_string(4,  9, menu[4]);
465
        write_ascii_string(4,  9, menu[4]);
466
        write_ascii_string(4, 10, menu[5]);
466
        write_ascii_string(4, 10, menu[5]);
467
        write_ascii_string(4, 11, menu[6]);
467
        write_ascii_string(4, 11, menu[6]);
468
        write_ascii_string(4, 12, menu[7]);
468
        write_ascii_string(4, 12, menu[7]);
469
        write_ascii_string(4, 13, menu[8]);
469
        write_ascii_string(4, 13, menu[8]);
470
 
470
 
471
        config_menu_drawings(chosen);
471
        config_menu_drawings(chosen);
472
 
472
 
473
        while (inmenu) {
473
        while (inmenu) {
474
                        if (s2_pressed()) {
474
                        if (s2_pressed()) {
475
                                write_ascii_string(3,  chosen+5, " ");
475
                                write_ascii_string(3,  chosen+5, " ");
476
                                chosen = (chosen + 1) % 9;
476
                                chosen = (chosen + 1) % 9;
477
                                write_ascii_string(3,  chosen+5, ">");
477
                                write_ascii_string(3,  chosen+5, ">");
478
                                _delay_ms(500);
478
                                _delay_ms(500);
479
                        } else if (s1_pressed()) {
479
                        } else if (s1_pressed()) {
480
                                switch (chosen) {
480
                                switch (chosen) {
481
                                        case 0:         // full HUD
481
                                        case 0:         // full HUD
482
                                                COSD_FLAGS ^= COSD_FLAG_HUD;
482
                                                COSD_FLAGS ^= COSD_FLAG_HUD;
483
                                                config_menu_drawings(chosen);
483
                                                config_menu_drawings(chosen);
484
                                                break;
484
                                                break;
485
                                        case 1:         // art horizon
485
                                        case 1:         // art horizon
486
                                                COSD_FLAGS ^= COSD_FLAG_ARTHORIZON;
486
                                                COSD_FLAGS ^= COSD_FLAG_ARTHORIZON;
487
                                                config_menu_drawings(chosen);
487
                                                config_menu_drawings(chosen);
488
                                                break;
488
                                                break;
489
                                        case 2:         // big vario
489
                                        case 2:         // big vario
490
                                                COSD_FLAGS ^= COSD_FLAG_BIGVARIO;
490
                                                COSD_FLAGS ^= COSD_FLAG_BIGVARIO;
491
                                                config_menu_drawings(chosen);
491
                                                config_menu_drawings(chosen);
492
                                                break;
492
                                                break;
493
                                        case 3:         // statistics
493
                                        case 3:         // statistics
494
                                                COSD_FLAGS ^= COSD_FLAG_STATS;
494
                                                COSD_FLAGS ^= COSD_FLAG_STATS;
495
                                                config_menu_drawings(chosen);
495
                                                config_menu_drawings(chosen);
496
                                                break;
496
                                                break;
497
                                        case 4:         // warnings
497
                                        case 4:         // warnings
498
                                                COSD_FLAGS ^= COSD_FLAG_WARNINGS;
498
                                                COSD_FLAGS ^= COSD_FLAG_WARNINGS;
499
                                                config_menu_drawings(chosen);
499
                                                config_menu_drawings(chosen);
500
                                                break;
500
                                                break;
501
                                        case 5:         // reset uptime
501
                                        case 5:         // reset uptime
502
                                                uptime = 0;
502
                                                uptime = 0;
503
                                                config_menu_doclick(chosen, menu);
503
                                                config_menu_doclick(chosen, menu);
504
                                                break;
504
                                                break;
505
                                        case 6:         // re-request OSD data
505
                                        case 6:         // re-request OSD data
506
                                                // request OSD Data from NC every 100ms
506
                                                // request OSD Data from NC every 100ms
507
                                                usart1_request_mk_data(1, 'o', 100);
507
                                                usart1_request_mk_data(1, 'o', 100);
508
                                                config_menu_doclick(chosen, menu);
508
                                                config_menu_doclick(chosen, menu);
509
                                                break;
509
                                                break;
510
                                        case 7:         // disable debug data
510
                                        case 7:         // disable debug data
511
                                                // disable sending of debug data
511
                                                // disable sending of debug data
512
                                                // may result in smoother ddata display
512
                                                // may result in smoother ddata display
513
                                                usart1_request_mk_data(0, 'd', 0);
513
                                                usart1_request_mk_data(0, 'd', 0);
514
                                                config_menu_doclick(chosen, menu);
514
                                                config_menu_doclick(chosen, menu);
515
                                                break;
515
                                                break;
516
                                        case 8:         // exit
516
                                        case 8:         // exit
517
                                                inmenu = 0;
517
                                                inmenu = 0;
518
                                                break;
518
                                                break;
519
                                }
519
                                }
520
                                _delay_ms(250);
520
                                _delay_ms(250);
521
                        }
521
                        }
522
        }
522
        }
523
 
523
 
524
        // clear screen up again
524
        // clear screen up again
525
        clear();
525
        clear();
526
 
526
 
527
        // update flags to paint display again if needed
527
        // update flags to paint display again if needed
528
        COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
528
        COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
529
 
529
 
530
        // enable interrupts again
530
        // enable interrupts again
531
        sei();
531
        sei();
532
}
532
}
533
 
533
 
534
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
534
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
535
/* ##########################################################################
535
/* ##########################################################################
536
 * MAIN
536
 * MAIN
537
 * ##########################################################################*/
537
 * ##########################################################################*/
538
int main(void) {
538
int main(void) {
539
    // set up FLAGS, compiler should flatten this one
539
    // set up FLAGS, compiler should flatten this one
540
    COSD_FLAGS = (NTSC << 0);
540
    COSD_FLAGS = (NTSC << 0);
541
    COSD_FLAGS |= (HUD << 1);
541
    COSD_FLAGS |= (HUD << 1);
542
    COSD_FLAGS |= (ARTHORIZON << 2);
542
    COSD_FLAGS |= (ARTHORIZON << 2);
543
        COSD_FLAGS |= (BIGVARIO << 3);
543
        COSD_FLAGS |= (BIGVARIO << 3);
544
        COSD_FLAGS |= (STATS << 4);
544
        COSD_FLAGS |= (STATS << 4);
545
    COSD_FLAGS |= (WARNINGS << 5);
545
    COSD_FLAGS |= (WARNINGS << 5);
546
 
546
 
547
    // set up Atmega162 Ports
547
    // set up Atmega162 Ports
548
    DDRA |= (1 << PA1); // PA1 output (/CS)
548
    DDRA |= (1 << PA1); // PA1 output (/CS)
549
    MAX_CS_HIGH
549
    MAX_CS_HIGH
550
    DDRA |= (1 << PA2); // PA2 output (SDIN)
550
    DDRA |= (1 << PA2); // PA2 output (SDIN)
551
    MAX_SDIN_LOW
551
    MAX_SDIN_LOW
552
    DDRA |= (1 << PA3); // PA3 output (SCLK)
552
    DDRA |= (1 << PA3); // PA3 output (SCLK)
553
    MAX_SCLK_LOW
553
    MAX_SCLK_LOW
554
    DDRA |= (1 << PA5); // PA5 output (RESET)
554
    DDRA |= (1 << PA5); // PA5 output (RESET)
555
    MAX_RESET_HIGH
555
    MAX_RESET_HIGH
556
 
556
 
557
    DDRC |= (1 << PC0); // PC0 output (LED1 gn)
557
    DDRC |= (1 << PC0); // PC0 output (LED1 gn)
558
    LED1_OFF
558
    LED1_OFF
559
    DDRC |= (1 << PC1); // PC1 output (LED2 rt)
559
    DDRC |= (1 << PC1); // PC1 output (LED2 rt)
560
    LED2_OFF
560
    LED2_OFF
561
    DDRC |= (1 << PC2); // PC2 output (LED3 gn)
561
    DDRC |= (1 << PC2); // PC2 output (LED3 gn)
562
    LED3_OFF
562
    LED3_OFF
563
    DDRC |= (1 << PC3); // PC3 output (LED4 rt)
563
    DDRC |= (1 << PC3); // PC3 output (LED4 rt)
564
    LED4_OFF
564
    LED4_OFF
565
 
565
 
566
    DDRC &= ~(1 << PC4); // PC4 input  (MODE)
566
    DDRC &= ~(1 << PC4); // PC4 input  (MODE)
567
    PORTC |= (1 << PC4); // pullup
567
    PORTC |= (1 << PC4); // pullup
568
    DDRC &= ~(1 << PC5); // PC5 input  (SET)
568
    DDRC &= ~(1 << PC5); // PC5 input  (SET)
569
    PORTC |= (1 << PC5); // pullup
569
    PORTC |= (1 << PC5); // pullup
570
 
570
 
571
    // set up top and bottom lines
571
    // set up top and bottom lines
572
    if (COSD_FLAGS & COSD_FLAG_NTSC) {
572
    if (COSD_FLAGS & COSD_FLAG_NTSC) {
573
        bottom_line = 12;
573
        bottom_line = 12;
574
    } else {
574
    } else {
575
        bottom_line = 14;
575
        bottom_line = 14;
576
    }
576
    }
577
 
577
 
578
    // reset the MAX7456 to be sure any undefined states do no harm
578
    // reset the MAX7456 to be sure any undefined states do no harm
579
    MAX_RESET_LOW
579
    MAX_RESET_LOW
580
    MAX_RESET_HIGH
580
    MAX_RESET_HIGH
581
 
581
 
582
    // give the FC/NC and the maxim time to come up
582
    // give the FC/NC and the maxim time to come up
583
    LED4_ON
583
    LED4_ON
584
    _delay_ms(2000);
584
    _delay_ms(2000);
585
 
585
 
586
    LED4_OFF
586
    LED4_OFF
587
 
587
 
588
 
588
 
589
    //Pushing NEW chars to the MAX7456
589
    //Pushing NEW chars to the MAX7456
590
#if (WRITECHARS != -1)
590
#if (WRITECHARS != -1)
591
    // DISABLE display (VM0)
591
    // DISABLE display (VM0)
592
    spi_send_byte(0x00, 0b00000000);
592
    spi_send_byte(0x00, 0b00000000);
593
#include "characters.c"
593
#include "characters.c"
594
 
594
 
595
#endif 
595
#endif 
596
 
596
 
597
    // Setup Video Mode
597
    // Setup Video Mode
598
    if (COSD_FLAGS & COSD_FLAG_NTSC) {
598
    if (COSD_FLAGS & COSD_FLAG_NTSC) {
599
        // NTSC + enable display immediately (VM0)
599
        // NTSC + enable display immediately (VM0)
600
        spi_send_byte(0x00, 0b00001000);
600
        spi_send_byte(0x00, 0b00001000);
601
    } else {
601
    } else {
602
        // PAL + enable display immediately (VM0)
602
        // PAL + enable display immediately (VM0)
603
        spi_send_byte(0x00, 0b01001000);
603
        spi_send_byte(0x00, 0b01001000);
604
    }
604
    }
605
 
605
 
606
    // clear all display-mem (DMM)
606
    // clear all display-mem (DMM)
607
    spi_send_byte(0x04, 0b00000100);
607
    spi_send_byte(0x04, 0b00000100);
608
 
608
 
609
    // clearing takes 12uS according to maxim so lets wait longer
609
    // clearing takes 12uS according to maxim so lets wait longer
610
    _delay_us(120);
610
    _delay_us(120);
611
 
611
 
612
    // 8bit mode
612
    // 8bit mode
613
    spi_send_byte(0x04, 0b01000000);
613
    spi_send_byte(0x04, 0b01000000);
614
 
614
 
615
    // write blank chars to whole screen
615
    // write blank chars to whole screen
616
    clear();
616
    clear();
617
 
617
 
618
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
618
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
619
    // init usart
619
    // init usart
620
    usart1_init();
620
    usart1_init();
621
 
621
 
622
    // set up timer
622
    // set up timer
623
    TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64
623
    TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64
624
    OCR0 = 15; // preload
624
    OCR0 = 15; // preload
625
    TIMSK |= (1 << TOIE0); // enable overflow timer0
625
    TIMSK |= (1 << TOIE0); // enable overflow timer0
626
 
626
 
627
    // enable interrupts
627
    // enable interrupts
628
    sei();
628
    sei();
629
#endif
629
#endif
630
 
630
 
631
    //write_ascii_string(2,  7, "         CaScAdE          ");
631
    //write_ascii_string(2,  7, "         CaScAdE          ");
632
    //write_ascii_string(2,  8, "is TESTING his open source");
632
    //write_ascii_string(2,  8, "is TESTING his open source");
633
    //write_ascii_string(2,  9, "    EPi OSD Firmware");
633
    //write_ascii_string(2,  9, "    EPi OSD Firmware");
634
 
634
 
635
    // custom char preview
635
    // custom char preview
636
    /*write_char_xy( 2, 7, 200);
636
    /*write_char_xy( 2, 7, 200);
637
    write_char_xy( 3, 7, 201);
637
    write_char_xy( 3, 7, 201);
638
    write_char_xy( 4, 7, 202);
638
    write_char_xy( 4, 7, 202);
639
    write_char_xy( 5, 7, 203);
639
    write_char_xy( 5, 7, 203);
640
    write_char_xy( 6, 7, 204);
640
    write_char_xy( 6, 7, 204);
641
    write_char_xy( 7, 7, 205);
641
    write_char_xy( 7, 7, 205);
642
    write_char_xy( 8, 7, 206);
642
    write_char_xy( 8, 7, 206);
643
    write_char_xy( 9, 7, 207);
643
    write_char_xy( 9, 7, 207);
644
    write_char_xy(10, 7, 208);
644
    write_char_xy(10, 7, 208);
645
    write_char_xy(11, 7, 209);
645
    write_char_xy(11, 7, 209);
646
    write_char_xy(12, 7, 210);
646
    write_char_xy(12, 7, 210);
647
    write_char_xy(13, 7, 211);
647
    write_char_xy(13, 7, 211);
648
    write_char_xy(14, 7, 212);
648
    write_char_xy(14, 7, 212);
649
    write_char_xy(15, 7, 213);
649
    write_char_xy(15, 7, 213);
650
    write_char_xy(16, 7, 214);
650
    write_char_xy(16, 7, 214);
651
    write_char_xy(17, 7, 215);*/
651
    write_char_xy(17, 7, 215);*/
652
 
652
 
653
    // we are ready
653
    // we are ready
654
    LED3_ON
654
    LED3_ON
655
 
655
 
656
 
656
 
657
 
657
 
658
#if ALLCHARSDEBUG | (WRITECHARS != -1)
658
#if ALLCHARSDEBUG | (WRITECHARS != -1)
659
        clear();
659
        clear();
660
    write_all_chars();
660
    write_all_chars();
661
#else
661
#else
662
        // clear serial screen
662
        // clear serial screen
663
        //usart1_puts("\x1B[2J\x1B[H");
663
        //usart1_puts("\x1B[2J\x1B[H");
664
        //usart1_puts("hello world!\r\n");
664
        //usart1_puts("hello world!\r\n");
665
 
665
 
666
 
666
 
667
        // request data ever 100ms from FC;
667
        // request data ever 100ms from FC;
668
        //usart1_request_mk_data(0, 'd', 100);
668
        //usart1_request_mk_data(0, 'd', 100);
669
 
669
 
670
        // request OSD Data from NC every 100ms
670
        // request OSD Data from NC every 100ms
671
        usart1_request_mk_data(1, 'o', 100);
671
        usart1_request_mk_data(1, 'o', 100);
672
 
672
 
673
    // and disable debug...
673
    // and disable debug...
674
        usart1_request_mk_data(0, 'd', 0);
674
        usart1_request_mk_data(0, 'd', 0);
675
 
675
 
676
    // disable TXD-pin
676
    // disable TXD-pin
677
    //usart1_DisableTXD();
677
    //usart1_DisableTXD();
678
 
678
 
679
    // stats for after flight
679
    // stats for after flight
680
    int16_t max_Altimeter = 0;
680
    int16_t max_Altimeter = 0;
681
    uint16_t max_GroundSpeed = 0;
681
    uint16_t max_GroundSpeed = 0;
682
    int16_t max_Distance = 0;
682
    int16_t max_Distance = 0;
683
    uint8_t min_UBat = 255;
683
    uint8_t min_UBat = 255;
684
    uint16_t max_FlyingTime = 0;
684
    uint16_t max_FlyingTime = 0;
685
 
685
 
686
    // flags from last round to check for changes
686
    // flags from last round to check for changes
687
    uint8_t old_MKFlags = 0;
687
    uint8_t old_MKFlags = 0;
688
 
688
 
689
    char* directions[8] = {"NE", "E ", "SE", "S ", "SW", "W ", "NW", "N "};
689
    char* directions[8] = {"NE", "E ", "SE", "S ", "SW", "W ", "NW", "N "};
690
    //char arrowdir[8] = {218, 217, 224, 223, 222, 221, 220, 219};
690
    //char arrowdir[8] = {218, 217, 224, 223, 222, 221, 220, 219};
691
 
691
 
692
        /*write_ndigit_number_s_10th(5, 10, 1, 100, 0);
692
        /*write_ndigit_number_s_10th(5, 10, 1, 100, 0);
693
        write_ndigit_number_s_10th(5, 11, -1, 100, 0);
693
        write_ndigit_number_s_10th(5, 11, -1, 100, 0);
694
        write_ndigit_number_s_10th(5, 12, -11, 100, 0);*/
694
        write_ndigit_number_s_10th(5, 12, -11, 100, 0);*/
695
 
695
 
696
        //write_ndigit_number_u(2,2, heading_fine_conv(34), 100, 0);
696
        //write_ndigit_number_u(2,2, heading_fine_conv(34), 100, 0);
697
        //write_char_xy(1, 2, 0xa0 + heading_fine_conv(34));
697
        //write_char_xy(1, 2, 0xa0 + heading_fine_conv(34));
698
 
698
 
699
    while (1) {
699
    while (1) {
700
        // write icons at init or after menu/mode-switch
700
        // write icons at init or after menu/mode-switch
701
        if (!(COSD_FLAGS & COSD_ICONS_WRITTEN) && (COSD_FLAGS & COSD_FLAG_HUD)) {
701
        if (!(COSD_FLAGS & COSD_ICONS_WRITTEN) && (COSD_FLAGS & COSD_FLAG_HUD)) {
702
            write_char_xy(5, top_line, 0xCB); // km/h
702
            write_char_xy(5, top_line, 0xCB); // km/h
703
            write_char_xy(10, top_line, 0xCA); // RC-transmitter
703
            write_char_xy(10, top_line, 0xCA); // RC-transmitter
704
            write_char_xy(16, top_line, 0xD0); // degree symbol
704
            write_char_xy(16, top_line, 0xD0); // degree symbol
705
            write_char_xy(27, top_line, 0xCC); // small meters m height
705
            write_char_xy(27, top_line, 0xCC); // small meters m height
706
                        write_char_xy(20, top_line+1, 0xB0); // left circle
706
                        write_char_xy(20, top_line+1, 0xB0); // left circle
707
                        write_char_xy(22, top_line+1, 0xB2); // right circle
707
                        write_char_xy(22, top_line+1, 0xB2); // right circle
708
                        write_char_xy(27, top_line+1, 0xCC); // small meters m home
708
                        write_char_xy(27, top_line+1, 0xCC); // small meters m home
709
                        write_char_xy(7, bottom_line, 0x9E); // small v
709
                        write_char_xy(7, bottom_line, 0x9E); // small v
710
            write_char_xy(14, bottom_line, 0xD1); // on clock
710
            write_char_xy(14, bottom_line, 0xD1); // on clock
711
            write_char_xy(22, bottom_line, 0xD2); // fly clock
711
            write_char_xy(22, bottom_line, 0xD2); // fly clock
712
            write_char_xy(26, bottom_line, 0xC8); // sat1
712
            write_char_xy(26, bottom_line, 0xC8); // sat1
713
            write_char_xy(27, bottom_line, 0xC9); // sat2
713
            write_char_xy(27, bottom_line, 0xC9); // sat2
714
            COSD_FLAGS |= COSD_ICONS_WRITTEN;
714
            COSD_FLAGS |= COSD_ICONS_WRITTEN;
715
        }
715
        }
716
        if (rxd_buffer_locked) {
716
        if (rxd_buffer_locked) {
717
            if (COSD_FLAGS & COSD_FLAG_HUD) {
717
            if (COSD_FLAGS & COSD_FLAG_HUD) {
718
                if (rxd_buffer[2] == 'D') { // FC Data
718
                if (rxd_buffer[2] == 'D') { // FC Data
719
                    /*Decode64();
719
                    /*Decode64();
720
                    debugData = *((DebugOut_t*) pRxData);
720
                    debugData = *((DebugOut_t*) pRxData);
721
                    write_number_s(12, 2, RxDataLen);
721
                    write_number_s(12, 2, RxDataLen);
722
                    write_number_s(20, 2, setsReceived++);
722
                    write_number_s(20, 2, setsReceived++);
723
                    write_number_s(12, 3, debugData.Analog[0]); // AngleNick
723
                    write_number_s(12, 3, debugData.Analog[0]); // AngleNick
724
                    write_number_s(12, 4, debugData.Analog[1]); // AngleRoll
724
                    write_number_s(12, 4, debugData.Analog[1]); // AngleRoll
725
                                        write_number_s(12, 5, debugData.Analog[5]); // Height
725
                                        write_number_s(12, 5, debugData.Analog[5]); // Height
726
                    write_number_s(12, 6, debugData.Analog[9]); // Voltage
726
                    write_number_s(12, 6, debugData.Analog[9]); // Voltage
727
                    write_number_s(12, 7, debugData.Analog[10]);// RC Signal
727
                    write_number_s(12, 7, debugData.Analog[10]);// RC Signal
728
                                        write_number_s(12, 8, debugData.Analog[11]);// Gyro compass*/
728
                                        write_number_s(12, 8, debugData.Analog[11]);// Gyro compass
-
 
729
                                        seconds_since_last_data = 0;*/
729
                } else if (rxd_buffer[2] == 'O') { // NC OSD Data
730
                } else if (rxd_buffer[2] == 'O') { // NC OSD Data
730
                    Decode64();
731
                    Decode64();
731
                    naviData = *((NaviData_t*) pRxData);
732
                    naviData = *((NaviData_t*) pRxData);
732
                                       
733
                                       
733
                    // first line
734
                    // first line
734
                    write_ndigit_number_u(2, top_line, (uint16_t) (((uint32_t) naviData.GroundSpeed * (uint32_t)9) / (uint32_t)250), 100, 0);
735
                    write_ndigit_number_u(2, top_line, (uint16_t) (((uint32_t) naviData.GroundSpeed * (uint32_t)9) / (uint32_t)250), 100, 0);
735
 
736
 
736
                    write_ndigit_number_u(7, top_line, naviData.RC_Quality, 100, 0);
737
                    write_ndigit_number_u(7, top_line, naviData.RC_Quality, 100, 0);
737
                    if (naviData.RC_Quality <= RCLVL_WRN && last_RC_Quality > RCLVL_WRN) {
738
                    if (naviData.RC_Quality <= RCLVL_WRN && last_RC_Quality > RCLVL_WRN) {
738
                        for (uint8_t x = 0; x < 4; x++)
739
                        for (uint8_t x = 0; x < 4; x++)
739
                            write_char_att_xy(7 + x, top_line, BLINK);
740
                            write_char_att_xy(7 + x, top_line, BLINK);
740
                    } else if (naviData.RC_Quality > RCLVL_WRN && last_RC_Quality <= RCLVL_WRN) {
741
                    } else if (naviData.RC_Quality > RCLVL_WRN && last_RC_Quality <= RCLVL_WRN) {
741
                        for (uint8_t x = 0; x < 4; x++)
742
                        for (uint8_t x = 0; x < 4; x++)
742
                            write_char_att_xy(7 + x, top_line, 0);
743
                            write_char_att_xy(7 + x, top_line, 0);
743
                    }
744
                    }
744
                    last_RC_Quality = naviData.RC_Quality;
745
                    last_RC_Quality = naviData.RC_Quality;
745
 
746
 
746
                    write_ndigit_number_u(13, top_line, naviData.CompassHeading, 100, 0);
747
                    write_ndigit_number_u(13, top_line, naviData.CompassHeading, 100, 0);
747
 
748
 
748
                    write_ascii_string(17, top_line, directions[heading_conv(naviData.CompassHeading)]);
749
                    write_ascii_string(17, top_line, directions[heading_conv(naviData.CompassHeading)]);
749
                                       
750
                                       
750
                                        draw_variometer(21, top_line, naviData.Variometer);
751
                                        draw_variometer(21, top_line, naviData.Variometer);
751
 
752
 
752
                    //note:lephisto:according to several sources it's /30
753
                    //note:lephisto:according to several sources it's /30
753
                    if (naviData.Altimeter > 300 || naviData.Altimeter < -300) {
754
                    if (naviData.Altimeter > 300 || naviData.Altimeter < -300) {
754
                        // above 10m only write full meters
755
                        // above 10m only write full meters
755
                        write_ndigit_number_s(23, top_line, naviData.Altimeter / 30, 1000, 0);
756
                        write_ndigit_number_s(23, top_line, naviData.Altimeter / 30, 1000, 0);
756
                    } else {
757
                    } else {
757
                        // up to 10m write meters.dm
758
                        // up to 10m write meters.dm
758
                        //write_number_u_10th(21, top_line, naviData.Altimeter / 3);
759
                        //write_number_u_10th(21, top_line, naviData.Altimeter / 3);
759
                                                write_ndigit_number_s_10th(23, top_line, naviData.Altimeter / 3, 100, 0);
760
                                                write_ndigit_number_s_10th(23, top_line, naviData.Altimeter / 3, 100, 0);
760
                    }
761
                    }
761
 
762
 
762
                    // seccond line
763
                    // seccond line
763
                    draw_compass(11, top_line + 1, naviData.CompassHeading);
764
                    draw_compass(11, top_line + 1, naviData.CompassHeading);
764
 
765
 
765
                    // TODO: verify correctness
766
                    // TODO: verify correctness
766
                    uint16_t heading_home = (naviData.HomePositionDeviation.Bearing + 360 - naviData.CompassHeading) % 360;
767
                    uint16_t heading_home = (naviData.HomePositionDeviation.Bearing + 360 - naviData.CompassHeading) % 360;
767
                    //write_char_xy(21, top_line + 1, arrowdir[heading_conv(heading_home)]);
768
                    //write_char_xy(21, top_line + 1, arrowdir[heading_conv(heading_home)]);
768
                                        // finer resolution, 0xa0 is first character and we add the index 0 <= index < 16
769
                                        // finer resolution, 0xa0 is first character and we add the index 0 <= index < 16
769
                                        write_char_xy(21, top_line + 1, 0xa0 + heading_fine_conv(heading_home));
770
                                        write_char_xy(21, top_line + 1, 0xa0 + heading_fine_conv(heading_home));
770
 
771
 
771
                    write_ndigit_number_u(24, top_line + 1, naviData.HomePositionDeviation.Distance / 10, 100, 0);
772
                    write_ndigit_number_u(24, top_line + 1, naviData.HomePositionDeviation.Distance / 10, 100, 0);
772
 
773
 
773
                    // center
774
                    // center
774
                    if (naviData.MKFlags & FLAG_MOTOR_RUN) { // should be engines running
775
                    if (naviData.MKFlags & FLAG_MOTOR_RUN) { // should be engines running
775
                        if (!(old_MKFlags & FLAG_MOTOR_RUN)) { // motors just started, clear middle
776
                        if (!(old_MKFlags & FLAG_MOTOR_RUN)) { // motors just started, clear middle
776
                            clear();
777
                            clear();
777
                            // update flags to paint display again if needed
778
                            // update flags to paint display again if needed
778
                            COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
779
                            COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
779
                        }
780
                        }
780
                        if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
781
                        if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
781
                            draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
782
                            draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
782
                        }
783
                        }
783
                    } else {
784
                    } else {
784
                                                // stats
785
                                                // stats
785
                                                if (COSD_FLAGS & COSD_FLAG_STATS) {
786
                                                if (COSD_FLAGS & COSD_FLAG_STATS) {
786
                                                        write_ascii_string_pgm(2, 5, stats_item_pointers[0]); // max Altitude
787
                                                        write_ascii_string_pgm(2, 5, stats_item_pointers[0]); // max Altitude
787
                                write_ndigit_number_s(18, 5, max_Altimeter / 30, 1000, 0);
788
                                write_ndigit_number_s(18, 5, max_Altimeter / 30, 1000, 0);
788
                                write_char_xy(22, 5, 204); // small meters m
789
                                write_char_xy(22, 5, 204); // small meters m
789
                                                        write_ascii_string_pgm(2, 6, stats_item_pointers[1]); // max Speed
790
                                                        write_ascii_string_pgm(2, 6, stats_item_pointers[1]); // max Speed
790
                                write_ndigit_number_u(19, 6, (uint16_t) (((uint32_t) max_GroundSpeed * 36) / 1000), 100, 0);
791
                                write_ndigit_number_u(19, 6, (uint16_t) (((uint32_t) max_GroundSpeed * 36) / 1000), 100, 0);
791
                                write_char_xy(22, 6, 203); // km/h
792
                                write_char_xy(22, 6, 203); // km/h
792
                                                        write_ascii_string_pgm(2, 7, stats_item_pointers[2]); // max Distance
793
                                                        write_ascii_string_pgm(2, 7, stats_item_pointers[2]); // max Distance
793
                                write_ndigit_number_u(19, 7, max_Distance / 100, 100, 0);
794
                                write_ndigit_number_u(19, 7, max_Distance / 100, 100, 0);
794
                                write_char_xy(22, 7, 204); // small meters m
795
                                write_char_xy(22, 7, 204); // small meters m
795
                                                        write_ascii_string_pgm(2, 8, stats_item_pointers[3]); // min voltage
796
                                                        write_ascii_string_pgm(2, 8, stats_item_pointers[3]); // min voltage
796
                                                        write_ndigit_number_u_10th(18, 8, min_UBat, 100, 0);
797
                                                        write_ndigit_number_u_10th(18, 8, min_UBat, 100, 0);
797
                                                        write_char_xy(22, 8, 0x9E); // small v
798
                                                        write_char_xy(22, 8, 0x9E); // small v
798
                                                        write_ascii_string_pgm(2, 9, stats_item_pointers[4]); // max time
799
                                                        write_ascii_string_pgm(2, 9, stats_item_pointers[4]); // max time
799
                                write_time(16, 9, max_FlyingTime);
800
                                write_time(16, 9, max_FlyingTime);
800
                                write_char_xy(22, 9, 210); // fly clock
801
                                write_char_xy(22, 9, 210); // fly clock
801
                                                } else if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) { // if no stats there is space horizon
802
                                                } else if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) { // if no stats there is space horizon
802
                            draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
803
                            draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
803
                        }
804
                        }
804
                    }
805
                    }
805
                                        if (COSD_FLAGS & COSD_FLAG_BIGVARIO) {
806
                                        if (COSD_FLAGS & COSD_FLAG_BIGVARIO) {
806
                                                draw_big_variometer(27, 8, naviData.Variometer);
807
                                                draw_big_variometer(27, 8, naviData.Variometer);
807
                                        }
808
                                        }
808
 
809
 
809
                    // bottom line
810
                    // bottom line
810
                                        draw_battery(2, bottom_line, naviData.UBat);
811
                                        draw_battery(2, bottom_line, naviData.UBat);
811
                                        write_ndigit_number_u_10th(3, bottom_line, naviData.UBat, 100, 0);
812
                                        write_ndigit_number_u_10th(3, bottom_line, naviData.UBat, 100, 0);
812
                    if (naviData.UBat <= UBAT_WRN && last_UBat > UBAT_WRN) {
813
                    if (naviData.UBat <= UBAT_WRN && last_UBat > UBAT_WRN) {
813
                        for (uint8_t x = 2; x < 8; x++)
814
                        for (uint8_t x = 2; x < 8; x++)
814
                            write_char_att_xy(x, bottom_line, BLINK);
815
                            write_char_att_xy(x, bottom_line, BLINK);
815
                    } else {
816
                    } else {
816
                        for (uint8_t x = 2; x < 8; x++)
817
                        for (uint8_t x = 2; x < 8; x++)
817
                            write_char_att_xy(x, bottom_line, 0);
818
                            write_char_att_xy(x, bottom_line, 0);
818
                    }
819
                    }
819
                                       
820
                                       
820
 
821
 
821
                    write_time(8, bottom_line, uptime);
822
                    write_time(8, bottom_line, uptime);
822
                    write_time(16, bottom_line, naviData.FlyingTime);
823
                    write_time(16, bottom_line, naviData.FlyingTime);
823
 
824
 
824
                    write_ndigit_number_u(24, bottom_line, naviData.SatsInUse, 10, 0);
825
                    write_ndigit_number_u(24, bottom_line, naviData.SatsInUse, 10, 0);
825
 
826
 
826
                    if (naviData.NCFlags & NC_FLAG_CH) {
827
                    if (naviData.NCFlags & NC_FLAG_CH) {
827
                        write_char_xy(27, bottom_line, 231); // gps ch
828
                        write_char_xy(27, bottom_line, 231); // gps ch
828
                    } else if (naviData.NCFlags & NC_FLAG_PH) {
829
                    } else if (naviData.NCFlags & NC_FLAG_PH) {
829
                        write_char_xy(27, bottom_line, 230); // gps ph
830
                        write_char_xy(27, bottom_line, 230); // gps ph
830
                    } else { // (naviData.NCFlags & NC_FLAG_FREE)
831
                    } else { // (naviData.NCFlags & NC_FLAG_FREE)
831
                        write_char_xy(27, bottom_line, 201); // sat2 (free)
832
                        write_char_xy(27, bottom_line, 201); // sat2 (free)
832
                    }
833
                    }
833
 
834
 
834
                    //write_number_s(8, 5, RxDataLen);
835
                    //write_number_s(8, 5, RxDataLen);
835
                    //write_number_s(16, 5, setsReceived++);
836
                    //write_number_s(16, 5, setsReceived++);
836
 
837
 
837
                    // remember statistics
838
                    // remember statistics
838
                    if (naviData.Altimeter > max_Altimeter) max_Altimeter = naviData.Altimeter;
839
                    if (naviData.Altimeter > max_Altimeter) max_Altimeter = naviData.Altimeter;
839
                    if (naviData.GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData.GroundSpeed;
840
                    if (naviData.GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData.GroundSpeed;
840
                    if (naviData.HomePositionDeviation.Distance > max_Distance) {
841
                    if (naviData.HomePositionDeviation.Distance > max_Distance) {
841
                        max_Distance = naviData.HomePositionDeviation.Distance;
842
                        max_Distance = naviData.HomePositionDeviation.Distance;
842
                    }
843
                    }
843
                    if (naviData.UBat < min_UBat) min_UBat = naviData.UBat;
844
                    if (naviData.UBat < min_UBat) min_UBat = naviData.UBat;
844
                    if (naviData.FlyingTime > max_FlyingTime) max_FlyingTime = naviData.FlyingTime;
845
                    if (naviData.FlyingTime > max_FlyingTime) max_FlyingTime = naviData.FlyingTime;
845
 
846
 
846
                    old_MKFlags = naviData.MKFlags;
847
                    old_MKFlags = naviData.MKFlags;
-
 
848
                                        seconds_since_last_data = 0;
847
                }
849
                }
848
            }
850
            }
849
            seconds_since_last_data = 0;
-
 
850
            rxd_buffer_locked = 0;
851
            rxd_buffer_locked = 0;
851
        }
852
        }
852
        // handle keypress
853
        // handle keypress
853
        if (s1_pressed()) {
854
        if (s1_pressed()) {
854
            config_menu();
855
            config_menu();
855
        }
856
        }
856
        if (seconds_since_last_data > 2) {
857
        if (seconds_since_last_data > 2) {
857
                        /*if (COSD_FLAGS & COSD_FLAG_HUD) {
858
                        /*if (COSD_FLAGS & COSD_FLAG_HUD) {
858
                                write_ascii_string(2, 3, "ERROR: NO DATA for");
859
                                write_ascii_string(2, 3, "ERROR: NO DATA for");
859
                                write_time(21, 3, seconds_since_last_data);
860
                                write_time(21, 3, seconds_since_last_data);
860
                        }*/
861
                        }*/
861
                        // request OSD Data from NC every 100ms
862
                        // request OSD Data from NC every 100ms
862
                        usart1_request_mk_data(1, 'o', 100);
863
                        usart1_request_mk_data(1, 'o', 100);
863
                        _delay_ms(200);
864
                        _delay_ms(200);
864
                        //seconds_since_last_data = 0;
865
                        //seconds_since_last_data = 0;
865
        }
866
        }
866
    }
867
    }
867
#endif
868
#endif
868
    return 0;
869
    return 0;
869
}
870
}
870
 
871