Subversion Repositories Projects

Rev

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

Rev 336 Rev 339
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 "max7456_software_spi.c"
31
#include "max7456_software_spi.c"
32
#include "usart1.h"
32
#include "usart1.h"
33
 
33
 
34
/* TODO:
34
/* TODO:
35
 * - verifiy correctness of values
35
 * - verifiy correctness of values
36
 * - clean up code :)
36
 * - clean up code :)
37
 */
37
 */
38
 
38
 
39
/* ##########################################################################
39
/* ##########################################################################
40
 * Debugging and general purpose definitions
40
 * Debugging and general purpose definitions
41
 * ##########################################################################*/
41
 * ##########################################################################*/
42
#define ALLCHARSDEBUG 0         // set to 1 and flash firmware to see all chars
42
#define ALLCHARSDEBUG 0         // set to 1 and flash firmware to see all chars
43
 
43
 
44
#ifndef WRITECHARS                      // if WRITECHARS not set via makefile
44
#ifndef WRITECHARS                      // if WRITECHARS not set via makefile
45
#define WRITECHARS -1           // set to 2XX and flash firmware to write new char
45
#define WRITECHARS -1           // set to 2XX and flash firmware to write new char
46
                                                        // enables the allchars as well to see results
46
                                                        // enables the allchars as well to see results
47
#endif
47
#endif
48
 
48
 
49
#ifndef NTSC                            // if NTSC is not thet via makefile
49
#ifndef NTSC                            // if NTSC is not thet via makefile
50
#define NTSC 0                          // set to 1 for NTSC mode + lifts the bottom line
50
#define NTSC 1                          // set to 1 for NTSC mode + lifts the bottom line
51
#endif
51
#endif
52
 
52
 
53
#define ARTHORIZON 0            // set to 1 to enable roll&nick artificial horizon
53
#define HUD 1                           // set to 0 to disable HUD by default
54
#define NOOSD 0                         // set to 1 to disable OSD completely
54
#define ARTHORIZON 0            // set to 1 to enable roll&nick artificial horizon by default
55
#define NOOSD_BUT_WRN 0         // set to 1 to disable OSD completely but show 
55
#define STATS 1                         // set to 1 to enable statistics during motor off by default
-
 
56
#define WARNINGS 1                      // set to 1 to display battery+rc warning even if HUD is disabled
56
                                                        // battery and receive signal warnings
57
 
57
#define UBAT_WRN 94                     // voltage for blinking warning, like FC settings
58
#define UBAT_WRN 94                     // voltage for blinking warning, like FC settings
58
#define RCLVL_WRN 100           // make the RC level blink if below this number
59
#define RCLVL_WRN 100           // make the RC level blink if below this number
59
 
60
 
60
// ### read datasheet before changing stuff below this line :)
61
// ### read datasheet before changing stuff below this line :)
61
#define BLINK   0b01001111      // attribute byte for blinking chars
62
#define BLINK   0b01001111      // attribute byte for blinking chars
62
 
63
 
63
/* ##########################################################################
64
/* ##########################################################################
64
 * FLAGS usable during runtime
65
 * FLAGS usable during runtime
65
 * ##########################################################################*/
66
 * ##########################################################################*/
66
#define COSD_FLAG_NTSC                   1
67
#define COSD_FLAG_NTSC                   1
-
 
68
#define COSD_FLAG_HUD                    2
67
#define COSD_FLAG_ARTHORIZON     2
69
#define COSD_FLAG_ARTHORIZON     4
68
#define COSD_FLAG_NOOSD                  4
70
#define COSD_FLAG_STATS                  8
69
#define COSD_FLAG_NOOSD_BUT_WRN  8
71
#define COSD_FLAG_WARNINGS              16
70
#define COSD_ICONS_WRITTEN              16
72
#define COSD_ICONS_WRITTEN              32
71
 
73
 
72
/* ##########################################################################
74
/* ##########################################################################
73
 * LED controll
75
 * LED controll
74
 * ##########################################################################*/
76
 * ##########################################################################*/
75
#define LED1_ON                 PORTC |=  (1 << PC0);
77
#define LED1_ON                 PORTC |=  (1 << PC0);
76
#define LED1_OFF                PORTC &= ~(1 << PC0);
78
#define LED1_OFF                PORTC &= ~(1 << PC0);
77
#define LED2_ON                 PORTC |=  (1 << PC1);
79
#define LED2_ON                 PORTC |=  (1 << PC1);
78
#define LED2_OFF                PORTC &= ~(1 << PC1);
80
#define LED2_OFF                PORTC &= ~(1 << PC1);
79
#define LED3_ON                 PORTC |=  (1 << PC2);
81
#define LED3_ON                 PORTC |=  (1 << PC2);
80
#define LED3_OFF                PORTC &= ~(1 << PC2);
82
#define LED3_OFF                PORTC &= ~(1 << PC2);
81
#define LED4_ON                 PORTC |=  (1 << PC3);
83
#define LED4_ON                 PORTC |=  (1 << PC3);
82
#define LED4_OFF                PORTC &= ~(1 << PC3);
84
#define LED4_OFF                PORTC &= ~(1 << PC3);
83
 
85
 
84
/* ##########################################################################
86
/* ##########################################################################
85
 * switch controll
87
 * switch controll
86
 * ##########################################################################*/
88
 * ##########################################################################*/
87
#define S1_PRESSED              !(PINC & (1<<PC5))
89
#define S1_PRESSED              !(PINC & (1<<PC5))
88
#define S2_PRESSED              !(PINC & (1<<PC4))
90
#define S2_PRESSED              !(PINC & (1<<PC4))
89
 
91
 
90
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
92
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
91
// data structs
93
// data structs
92
#include "mk-data-structs.h"
94
#include "mk-data-structs.h"
93
 
95
 
94
/* ##########################################################################
96
/* ##########################################################################
95
 * global definitions and global vars
97
 * global definitions and global vars
96
 * ##########################################################################*/
98
 * ##########################################################################*/
97
volatile uint8_t rxd_buffer_locked = 0;
99
volatile uint8_t rxd_buffer_locked = 0;
98
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
100
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
99
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
101
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
100
volatile uint8_t ReceivedBytes = 0;
102
volatile uint8_t ReceivedBytes = 0;
101
volatile uint8_t *pRxData = 0;
103
volatile uint8_t *pRxData = 0;
102
volatile uint8_t RxDataLen = 0;
104
volatile uint8_t RxDataLen = 0;
103
volatile uint16_t setsReceived = 0;
105
volatile uint16_t setsReceived = 0;
104
 
106
 
105
volatile NaviData_t naviData;
107
volatile NaviData_t naviData;
106
volatile DebugOut_t debugData;
108
volatile DebugOut_t debugData;
107
 
109
 
108
// cache old vars for blinking attribute, checkup is faster than full
110
// cache old vars for blinking attribute, checkup is faster than full
109
// attribute write each time
111
// attribute write each time
110
volatile uint8_t last_UBat = 255;
112
volatile uint8_t last_UBat = 255;
111
volatile uint8_t last_RC_Quality = 255;
113
volatile uint8_t last_RC_Quality = 255;
112
 
114
 
113
// 16bit should be enough, normal LiPos don't last that long
115
// 16bit should be enough, normal LiPos don't last that long
114
volatile uint16_t uptime = 0;
116
volatile uint16_t uptime = 0;
115
volatile uint16_t timer = 0;
117
volatile uint16_t timer = 0;
116
 
118
 
117
// remember last time data was received
119
// remember last time data was received
118
volatile uint8_t seconds_since_last_data = 0;
120
volatile uint8_t seconds_since_last_data = 0;
119
 
121
 
120
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
122
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
121
 
123
 
122
// general PAL|NTSC distingiusch stuff
124
// general PAL|NTSC distingiusch stuff
123
uint8_t top_line = 1;
125
uint8_t top_line = 1;
124
uint8_t bottom_line = 14;
126
uint8_t bottom_line = 14;
125
 
127
 
126
// Flags
128
// Flags
127
uint8_t COSD_FLAGS = 0;
129
uint8_t COSD_FLAGS = 0;
128
 
130
 
129
/* ##########################################################################
131
/* ##########################################################################
130
 * debounce buttons
132
 * debounce buttons
131
 * ##########################################################################*/
133
 * ##########################################################################*/
132
int s1_pressed() {
134
int s1_pressed() {
133
        if (S1_PRESSED) {
135
        if (S1_PRESSED) {
134
                _delay_ms(25);
136
                _delay_ms(25);
135
                if (S1_PRESSED) return 1;
137
                if (S1_PRESSED) return 1;
136
        }
138
        }
137
        return 0;
139
        return 0;
138
}
140
}
139
 
141
 
140
int s2_pressed() {
142
int s2_pressed() {
141
        if (S2_PRESSED) {
143
        if (S2_PRESSED) {
142
                _delay_ms(25);
144
                _delay_ms(25);
143
                if (S2_PRESSED) return 1;
145
                if (S2_PRESSED) return 1;
144
        }
146
        }
145
        return 0;
147
        return 0;
146
}
148
}
147
 
149
 
148
 
150
 
149
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
151
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
150
 
152
 
151
/**
153
/**
152
 * serial support
154
 * serial support
153
 */
155
 */
154
#include "usart1.c"
156
#include "usart1.c"
155
 
157
 
156
 
158
 
157
/* ##########################################################################
159
/* ##########################################################################
158
 * timer stuff
160
 * timer stuff
159
 * ##########################################################################*/
161
 * ##########################################################################*/
160
 
162
 
161
/**
163
/**
162
 * timer kicks in every 1000uS ^= 1ms
164
 * timer kicks in every 1000uS ^= 1ms
163
 */
165
 */
164
ISR(TIMER0_OVF_vect) {
166
ISR(TIMER0_OVF_vect) {
165
    OCR0 = 6; // preload
167
    OCR0 = 6; // preload
166
    if (!timer--) {
168
    if (!timer--) {
167
        uptime++;
169
        uptime++;
168
        timer = 999;
170
        timer = 999;
169
                seconds_since_last_data++;
171
                seconds_since_last_data++;
170
    }
172
    }
171
}
173
}
172
 
174
 
173
/* ##########################################################################
175
/* ##########################################################################
174
 * compass stuff
176
 * compass stuff
175
 * ##########################################################################*/
177
 * ##########################################################################*/
176
 
178
 
177
/**
179
/**
178
 * convert the <heading> gotton from NC into an index
180
 * convert the <heading> gotton from NC into an index
179
 */
181
 */
180
uint8_t heading_conv(uint16_t heading) {
182
uint8_t heading_conv(uint16_t heading) {
181
    if (heading > 23 && heading < 68) {
183
    if (heading > 23 && heading < 68) {
182
        //direction = "NE";
184
        //direction = "NE";
183
        return 0;
185
        return 0;
184
    } else if (heading > 67 && heading < 113) {
186
    } else if (heading > 67 && heading < 113) {
185
        //direction = "E ";
187
        //direction = "E ";
186
        return 1;
188
        return 1;
187
    } else if (heading > 112 && heading < 158) {
189
    } else if (heading > 112 && heading < 158) {
188
        //direction = "SE";
190
        //direction = "SE";
189
        return 2;
191
        return 2;
190
    } else if (heading > 157 && heading < 203) {
192
    } else if (heading > 157 && heading < 203) {
191
        //direction = "S ";
193
        //direction = "S ";
192
        return 3;
194
        return 3;
193
    } else if (heading > 202 && heading < 248) {
195
    } else if (heading > 202 && heading < 248) {
194
        //direction = "SW";
196
        //direction = "SW";
195
        return 4;
197
        return 4;
196
    } else if (heading > 247 && heading < 293) {
198
    } else if (heading > 247 && heading < 293) {
197
        //direction = "W ";
199
        //direction = "W ";
198
        return 5;
200
        return 5;
199
    } else if (heading > 292 && heading < 338) {
201
    } else if (heading > 292 && heading < 338) {
200
        //direction = "NW";
202
        //direction = "NW";
201
        return 6;
203
        return 6;
202
    }
204
    }
203
    //direction = "N ";
205
    //direction = "N ";
204
    return 7;
206
    return 7;
205
}
207
}
206
 
208
 
207
/**
209
/**
208
 * draw a compass rose at <x>/<y> for <heading>
210
 * draw a compass rose at <x>/<y> for <heading>
209
 */
211
 */
210
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
212
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
211
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
213
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
212
    char rose[48] = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
214
    char rose[48] = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
213
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
215
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
214
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
216
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
215
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
217
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
216
        // the center is char 19 (north), we add the current heading in 8th
218
        // the center is char 19 (north), we add the current heading in 8th
217
        // which would be 22.5 degrees, but float would bloat up the code
219
        // which would be 22.5 degrees, but float would bloat up the code
218
        // and *10 / 225 would take ages... so we take the uncorrect way
220
        // and *10 / 225 would take ages... so we take the uncorrect way
219
    uint8_t front = 19 + (heading / 22);
221
    uint8_t front = 19 + (heading / 22);
220
    for (uint8_t i = 0; i < 9; i++) {
222
    for (uint8_t i = 0; i < 9; i++) {
221
                write_char_xy(x++, y, rose[front - 4 + i]);
223
                write_char_xy(x++, y, rose[front - 4 + i]);
222
    }
224
    }
223
}
225
}
224
 
226
 
225
/* ##########################################################################
227
/* ##########################################################################
226
 * artificial horizon
228
 * artificial horizon
227
 * ##########################################################################*/
229
 * ##########################################################################*/
228
// remember last time displayed values
230
// remember last time displayed values
229
int8_t old_af_x = -1, old_af_y = -1;
231
int8_t old_af_x = -1, old_af_y = -1;
230
 
232
 
231
/**
233
/**
232
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
234
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
233
 * from line <firstline> to <listlines> for given <nick> and <roll> values
235
 * from line <firstline> to <listlines> for given <nick> and <roll> values
234
 */
236
 */
235
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
237
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
236
        char noodle[5] = {225, 225, 226, 227, 227};
238
        char noodle[5] = {225, 225, 226, 227, 227};
237
        uint8_t center_x = 15;
239
        uint8_t center_x = 15;
238
        uint8_t center_y = lastline - firstline;
240
        uint8_t center_y = lastline - firstline;
239
        center_y = 7;
241
        center_y = 7;
240
        write_char_xy(center_x,center_y,228);
242
        write_char_xy(center_x,center_y,228);
241
        uint8_t cpos, nicky, rollx;
243
        uint8_t cpos, nicky, rollx;
242
       
244
       
243
        // which line
245
        // which line
244
        int8_t ypos =  nick / 20;
246
        int8_t ypos =  nick / 20;
245
        // which character from the array?
247
        // which character from the array?
246
        if (nick < 0) {
248
        if (nick < 0) {
247
                cpos = -1*((nick - (ypos * 20))/4);
249
                cpos = -1*((nick - (ypos * 20))/4);
248
                ypos--;
250
                ypos--;
249
        } else cpos = 4-((nick - (ypos * 20))/4);
251
        } else cpos = 4-((nick - (ypos * 20))/4);
250
        if (cpos > 4) cpos = 4;
252
        if (cpos > 4) cpos = 4;
251
 
253
 
252
        nicky = center_y - ypos;
254
        nicky = center_y - ypos;
253
        if (nicky > lastline) nicky = lastline;
255
        if (nicky > lastline) nicky = lastline;
254
        else if (nicky < firstline) nicky = firstline;
256
        else if (nicky < firstline) nicky = firstline;
255
 
257
 
256
        // ensure roll-borders
258
        // ensure roll-borders
257
        rollx = (roll / 8)+15;
259
        rollx = (roll / 8)+15;
258
        if (rollx < 2) rollx = 2;
260
        if (rollx < 2) rollx = 2;
259
        else if (rollx > 28) rollx = 28;
261
        else if (rollx > 28) rollx = 28;
260
 
262
 
261
 
263
 
262
        // clear roll
264
        // clear roll
263
        if (old_af_x != rollx && old_af_x >= 0) {
265
        if (old_af_x != rollx && old_af_x >= 0) {
264
                write_char_xy(old_af_x,13,0);
266
                write_char_xy(old_af_x,13,0);
265
        }
267
        }
266
 
268
 
267
        // clear nick
269
        // clear nick
268
        if (old_af_y != nicky && old_af_y >= 0) {
270
        if (old_af_y != nicky && old_af_y >= 0) {
269
                write_char_xy(center_x-1,old_af_y,0);
271
                write_char_xy(center_x-1,old_af_y,0);
270
                write_char_xy(center_x+1,old_af_y,0);
272
                write_char_xy(center_x+1,old_af_y,0);
271
        }
273
        }
272
 
274
 
273
 
275
 
274
        // draw nick
276
        // draw nick
275
        write_char_xy(center_x-1,nicky,noodle[cpos]);
277
        write_char_xy(center_x-1,nicky,noodle[cpos]);
276
        write_char_xy(center_x+1,nicky,noodle[cpos]);
278
        write_char_xy(center_x+1,nicky,noodle[cpos]);
277
 
279
 
278
        // draw roll
280
        // draw roll
279
        write_char_xy(rollx,lastline,229);
281
        write_char_xy(rollx,lastline,229);
280
 
282
 
281
        // update old vars
283
        // update old vars
282
        old_af_x = rollx;
284
        old_af_x = rollx;
283
        old_af_y = nicky;
285
        old_af_y = nicky;
284
 
286
 
285
        // debug numbers
287
        // debug numbers
286
        //write_3digit_number_u(20,6,cpos);
288
        //write_3digit_number_u(20,6,cpos);
287
        //write_number_s(20,7,ypos);    
289
        //write_number_s(20,7,ypos);    
288
        //write_number_s(0,7,nick);             
290
        //write_number_s(0,7,nick);             
289
        //write_number_s(18,11,roll);   
291
        //write_number_s(18,11,roll);   
290
}
292
}
291
 
293
 
292
/* ##########################################################################
294
/* ##########################################################################
293
 * A simple config menu for the flags
295
 * A simple config menu for the flags
294
 * ##########################################################################*/
296
 * ##########################################################################*/
-
 
297
 
-
 
298
/**
-
 
299
 * helper function for menu updating
-
 
300
 */
-
 
301
void config_menu_drawings(uint8_t chosen) {
-
 
302
    // clear prevoius _cursor_
-
 
303
    write_ascii_string(3, (chosen + 4) % 5, " ");
-
 
304
    // draw current _cursor_
-
 
305
    write_ascii_string(3, chosen + 6, ">");
-
 
306
    if (COSD_FLAGS & COSD_FLAG_HUD) {
-
 
307
        write_ascii_string(23, 6, "ON ");
-
 
308
    } else {
-
 
309
        write_ascii_string(23, 6, "OFF");
-
 
310
    }
-
 
311
    if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
-
 
312
        write_ascii_string(23, 7, "ON ");
-
 
313
    } else {
-
 
314
        write_ascii_string(23, 7, "OFF");
-
 
315
    }
-
 
316
        if (COSD_FLAGS & COSD_FLAG_STATS) {
-
 
317
        write_ascii_string(23, 8, "ON ");
-
 
318
    } else {
-
 
319
        write_ascii_string(23, 8, "OFF");
-
 
320
    }
-
 
321
    if (COSD_FLAGS & COSD_FLAG_WARNINGS) {
-
 
322
        write_ascii_string(23, 9, "ON ");
-
 
323
    } else {
-
 
324
        write_ascii_string(23, 9, "OFF");
-
 
325
    }
-
 
326
}
-
 
327
 
-
 
328
/**
-
 
329
 * a simple config menu tryout
-
 
330
 */
295
void config_menu(void) {
331
void config_menu(void) {
296
        // disable interrupts (makes the menu more smoothely)
332
        // disable interrupts (makes the menu more smoothely)
297
        cli();
333
        cli();
298
 
334
 
299
        // clear screen
335
        // clear screen
300
        clear();
336
        clear();
301
       
337
       
302
        char* menu[4] = {"Normal OSD      ",
338
        char* menu[5] = {"Full HUD",
303
                                         "Art.Horizon     ",
339
                                         "Art.Horizon in HUD",
-
 
340
                                         "Statistics",
304
                                         "NO OSD          ",
341
                                         "Warnings",    // TODO: do it!
305
                                         "NO OSD but WRN  "};
342
                                         "EXIT"};
306
 
343
 
307
        uint8_t inmenu = 1;
344
        uint8_t inmenu = 1;
308
        uint8_t chosen = 0;
345
        uint8_t chosen = 0;
309
        write_ascii_string(10,  4, "Config Menu");
346
        write_ascii_string(6,  2, "C-OSD Config Menu");
310
       
-
 
311
        // clear all mode flags
-
 
312
        COSD_FLAGS &= ~(COSD_FLAG_ARTHORIZON | COSD_FLAG_NOOSD | COSD_FLAG_NOOSD_BUT_WRN);
-
 
313
 
347
 
314
        // wait a bit before doing stuff so user has chance to release button
348
        // wait a bit before doing stuff so user has chance to release button
315
        _delay_ms(250);
349
        _delay_ms(250);
-
 
350
 
-
 
351
        write_ascii_string(4,  6, menu[0]);
-
 
352
        write_ascii_string(4,  7, menu[1]);
-
 
353
        write_ascii_string(4,  8, menu[2]);
-
 
354
        write_ascii_string(4,  9, menu[3]);
-
 
355
        write_ascii_string(4, 10, menu[4]);
-
 
356
 
-
 
357
        config_menu_drawings(chosen);
316
 
358
 
317
        while (inmenu) {
-
 
318
                        write_ascii_string(2,  7, menu[chosen]);
359
        while (inmenu) {
-
 
360
                        if (s2_pressed()) {
319
                        if (s2_pressed()) {
361
                                write_ascii_string(3,  chosen+6, " ");
-
 
362
                                chosen = (chosen + 1) % 5;
320
                                chosen = (chosen + 1) % 4;
363
                                write_ascii_string(3,  chosen+6, ">");
321
                                _delay_ms(500);
364
                                _delay_ms(500);
322
                        } else if (s1_pressed()) {
365
                        } else if (s1_pressed()) {
323
                                switch (chosen) {
366
                                switch (chosen) {
324
                                        case 1:         // artificial horizon
367
                                        case 0:         // full HUD
325
                                                COSD_FLAGS |= COSD_FLAG_ARTHORIZON;
368
                                                COSD_FLAGS ^= COSD_FLAG_HUD;
-
 
369
                                                config_menu_drawings(chosen);
326
                                                break;
370
                                                break;
327
                                        case 2:         // everything off
371
                                        case 1:         // art horizon
328
                                                COSD_FLAGS |= COSD_FLAG_NOOSD;
372
                                                COSD_FLAGS ^= COSD_FLAG_ARTHORIZON;
-
 
373
                                                config_menu_drawings(chosen);
329
                                                break;
374
                                                break;
-
 
375
                                        case 2:         // statistics
-
 
376
                                                COSD_FLAGS ^= COSD_FLAG_STATS;
-
 
377
                                                config_menu_drawings(chosen);
-
 
378
                                                break;
330
                                        case 3:         // only warning
379
                                        case 3:         // warnings
331
                                                COSD_FLAGS |= COSD_FLAG_NOOSD_BUT_WRN;
380
                                                COSD_FLAGS ^= COSD_FLAG_WARNINGS;
-
 
381
                                                config_menu_drawings(chosen);
-
 
382
                                                break;
-
 
383
                                        case 4:         // exit
-
 
384
                                                inmenu = 0;
332
                                                break;
385
                                                break;
333
                                        //default:      // normal OSD, so let the flags cleared
-
 
334
                                }
386
                                }
335
                                // leave menu
-
 
336
                                inmenu = 0;
-
 
337
                                _delay_ms(500);
387
                                _delay_ms(250);
338
                        }
388
                        }
339
        }
389
        }
340
 
390
 
341
        // clear screen up again
391
        // clear screen up again
342
        clear();
392
        clear();
343
 
393
 
344
        // update flags to paint display again if needed
394
        // update flags to paint display again if needed
345
        COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
395
        COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
346
 
396
 
347
        // enable interrupts again
397
        // enable interrupts again
348
        sei();
398
        sei();
349
}
399
}
350
 
400
 
351
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
401
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
352
 
-
 
353
/* ##########################################################################
402
/* ##########################################################################
354
 * MAIN
403
 * MAIN
355
 * ##########################################################################*/
404
 * ##########################################################################*/
356
int main(void) {
405
int main(void) {
357
        // set up FLAGS, compiler should flatten this one
406
    // set up FLAGS, compiler should flatten this one
358
        COSD_FLAGS = (NTSC << (COSD_FLAG_NTSC - 1));
407
    COSD_FLAGS = (NTSC << 0);
-
 
408
    COSD_FLAGS |= (HUD << 1);
359
        COSD_FLAGS |= (ARTHORIZON << (COSD_FLAG_ARTHORIZON - 1));
409
    COSD_FLAGS |= (ARTHORIZON << 2);
360
        COSD_FLAGS |= (NOOSD << (COSD_FLAG_NOOSD - 1));
410
        COSD_FLAGS |= (STATS << 3);
361
        COSD_FLAGS |= (NOOSD_BUT_WRN << (COSD_FLAG_NOOSD_BUT_WRN - 1));
411
    COSD_FLAGS |= (WARNINGS << 4);
362
 
412
 
363
        // set up Atmega162 Ports
413
    // set up Atmega162 Ports
364
    DDRA |= (1 << PA1); // PA1 output (/CS)
414
    DDRA |= (1 << PA1); // PA1 output (/CS)
365
    MAX_CS_HIGH
415
    MAX_CS_HIGH
366
    DDRA |= (1 << PA2); // PA2 output (SDIN)
416
    DDRA |= (1 << PA2); // PA2 output (SDIN)
367
    MAX_SDIN_LOW
417
    MAX_SDIN_LOW
368
    DDRA |= (1 << PA3); // PA3 output (SCLK)
418
    DDRA |= (1 << PA3); // PA3 output (SCLK)
369
    MAX_SCLK_LOW
419
    MAX_SCLK_LOW
370
    DDRA |= (1 << PA5); // PA5 output (RESET)
420
    DDRA |= (1 << PA5); // PA5 output (RESET)
371
    MAX_RESET_HIGH
421
    MAX_RESET_HIGH
372
 
422
 
373
    DDRC |= (1 << PC0); // PC0 output (LED1 gn)
423
    DDRC |= (1 << PC0); // PC0 output (LED1 gn)
374
    LED1_OFF
424
    LED1_OFF
375
    DDRC |= (1 << PC1); // PC1 output (LED2 rt)
425
    DDRC |= (1 << PC1); // PC1 output (LED2 rt)
376
    LED2_OFF
426
    LED2_OFF
377
    DDRC |= (1 << PC2); // PC2 output (LED3 gn)
427
    DDRC |= (1 << PC2); // PC2 output (LED3 gn)
378
    LED3_OFF
428
    LED3_OFF
379
    DDRC |= (1 << PC3); // PC3 output (LED4 rt)
429
    DDRC |= (1 << PC3); // PC3 output (LED4 rt)
380
    LED4_OFF
430
    LED4_OFF
381
 
431
 
382
    DDRC &= ~(1 << PC4); // PC4 input  (MODE)
432
    DDRC &= ~(1 << PC4); // PC4 input  (MODE)
383
    PORTC |= (1 << PC4); // pullup
433
    PORTC |= (1 << PC4); // pullup
384
    DDRC &= ~(1 << PC5); // PC5 input  (SET)
434
    DDRC &= ~(1 << PC5); // PC5 input  (SET)
385
    PORTC |= (1 << PC5); // pullup
435
    PORTC |= (1 << PC5); // pullup
386
 
436
 
387
        // set up top and bottom lines
437
    // set up top and bottom lines
388
        if (COSD_FLAGS & COSD_FLAG_NTSC) {
438
    if (COSD_FLAGS & COSD_FLAG_NTSC) {
389
                bottom_line = 12;
439
        bottom_line = 12;
390
        } else {
440
    } else {
391
                bottom_line = 14;
441
        bottom_line = 14;
392
        }
442
    }
393
 
443
 
394
        // reset the MAX7456 to be sure any undefined states do no harm
444
    // reset the MAX7456 to be sure any undefined states do no harm
395
    MAX_RESET_LOW
445
    MAX_RESET_LOW
396
    MAX_RESET_HIGH
446
    MAX_RESET_HIGH
397
 
-
 
398
        // check for keypress at startup
-
 
399
        if (s2_pressed()) { // togle COSD_FLAG_ARTHORIZON
-
 
400
                        COSD_FLAGS ^= (1 << (COSD_FLAG_ARTHORIZON - 1));
-
 
401
                        _delay_ms(100);
-
 
402
    }
-
 
403
 
447
 
404
    // give the FC/NC and the maxim time to come up
448
    // give the FC/NC and the maxim time to come up
405
    LED4_ON
449
    LED4_ON
406
    _delay_ms(2000);
450
    _delay_ms(2000);
407
 
451
 
408
    LED4_OFF
452
    LED4_OFF
409
 
453
 
410
 
454
 
411
     //Pushing NEW chars to the MAX7456
455
    //Pushing NEW chars to the MAX7456
412
#if (WRITECHARS != -1)
456
#if (WRITECHARS != -1)
413
        // DISABLE display (VM0)
457
    // DISABLE display (VM0)
-
 
458
    spi_send_byte(0x00, 0b00000000);
414
    spi_send_byte(0x00, 0b00000000);
-
 
415
 
459
#include "characters.c"
416
        #include "characters.c"
460
 
417
#endif 
461
#endif 
418
 
462
 
419
        // Setup Video Mode
463
    // Setup Video Mode
420
        if (COSD_FLAGS & COSD_FLAG_NTSC) {
464
    if (COSD_FLAGS & COSD_FLAG_NTSC) {
421
        // NTSC + enable display immediately (VM0)
465
        // NTSC + enable display immediately (VM0)
422
        spi_send_byte(0x00, 0b00001000);
466
        spi_send_byte(0x00, 0b00001000);
423
        } else {
467
    } else {
424
        // PAL + enable display immediately (VM0)
468
        // PAL + enable display immediately (VM0)
425
        spi_send_byte(0x00, 0b01001000);
469
        spi_send_byte(0x00, 0b01001000);
426
        }
470
    }
427
 
471
 
428
    // clear all display-mem (DMM)
472
    // clear all display-mem (DMM)
429
    spi_send_byte(0x04, 0b00000100);
473
    spi_send_byte(0x04, 0b00000100);
430
 
474
 
431
    // clearing takes 12uS according to maxim so lets wait longer
475
    // clearing takes 12uS according to maxim so lets wait longer
432
    _delay_us(120);
476
    _delay_us(120);
433
 
477
 
434
    // 8bit mode
478
    // 8bit mode
435
    spi_send_byte(0x04, 0b01000000);
479
    spi_send_byte(0x04, 0b01000000);
436
 
480
 
437
    // write blank chars to whole screen
481
    // write blank chars to whole screen
438
    clear();
482
    clear();
439
 
483
 
440
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
484
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
441
    // init usart
485
    // init usart
442
    usart1_init();
486
    usart1_init();
443
 
487
 
444
    // set up timer
488
    // set up timer
445
    TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64
489
    TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64
446
    OCR0 = 6; // preload
490
    OCR0 = 6; // preload
447
    TIMSK |= (1 << TOIE0); // enable overflow timer0
491
    TIMSK |= (1 << TOIE0); // enable overflow timer0
448
 
492
 
449
    // enable interrupts
493
    // enable interrupts
450
    sei();
494
    sei();
451
#endif
495
#endif
452
 
496
 
453
    //write_ascii_string(2,  7, "         CaScAdE          ");
497
    //write_ascii_string(2,  7, "         CaScAdE          ");
454
    //write_ascii_string(2,  8, "is TESTING his open source");
498
    //write_ascii_string(2,  8, "is TESTING his open source");
455
    //write_ascii_string(2,  9, "    EPi OSD Firmware");
499
    //write_ascii_string(2,  9, "    EPi OSD Firmware");
456
 
500
 
457
    // custom char preview
501
    // custom char preview
458
    /*write_char_xy( 2, 7, 200);
502
    /*write_char_xy( 2, 7, 200);
459
    write_char_xy( 3, 7, 201);
503
    write_char_xy( 3, 7, 201);
460
    write_char_xy( 4, 7, 202);
504
    write_char_xy( 4, 7, 202);
461
    write_char_xy( 5, 7, 203);
505
    write_char_xy( 5, 7, 203);
462
    write_char_xy( 6, 7, 204);
506
    write_char_xy( 6, 7, 204);
463
    write_char_xy( 7, 7, 205);
507
    write_char_xy( 7, 7, 205);
464
    write_char_xy( 8, 7, 206);
508
    write_char_xy( 8, 7, 206);
465
    write_char_xy( 9, 7, 207);
509
    write_char_xy( 9, 7, 207);
466
    write_char_xy(10, 7, 208);
510
    write_char_xy(10, 7, 208);
467
    write_char_xy(11, 7, 209);
511
    write_char_xy(11, 7, 209);
468
    write_char_xy(12, 7, 210);
512
    write_char_xy(12, 7, 210);
469
    write_char_xy(13, 7, 211);
513
    write_char_xy(13, 7, 211);
470
    write_char_xy(14, 7, 212);
514
    write_char_xy(14, 7, 212);
471
    write_char_xy(15, 7, 213);
515
    write_char_xy(15, 7, 213);
472
    write_char_xy(16, 7, 214);
516
    write_char_xy(16, 7, 214);
473
    write_char_xy(17, 7, 215);*/
517
    write_char_xy(17, 7, 215);*/
474
 
518
 
475
    // we are ready
519
    // we are ready
476
    LED3_ON
520
    LED3_ON
477
 
521
 
478
 
522
 
479
 
523
 
480
#if ALLCHARSDEBUG | (WRITECHARS != -1)
524
#if ALLCHARSDEBUG | (WRITECHARS != -1)
481
        clear();
525
        clear();
482
    write_all_chars();
526
    write_all_chars();
483
#else
527
#else
484
    // clear serial screen
528
        // clear serial screen
485
    //usart1_puts("\x1B[2J\x1B[H");
529
        //usart1_puts("\x1B[2J\x1B[H");
486
    //usart1_puts("hello world!\r\n");
530
        //usart1_puts("hello world!\r\n");
487
 
531
 
488
   
532
 
489
    // request data ever 100ms from FC
533
        // request data ever 100ms from FC
490
        //unsigned char ms = 10;
534
        //unsigned char ms = 10;
491
        //sendMKData('d', 0, &ms, 1);
535
        //sendMKData('d', 0, &ms, 1);
492
     
536
 
493
    // request OSD Data from NC every 100ms
537
        // request OSD Data from NC every 100ms
494
        unsigned char ms = 10;
538
        unsigned char ms = 10;
495
    sendMKData('o', 1, &ms, 1);
539
    sendMKData('o', 1, &ms, 1);
496
        // and disable debug...
540
    // and disable debug...
497
        //ms = 0;
541
    //ms = 0;
-
 
542
    //sendMKData('d', 0, &ms, 1);
-
 
543
 
-
 
544
    // disable TXD-pin
-
 
545
    usart1_DisableTXD();
-
 
546
 
-
 
547
    // stats for after flight
-
 
548
    int16_t max_Altimeter = 0;
-
 
549
    uint16_t max_GroundSpeed = 0;
-
 
550
    int16_t max_Distance = 0;
-
 
551
    uint8_t min_UBat = 255;
498
        //sendMKData('d', 0, &ms, 1);
552
    uint16_t max_FlyingTime = 0;
499
 
553
 
500
        // disable TXD-pin
-
 
501
        usart1_DisableTXD();
-
 
502
 
-
 
503
        // stats for after flight
-
 
504
        int16_t max_Altimeter = 0;
-
 
505
        uint16_t max_GroundSpeed = 0;
-
 
506
        int16_t max_Distance = 0;
-
 
507
        uint8_t min_UBat = 255;
-
 
508
        uint16_t max_FlyingTime = 0;
-
 
509
 
-
 
510
        // flags from last round to check for changes
554
    // flags from last round to check for changes
511
        uint8_t old_MKFlags = 0;
555
    uint8_t old_MKFlags = 0;
512
       
556
 
513
    char* directions[8] = {"NE", "E ", "SE", "S ", "SW", "W ", "NW", "N "};
557
    char* directions[8] = {"NE", "E ", "SE", "S ", "SW", "W ", "NW", "N "};
514
        char arrowdir[8] =   { 218,  217,  224,  223,  222,  221,  220, 219};
558
    char arrowdir[8] = {218, 217, 224, 223, 222, 221, 220, 219};
515
 
559
 
516
    while (1) {
560
    while (1) {
517
                // write icons at init or after menu/mode-switch
561
        // write icons at init or after menu/mode-switch
518
                if (!(COSD_FLAGS & COSD_ICONS_WRITTEN) && !(COSD_FLAGS & COSD_FLAG_NOOSD)) {
562
        if (!(COSD_FLAGS & COSD_ICONS_WRITTEN) && (COSD_FLAGS & COSD_FLAG_HUD)) {
519
                            write_char_xy(5, top_line, 203); // km/h
563
            write_char_xy(5, top_line, 203); // km/h
520
                            write_char_xy(10, top_line, 202); // RC-transmitter
564
            write_char_xy(10, top_line, 202); // RC-transmitter
521
                            write_char_xy(16, top_line, 208); // degree symbol
565
            write_char_xy(16, top_line, 208); // degree symbol
522
                            write_char_xy(27, top_line, 204); // small meters m
566
            write_char_xy(27, top_line, 204); // small meters m
523
                            write_ascii_string(6, bottom_line, "V"); // voltage
567
            write_ascii_string(6, bottom_line, "V"); // voltage
524
                            write_char_xy(14, bottom_line, 209); // on clock
568
            write_char_xy(14, bottom_line, 209); // on clock
525
                            write_char_xy(22, bottom_line, 210); // fly clock
569
            write_char_xy(22, bottom_line, 210); // fly clock
526
                            write_char_xy(26, bottom_line, 200); // sat1
570
            write_char_xy(26, bottom_line, 200); // sat1
527
                            write_char_xy(27, bottom_line, 201); // sat2
571
            write_char_xy(27, bottom_line, 201); // sat2
528
                                COSD_FLAGS |= COSD_ICONS_WRITTEN;
572
            COSD_FLAGS |= COSD_ICONS_WRITTEN;
529
                }
573
        }
530
        if (rxd_buffer_locked) {
574
        if (rxd_buffer_locked) {
531
                if (!(COSD_FLAGS & COSD_FLAG_NOOSD)) {
575
            if (COSD_FLAGS & COSD_FLAG_HUD) {
532
                    if (rxd_buffer[2] == 'D') { // FC Data
576
                if (rxd_buffer[2] == 'D') { // FC Data
533
                        /*Decode64();
577
                    /*Decode64();
534
                        debugData = *((DebugOut_t*) pRxData);
578
                    debugData = *((DebugOut_t*) pRxData);
535
                        write_number_s(12, 2, RxDataLen);
579
                    write_number_s(12, 2, RxDataLen);
536
                        write_number_s(20, 2, setsReceived++);
580
                    write_number_s(20, 2, setsReceived++);
537
                        write_number_s(12, 3, debugData.Analog[0]); // AngleNick
581
                    write_number_s(12, 3, debugData.Analog[0]); // AngleNick
538
                        write_number_s(12, 4, debugData.Analog[1]); // AngleRoll
582
                    write_number_s(12, 4, debugData.Analog[1]); // AngleRoll
539
                                        write_number_s(12, 5, debugData.Analog[5]); // Height
583
                                        write_number_s(12, 5, debugData.Analog[5]); // Height
540
                        write_number_s(12, 6, debugData.Analog[9]); // Voltage
584
                    write_number_s(12, 6, debugData.Analog[9]); // Voltage
541
                        write_number_s(12, 7, debugData.Analog[10]);// RC Signal
585
                    write_number_s(12, 7, debugData.Analog[10]);// RC Signal
542
                                        write_number_s(12, 8, debugData.Analog[11]);// Gyro compass*/
586
                                        write_number_s(12, 8, debugData.Analog[11]);// Gyro compass*/
543
                    } else if (rxd_buffer[2] == 'O') { // NC OSD Data
587
                } else if (rxd_buffer[2] == 'O') { // NC OSD Data
544
                        Decode64();
588
                    Decode64();
545
                        naviData = *((NaviData_t*) pRxData);
589
                    naviData = *((NaviData_t*) pRxData);
546
 
590
 
547
                                        // first line
591
                    // first line
548
                                        write_3digit_number_u(2, top_line, (uint16_t)(((uint32_t)naviData.GroundSpeed*36)/1000));
592
                    write_3digit_number_u(2, top_line, (uint16_t) (((uint32_t) naviData.GroundSpeed * 36) / 1000));
549
 
593
 
550
                        write_3digit_number_u(7, top_line, naviData.RC_Quality);
594
                    write_3digit_number_u(7, top_line, naviData.RC_Quality);
551
                        if (naviData.RC_Quality <= RCLVL_WRN && last_RC_Quality > RCLVL_WRN) {
595
                    if (naviData.RC_Quality <= RCLVL_WRN && last_RC_Quality > RCLVL_WRN) {
552
                            for (uint8_t x = 0; x < 4; x++)
596
                        for (uint8_t x = 0; x < 4; x++)
553
                                write_char_att_xy(7 + x, top_line, BLINK);
597
                            write_char_att_xy(7 + x, top_line, BLINK);
554
                        } else if (naviData.RC_Quality > RCLVL_WRN && last_RC_Quality <= RCLVL_WRN) {
598
                    } else if (naviData.RC_Quality > RCLVL_WRN && last_RC_Quality <= RCLVL_WRN) {
555
                            for (uint8_t x = 0; x < 4; x++)
599
                        for (uint8_t x = 0; x < 4; x++)
556
                                write_char_att_xy(7 + x, top_line, 0);
600
                            write_char_att_xy(7 + x, top_line, 0);
557
                        }
601
                    }
558
                        last_RC_Quality = naviData.RC_Quality;
602
                    last_RC_Quality = naviData.RC_Quality;
559
 
603
 
560
                        write_3digit_number_u(13, top_line, naviData.CompassHeading);
604
                    write_3digit_number_u(13, top_line, naviData.CompassHeading);
561
 
605
 
562
                        write_ascii_string(17, top_line, directions[heading_conv(naviData.CompassHeading)]);
606
                    write_ascii_string(17, top_line, directions[heading_conv(naviData.CompassHeading)]);
563
 
607
 
564
                                        if (naviData.Variometer == 0) {
608
                    if (naviData.Variometer == 0) {
565
                                                write_char_xy(20, top_line, 206); // plain line
609
                        write_char_xy(20, top_line, 206); // plain line
566
                                        } else if (naviData.Variometer > 0 && naviData.Variometer <= 10) {
610
                    } else if (naviData.Variometer > 0 && naviData.Variometer <= 10) {
567
                                                write_char_xy(20, top_line, 234); // small arrow up
611
                        write_char_xy(20, top_line, 234); // small arrow up
568
                                        } else if (naviData.Variometer > 10) {
612
                    } else if (naviData.Variometer > 10) {
569
                                                write_char_xy(20, top_line, 235); // big arrow up
613
                        write_char_xy(20, top_line, 235); // big arrow up
570
                                        } else if (naviData.Variometer < 0 && naviData.Variometer >= -10) {
614
                    } else if (naviData.Variometer < 0 && naviData.Variometer >= -10) {
571
                                                write_char_xy(20, top_line, 232); // small arrow down
615
                        write_char_xy(20, top_line, 232); // small arrow down
572
                                        } else {
-
 
573
                                                write_char_xy(20, top_line, 233); //big arrow down
616
                    } else {
574
                                        }
-
 
575
 
617
                        write_char_xy(20, top_line, 233); //big arrow down
576
                                        // TODO: is this really dm?
618
                    }
577
                                        //note:lephisto:according to several sources it's /30
619
 
578
                        //write_number_s(22, top_line, naviData.Altimeter/30);
620
                    //note:lephisto:according to several sources it's /30
579
                                        if (naviData.Altimeter > 300) {
621
                    if (naviData.Altimeter > 300) {
580
                                                // above 10m only write full meters
622
                        // above 10m only write full meters
581
                                                write_number_s(22, top_line, naviData.Altimeter/30);
623
                        write_number_s(22, top_line, naviData.Altimeter / 30);
582
                                        } else {
624
                    } else {
583
                                                // up to 10m write meters.dm
625
                        // up to 10m write meters.dm
584
                                                write_number_u_10th(21, top_line, naviData.Altimeter/3);
626
                        write_number_u_10th(21, top_line, naviData.Altimeter / 3);
585
                                        }
627
                    }
586
 
628
 
587
                                        // seccond line
629
                    // seccond line
588
                        draw_compass(11, top_line + 1, naviData.CompassHeading);
630
                    draw_compass(11, top_line + 1, naviData.CompassHeading);
589
 
-
 
590
                                        // TODO: verify correctness
631
 
591
                                        uint16_t heading_home = (naviData.HomePositionDeviation.Bearing + 360 - naviData.CompassHeading) % 360;
632
                    // TODO: verify correctness
592
                                        write_char_xy(27, top_line + 1, arrowdir[heading_conv(heading_home)]);
633
                    uint16_t heading_home = (naviData.HomePositionDeviation.Bearing + 360 - naviData.CompassHeading) % 360;
593
 
634
                    write_char_xy(27, top_line + 1, arrowdir[heading_conv(heading_home)]);
594
       
635
 
595
                                        write_number_s(22, top_line + 1, naviData.HomePositionDeviation.Distance/100);
636
                    write_number_s(22, top_line + 1, naviData.HomePositionDeviation.Distance / 100);
596
 
637
 
597
                                        // center
638
                    // center
598
                                        if (naviData.MKFlags & FLAG_MOTOR_RUN) { // should be engines running
639
                    if (naviData.MKFlags & FLAG_MOTOR_RUN) { // should be engines running
599
                                                if (!(old_MKFlags & FLAG_MOTOR_RUN)) { // motors just started, clear middle
640
                        if (!(old_MKFlags & FLAG_MOTOR_RUN)) { // motors just started, clear middle
600
                                                        clear();
641
                            clear();
601
                                                        // update flags to paint display again if needed
642
                            // update flags to paint display again if needed
602
                                                        COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
643
                            COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
603
                                                }
644
                        }
604
                                        if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
645
                        if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
-
 
646
                            draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
605
                                                draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
647
                        }
606
                                        }
648
                    } else {
607
                                        } else {
649
                                                // stats
608
                                                // stats
650
                                                if (COSD_FLAGS & COSD_FLAG_STATS) {
609
                                                write_ascii_string(2, 5, "max Altitude:");
651
                                write_ascii_string(2, 5, "max Altitude:");
610
                                                write_number_s(17, 5, max_Altimeter/30);
652
                                write_number_s(17, 5, max_Altimeter / 30);
611
                                                write_char_xy(22, 5, 204); // small meters m
653
                                write_char_xy(22, 5, 204); // small meters m
612
                                                write_ascii_string(2, 6, "max Speed   :");
654
                                write_ascii_string(2, 6, "max Speed   :");
613
                                                write_3digit_number_u(19, 6, (uint16_t)(((uint32_t)max_GroundSpeed*36)/1000));
655
                                write_3digit_number_u(19, 6, (uint16_t) (((uint32_t) max_GroundSpeed * 36) / 1000));
614
                                                write_char_xy(22, 6, 203); // km/h
656
                                write_char_xy(22, 6, 203); // km/h
615
                                                write_ascii_string(2, 7, "max Distance:");
-
 
616
                                                write_number_s(17, 7, max_Distance/100);
657
                                write_ascii_string(2, 7, "max Distance:");
617
                                                write_char_xy(22, 7, 204); // small meters m
658
                                write_number_s(17, 7, max_Distance / 100);
618
                                                write_ascii_string(2, 8, "min voltage :");
659
                                write_char_xy(22, 7, 204); // small meters m
619
                                                //write_number_s(17, 8, min_UBat/10);
660
                                write_ascii_string(2, 8, "min voltage :");
620
                                                write_number_u_10th(16, 8, min_UBat);
661
                                write_number_u_10th(16, 8, min_UBat);
-
 
662
                                write_ascii_string(22, 8, "V"); // voltage
-
 
663
                                write_ascii_string(2, 9, "max time    :");
-
 
664
                                write_time(16, 9, max_FlyingTime);
621
                                                write_ascii_string(22, 8, "V"); // voltage
665
                                write_char_xy(22, 9, 210); // fly clock
622
                                                write_ascii_string(2, 9, "max time    :");
666
                                                } else if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) { // if no stats there is space horizon
623
                                                write_time(16, 9, max_FlyingTime);
667
                            draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
624
                                                write_char_xy(22, 9, 210); // fly clock
668
                        }
625
                                        }
669
                    }
626
 
670
 
627
                                        // bottom line
671
                    // bottom line
628
                        write_number_u_10th(0, bottom_line, naviData.UBat);
672
                    write_number_u_10th(0, bottom_line, naviData.UBat);
629
                        if (naviData.UBat <= UBAT_WRN && last_UBat > UBAT_WRN) {
673
                    if (naviData.UBat <= UBAT_WRN && last_UBat > UBAT_WRN) {
630
                            for (uint8_t x = 0; x < 7; x++)
674
                        for (uint8_t x = 0; x < 7; x++)
631
                                write_char_att_xy(x, bottom_line, BLINK);
675
                            write_char_att_xy(x, bottom_line, BLINK);
632
                        } else {
676
                    } else {
633
                            for (uint8_t x = 0; x < 7; x++)
677
                        for (uint8_t x = 0; x < 7; x++)
634
                                write_char_att_xy(x, bottom_line, 0);
678
                            write_char_att_xy(x, bottom_line, 0);
635
                        }
679
                    }
636
 
680
 
637
                        write_time(8, bottom_line, uptime);
681
                    write_time(8, bottom_line, uptime);
638
                        write_time(16, bottom_line, naviData.FlyingTime);
682
                    write_time(16, bottom_line, naviData.FlyingTime);
639
 
683
 
640
                        write_3digit_number_u(23, bottom_line, naviData.SatsInUse);
684
                    write_3digit_number_u(23, bottom_line, naviData.SatsInUse);
641
 
685
 
642
                                        if (naviData.NCFlags & NC_FLAG_CH) {
686
                    if (naviData.NCFlags & NC_FLAG_CH) {
643
                                                write_char_xy(27, bottom_line, 231);    // gps ch
687
                        write_char_xy(27, bottom_line, 231); // gps ch
644
                                        } else if (naviData.NCFlags & NC_FLAG_PH) {
688
                    } else if (naviData.NCFlags & NC_FLAG_PH) {
645
                                                write_char_xy(27, bottom_line, 230);    // gps ph
689
                        write_char_xy(27, bottom_line, 230); // gps ph
646
                                        } else { // (naviData.NCFlags & NC_FLAG_FREE)
690
                    } else { // (naviData.NCFlags & NC_FLAG_FREE)
647
                                                write_char_xy(27, bottom_line, 201);    // sat2 (free)
691
                        write_char_xy(27, bottom_line, 201); // sat2 (free)
648
                                        }
692
                    }
649
 
693
 
650
                        //write_number_s(8, 5, RxDataLen);
694
                    //write_number_s(8, 5, RxDataLen);
651
                        //write_number_s(16, 5, setsReceived++);
695
                    //write_number_s(16, 5, setsReceived++);
652
 
696
 
653
                                        // remember statistics
697
                    // remember statistics
654
                                        if (naviData.Altimeter > max_Altimeter) max_Altimeter = naviData.Altimeter;
698
                    if (naviData.Altimeter > max_Altimeter) max_Altimeter = naviData.Altimeter;
655
                                        if (naviData.GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData.GroundSpeed;
699
                    if (naviData.GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData.GroundSpeed;
656
                                        if (naviData.HomePositionDeviation.Distance > max_Distance) {
700
                    if (naviData.HomePositionDeviation.Distance > max_Distance) {
657
                                                max_Distance = naviData.HomePositionDeviation.Distance;
701
                        max_Distance = naviData.HomePositionDeviation.Distance;
658
                                        }
702
                    }
659
                                        if (naviData.UBat < min_UBat) min_UBat = naviData.UBat;
703
                    if (naviData.UBat < min_UBat) min_UBat = naviData.UBat;
660
                                        if (naviData.FlyingTime > max_FlyingTime) max_FlyingTime = naviData.FlyingTime;
704
                    if (naviData.FlyingTime > max_FlyingTime) max_FlyingTime = naviData.FlyingTime;
661
                               
705
 
662
                                        old_MKFlags = naviData.MKFlags;
706
                    old_MKFlags = naviData.MKFlags;
663
                    } // (!(COSD_FLAGS & COSD_FLAG_NOOSD))
707
                }
664
                        }
708
            }
665
                        seconds_since_last_data = 0;
709
            seconds_since_last_data = 0;
666
            rxd_buffer_locked = 0;
710
            rxd_buffer_locked = 0;
667
        }
711
        }
668
        // handle keypress
712
        // handle keypress
669
        if (s1_pressed()) {
713
        if (s1_pressed()) {
670
                        //sendMKData('d', 1, (unsigned char*) 0, 1);
714
            //sendMKData('d', 1, (unsigned char*) 0, 1);
671
            // request OSD Data from NC every 100ms
715
            // request OSD Data from NC every 100ms
672
                        /*unsigned char ms = 10;
716
            /*unsigned char ms = 10;
673
            sendMKData('o', 1, &ms, 1);
717
                        sendMKData('o', 1, &ms, 1);
674
            _delay_ms(500);*/
718
                        _delay_ms(500);*/
675
                        config_menu();
719
            config_menu();
676
        }
720
        }
677
                if (s2_pressed()) {
721
        if (s2_pressed()) {
678
            uptime = 0;
722
            uptime = 0;
679
            _delay_ms(100);
723
            _delay_ms(100);
680
        }
724
        }
681
                if (seconds_since_last_data > 2) {
725
        if (seconds_since_last_data > 2) {
682
                        // re-request OSD Data from NC
726
            // re-request OSD Data from NC
683
                       
727
 
684
                        // re-enable TXD pin
728
            // re-enable TXD pin
685
                        usart1_EnableTXD();
729
            usart1_EnableTXD();
686
                       
730
 
687
                        // every 100ms
731
            // every 100ms
688
                        unsigned char ms = 10;
732
            unsigned char ms = 10;
689
            sendMKData('o', 1, &ms, 1);
733
            sendMKData('o', 1, &ms, 1);
690
                       
-
 
691
                        // disable TXD pin again
-
 
692
                        usart1_DisableTXD();
-
 
-
 
734
 
-
 
735
            // disable TXD pin again
-
 
736
            usart1_DisableTXD();
693
 
737
 
694
                        seconds_since_last_data = 0;
738
            seconds_since_last_data = 0;
695
                }
739
        }
696
    }
740
    }
697
#endif
741
#endif
698
    return 0;
742
    return 0;
699
}
743
}
700
 
744