Subversion Repositories Projects

Rev

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

Rev 330 Rev 331
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"
-
 
32
#include "usart1.h"
31
 
33
 
32
/* TODO:
34
/* TODO:
33
 * - verifiy correctness of values
35
 * - verifiy correctness of values
34
 * - clean up code :)
36
 * - clean up code :)
35
 */
37
 */
36
 
38
 
37
/* ##########################################################################
39
/* ##########################################################################
38
 * Debugging and general purpose definitions
40
 * Debugging and general purpose definitions
39
 * ##########################################################################*/
41
 * ##########################################################################*/
40
#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
41
 
43
 
42
#ifndef WRITECHARS                      // if WRITECHARS not set via makefile
44
#ifndef WRITECHARS                      // if WRITECHARS not set via makefile
43
#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
44
                                                        // enables the allchars as well to see results
46
                                                        // enables the allchars as well to see results
45
#endif
47
#endif
46
 
48
 
47
#ifndef NTSC                            // if NTSC is not thet via makefile
49
#ifndef NTSC                            // if NTSC is not thet via makefile
48
#define NTSC 0                          // set to 1 for NTSC mode + lifts the bottom line
50
#define NTSC 0                          // set to 1 for NTSC mode + lifts the bottom line
49
#endif
51
#endif
50
 
52
 
51
#define ARTHORIZON 0            // set to 1 to enable roll&nick artificial horizon
53
#define ARTHORIZON 0            // set to 1 to enable roll&nick artificial horizon
52
#define NOOSD 0                         // set to 1 to disable OSD completely
54
#define NOOSD 0                         // set to 1 to disable OSD completely
53
#define NOOSD_BUT_WRN 0         // set to 1 to disable OSD completely but show 
55
#define NOOSD_BUT_WRN 0         // set to 1 to disable OSD completely but show 
54
                                                        // battery and receive signal warnings
56
                                                        // battery and receive signal warnings
55
#define UBAT_WRN 94                     // voltage for blinking warning, like FC settings
57
#define UBAT_WRN 94                     // voltage for blinking warning, like FC settings
56
#define RCLVL_WRN 100           // make the RC level blink if below this number
58
#define RCLVL_WRN 100           // make the RC level blink if below this number
57
 
59
 
58
// ### read datasheet before changing stuff below this line :)
60
// ### read datasheet before changing stuff below this line :)
59
#define BLINK   0b01001111      // attribute byte for blinking chars
61
#define BLINK   0b01001111      // attribute byte for blinking chars
60
 
62
 
61
/* ##########################################################################
63
/* ##########################################################################
62
 * FLAGS usable during runtime
64
 * FLAGS usable during runtime
63
 * ##########################################################################*/
65
 * ##########################################################################*/
64
#define COSD_FLAG_NTSC                   1
66
#define COSD_FLAG_NTSC                   1
65
#define COSD_FLAG_ARTHORIZON     2
67
#define COSD_FLAG_ARTHORIZON     2
66
#define COSD_FLAG_NOOSD                  4
68
#define COSD_FLAG_NOOSD                  4
67
#define COSD_FLAG_NOOSD_BUT_WRN  8
69
#define COSD_FLAG_NOOSD_BUT_WRN  8
68
#define COSD_ICONS_WRITTEN              16
70
#define COSD_ICONS_WRITTEN              16
69
 
71
 
70
/* ##########################################################################
72
/* ##########################################################################
71
 * Software SPI to communicate with MAX7456
-
 
72
 * ##########################################################################*/
-
 
73
#define MAX_CS_HIGH             PORTA |=  (1 << PA1);
-
 
74
#define MAX_CS_LOW              PORTA &= ~(1 << PA1);
-
 
75
#define MAX_SDIN_HIGH           PORTA |=  (1 << PA2);
-
 
76
#define MAX_SDIN_LOW            PORTA &= ~(1 << PA2);
-
 
77
#define MAX_SCLK_HIGH           PORTA |=  (1 << PA3);
-
 
78
#define MAX_SCLK_LOW            PORTA &= ~(1 << PA3);
-
 
79
#define MAX_RESET_HIGH          PORTA |=  (1 << PA5);
-
 
80
#define MAX_RESET_LOW           PORTA &= ~(1 << PA5);
-
 
81
 
-
 
82
/* ##########################################################################
-
 
83
 * LED controll
73
 * LED controll
84
 * ##########################################################################*/
74
 * ##########################################################################*/
85
#define LED1_ON                 PORTC |=  (1 << PC0);
75
#define LED1_ON                 PORTC |=  (1 << PC0);
86
#define LED1_OFF                PORTC &= ~(1 << PC0);
76
#define LED1_OFF                PORTC &= ~(1 << PC0);
87
#define LED2_ON                 PORTC |=  (1 << PC1);
77
#define LED2_ON                 PORTC |=  (1 << PC1);
88
#define LED2_OFF                PORTC &= ~(1 << PC1);
78
#define LED2_OFF                PORTC &= ~(1 << PC1);
89
#define LED3_ON                 PORTC |=  (1 << PC2);
79
#define LED3_ON                 PORTC |=  (1 << PC2);
90
#define LED3_OFF                PORTC &= ~(1 << PC2);
80
#define LED3_OFF                PORTC &= ~(1 << PC2);
91
#define LED4_ON                 PORTC |=  (1 << PC3);
81
#define LED4_ON                 PORTC |=  (1 << PC3);
92
#define LED4_OFF                PORTC &= ~(1 << PC3);
82
#define LED4_OFF                PORTC &= ~(1 << PC3);
93
 
83
 
94
/* ##########################################################################
84
/* ##########################################################################
95
 * switch controll
85
 * switch controll
96
 * ##########################################################################*/
86
 * ##########################################################################*/
97
#define S1_PRESSED              !(PINC & (1<<PC5))
87
#define S1_PRESSED              !(PINC & (1<<PC5))
98
#define S2_PRESSED              !(PINC & (1<<PC4))
88
#define S2_PRESSED              !(PINC & (1<<PC4))
99
 
-
 
100
/* ##########################################################################
-
 
101
 * gain some fake arm compat :)
-
 
102
 * ##########################################################################*/
-
 
103
#define u8 uint8_t
-
 
104
#define s8 int8_t
-
 
105
#define u16 uint16_t
-
 
106
#define s16 int16_t
-
 
107
#define u32 uint32_t
-
 
108
#define s32 int32_t
-
 
109
 
89
 
110
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
-
 
111
/* ##########################################################################
-
 
112
 * MK data strucs & flags
-
 
113
 * ##########################################################################*/
-
 
114
#define NC_FLAG_FREE                    1
-
 
115
#define NC_FLAG_PH                      2
-
 
116
#define NC_FLAG_CH                      4
-
 
117
#define NC_FLAG_RANGE_LIMIT             8
-
 
118
#define NC_SERIAL_LINK_OK               16
-
 
119
#define NC_FLAG_TARGET_REACHED          32
-
 
120
 
-
 
121
#define FLAG_MOTOR_RUN  1
-
 
122
#define FLAG_FLY        2
-
 
123
#define FLAG_CALIBRATE  4
-
 
124
#define FLAG_START      8
-
 
125
 
-
 
126
/*
-
 
127
 * FC Debug Struct
-
 
128
 * portions taken and adapted from
-
 
129
 * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=FlightCtrl&path=%2Ftags%2FV0.72p%2Fuart.h
-
 
130
 */
90
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
131
typedef struct {
-
 
132
    uint8_t Digital[2];
-
 
133
    uint16_t Analog[32]; // Debugvalues
-
 
134
} __attribute__((packed)) DebugOut_t;
-
 
135
 
-
 
136
/*
91
// data structs
137
 * NaviCtrl OSD Structs
-
 
138
 * portions taken and adapted from
-
 
139
 * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=NaviCtrl&path=%2Ftags%2FV0.14e%2Fuart1.h
-
 
140
 */
-
 
141
typedef struct {
-
 
142
    s32 Longitude; // in 1E-7 deg
-
 
143
    s32 Latitude; // in 1E-7 deg
-
 
144
    s32 Altitude; // in mm
-
 
145
    u8 Status; // validity of data
-
 
146
} __attribute__((packed)) GPS_Pos_t;
-
 
147
 
-
 
148
typedef struct {
-
 
149
    s16 Distance; // distance to target in cm
-
 
150
    s16 Bearing; // course to target in deg
-
 
151
} __attribute__((packed)) GPS_PosDev_t;
-
 
152
 
-
 
153
typedef struct {
-
 
154
    GPS_Pos_t CurrentPosition; // see ubx.h for details
-
 
155
    GPS_Pos_t TargetPosition;
-
 
156
    GPS_PosDev_t TargetPositionDeviation;
-
 
157
    GPS_Pos_t HomePosition;
-
 
158
    GPS_PosDev_t HomePositionDeviation;
-
 
159
    u8 WaypointIndex; // index of current waypoints running from 0 to WaypointNumber-1
-
 
160
    u8 WaypointNumber; // number of stored waypoints
-
 
161
    u8 SatsInUse; // no of satellites used for position solution
-
 
162
    s16 Altimeter; // hight according to air pressure
-
 
163
    s16 Variometer; // climb(+) and sink(-) rate
-
 
164
    u16 FlyingTime; // in seconds
-
 
165
    u8 UBat; // Battery Voltage in 0.1 Volts
-
 
166
    u16 GroundSpeed; // speed over ground in cm/s (2D)
-
 
167
    s16 Heading; // current flight direction in deg as angle to north
-
 
168
    s16 CompassHeading; // current compass value
-
 
169
    s8 AngleNick; // current Nick angle in 1°
-
 
170
    s8 AngleRoll; // current Rick angle in 1°
-
 
171
    u8 RC_Quality; // RC_Quality
-
 
172
    u8 MKFlags; // Flags from FC
-
 
173
    u8 NCFlags; // Flags from NC
-
 
174
    u8 Errorcode; // 0 --> okay
-
 
175
    u8 OperatingRadius; // current operation radius around the Home Position in m
-
 
176
    u8 Reserve[7]; // for future use
-
 
177
} __attribute__((packed)) NaviData_t;
-
 
178
 
92
#include "mk-data-structs.h"
179
 
93
 
180
/* ##########################################################################
94
/* ##########################################################################
181
 * global definitions and global vars
95
 * global definitions and global vars
182
 * ##########################################################################*/
96
 * ##########################################################################*/
183
#define baud 57600
-
 
184
 
-
 
185
#define RXD_BUFFER_LEN          150
-
 
186
#define TXD_BUFFER_LEN          150
-
 
187
 
-
 
188
volatile uint8_t rxd_buffer_locked = 0;
97
volatile uint8_t rxd_buffer_locked = 0;
189
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
98
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
190
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
99
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
191
volatile uint8_t ReceivedBytes = 0;
100
volatile uint8_t ReceivedBytes = 0;
192
volatile uint8_t *pRxData = 0;
101
volatile uint8_t *pRxData = 0;
193
volatile uint8_t RxDataLen = 0;
102
volatile uint8_t RxDataLen = 0;
194
volatile uint16_t setsReceived = 0;
103
volatile uint16_t setsReceived = 0;
195
 
104
 
196
volatile NaviData_t naviData;
105
volatile NaviData_t naviData;
197
volatile DebugOut_t debugData;
106
volatile DebugOut_t debugData;
198
 
107
 
199
// cache old vars for blinking attribute, checkup is faster than full
108
// cache old vars for blinking attribute, checkup is faster than full
200
// attribute write each time
109
// attribute write each time
201
volatile uint8_t last_UBat = 255;
110
volatile uint8_t last_UBat = 255;
202
volatile uint8_t last_RC_Quality = 255;
111
volatile uint8_t last_RC_Quality = 255;
203
 
112
 
204
// 16bit should be enough, normal LiPos don't last that long
113
// 16bit should be enough, normal LiPos don't last that long
205
volatile uint16_t uptime = 0;
114
volatile uint16_t uptime = 0;
206
volatile uint16_t timer = 0;
115
volatile uint16_t timer = 0;
-
 
116
 
-
 
117
// remember last time data was received
-
 
118
volatile uint8_t seconds_since_last_data = 0;
207
 
119
 
208
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
120
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
209
 
121
 
210
// general PAL|NTSC distingiusch stuff
122
// general PAL|NTSC distingiusch stuff
211
uint8_t top_line = 1;
123
uint8_t top_line = 1;
212
uint8_t bottom_line = 14;
124
uint8_t bottom_line = 14;
213
 
125
 
214
// Flags
126
// Flags
215
uint8_t COSD_FLAGS = 0;
127
uint8_t COSD_FLAGS = 0;
216
 
128
 
217
/* ##########################################################################
129
/* ##########################################################################
218
 * debounce buttons
130
 * debounce buttons
219
 * ##########################################################################*/
131
 * ##########################################################################*/
220
int s1_pressed() {
132
int s1_pressed() {
221
        if (S1_PRESSED) {
133
        if (S1_PRESSED) {
222
                _delay_ms(25);
134
                _delay_ms(25);
223
                if (S1_PRESSED) return 1;
135
                if (S1_PRESSED) return 1;
224
        }
136
        }
225
        return 0;
137
        return 0;
226
}
138
}
227
 
139
 
228
int s2_pressed() {
140
int s2_pressed() {
229
        if (S2_PRESSED) {
141
        if (S2_PRESSED) {
230
                _delay_ms(25);
142
                _delay_ms(25);
231
                if (S2_PRESSED) return 1;
143
                if (S2_PRESSED) return 1;
232
        }
144
        }
233
        return 0;
145
        return 0;
234
}
146
}
235
 
-
 
236
/* ##########################################################################
-
 
237
 * MAX7456 SPI & Display stuff
-
 
238
 * ##########################################################################*/
-
 
239
 
-
 
240
/**
-
 
241
 * Send a byte through SPI
-
 
242
 */
-
 
243
void spi_send(uint8_t byte) {
-
 
244
    for (int8_t i = 7; i >= 0; i--) {
-
 
245
        if (((byte >> i) & 1)) {
-
 
246
            MAX_SDIN_HIGH
-
 
247
        } else {
-
 
248
            MAX_SDIN_LOW
-
 
249
        }
-
 
250
        MAX_SCLK_HIGH
-
 
251
        MAX_SCLK_LOW
-
 
252
    }
-
 
253
}
-
 
254
 
-
 
255
/**
-
 
256
 *  Send <byte> to <address> of MAX7456
-
 
257
 */
-
 
258
void spi_send_byte(uint8_t address, uint8_t byte) {
-
 
259
    // start sending
-
 
260
    MAX_CS_LOW
-
 
261
 
-
 
262
    spi_send(address);
-
 
263
    spi_send(byte);
-
 
264
 
-
 
265
    // end sending
-
 
266
    MAX_CS_HIGH
-
 
267
}
-
 
268
 
-
 
269
/**
-
 
270
 *  write a <character> to <address> of MAX7456 display memory
-
 
271
 */
-
 
272
void write_char(uint16_t address, char character) {
-
 
273
    spi_send_byte(0x05, (address & 0xFF00) >> 8); // DMAH
-
 
274
    spi_send_byte(0x06, (address & 0x00FF)); // DMAL
-
 
275
    spi_send_byte(0x07, character); // DMDI
-
 
276
}
-
 
277
 
-
 
278
/**
-
 
279
 *  write a character <attribute> to <address> of MAX7456 display memory
-
 
280
 */
-
 
281
void write_char_att(uint16_t address, char attribute) {
-
 
282
    // the only important part is that the DMAH[1] is set
-
 
283
    // so we add 2 which binary is the 2nd lowest byte
-
 
284
    spi_send_byte(0x05, ((address & 0xFF00) >> 8) | 2); // DMAH
-
 
285
    spi_send_byte(0x06, (address & 0x00FF)); // DMAL
-
 
286
    spi_send_byte(0x07, attribute); // DMDI
-
 
287
}
-
 
288
 
-
 
289
/**
-
 
290
 *  write a <character> at <x>/<y> to MAX7456 display memory
-
 
291
 */
-
 
292
void write_char_xy(uint8_t x, uint8_t y, char character) {
-
 
293
    uint16_t address = y * 30 + x;
-
 
294
    write_char(address, character);
-
 
295
}
-
 
296
 
-
 
297
/**
-
 
298
 *  write a  character <attribute> at <x>/<y> to MAX7456 display memory
-
 
299
 */
-
 
300
void write_char_att_xy(uint8_t x, uint8_t y, char attribute) {
-
 
301
    uint16_t address = y * 30 + x;
-
 
302
    write_char_att(address, attribute);
-
 
303
}
-
 
304
 
-
 
305
/**
-
 
306
 *  clear display by writing blank characters all over it
-
 
307
 */
-
 
308
void clear(void) {
-
 
309
    uint16_t memory_address = 0;
-
 
310
    for (unsigned int a = 0; a < 480; a++) {
-
 
311
        write_char(memory_address++, 0);
-
 
312
    }
-
 
313
}
-
 
314
 
-
 
315
/**
-
 
316
 *  write an ascii <character> to <address> of MAX7456 display memory
-
 
317
 */
-
 
318
void write_ascii_char(uint16_t address, char c) {
-
 
319
    if (c == 32) c = 0; // remap space
-
 
320
    else if (c > 48 && c <= 57) c -= 48; // remap numbers
-
 
321
    else if (c == '0') c = 10; // remap zero
-
 
322
    else if (c >= 65 && c <= 90) c -= 54; // remap big letters
-
 
323
    else if (c >= 97 && c <= 122) c -= 60; // remap small letters
-
 
324
    else if (c == '(') c = 63; // remap
-
 
325
    else if (c == ')') c = 64; // remap
-
 
326
    else if (c == '.') c = 65; // remap
-
 
327
    else if (c == '?') c = 66; // remap
-
 
328
    else if (c == ';') c = 67; // remap
-
 
329
    else if (c == ':') c = 68; // remap
-
 
330
    else if (c == ',') c = 69; // remap
-
 
331
    else if (c == '\'') c = 70; // remap
-
 
332
    else if (c == '/') c = 71; // remap
-
 
333
    else if (c == '"') c = 72; // remap
-
 
334
    else if (c == '-') c = 73; // remap minus
-
 
335
    else if (c == '<') c = 74; // remap
-
 
336
    else if (c == '>') c = 75; // remap
-
 
337
    else if (c == '@') c = 76; // remap
-
 
338
    write_char(address, c);
-
 
339
}
-
 
340
 
-
 
341
/**
-
 
342
 *  write an ascii <string> at <x>/<y> to MAX7456 display memory
-
 
343
 */
-
 
344
void write_ascii_string(uint8_t x, uint8_t y, char *string) {
-
 
345
    while (*string) {
-
 
346
        write_ascii_char(((x++)+(y * 30)), *string);
-
 
347
        string++;
-
 
348
    }
-
 
349
}
-
 
350
 
-
 
351
/**
-
 
352
 *  Write only the last three digits of a <number> at <x>/<y> to MAX7456
-
 
353
 *  display memory. takes full 16bit numbers as well for stuff
-
 
354
 *  like compass only taking three characters (values <= 999)
-
 
355
 */
-
 
356
void write_3digit_number_u(uint8_t x, uint8_t y, uint16_t number) {
-
 
357
    uint16_t num = 100;
-
 
358
    uint8_t started = 0;
-
 
359
 
-
 
360
    while (num > 0) {
-
 
361
        uint8_t b = number / num;
-
 
362
        if (b > 0 || started || num == 1) {
-
 
363
            write_ascii_char((x++)+(y * 30), '0' + b);
-
 
364
            started = 1;
-
 
365
        } else {
-
 
366
            write_ascii_char((x++)+(y * 30), 0);
-
 
367
        }
-
 
368
        number -= b * num;
-
 
369
 
-
 
370
        num /= 10;
-
 
371
    }
-
 
372
}
-
 
373
 
-
 
374
/**
-
 
375
 *  Write only the last two digits of a number at <x>/<y> to MAX7456
-
 
376
 *  display memory. takes full 16bit numbers as well for stuff
-
 
377
 *  like seconds only taking two characters (values <= 99)
-
 
378
 *  Since this is used for seconds only and it looks better, there
-
 
379
 *  is a trading 0 attached
-
 
380
 */
-
 
381
void write_2digit_number_u(uint8_t x, uint8_t y, uint16_t number) {
-
 
382
    uint16_t num = 10;
-
 
383
    uint8_t started = 0;
-
 
384
 
-
 
385
    while (num > 0) {
-
 
386
        uint8_t b = number / num;
-
 
387
        if (b > 0 || started || num == 1) {
-
 
388
            write_ascii_char((x++)+(y * 30), '0' + b);
-
 
389
            started = 1;
-
 
390
        } else {
-
 
391
            write_ascii_char((x++)+(y * 30), '0');
-
 
392
        }
-
 
393
        number -= b * num;
-
 
394
 
-
 
395
        num /= 10;
-
 
396
    }
-
 
397
}
-
 
398
 
-
 
399
/**
-
 
400
 *  write a unsigned number as /10th at <x>/<y> to MAX7456 display memory
-
 
401
 */
-
 
402
void write_number_u_10th(uint8_t x, uint8_t y, uint16_t number) {
-
 
403
    uint16_t num = 10000;
-
 
404
    uint8_t started = 0;
-
 
405
 
-
 
406
    while (num > 0) {
-
 
407
        uint8_t b = number / num;
-
 
408
 
-
 
409
        if (b > 0 || started || num == 1) {
-
 
410
            if ((num / 10) == 0) write_char((x++)+(y * 30), 65);
-
 
411
            write_ascii_char((x++)+(y * 30), '0' + b);
-
 
412
            started = 1;
-
 
413
        } else {
-
 
414
            write_ascii_char((x++)+(y * 30), 0);
-
 
415
        }
-
 
416
        number -= b * num;
-
 
417
 
-
 
418
        num /= 10;
-
 
419
    }
-
 
420
}
-
 
421
 
-
 
422
/**
-
 
423
 *  write a unsigned number at <x>/<y> to MAX7456 display memory
-
 
424
 */
-
 
425
void write_number_u(uint8_t x, uint8_t y, uint16_t number) {
-
 
426
    uint16_t num = 10000;
-
 
427
    uint8_t started = 0;
-
 
428
 
-
 
429
    while (num > 0) {
-
 
430
        uint8_t b = number / num;
-
 
431
        if (b > 0 || started || num == 1) {
-
 
432
            write_ascii_char((x++)+(y * 30), '0' + b);
-
 
433
            started = 1;
-
 
434
        } else {
-
 
435
            write_ascii_char((x++)+(y * 30), 0);
-
 
436
        }
-
 
437
        number -= b * num;
-
 
438
 
-
 
439
        num /= 10;
-
 
440
    }
-
 
441
}
-
 
442
 
-
 
443
/**
-
 
444
 *  write a signed number at <x>/<y> to MAX7456 display memory
-
 
445
 */
-
 
446
void write_number_s(uint8_t x, uint8_t y, int16_t w) {
-
 
447
    if (((uint16_t) w) > 32767) {
-
 
448
        w = w - 65536;
-
 
449
 
-
 
450
        int16_t num = -10000;
-
 
451
        uint8_t started = 0;
-
 
452
 
-
 
453
        while (num < 0) {
-
 
454
            uint8_t b = w / num;
-
 
455
            if (b > 0 || started || num == 1) {
-
 
456
                if (!started) write_char((x - 1)+(y * 30), 0x49);
-
 
457
                write_ascii_char((x++)+(y * 30), '0' + b);
-
 
458
                started = 1;
-
 
459
            } else {
-
 
460
                write_ascii_char((x++)+(y * 30), 0);
-
 
461
            }
-
 
462
            w -= b * num;
-
 
463
 
-
 
464
            num /= 10;
-
 
465
        }
-
 
466
    } else {
-
 
467
        write_char((x)+(y * 30), 0);
-
 
468
        write_number_u(x, y, w);
-
 
469
    }
-
 
470
}
-
 
471
 
-
 
472
/**
-
 
473
 *  write <seconds> as human readable time at <x>/<y> to MAX7456 display mem
-
 
474
 */
-
 
475
void write_time(uint8_t x, uint8_t y, uint16_t seconds) {
-
 
476
    uint16_t min = seconds / 60;
-
 
477
    seconds -= min * 60;
-
 
478
    write_3digit_number_u(x, y, min);
-
 
479
    write_char_xy(x + 3, y, 68);
-
 
480
    write_2digit_number_u(x + 4, y, seconds);
-
 
481
}
-
 
482
 
-
 
483
/**
-
 
484
 * for testing write all chars to screen
-
 
485
 */
-
 
486
void write_all_chars() {
-
 
487
    uint16_t x = 3, y = 2, t = 0;
-
 
488
    while (t < 256) {
-
 
489
        write_char_xy(x++, y, t++);
-
 
490
        if (x > 25) {
-
 
491
            y++;
-
 
492
            x = 3;
-
 
493
        }
-
 
494
    }
-
 
495
}
147
 
496
 
-
 
497
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
-
 
498
/* ##########################################################################
-
 
499
 * USART stuff
-
 
500
 * ##########################################################################*/
-
 
501
 
-
 
502
/**
-
 
503
 * init usart1
-
 
504
 */
-
 
505
void usart1_init() {
-
 
506
    UBRR1H = ((F_CPU / (16UL * baud)) - 1) >> 8;
-
 
507
    UBRR1L = (F_CPU / (16UL * baud)) - 1;
-
 
508
 
-
 
509
    // Enable receiver and transmitter; enable RX interrupt
-
 
510
    UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);
-
 
511
 
-
 
512
    //asynchronous 8N1
-
 
513
    UCSR1C = (1 << URSEL1) | (3 << UCSZ10);
-
 
514
}
-
 
515
 
-
 
516
/**
-
 
517
 * send a single <character> through usart1
-
 
518
 */
-
 
519
void usart1_putc(unsigned char character) {
-
 
520
    // wait until UDR ready
-
 
521
    while (!(UCSR1A & (1 << UDRE1)));
-
 
522
    UDR1 = character;
-
 
523
}
-
 
524
 
-
 
525
/**
-
 
526
 * send a <string> throught usart1
-
 
527
 */
-
 
528
void usart1_puts(char *s) {
-
 
529
    while (*s) {
-
 
530
        usart1_putc(*s);
-
 
531
        s++;
-
 
532
    }
-
 
533
}
-
 
534
 
-
 
535
/**
-
 
536
 * receive data through usart1
-
 
537
 * portions taken and adapted from
-
 
538
 * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=FlightCtrl&path=%2Fbranches%2FV0.72p+Code+Redesign+killagreg%2Fuart0.c
-
 
539
 */
-
 
540
ISR(SIG_USART1_RECV) {
-
 
541
    if (rxd_buffer_locked) return; // if rxd buffer is locked immediately return
-
 
542
    LED1_ON
-
 
543
            static uint16_t crc;
-
 
544
    static uint8_t ptr_rxd_buffer = 0;
-
 
545
    uint8_t crc1, crc2;
-
 
546
    uint8_t c;
-
 
547
 
-
 
548
    c = UDR1; // catch the received byte
-
 
549
 
-
 
550
    // the rxd buffer is unlocked
-
 
551
    if ((ptr_rxd_buffer == 0) && (c == '#')) // if rxd buffer is empty and syncronisation character is received
-
 
552
    {
-
 
553
                /*
-
 
554
                // skip other datasets
-
 
555
        if (ptr_rxd_buffer == 2 && rxd_buffer[ptr_rxd_buffer] != 'O') {
-
 
556
                        ptr_rxd_buffer = 0; // reset rxd buffer
-
 
557
                rxd_buffer_locked = 0; // unlock rxd buffer
-
 
558
                }*/
-
 
559
                rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
-
 
560
        crc = c; // init crc
-
 
561
    } else if (ptr_rxd_buffer < RXD_BUFFER_LEN) // collect incomming bytes
-
 
562
    {
-
 
563
        if (c != '\r') // no termination character
-
 
564
        {
-
 
565
            rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
-
 
566
            crc += c; // update crc
-
 
567
        } else // termination character was received
-
 
568
        {
-
 
569
            // the last 2 bytes are no subject for checksum calculation
-
 
570
            // they are the checksum itself
-
 
571
            crc -= rxd_buffer[ptr_rxd_buffer - 2];
-
 
572
            crc -= rxd_buffer[ptr_rxd_buffer - 1];
-
 
573
            // calculate checksum from transmitted data
-
 
574
            crc %= 4096;
-
 
575
            crc1 = '=' + crc / 64;
-
 
576
            crc2 = '=' + crc % 64;
-
 
577
            // compare checksum to transmitted checksum bytes
-
 
578
            if ((crc1 == rxd_buffer[ptr_rxd_buffer - 2]) && (crc2 == rxd_buffer[ptr_rxd_buffer - 1])) { // checksum valid
-
 
579
                rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
-
 
580
                ReceivedBytes = ptr_rxd_buffer + 1; // store number of received bytes
-
 
581
                rxd_buffer_locked = 1; // lock the rxd buffer
-
 
582
            } else { // checksum invalid
-
 
583
                rxd_buffer_locked = 0; // unlock rxd buffer
-
 
584
            }
-
 
585
            ptr_rxd_buffer = 0; // reset rxd buffer pointer
-
 
586
        }
-
 
587
    } else // rxd buffer overrun
-
 
588
    {
-
 
589
        ptr_rxd_buffer = 0; // reset rxd buffer
-
 
590
        rxd_buffer_locked = 0; // unlock rxd buffer
-
 
591
    }
-
 
592
    LED1_OFF
148
 
593
}
149
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
594
 
-
 
595
/**
-
 
596
 * Decode the recevied Buffer
150
 
597
 * portions taken and adapted from
-
 
598
 * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=FlightCtrl&path=%2Ftags%2FV0.72p%2Fuart.c
-
 
599
 */
-
 
600
void Decode64(void) {
-
 
601
    uint8_t a, b, c, d;
-
 
602
    uint8_t x, y, z;
-
 
603
    uint8_t ptrIn = 3;
-
 
604
    uint8_t ptrOut = 3;
-
 
605
    uint8_t len = ReceivedBytes - 6;
-
 
606
 
-
 
607
    while (len) {
-
 
608
        a = rxd_buffer[ptrIn++] - '=';
-
 
609
        b = rxd_buffer[ptrIn++] - '=';
-
 
610
        c = rxd_buffer[ptrIn++] - '=';
-
 
611
        d = rxd_buffer[ptrIn++] - '=';
-
 
612
 
-
 
613
        x = (a << 2) | (b >> 4);
-
 
614
        y = ((b & 0x0f) << 4) | (c >> 2);
-
 
615
        z = ((c & 0x03) << 6) | d;
151
/**
616
 
-
 
617
        if (len--) rxd_buffer[ptrOut++] = x;
-
 
618
        else break;
-
 
619
        if (len--) rxd_buffer[ptrOut++] = y;
-
 
620
        else break;
-
 
621
        if (len--) rxd_buffer[ptrOut++] = z;
-
 
622
        else break;
-
 
623
    }
-
 
624
    pRxData = &rxd_buffer[3];
-
 
625
    RxDataLen = ptrOut - 3;
-
 
626
}
-
 
627
 
-
 
628
/**
-
 
629
 * request Data through USART in special MK format by adding checksum and
-
 
630
 * encode data in modified Base64
-
 
631
 * portions taken and adapted from
-
 
632
 * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=FlightCtrl&path=%2Ftags%2FV0.72p%2Fuart.c
-
 
633
 */
-
 
634
void sendMKData(unsigned char cmd, unsigned char addr, unsigned char *snd, unsigned char len) {
-
 
635
    unsigned int pt = 0;
-
 
636
    unsigned char a, b, c;
-
 
637
    unsigned char ptr = 0;
-
 
638
 
-
 
639
    txd_buffer[pt++] = '#'; // Start-Byte
-
 
640
    txd_buffer[pt++] = 'a' + addr; // Adress
-
 
641
    txd_buffer[pt++] = cmd; // Command
-
 
642
    while (len) {
-
 
643
        if (len) {
-
 
644
            a = snd[ptr++];
-
 
645
            len--;
-
 
646
        } else a = 0;
-
 
647
        if (len) {
-
 
648
            b = snd[ptr++];
-
 
649
            len--;
-
 
650
        } else b = 0;
-
 
651
        if (len) {
-
 
652
            c = snd[ptr++];
-
 
653
            len--;
-
 
654
        } else c = 0;
-
 
655
        txd_buffer[pt++] = '=' + (a >> 2);
-
 
656
        txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
-
 
657
        txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
-
 
658
        txd_buffer[pt++] = '=' + (c & 0x3f);
-
 
659
    }
-
 
660
 
-
 
661
    // add crc
-
 
662
    unsigned int tmpCRC = 0, i;
-
 
663
    for (i = 0; i < pt; i++) {
-
 
664
        tmpCRC += txd_buffer[i];
-
 
665
    }
-
 
666
    tmpCRC %= 4096;
-
 
667
    txd_buffer[i++] = '=' + tmpCRC / 64;
-
 
668
    txd_buffer[i++] = '=' + tmpCRC % 64;
-
 
669
    txd_buffer[i++] = '\r';
152
 * serial support
670
 
153
 */
671
    usart1_puts((char*) txd_buffer);
154
#include "usart1.c"
672
}
155
 
673
 
156
 
674
/* ##########################################################################
157
/* ##########################################################################
675
 * timer stuff
158
 * timer stuff
676
 * ##########################################################################*/
159
 * ##########################################################################*/
677
 
160
 
678
/*
161
/**
679
 * timer kicks in every 1000uS
162
 * timer kicks in every 1000uS ^= 1ms
680
 */
163
 */
681
ISR(TIMER0_OVF_vect) {
164
ISR(TIMER0_OVF_vect) {
682
    OCR0 = 6; // preload
165
    OCR0 = 6; // preload
683
    if (!timer--) {
166
    if (!timer--) {
684
        uptime++;
167
        uptime++;
685
        timer = 999;
168
        timer = 999;
-
 
169
                seconds_since_last_data++;
686
    }
170
    }
687
}
171
}
688
 
172
 
689
/* ##########################################################################
173
/* ##########################################################################
690
 * compass stuff
174
 * compass stuff
691
 * ##########################################################################*/
175
 * ##########################################################################*/
692
 
176
 
693
/**
177
/**
694
 * convert the <heading> gotton from NC into an index
178
 * convert the <heading> gotton from NC into an index
695
 */
179
 */
696
uint8_t heading_conv(uint16_t heading) {
180
uint8_t heading_conv(uint16_t heading) {
697
    if (heading > 23 && heading < 68) {
181
    if (heading > 23 && heading < 68) {
698
        //direction = "NE";
182
        //direction = "NE";
699
        return 0;
183
        return 0;
700
    } else if (heading > 67 && heading < 113) {
184
    } else if (heading > 67 && heading < 113) {
701
        //direction = "E ";
185
        //direction = "E ";
702
        return 1;
186
        return 1;
703
    } else if (heading > 112 && heading < 158) {
187
    } else if (heading > 112 && heading < 158) {
704
        //direction = "SE";
188
        //direction = "SE";
705
        return 2;
189
        return 2;
706
    } else if (heading > 157 && heading < 203) {
190
    } else if (heading > 157 && heading < 203) {
707
        //direction = "S ";
191
        //direction = "S ";
708
        return 3;
192
        return 3;
709
    } else if (heading > 202 && heading < 248) {
193
    } else if (heading > 202 && heading < 248) {
710
        //direction = "SW";
194
        //direction = "SW";
711
        return 4;
195
        return 4;
712
    } else if (heading > 247 && heading < 293) {
196
    } else if (heading > 247 && heading < 293) {
713
        //direction = "W ";
197
        //direction = "W ";
714
        return 5;
198
        return 5;
715
    } else if (heading > 292 && heading < 338) {
199
    } else if (heading > 292 && heading < 338) {
716
        //direction = "NW";
200
        //direction = "NW";
717
        return 6;
201
        return 6;
718
    }
202
    }
719
    //direction = "N ";
203
    //direction = "N ";
720
    return 7;
204
    return 7;
721
}
205
}
722
 
206
 
723
/**
207
/**
724
 * draw a compass rose at <x>/<y> for <heading>
208
 * draw a compass rose at <x>/<y> for <heading>
725
 */
209
 */
726
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
210
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
727
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
211
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
728
    char rose[48] = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
212
    char rose[48] = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
729
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
213
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
730
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
214
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
731
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
215
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
732
        // the center is char 19 (north), we add the current heading in 8th
216
        // the center is char 19 (north), we add the current heading in 8th
733
        // which would be 22.5 degrees, but float would bloat up the code
217
        // which would be 22.5 degrees, but float would bloat up the code
734
        // and *10 / 225 would take ages... so we take the uncorrect way
218
        // and *10 / 225 would take ages... so we take the uncorrect way
735
    uint8_t front = 19 + (heading / 22);
219
    uint8_t front = 19 + (heading / 22);
736
    for (uint8_t i = 0; i < 9; i++) {
220
    for (uint8_t i = 0; i < 9; i++) {
737
                write_char_xy(x++, y, rose[front - 4 + i]);
221
                write_char_xy(x++, y, rose[front - 4 + i]);
738
    }
222
    }
739
}
223
}
740
 
224
 
741
/* ##########################################################################
225
/* ##########################################################################
742
 * artificial horizon
226
 * artificial horizon
743
 * ##########################################################################*/
227
 * ##########################################################################*/
744
// remember last time displayed values
228
// remember last time displayed values
745
int8_t old_af_x = -1, old_af_y = -1;
229
int8_t old_af_x = -1, old_af_y = -1;
746
 
230
 
747
/**
231
/**
748
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
232
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
749
 * from line <firstline> to <listlines> for given <nick> and <roll> values
233
 * from line <firstline> to <listlines> for given <nick> and <roll> values
750
 */
234
 */
751
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
235
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
752
        char noodle[5] = {225, 225, 226, 227, 227};
236
        char noodle[5] = {225, 225, 226, 227, 227};
753
        uint8_t center_x = 15;
237
        uint8_t center_x = 15;
754
        uint8_t center_y = lastline - firstline;
238
        uint8_t center_y = lastline - firstline;
755
        center_y = 7;
239
        center_y = 7;
756
        write_char_xy(center_x,center_y,228);
240
        write_char_xy(center_x,center_y,228);
757
        uint8_t cpos, nicky, rollx;
241
        uint8_t cpos, nicky, rollx;
758
       
242
       
759
        // which line
243
        // which line
760
        int8_t ypos =  nick / 20;
244
        int8_t ypos =  nick / 20;
761
        // which character from the array?
245
        // which character from the array?
762
        if (nick < 0) {
246
        if (nick < 0) {
763
                cpos = -1*((nick - (ypos * 20))/4);
247
                cpos = -1*((nick - (ypos * 20))/4);
764
                ypos--;
248
                ypos--;
765
        } else cpos = 4-((nick - (ypos * 20))/4);
249
        } else cpos = 4-((nick - (ypos * 20))/4);
766
        if (cpos > 4) cpos = 4;
250
        if (cpos > 4) cpos = 4;
767
 
251
 
768
        nicky = center_y - ypos;
252
        nicky = center_y - ypos;
769
        if (nicky > lastline) nicky = lastline;
253
        if (nicky > lastline) nicky = lastline;
770
        else if (nicky < firstline) nicky = firstline;
254
        else if (nicky < firstline) nicky = firstline;
771
 
255
 
772
        // ensure roll-borders
256
        // ensure roll-borders
773
        rollx = (roll / 8)+15;
257
        rollx = (roll / 8)+15;
774
        if (rollx < 2) rollx = 2;
258
        if (rollx < 2) rollx = 2;
775
        else if (rollx > 28) rollx = 28;
259
        else if (rollx > 28) rollx = 28;
776
 
260
 
777
 
261
 
778
        // clear roll
262
        // clear roll
779
        if (old_af_x != rollx && old_af_x >= 0) {
263
        if (old_af_x != rollx && old_af_x >= 0) {
780
                write_char_xy(old_af_x,13,0);
264
                write_char_xy(old_af_x,13,0);
781
        }
265
        }
782
 
266
 
783
        // clear nick
267
        // clear nick
784
        if (old_af_y != nicky && old_af_y >= 0) {
268
        if (old_af_y != nicky && old_af_y >= 0) {
785
                write_char_xy(center_x-1,old_af_y,0);
269
                write_char_xy(center_x-1,old_af_y,0);
786
                write_char_xy(center_x+1,old_af_y,0);
270
                write_char_xy(center_x+1,old_af_y,0);
787
        }
271
        }
788
 
272
 
789
 
273
 
790
        // draw nick
274
        // draw nick
791
        write_char_xy(center_x-1,nicky,noodle[cpos]);
275
        write_char_xy(center_x-1,nicky,noodle[cpos]);
792
        write_char_xy(center_x+1,nicky,noodle[cpos]);
276
        write_char_xy(center_x+1,nicky,noodle[cpos]);
793
 
277
 
794
        // draw roll
278
        // draw roll
795
        write_char_xy(rollx,lastline,229);
279
        write_char_xy(rollx,lastline,229);
796
 
280
 
797
        // update old vars
281
        // update old vars
798
        old_af_x = rollx;
282
        old_af_x = rollx;
799
        old_af_y = nicky;
283
        old_af_y = nicky;
800
 
284
 
801
        // debug numbers
285
        // debug numbers
802
        //write_3digit_number_u(20,6,cpos);
286
        //write_3digit_number_u(20,6,cpos);
803
        //write_number_s(20,7,ypos);    
287
        //write_number_s(20,7,ypos);    
804
        //write_number_s(0,7,nick);             
288
        //write_number_s(0,7,nick);             
805
        //write_number_s(18,11,roll);   
289
        //write_number_s(18,11,roll);   
806
}
290
}
807
 
291
 
808
/* ##########################################################################
292
/* ##########################################################################
809
 * A simple config menu for the flags
293
 * A simple config menu for the flags
810
 * ##########################################################################*/
294
 * ##########################################################################*/
811
void config_menu(void) {
295
void config_menu(void) {
812
        // disable interrupts (makes the menu more smoothely)
296
        // disable interrupts (makes the menu more smoothely)
813
        cli();
297
        cli();
814
 
298
 
815
        // clear screen
299
        // clear screen
816
        clear();
300
        clear();
817
       
301
       
818
        char* menu[4] = {"Normal OSD      ",
302
        char* menu[4] = {"Normal OSD      ",
819
                                         "Art.Horizon     ",
303
                                         "Art.Horizon     ",
820
                                         "NO OSD          ",
304
                                         "NO OSD          ",
821
                                         "NO OSD but WRN  "};
305
                                         "NO OSD but WRN  "};
822
 
306
 
823
        uint8_t inmenu = 1;
307
        uint8_t inmenu = 1;
824
        uint8_t chosen = 0;
308
        uint8_t chosen = 0;
825
        write_ascii_string(10,  4, "Config Menu");
309
        write_ascii_string(10,  4, "Config Menu");
826
       
310
       
827
        // clear all mode flags
311
        // clear all mode flags
828
        COSD_FLAGS &= ~(COSD_FLAG_ARTHORIZON | COSD_FLAG_NOOSD | COSD_FLAG_NOOSD_BUT_WRN);
312
        COSD_FLAGS &= ~(COSD_FLAG_ARTHORIZON | COSD_FLAG_NOOSD | COSD_FLAG_NOOSD_BUT_WRN);
829
 
313
 
830
        // wait a bit before doing stuff so user has chance to release button
314
        // wait a bit before doing stuff so user has chance to release button
831
        _delay_ms(250);
315
        _delay_ms(250);
832
 
316
 
833
        while (inmenu) {
317
        while (inmenu) {
834
                        write_ascii_string(2,  7, menu[chosen]);
318
                        write_ascii_string(2,  7, menu[chosen]);
835
                        if (s2_pressed()) {
319
                        if (s2_pressed()) {
836
                                chosen = (chosen + 1) % 4;
320
                                chosen = (chosen + 1) % 4;
837
                                _delay_ms(500);
321
                                _delay_ms(500);
838
                        } else if (s1_pressed()) {
322
                        } else if (s1_pressed()) {
839
                                switch (chosen) {
323
                                switch (chosen) {
840
                                        case 1:         // artificial horizon
324
                                        case 1:         // artificial horizon
841
                                                COSD_FLAGS |= COSD_FLAG_ARTHORIZON;
325
                                                COSD_FLAGS |= COSD_FLAG_ARTHORIZON;
842
                                                break;
326
                                                break;
843
                                        case 2:         // everything off
327
                                        case 2:         // everything off
844
                                                COSD_FLAGS |= COSD_FLAG_NOOSD;
328
                                                COSD_FLAGS |= COSD_FLAG_NOOSD;
845
                                                break;
329
                                                break;
846
                                        case 3:         // only warning
330
                                        case 3:         // only warning
847
                                                COSD_FLAGS |= COSD_FLAG_NOOSD_BUT_WRN;
331
                                                COSD_FLAGS |= COSD_FLAG_NOOSD_BUT_WRN;
848
                                                break;
332
                                                break;
849
                                        //default:      // normal OSD, so let the flags cleared
333
                                        //default:      // normal OSD, so let the flags cleared
850
                                }
334
                                }
851
                                // leave menu
335
                                // leave menu
852
                                inmenu = 0;
336
                                inmenu = 0;
853
                                _delay_ms(500);
337
                                _delay_ms(500);
854
                        }
338
                        }
855
        }
339
        }
856
 
340
 
857
        // clear screen up again
341
        // clear screen up again
858
        clear();
342
        clear();
859
 
343
 
860
        // update flags to paint display again if needed
344
        // update flags to paint display again if needed
861
        COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
345
        COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
862
 
346
 
863
        // enable interrupts again
347
        // enable interrupts again
864
        sei();
348
        sei();
865
}
349
}
866
 
350
 
867
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
351
#endif // ends !(ALLCHARSDEBUG|(WRITECHARS != -1))
868
 
352
 
869
/* ##########################################################################
353
/* ##########################################################################
870
 * MAIN
354
 * MAIN
871
 * ##########################################################################*/
355
 * ##########################################################################*/
872
int main(void) {
356
int main(void) {
873
        // set up FLAGS, compiler should flatten this one
357
        // set up FLAGS, compiler should flatten this one
874
        COSD_FLAGS = (NTSC << (COSD_FLAG_NTSC - 1));
358
        COSD_FLAGS = (NTSC << (COSD_FLAG_NTSC - 1));
875
        COSD_FLAGS |= (ARTHORIZON << (COSD_FLAG_ARTHORIZON - 1));
359
        COSD_FLAGS |= (ARTHORIZON << (COSD_FLAG_ARTHORIZON - 1));
876
        COSD_FLAGS |= (NOOSD << (COSD_FLAG_NOOSD - 1));
360
        COSD_FLAGS |= (NOOSD << (COSD_FLAG_NOOSD - 1));
877
        COSD_FLAGS |= (NOOSD_BUT_WRN << (COSD_FLAG_NOOSD_BUT_WRN - 1));
361
        COSD_FLAGS |= (NOOSD_BUT_WRN << (COSD_FLAG_NOOSD_BUT_WRN - 1));
878
 
362
 
879
        // set up Atmega162 Ports
363
        // set up Atmega162 Ports
880
    DDRA |= (1 << PA1); // PA1 output (/CS)
364
    DDRA |= (1 << PA1); // PA1 output (/CS)
881
    MAX_CS_HIGH
365
    MAX_CS_HIGH
882
    DDRA |= (1 << PA2); // PA2 output (SDIN)
366
    DDRA |= (1 << PA2); // PA2 output (SDIN)
883
    MAX_SDIN_LOW
367
    MAX_SDIN_LOW
884
    DDRA |= (1 << PA3); // PA3 output (SCLK)
368
    DDRA |= (1 << PA3); // PA3 output (SCLK)
885
    MAX_SCLK_LOW
369
    MAX_SCLK_LOW
886
    DDRA |= (1 << PA5); // PA5 output (RESET)
370
    DDRA |= (1 << PA5); // PA5 output (RESET)
887
    MAX_RESET_HIGH
371
    MAX_RESET_HIGH
888
 
372
 
889
    DDRC |= (1 << PC0); // PC0 output (LED1 gn)
373
    DDRC |= (1 << PC0); // PC0 output (LED1 gn)
890
    LED1_OFF
374
    LED1_OFF
891
    DDRC |= (1 << PC1); // PC1 output (LED2 rt)
375
    DDRC |= (1 << PC1); // PC1 output (LED2 rt)
892
    LED2_OFF
376
    LED2_OFF
893
    DDRC |= (1 << PC2); // PC2 output (LED3 gn)
377
    DDRC |= (1 << PC2); // PC2 output (LED3 gn)
894
    LED3_OFF
378
    LED3_OFF
895
    DDRC |= (1 << PC3); // PC3 output (LED4 rt)
379
    DDRC |= (1 << PC3); // PC3 output (LED4 rt)
896
    LED4_OFF
380
    LED4_OFF
897
 
381
 
898
    DDRC &= ~(1 << PC4); // PC4 input  (MODE)
382
    DDRC &= ~(1 << PC4); // PC4 input  (MODE)
899
    PORTC |= (1 << PC4); // pullup
383
    PORTC |= (1 << PC4); // pullup
900
    DDRC &= ~(1 << PC5); // PC5 input  (SET)
384
    DDRC &= ~(1 << PC5); // PC5 input  (SET)
901
    PORTC |= (1 << PC5); // pullup
385
    PORTC |= (1 << PC5); // pullup
902
 
386
 
903
        // set up top and bottom lines
387
        // set up top and bottom lines
904
        if (COSD_FLAGS & COSD_FLAG_NTSC) {
388
        if (COSD_FLAGS & COSD_FLAG_NTSC) {
905
                bottom_line = 12;
389
                bottom_line = 12;
906
        } else {
390
        } else {
907
                bottom_line = 14;
391
                bottom_line = 14;
908
        }
392
        }
909
 
393
 
910
        // reset the MAX7456 to be sure any undefined states do no harm
394
        // reset the MAX7456 to be sure any undefined states do no harm
911
    MAX_RESET_LOW
395
    MAX_RESET_LOW
912
    MAX_RESET_HIGH
396
    MAX_RESET_HIGH
913
 
397
 
914
        // check for keypress at startup
398
        // check for keypress at startup
915
        if (s2_pressed()) { // togle COSD_FLAG_ARTHORIZON
399
        if (s2_pressed()) { // togle COSD_FLAG_ARTHORIZON
916
                        COSD_FLAGS ^= (1 << (COSD_FLAG_ARTHORIZON - 1));
400
                        COSD_FLAGS ^= (1 << (COSD_FLAG_ARTHORIZON - 1));
917
                        _delay_ms(100);
401
                        _delay_ms(100);
918
    }
402
    }
919
 
403
 
920
    // give the FC/NC and the maxim time to come up
404
    // give the FC/NC and the maxim time to come up
921
    LED4_ON
405
    LED4_ON
922
    _delay_ms(2000);
406
    _delay_ms(2000);
923
 
407
 
924
    LED4_OFF
408
    LED4_OFF
925
 
-
 
926
    /* ##########################################################################
-
 
927
     * Pushing NEW chars to the MAX7456
-
 
928
     * ##########################################################################*/
-
 
929
#if (WRITECHARS != -1)
-
 
930
        void learn_char(uint8_t number, unsigned char* data) {
-
 
931
        // select character to write (CMAH)
-
 
932
        spi_send_byte(0x09, number);
-
 
933
 
-
 
934
        for (uint8_t i = 0; i < 54; i++) {
-
 
935
            // select 4pixel byte of char (CMAL)
-
 
936
            spi_send_byte(0x0A, i);
-
 
937
 
-
 
938
            // write 4pixel byte of char (CMDI)
-
 
939
            spi_send_byte(0x0B, data[i]);
-
 
940
        }
-
 
941
 
-
 
942
        // write to the NVM array from the shadow RAM (CMM)
-
 
943
        spi_send_byte(0x08, 0b10100000);
409
 
944
 
410
 
945
        // according to maxim writing to nvram takes about 12ms, lets wait longer
-
 
946
        _delay_ms(120);
-
 
947
    }
411
     //Pushing NEW chars to the MAX7456
948
 
412
#if (WRITECHARS != -1)
949
    // DISABLE display (VM0)
-
 
950
    spi_send_byte(0x00, 0b00000000);
413
        // DISABLE display (VM0)
951
 
-
 
952
    /**
-
 
953
     * easy char creation:
-
 
954
     * http://cascade.dyndns.org/~cascade/scripts/max7456/
-
 
955
     */
-
 
956
        // flashing more than 8 chars per time is not proven to be safe
-
 
957
        // so take care
-
 
958
#if WRITECHARS == 200
-
 
959
        // GPS
-
 
960
    unsigned char cc8[54] = {0x55, 0x50, 0x55, 0x55, 0x4a, 0x15, 0x55, 0x2a,
-
 
961
        0x85, 0x55, 0x2a, 0xa1, 0x55, 0x4a, 0xa8, 0x55,
-
 
962
        0x52, 0xa8, 0x55, 0x54, 0xaa, 0x55, 0x55, 0x09,
-
 
963
        0x55, 0x55, 0x52, 0x55, 0x55, 0x1a, 0x55, 0x51,
-
 
964
        0x96, 0x55, 0x18, 0x85, 0x54, 0x88, 0x28, 0x54,
-
 
965
        0x82, 0x05, 0x55, 0x20, 0xa1, 0x55, 0x48, 0x15,
-
 
966
        0x55, 0x52, 0x85, 0x55, 0x54, 0x15};
-
 
967
 
-
 
968
    unsigned char cc9[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
969
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45,
-
 
970
        0x55, 0x55, 0x21, 0x55, 0x55, 0xa8, 0x55, 0x55,
-
 
971
        0xa1, 0x55, 0x55, 0x98, 0x15, 0x55, 0x2a, 0x85,
-
 
972
        0x55, 0x4a, 0xa1, 0x55, 0x4a, 0xa8, 0x55, 0x52,
-
 
973
        0xaa, 0x15, 0x54, 0xaa, 0x15, 0x55, 0x28, 0x55,
-
 
974
        0x55, 0x41, 0x55, 0x55, 0x55, 0x55};
-
 
975
 
-
 
976
    // RC
-
 
977
    unsigned char cca[54] = {0x54, 0xaa, 0x85, 0x52, 0x00, 0x21, 0x48, 0x2a,
-
 
978
        0x08, 0x60, 0x80, 0x82, 0x62, 0x08, 0x22, 0x62,
-
 
979
        0x2a, 0x22, 0x62, 0x08, 0x22, 0x60, 0x88, 0x82,
-
 
980
        0x48, 0x08, 0x08, 0x52, 0x08, 0x21, 0x54, 0x48,
-
 
981
        0x45, 0x55, 0x48, 0x55, 0x55, 0x48, 0x55, 0x55,
-
 
982
        0x48, 0x55, 0x55, 0x48, 0x55, 0x55, 0x48, 0x55,
-
 
983
        0x55, 0x2a, 0x15, 0x54, 0xaa, 0x85};
-
 
984
 
-
 
985
    // km/h
-
 
986
    unsigned char ccb[54] = {0x55, 0x55, 0x55, 0x01, 0x55, 0x55, 0x21, 0x55,
-
 
987
        0x55, 0x20, 0x15, 0x55, 0x22, 0x15, 0x55, 0x28,
-
 
988
        0x15, 0x55, 0x22, 0x15, 0x55, 0x00, 0x00, 0x15,
-
 
989
        0x52, 0xaa, 0x15, 0x52, 0x22, 0x15, 0x52, 0x22,
-
 
990
        0x15, 0x50, 0x00, 0x05, 0x55, 0x54, 0x85, 0x55,
-
 
991
        0x54, 0x80, 0x55, 0x54, 0xa8, 0x55, 0x54, 0x88,
-
 
992
        0x55, 0x54, 0x88, 0x55, 0x54, 0x00};
-
 
993
 
-
 
994
 
-
 
995
    // small meters m
-
 
996
    unsigned char ccc[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
997
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
998
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
999
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1000
        0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x15, 0x22,
-
 
1001
        0x8a, 0x15, 0x28, 0xa2, 0x15, 0x20, 0x82, 0x15,
-
 
1002
        0x20, 0x82, 0x15, 0x00, 0x00, 0x15};
-
 
1003
 
-
 
1004
    // vario down
-
 
1005
    unsigned char ccd[54] = {0x55, 0x00, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28,
-
 
1006
        0x55, 0x55, 0x28, 0x55, 0x55, 0x28, 0x55, 0x55,
-
 
1007
        0x28, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28, 0x55,
-
 
1008
        0x55, 0x28, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28,
-
 
1009
        0x55, 0x00, 0x28, 0x00, 0x2a, 0xaa, 0xa8, 0x0a,
-
 
1010
        0xaa, 0xa0, 0x42, 0xaa, 0x81, 0x50, 0xaa, 0x05,
-
 
1011
        0x54, 0x28, 0x15, 0x55, 0x00, 0x55};
-
 
1012
 
-
 
1013
    // vario hold
-
 
1014
    unsigned char cce[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1015
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1016
        0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00,
-
 
1017
        0x2a, 0xaa, 0xa8, 0x2a, 0xaa, 0xa8, 0x00, 0x00,
-
 
1018
        0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1019
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1020
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1021
 
-
 
1022
    // vario up
-
 
1023
    unsigned char ccf[54] = {0x55, 0x00, 0x55, 0x54, 0x28, 0x15, 0x50, 0xaa,
-
 
1024
        0x05, 0x42, 0xaa, 0x81, 0x0a, 0xaa, 0xa0, 0x2a,
-
 
1025
        0xaa, 0xa8, 0x00, 0x28, 0x00, 0x55, 0x28, 0x55,
-
 
1026
        0x55, 0x28, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28,
-
 
1027
        0x55, 0x55, 0x28, 0x55, 0x55, 0x28, 0x55, 0x55,
-
 
1028
        0x28, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28, 0x55,
-
 
1029
        0x55, 0x28, 0x55, 0x55, 0x00, 0x55};
-
 
1030
 
-
 
1031
    learn_char(200, cc8);
-
 
1032
    learn_char(201, cc9);
-
 
1033
    learn_char(202, cca);
-
 
1034
    learn_char(203, ccb);
-
 
1035
    learn_char(204, ccc);
-
 
1036
    learn_char(205, ccd);
414
    spi_send_byte(0x00, 0b00000000);
1037
    learn_char(206, cce);
-
 
1038
    learn_char(207, ccf);
-
 
1039
#endif
-
 
1040
#if WRITECHARS == 208
-
 
1041
   // degree symbol
-
 
1042
    unsigned char cd0[54] = {0x55, 0x55, 0x55, 0x54, 0x01, 0x55, 0x52, 0xa8,
-
 
1043
        0x55, 0x48, 0x02, 0x15, 0x48, 0x52, 0x15, 0x48,
-
 
1044
        0x52, 0x15, 0x48, 0x02, 0x15, 0x52, 0xa8, 0x55,
-
 
1045
        0x54, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1046
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1047
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1048
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1049
 
-
 
1050
    // clock on symbol
-
 
1051
    unsigned char cd1[54] = {0x54, 0x14, 0x51, 0x52, 0x82, 0x08, 0x48, 0x22,
-
 
1052
        0x88, 0x48, 0x22, 0x28, 0x48, 0x22, 0x28, 0x52,
-
 
1053
        0x82, 0x08, 0x54, 0x14, 0x51, 0x55, 0x40, 0x55,
-
 
1054
        0x55, 0x2a, 0x15, 0x54, 0x88, 0x85, 0x52, 0x08,
-
 
1055
        0x21, 0x48, 0x48, 0x08, 0x48, 0x4a, 0x88, 0x48,
-
 
1056
        0x50, 0x08, 0x52, 0x15, 0x21, 0x54, 0x80, 0x85,
-
 
1057
        0x55, 0x2a, 0x15, 0x55, 0x40, 0x55};
-
 
1058
 
-
 
1059
    // clock fly symbol
-
 
1060
    unsigned char cd2[54] = {0x40, 0x45, 0x11, 0x2a, 0x20, 0x88, 0x20, 0x20,
-
 
1061
        0x88, 0x28, 0x21, 0x21, 0x21, 0x20, 0x21, 0x21,
-
 
1062
        0x2a, 0x21, 0x45, 0x40, 0x45, 0x55, 0x40, 0x55,
-
 
1063
        0x55, 0x2a, 0x15, 0x54, 0x88, 0x85, 0x52, 0x08,
-
 
1064
        0x21, 0x48, 0x48, 0x08, 0x48, 0x4a, 0x88, 0x48,
-
 
1065
        0x50, 0x08, 0x52, 0x15, 0x21, 0x54, 0x80, 0x85,
-
 
1066
        0x55, 0x2a, 0x15, 0x55, 0x40, 0x55};
-
 
1067
 
-
 
1068
    // compass north
-
 
1069
    unsigned char cd3[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1070
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54,
-
 
1071
        0x54, 0x55, 0x52, 0x12, 0x15, 0x52, 0x82, 0x15,
-
 
1072
        0x02, 0x82, 0x00, 0xa2, 0x22, 0x2a, 0x02, 0x0a,
-
 
1073
        0x00, 0x52, 0x0a, 0x15, 0x52, 0x12, 0x15, 0x54,
-
 
1074
        0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1075
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1076
 
-
 
1077
    // compass south
-
 
1078
    unsigned char cd4[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1079
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1080
        0x01, 0x55, 0x54, 0xa8, 0x55, 0x52, 0x02, 0x15,
-
 
1081
        0x04, 0x84, 0x40, 0xa1, 0x21, 0x2a, 0x04, 0x48,
-
 
1082
        0x40, 0x52, 0x02, 0x15, 0x54, 0xa8, 0x55, 0x55,
-
 
1083
        0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1084
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1085
 
-
 
1086
    // compass east
-
 
1087
    unsigned char cd5[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1088
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54,
-
 
1089
        0x00, 0x55, 0x52, 0xaa, 0x15, 0x52, 0x00, 0x55,
-
 
1090
        0x02, 0x05, 0x40, 0xa2, 0xa1, 0x2a, 0x02, 0x05,
-
 
1091
        0x40, 0x52, 0x00, 0x55, 0x52, 0xaa, 0x15, 0x54,
-
 
1092
        0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1093
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1094
 
-
 
1095
    // compass west
-
 
1096
    unsigned char cd6[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1097
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54,
-
 
1098
        0x54, 0x55, 0x52, 0x12, 0x15, 0x52, 0x12, 0x15,
-
 
1099
        0x02, 0x02, 0x00, 0xa2, 0x22, 0x2a, 0x02, 0x8a,
-
 
1100
        0x00, 0x52, 0x8a, 0x15, 0x52, 0x12, 0x15, 0x54,
-
 
1101
        0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1102
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1103
 
-
 
1104
    // compass between
-
 
1105
    unsigned char cd7[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1106
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1107
        0x55, 0x55, 0x55, 0x45, 0x55, 0x55, 0x21, 0x55,
-
 
1108
        0x01, 0x21, 0x00, 0xa8, 0x20, 0xaa, 0x01, 0x21,
-
 
1109
        0x00, 0x55, 0x21, 0x55, 0x55, 0x45, 0x55, 0x55,
-
 
1110
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1111
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1112
 
-
 
1113
    learn_char(208, cd0);
-
 
1114
    learn_char(209, cd1);
-
 
1115
    learn_char(210, cd2);
-
 
1116
    learn_char(211, cd3);
-
 
1117
    learn_char(212, cd4);
-
 
1118
    learn_char(213, cd5);
-
 
1119
    learn_char(214, cd6);
-
 
1120
    learn_char(215, cd7);
-
 
1121
#endif
-
 
1122
#if WRITECHARS == 216
-
 
1123
    // compass line
-
 
1124
    unsigned char cd8[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1125
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1126
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1127
        0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00,
-
 
1128
        0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1129
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1130
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1131
 
-
 
1132
    // arrow right
-
 
1133
    unsigned char cd9[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1134
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1135
        0x55, 0x15, 0x55, 0x54, 0x85, 0x40, 0x00, 0xa1,
-
 
1136
        0x2a, 0xaa, 0xa8, 0x2a, 0xaa, 0xa8, 0x40, 0x00,
-
 
1137
        0xa1, 0x55, 0x54, 0x85, 0x55, 0x55, 0x15, 0x55,
-
 
1138
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1139
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1140
 
-
 
1141
    // arrow right-up
-
 
1142
    unsigned char cda[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1143
        0x55, 0x55, 0x40, 0x01, 0x55, 0x2a, 0xa8, 0x55,
-
 
1144
        0x4a, 0xa8, 0x55, 0x52, 0xa8, 0x55, 0x4a, 0xa8,
-
 
1145
        0x55, 0x2a, 0x28, 0x54, 0xa8, 0x48, 0x52, 0xa1,
-
 
1146
        0x51, 0x4a, 0x85, 0x55, 0x52, 0x15, 0x55, 0x54,
-
 
1147
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1148
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1149
 
-
 
1150
    // arrow up
-
 
1151
    unsigned char cdb[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1152
        0x55, 0x55, 0x41, 0x55, 0x55, 0x28, 0x55, 0x54,
-
 
1153
        0xaa, 0x15, 0x52, 0xaa, 0x85, 0x54, 0x28, 0x15,
-
 
1154
        0x55, 0x28, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28,
-
 
1155
        0x55, 0x55, 0x28, 0x55, 0x55, 0x28, 0x55, 0x55,
-
 
1156
        0x28, 0x55, 0x55, 0x41, 0x55, 0x55, 0x55, 0x55,
-
 
1157
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1158
 
-
 
1159
    // arrow left-up
-
 
1160
    unsigned char cdc[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1161
        0x55, 0x40, 0x01, 0x55, 0x2a, 0xa8, 0x55, 0x2a,
-
 
1162
        0xa1, 0x55, 0x2a, 0x85, 0x55, 0x2a, 0xa1, 0x55,
-
 
1163
        0x28, 0xa8, 0x55, 0x21, 0x2a, 0x15, 0x45, 0x4a,
-
 
1164
        0x85, 0x55, 0x52, 0xa1, 0x55, 0x54, 0x85, 0x55,
-
 
1165
        0x55, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1166
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1167
 
-
 
1168
    // arrow left
-
 
1169
    unsigned char cdd[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1170
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54,
-
 
1171
        0x55, 0x55, 0x52, 0x15, 0x55, 0x4a, 0x00, 0x01,
-
 
1172
        0x2a, 0xaa, 0xa8, 0x2a, 0xaa, 0xa8, 0x4a, 0x00,
-
 
1173
        0x01, 0x52, 0x15, 0x55, 0x54, 0x55, 0x55, 0x55,
-
 
1174
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1175
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1176
 
-
 
1177
    // arrow left-down
-
 
1178
    unsigned char cde[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1179
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x55,
-
 
1180
        0x54, 0x85, 0x55, 0x52, 0xa1, 0x45, 0x4a, 0x85,
-
 
1181
        0x21, 0x2a, 0x15, 0x28, 0xa8, 0x55, 0x2a, 0xa1,
-
 
1182
        0x55, 0x2a, 0x85, 0x55, 0x2a, 0xa1, 0x55, 0x2a,
-
 
1183
        0xa8, 0x55, 0x40, 0x01, 0x55, 0x55, 0x55, 0x55,
-
 
1184
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1185
 
-
 
1186
    // arrow down
-
 
1187
    unsigned char cdf[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1188
        0x55, 0x55, 0x41, 0x55, 0x55, 0x28, 0x55, 0x55,
-
 
1189
        0x28, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28, 0x55,
-
 
1190
        0x55, 0x28, 0x55, 0x55, 0x28, 0x55, 0x54, 0x28,
-
 
1191
        0x15, 0x52, 0xaa, 0x85, 0x54, 0xaa, 0x15, 0x55,
-
 
1192
        0x28, 0x55, 0x55, 0x41, 0x55, 0x55, 0x55, 0x55,
-
 
1193
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1194
 
-
 
1195
    learn_char(216, cd8);
-
 
1196
        learn_char(217, cd9);
-
 
1197
    learn_char(218, cda);
-
 
1198
    learn_char(219, cdb);
-
 
1199
    learn_char(220, cdc);
-
 
1200
    learn_char(221, cdd);
-
 
1201
    learn_char(222, cde);
-
 
1202
    learn_char(223, cdf);
-
 
1203
#endif
-
 
1204
#if WRITECHARS == 224
-
 
1205
     // arrow right-down
-
 
1206
    unsigned char ce0[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1207
        0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x55, 0x52,
-
 
1208
        0x15, 0x55, 0x4a, 0x85, 0x55, 0x52, 0xa1, 0x51,
-
 
1209
        0x54, 0xa8, 0x48, 0x55, 0x2a, 0x28, 0x55, 0x4a,
-
 
1210
        0xa8, 0x55, 0x52, 0xa8, 0x55, 0x4a, 0xa8, 0x55,
-
 
1211
        0x2a, 0xa8, 0x55, 0x40, 0x01, 0x55, 0x55, 0x55,
-
 
1212
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1213
 
-
 
1214
        // horizon up
-
 
1215
    unsigned char ce1[54] ={0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0xaa, 0xaa,
-
 
1216
        0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x55,
-
 
1217
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1218
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1219
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1220
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1221
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1222
 
-
 
1223
        // horizon middle
-
 
1224
    unsigned char ce2[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1225
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1226
        0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00,
-
 
1227
        0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00,
-
 
1228
        0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1229
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1230
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-
 
1231
 
-
 
1232
        // horizon down
-
 
1233
    unsigned char ce3[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1234
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1235
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1236
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1237
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00,
-
 
1238
        0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-
 
1239
        0x00, 0x00, 0x00, 0x55, 0x55, 0x55};
-
 
1240
 
-
 
1241
        // horizon center
-
 
1242
    unsigned char ce4[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1243
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1244
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1245
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1246
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00,
-
 
1247
        0x14, 0x00, 0xaa, 0x14, 0xaa, 0xaa, 0x82, 0xaa,
-
 
1248
        0x00, 0xaa, 0x00, 0x54, 0x00, 0x15};
-
 
1249
 
-
 
1250
        // horizon roll
-
 
1251
    unsigned char ce5[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1252
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1253
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1254
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-
 
1255
        0x55, 0x00, 0x55, 0x00, 0x2a, 0x14, 0xa8, 0x4a,
-
 
1256
        0x82, 0xa1, 0x52, 0xaa, 0x85, 0x54, 0xaa, 0x15,
-
 
1257
        0x55, 0x28, 0x55, 0x55, 0x41, 0x55};
-
 
1258
       
-
 
1259
        // gps PH
-
 
1260
    unsigned char ce6[54] ={0x55, 0x05, 0x11, 0x54, 0xa0, 0x88, 0x54, 0x88,
-
 
1261
        0x88, 0x54, 0xa0, 0xa8, 0x54, 0x84, 0x88, 0x44,
-
 
1262
        0x84, 0x88, 0x21, 0x15, 0x11, 0xa8, 0x55, 0x55,
-
 
1263
        0xa1, 0x55, 0x55, 0x98, 0x15, 0x55, 0x2a, 0x85,
-
 
1264
        0x55, 0x4a, 0xa1, 0x55, 0x4a, 0xa8, 0x55, 0x52,
-
 
1265
        0xaa, 0x15, 0x54, 0xaa, 0x15, 0x55, 0x28, 0x55,
-
 
1266
        0x55, 0x41, 0x55, 0x55, 0x55, 0x55};
-
 
1267
       
-
 
1268
        // gps CH
-
 
1269
    unsigned char ce7[54] ={0x55, 0x55, 0x41, 0x55, 0x55, 0x28, 0x55, 0x54,
-
 
1270
        0x81, 0x55, 0x54, 0x85, 0x55, 0x54, 0x81, 0x45,
-
 
1271
        0x55, 0x28, 0x21, 0x55, 0x01, 0xa8, 0x54, 0x88,
-
 
1272
        0xa1, 0x54, 0x88, 0x98, 0x14, 0xa8, 0x2a, 0x84,
-
 
1273
        0x88, 0x4a, 0xa0, 0x88, 0x4a, 0xa8, 0x11, 0x52,
-
 
1274
        0xaa, 0x15, 0x54, 0xaa, 0x15, 0x55, 0x28, 0x55,
-
 
1275
        0x55, 0x41, 0x55, 0x55, 0x55, 0x55};
-
 
1276
 
-
 
1277
    learn_char(224, ce0);
-
 
1278
        learn_char(225, ce1);
-
 
1279
        learn_char(226, ce2);
-
 
1280
        learn_char(227, ce3);
-
 
1281
        learn_char(228, ce4);
-
 
1282
        learn_char(229, ce5);
-
 
1283
        learn_char(230, ce6);
-
 
1284
        learn_char(231, ce7);
-
 
1285
#endif
-
 
1286
 
-
 
1287
#if WRITECHARS == 232
-
 
1288
 
-
 
1289
    // small arrow down
-
 
1290
    unsigned char ce8[54] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1291
        0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1292
        0x55,0x55,0x55,0x55,0x55,0x00,0x00,0x00,
-
 
1293
        0x2a,0xaa,0xa8,0x2a,0xaa,0xa8,0x0a,0xaa,
-
 
1294
        0xa0,0x52,0xaa,0x85,0x54,0xaa,0x15,0x55,
-
 
1295
        0x28,0x55,0x55,0x41,0x55,0x55,0x55,0x55,
-
 
1296
        0x55,0x55,0x55,0x55,0x55,0x55};
-
 
1297
 
-
 
1298
    // big arrow down
-
 
1299
    unsigned char ce9[54] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1300
        0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1301
        0x55,0x55,0x55,0x55,0x55,0x00,0x00,0x00,
-
 
1302
        0x2a,0xaa,0xa8,0x2a,0xaa,0xa8,0x00,0x28,
-
 
1303
        0x00,0x55,0x28,0x55,0x40,0x28,0x01,0x2a,
-
 
1304
        0xaa,0xa8,0x4a,0xaa,0xa1,0x52,0xaa,0x85,
-
 
1305
        0x54,0xaa,0x15,0x55,0x28,0x55};
-
 
1306
 
-
 
1307
    // small arrow up
-
 
1308
    unsigned char cea[54] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1309
        0x55,0x55,0x41,0x55,0x55,0x28,0x55,0x54,
-
 
1310
        0xaa,0x15,0x52,0xaa,0x85,0x0a,0xaa,0xa0,
-
 
1311
        0x2a,0xaa,0xa8,0x2a,0xaa,0xa8,0x00,0x00,
-
 
1312
        0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1313
        0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1314
        0x55,0x55,0x55,0x55,0x55,0x55};
-
 
1315
 
-
 
1316
    // big arrow up
-
 
1317
    unsigned char ceb[54] = {0x55,0x28,0x55,0x54,0xaa,0x15,0x52,0xaa,
-
 
1318
        0x85,0x4a,0xaa,0xa1,0x2a,0xaa,0xa8,0x40,
-
 
1319
        0x28,0x01,0x55,0x28,0x55,0x00,0x28,0x00,
-
 
1320
        0x2a,0xaa,0xa8,0x2a,0xaa,0xa8,0x00,0x00,
-
 
1321
        0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1322
        0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-
 
1323
        0x55,0x55,0x55,0x55,0x55,0x55};
-
 
1324
 
-
 
1325
    learn_char(232, ce8);
-
 
1326
    learn_char(233, ce9);
-
 
1327
    learn_char(234, cea);
-
 
1328
    learn_char(235, ceb);
-
 
1329
 
-
 
1330
#endif
-
 
1331
 
-
 
1332
 
-
 
1333
 
-
 
1334
#endif // write char general
-
 
1335
    /* ##########################################################################
415
 
1336
     * continue normal main
416
        #include "characters.c"
1337
     * ##########################################################################*/
417
#endif 
1338
       
418
 
1339
        // Setup Video Mode
419
        // Setup Video Mode
1340
        if (COSD_FLAGS & COSD_FLAG_NTSC) {
420
        if (COSD_FLAGS & COSD_FLAG_NTSC) {
1341
        // NTSC + enable display immediately (VM0)
421
        // NTSC + enable display immediately (VM0)
1342
        spi_send_byte(0x00, 0b00001000);
422
        spi_send_byte(0x00, 0b00001000);
1343
        } else {
423
        } else {
1344
        // PAL + enable display immediately (VM0)
424
        // PAL + enable display immediately (VM0)
1345
        spi_send_byte(0x00, 0b01001000);
425
        spi_send_byte(0x00, 0b01001000);
1346
        }
426
        }
1347
 
427
 
1348
    // clear all display-mem (DMM)
428
    // clear all display-mem (DMM)
1349
    spi_send_byte(0x04, 0b00000100);
429
    spi_send_byte(0x04, 0b00000100);
1350
 
430
 
1351
    // clearing takes 12uS according to maxim so lets wait longer
431
    // clearing takes 12uS according to maxim so lets wait longer
1352
    _delay_us(120);
432
    _delay_us(120);
1353
 
433
 
1354
    // 8bit mode
434
    // 8bit mode
1355
    spi_send_byte(0x04, 0b01000000);
435
    spi_send_byte(0x04, 0b01000000);
1356
 
436
 
1357
    // write blank chars to whole screen
437
    // write blank chars to whole screen
1358
    clear();
438
    clear();
1359
 
439
 
1360
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
440
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
1361
    // init usart
441
    // init usart
1362
    usart1_init();
442
    usart1_init();
1363
 
443
 
1364
    // set up timer
444
    // set up timer
1365
    TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64
445
    TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64
1366
    OCR0 = 6; // preload
446
    OCR0 = 6; // preload
1367
    TIMSK |= (1 << TOIE0); // enable overflow timer0
447
    TIMSK |= (1 << TOIE0); // enable overflow timer0
1368
 
448
 
1369
    // enable interrupts
449
    // enable interrupts
1370
    sei();
450
    sei();
1371
#endif
451
#endif
1372
 
452
 
1373
    //write_ascii_string(2,  7, "         CaScAdE          ");
453
    //write_ascii_string(2,  7, "         CaScAdE          ");
1374
    //write_ascii_string(2,  8, "is TESTING his open source");
454
    //write_ascii_string(2,  8, "is TESTING his open source");
1375
    //write_ascii_string(2,  9, "    EPi OSD Firmware");
455
    //write_ascii_string(2,  9, "    EPi OSD Firmware");
1376
 
456
 
1377
    // custom char preview
457
    // custom char preview
1378
    /*write_char_xy( 2, 7, 200);
458
    /*write_char_xy( 2, 7, 200);
1379
    write_char_xy( 3, 7, 201);
459
    write_char_xy( 3, 7, 201);
1380
    write_char_xy( 4, 7, 202);
460
    write_char_xy( 4, 7, 202);
1381
    write_char_xy( 5, 7, 203);
461
    write_char_xy( 5, 7, 203);
1382
    write_char_xy( 6, 7, 204);
462
    write_char_xy( 6, 7, 204);
1383
    write_char_xy( 7, 7, 205);
463
    write_char_xy( 7, 7, 205);
1384
    write_char_xy( 8, 7, 206);
464
    write_char_xy( 8, 7, 206);
1385
    write_char_xy( 9, 7, 207);
465
    write_char_xy( 9, 7, 207);
1386
    write_char_xy(10, 7, 208);
466
    write_char_xy(10, 7, 208);
1387
    write_char_xy(11, 7, 209);
467
    write_char_xy(11, 7, 209);
1388
    write_char_xy(12, 7, 210);
468
    write_char_xy(12, 7, 210);
1389
    write_char_xy(13, 7, 211);
469
    write_char_xy(13, 7, 211);
1390
    write_char_xy(14, 7, 212);
470
    write_char_xy(14, 7, 212);
1391
    write_char_xy(15, 7, 213);
471
    write_char_xy(15, 7, 213);
1392
    write_char_xy(16, 7, 214);
472
    write_char_xy(16, 7, 214);
1393
    write_char_xy(17, 7, 215);*/
473
    write_char_xy(17, 7, 215);*/
1394
 
474
 
1395
    // we are ready
475
    // we are ready
1396
    LED3_ON
476
    LED3_ON
1397
 
477
 
1398
 
478
 
1399
 
479
 
1400
#if ALLCHARSDEBUG | (WRITECHARS != -1)
480
#if ALLCHARSDEBUG | (WRITECHARS != -1)
1401
        clear();
481
        clear();
1402
    write_all_chars();
482
    write_all_chars();
1403
#else
483
#else
1404
    // clear serial screen
484
    // clear serial screen
1405
    //usart1_puts("\x1B[2J\x1B[H");
485
    //usart1_puts("\x1B[2J\x1B[H");
1406
    //usart1_puts("hello world!\r\n");
486
    //usart1_puts("hello world!\r\n");
1407
 
487
 
1408
   
488
   
1409
    // request data ever 100ms from FC
489
    // request data ever 100ms from FC
1410
        //unsigned char ms = 10;
490
        //unsigned char ms = 10;
1411
        //sendMKData('d', 0, &ms, 1);
491
        //sendMKData('d', 0, &ms, 1);
1412
     
492
     
1413
    // request OSD Data from NC every 100ms
493
    // request OSD Data from NC every 100ms
1414
        unsigned char ms = 10;
494
        unsigned char ms = 10;
1415
    sendMKData('o', 1, &ms, 1);
495
    sendMKData('o', 1, &ms, 1);
1416
        // and disable debug...
496
        // and disable debug...
1417
        //ms = 0;
497
        //ms = 0;
1418
        //sendMKData('d', 0, &ms, 1);
498
        //sendMKData('d', 0, &ms, 1);
-
 
499
 
-
 
500
        // disable TXD-pin
-
 
501
        usart1_DisableTXD();
1419
 
502
 
1420
        // stats for after flight
503
        // stats for after flight
1421
        int16_t max_Altimeter = 0;
504
        int16_t max_Altimeter = 0;
1422
        uint16_t max_GroundSpeed = 0;
505
        uint16_t max_GroundSpeed = 0;
1423
        int16_t max_Distance = 0;
506
        int16_t max_Distance = 0;
1424
        uint8_t min_UBat = 255;
507
        uint8_t min_UBat = 255;
1425
        uint16_t max_FlyingTime = 0;
508
        uint16_t max_FlyingTime = 0;
1426
 
509
 
1427
        // flags from last round to check for changes
510
        // flags from last round to check for changes
1428
        uint8_t old_MKFlags = 0;
511
        uint8_t old_MKFlags = 0;
1429
       
512
       
1430
    char* directions[8] = {"NE", "E ", "SE", "S ", "SW", "W ", "NW", "N "};
513
    char* directions[8] = {"NE", "E ", "SE", "S ", "SW", "W ", "NW", "N "};
1431
        char arrowdir[8] =   { 218,  217,  224,  223,  222,  221,  220, 219};
514
        char arrowdir[8] =   { 218,  217,  224,  223,  222,  221,  220, 219};
1432
 
515
 
1433
    while (1) {
516
    while (1) {
1434
                // write icons at init or after menu/mode-switch
517
                // write icons at init or after menu/mode-switch
1435
                if (!(COSD_FLAGS & COSD_ICONS_WRITTEN)) {
518
                if (!(COSD_FLAGS & COSD_ICONS_WRITTEN)) {
1436
                            write_char_xy(5, top_line, 203); // km/h
519
                            write_char_xy(5, top_line, 203); // km/h
1437
                            write_char_xy(10, top_line, 202); // RC-transmitter
520
                            write_char_xy(10, top_line, 202); // RC-transmitter
1438
                            write_char_xy(16, top_line, 208); // degree symbol
521
                            write_char_xy(16, top_line, 208); // degree symbol
1439
                            write_char_xy(27, top_line, 204); // small meters m
522
                            write_char_xy(27, top_line, 204); // small meters m
1440
                            write_ascii_string(6, bottom_line, "V"); // voltage
523
                            write_ascii_string(6, bottom_line, "V"); // voltage
1441
                            write_char_xy(14, bottom_line, 209); // on clock
524
                            write_char_xy(14, bottom_line, 209); // on clock
1442
                            write_char_xy(22, bottom_line, 210); // fly clock
525
                            write_char_xy(22, bottom_line, 210); // fly clock
1443
                            write_char_xy(26, bottom_line, 200); // sat1
526
                            write_char_xy(26, bottom_line, 200); // sat1
1444
                            write_char_xy(27, bottom_line, 201); // sat2
527
                            write_char_xy(27, bottom_line, 201); // sat2
1445
                                COSD_FLAGS |= COSD_ICONS_WRITTEN;
528
                                COSD_FLAGS |= COSD_ICONS_WRITTEN;
1446
                }
529
                }
1447
        if (rxd_buffer_locked) {
530
        if (rxd_buffer_locked) {
1448
            if (rxd_buffer[2] == 'D') { // FC Data
531
            if (rxd_buffer[2] == 'D') { // FC Data
1449
                /*Decode64();
532
                /*Decode64();
1450
                debugData = *((DebugOut_t*) pRxData);
533
                debugData = *((DebugOut_t*) pRxData);
1451
                write_number_s(12, 2, RxDataLen);
534
                write_number_s(12, 2, RxDataLen);
1452
                write_number_s(20, 2, setsReceived++);
535
                write_number_s(20, 2, setsReceived++);
1453
                write_number_s(12, 3, debugData.Analog[0]);
536
                write_number_s(12, 3, debugData.Analog[0]); // AngleNick
1454
                write_number_s(12, 4, debugData.Analog[2]);
537
                write_number_s(12, 4, debugData.Analog[1]); // AngleRoll
1455
                write_number_s(12, 5, debugData.Analog[1]);
538
                                write_number_s(12, 5, debugData.Analog[5]); // Height
1456
                write_number_s(12, 6, debugData.Analog[3]);
-
 
1457
                write_number_s(12, 7, debugData.Analog[9]);
539
                write_number_s(12, 6, debugData.Analog[9]); // Voltage
1458
                write_number_s(12, 8, debugData.Analog[10]);
540
                write_number_s(12, 7, debugData.Analog[10]);// RC Signal
1459
                                write_number_s(12, 4, debugData.Analog[12]);
-
 
1460
                                write_number_s(12, 5, debugData.Analog[13]);
-
 
1461
                                write_number_s(12, 6, debugData.Analog[14]);
-
 
1462
                                write_number_s(12, 7, debugData.Analog[15]);*/
541
                                write_number_s(12, 8, debugData.Analog[11]);// Gyro compass*/
1463
            } else if (rxd_buffer[2] == 'O') { // NC OSD Data
542
            } else if (rxd_buffer[2] == 'O') { // NC OSD Data
1464
                Decode64();
543
                Decode64();
1465
                naviData = *((NaviData_t*) pRxData);
544
                naviData = *((NaviData_t*) pRxData);
1466
 
545
 
1467
                                // first line
546
                                // first line
1468
                                write_3digit_number_u(2, top_line, (uint16_t)(((uint32_t)naviData.GroundSpeed*36)/1000));
547
                                write_3digit_number_u(2, top_line, (uint16_t)(((uint32_t)naviData.GroundSpeed*36)/1000));
1469
 
548
 
1470
                write_3digit_number_u(7, top_line, naviData.RC_Quality);
549
                write_3digit_number_u(7, top_line, naviData.RC_Quality);
1471
                if (naviData.RC_Quality <= RCLVL_WRN && last_RC_Quality > RCLVL_WRN) {
550
                if (naviData.RC_Quality <= RCLVL_WRN && last_RC_Quality > RCLVL_WRN) {
1472
                    for (uint8_t x = 0; x < 4; x++)
551
                    for (uint8_t x = 0; x < 4; x++)
1473
                        write_char_att_xy(7 + x, top_line, BLINK);
552
                        write_char_att_xy(7 + x, top_line, BLINK);
1474
                } else if (naviData.RC_Quality > RCLVL_WRN && last_RC_Quality <= RCLVL_WRN) {
553
                } else if (naviData.RC_Quality > RCLVL_WRN && last_RC_Quality <= RCLVL_WRN) {
1475
                    for (uint8_t x = 0; x < 4; x++)
554
                    for (uint8_t x = 0; x < 4; x++)
1476
                        write_char_att_xy(7 + x, top_line, 0);
555
                        write_char_att_xy(7 + x, top_line, 0);
1477
                }
556
                }
1478
                last_RC_Quality = naviData.RC_Quality;
557
                last_RC_Quality = naviData.RC_Quality;
1479
 
558
 
1480
                write_3digit_number_u(13, top_line, naviData.CompassHeading);
559
                write_3digit_number_u(13, top_line, naviData.CompassHeading);
1481
 
560
 
1482
                write_ascii_string(17, top_line, directions[heading_conv(naviData.CompassHeading)]);
561
                write_ascii_string(17, top_line, directions[heading_conv(naviData.CompassHeading)]);
1483
 
562
 
1484
                if (naviData.Variometer == 0) {
563
                if (naviData.Variometer == 0) {
1485
                    write_char_xy(20, top_line, 206); // plain line
564
                    write_char_xy(20, top_line, 206); // plain line
1486
                } else if (naviData.Variometer > 0 && naviData.Variometer <= 10) {
565
                } else if (naviData.Variometer > 0 && naviData.Variometer <= 10) {
1487
                    write_char_xy(20, top_line, 234); // small arrow up
566
                    write_char_xy(20, top_line, 234); // small arrow up
1488
                } else if (naviData.Variometer > 10) {
567
                } else if (naviData.Variometer > 10) {
1489
                    write_char_xy(20, top_line, 235); // big arrow up
568
                    write_char_xy(20, top_line, 235); // big arrow up
1490
                } else if (naviData.Variometer < 0 && naviData.Variometer >= -10) {
569
                } else if (naviData.Variometer < 0 && naviData.Variometer >= -10) {
1491
                    write_char_xy(20, top_line, 232); // small arrow down
570
                    write_char_xy(20, top_line, 232); // small arrow down
1492
                } else {
571
                } else {
1493
                    write_char_xy(20, top_line, 233); //big arrow down
572
                    write_char_xy(20, top_line, 233); //big arrow down
1494
                }
573
                }
1495
 
574
 
1496
                                // TODO: is this really dm?
575
                                // TODO: is this really dm?
1497
                write_number_s(22, top_line, naviData.Altimeter/10);
576
                write_number_s(22, top_line, naviData.Altimeter/10);
1498
 
577
 
1499
                                // seccond line
578
                                // seccond line
1500
                draw_compass(11, top_line + 1, naviData.CompassHeading);
579
                draw_compass(11, top_line + 1, naviData.CompassHeading);
1501
 
580
 
1502
                                // TODO: verify correctness
581
                                // TODO: verify correctness
1503
                                uint16_t heading_home = (naviData.HomePositionDeviation.Bearing + 360 - naviData.CompassHeading) % 360;
582
                                uint16_t heading_home = (naviData.HomePositionDeviation.Bearing + 360 - naviData.CompassHeading) % 360;
1504
                                write_char_xy(27, top_line + 1, arrowdir[heading_conv(heading_home)]);
583
                                write_char_xy(27, top_line + 1, arrowdir[heading_conv(heading_home)]);
1505
 
584
 
1506
       
585
       
1507
                                write_number_s(22, top_line + 1, naviData.HomePositionDeviation.Distance/100);
586
                                write_number_s(22, top_line + 1, naviData.HomePositionDeviation.Distance/100);
1508
 
587
 
1509
                                // center
588
                                // center
1510
                                if (naviData.MKFlags & FLAG_MOTOR_RUN) { // should be engines running
589
                                if (naviData.MKFlags & FLAG_MOTOR_RUN) { // should be engines running
1511
                                        if (!(old_MKFlags & FLAG_MOTOR_RUN)) { // motors just started, clear middle
590
                                        if (!(old_MKFlags & FLAG_MOTOR_RUN)) { // motors just started, clear middle
1512
                                                clear();
591
                                                clear();
1513
                                                // update flags to paint display again if needed
592
                                                // update flags to paint display again if needed
1514
                                                COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
593
                                                COSD_FLAGS &= ~COSD_ICONS_WRITTEN;
1515
                                        }
594
                                        }
1516
                                if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
595
                                if (COSD_FLAGS & COSD_FLAG_ARTHORIZON) {
1517
                                        draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
596
                                        draw_artificial_horizon(top_line + 2, bottom_line - 1, naviData.AngleNick, naviData.AngleRoll);
1518
                                }
597
                                }
1519
                                } else {
598
                                } else {
1520
                                        // stats
599
                                        // stats
1521
                                        write_ascii_string(2, 5, "max Altitude:");
600
                                        write_ascii_string(2, 5, "max Altitude:");
1522
                                        write_number_s(17, 5, max_Altimeter/10);
601
                                        write_number_s(17, 5, max_Altimeter/10);
1523
                                        write_char_xy(22, 5, 204); // small meters m
602
                                        write_char_xy(22, 5, 204); // small meters m
1524
                                        write_ascii_string(2, 6, "max Speed   :");
603
                                        write_ascii_string(2, 6, "max Speed   :");
1525
                                        write_3digit_number_u(19, 6, (uint16_t)(((uint32_t)max_GroundSpeed*36)/1000));
604
                                        write_3digit_number_u(19, 6, (uint16_t)(((uint32_t)max_GroundSpeed*36)/1000));
1526
                                        write_char_xy(22, 6, 203); // km/h
605
                                        write_char_xy(22, 6, 203); // km/h
1527
                                        write_ascii_string(2, 7, "max Distance:");
606
                                        write_ascii_string(2, 7, "max Distance:");
1528
                                        write_number_s(17, 7, max_Distance/100);
607
                                        write_number_s(17, 7, max_Distance/100);
1529
                                        write_char_xy(22, 7, 204); // small meters m
608
                                        write_char_xy(22, 7, 204); // small meters m
1530
                                        write_ascii_string(2, 8, "min voltage :");
609
                                        write_ascii_string(2, 8, "min voltage :");
1531
                                        //write_number_s(17, 8, min_UBat/10);
610
                                        //write_number_s(17, 8, min_UBat/10);
1532
                                        write_number_u_10th(16, 8, min_UBat);
611
                                        write_number_u_10th(16, 8, min_UBat);
1533
                                        write_ascii_string(22, 8, "V"); // voltage
612
                                        write_ascii_string(22, 8, "V"); // voltage
1534
                                        write_ascii_string(2, 9, "max time    :");
613
                                        write_ascii_string(2, 9, "max time    :");
1535
                                        write_time(16, 9, max_FlyingTime);
614
                                        write_time(16, 9, max_FlyingTime);
1536
                                        write_char_xy(22, 9, 210); // fly clock
615
                                        write_char_xy(22, 9, 210); // fly clock
1537
                                }
616
                                }
1538
 
617
 
1539
                                // bottom line
618
                                // bottom line
1540
                write_number_u_10th(0, bottom_line, naviData.UBat);
619
                write_number_u_10th(0, bottom_line, naviData.UBat);
1541
                if (naviData.UBat <= UBAT_WRN && last_UBat > UBAT_WRN) {
620
                if (naviData.UBat <= UBAT_WRN && last_UBat > UBAT_WRN) {
1542
                    for (uint8_t x = 0; x < 7; x++)
621
                    for (uint8_t x = 0; x < 7; x++)
1543
                        write_char_att_xy(x, bottom_line, BLINK);
622
                        write_char_att_xy(x, bottom_line, BLINK);
1544
                } else {
623
                } else {
1545
                    for (uint8_t x = 0; x < 7; x++)
624
                    for (uint8_t x = 0; x < 7; x++)
1546
                        write_char_att_xy(x, bottom_line, 0);
625
                        write_char_att_xy(x, bottom_line, 0);
1547
                }
626
                }
1548
 
627
 
1549
                write_time(8, bottom_line, uptime);
628
                write_time(8, bottom_line, uptime);
1550
                write_time(16, bottom_line, naviData.FlyingTime);
629
                write_time(16, bottom_line, naviData.FlyingTime);
1551
 
630
 
1552
                write_3digit_number_u(23, bottom_line, naviData.SatsInUse);
631
                write_3digit_number_u(23, bottom_line, naviData.SatsInUse);
1553
 
632
 
1554
                                if (naviData.NCFlags & NC_FLAG_CH) {
633
                                if (naviData.NCFlags & NC_FLAG_CH) {
1555
                                        write_char_xy(27, bottom_line, 231);    // gps ch
634
                                        write_char_xy(27, bottom_line, 231);    // gps ch
1556
                                } else if (naviData.NCFlags & NC_FLAG_PH) {
635
                                } else if (naviData.NCFlags & NC_FLAG_PH) {
1557
                                        write_char_xy(27, bottom_line, 230);    // gps ph
636
                                        write_char_xy(27, bottom_line, 230);    // gps ph
1558
                                } else { // (naviData.NCFlags & NC_FLAG_FREE)
637
                                } else { // (naviData.NCFlags & NC_FLAG_FREE)
1559
                                        write_char_xy(27, bottom_line, 201);    // sat2 (free)
638
                                        write_char_xy(27, bottom_line, 201);    // sat2 (free)
1560
                                }
639
                                }
1561
 
640
 
1562
                //write_number_s(8, 5, RxDataLen);
641
                //write_number_s(8, 5, RxDataLen);
1563
                //write_number_s(16, 5, setsReceived++);
642
                //write_number_s(16, 5, setsReceived++);
1564
 
643
 
1565
                                // remember statistics
644
                                // remember statistics
1566
                                if (naviData.Altimeter > max_Altimeter) max_Altimeter = naviData.Altimeter;
645
                                if (naviData.Altimeter > max_Altimeter) max_Altimeter = naviData.Altimeter;
1567
                                if (naviData.GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData.GroundSpeed;
646
                                if (naviData.GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData.GroundSpeed;
1568
                                if (naviData.HomePositionDeviation.Distance > max_Distance) {
647
                                if (naviData.HomePositionDeviation.Distance > max_Distance) {
1569
                                        max_Distance = naviData.HomePositionDeviation.Distance;
648
                                        max_Distance = naviData.HomePositionDeviation.Distance;
1570
                                }
649
                                }
1571
                                if (naviData.UBat < min_UBat) min_UBat = naviData.UBat;
650
                                if (naviData.UBat < min_UBat) min_UBat = naviData.UBat;
1572
                                if (naviData.FlyingTime > max_FlyingTime) max_FlyingTime = naviData.FlyingTime;
651
                                if (naviData.FlyingTime > max_FlyingTime) max_FlyingTime = naviData.FlyingTime;
1573
                               
652
                               
1574
                                old_MKFlags = naviData.MKFlags;
653
                                old_MKFlags = naviData.MKFlags;
1575
            }
654
            }
-
 
655
                        seconds_since_last_data = 0;
1576
            rxd_buffer_locked = 0;
656
            rxd_buffer_locked = 0;
1577
        }
657
        }
1578
        // handle keypress
658
        // handle keypress
1579
        if (s1_pressed()) {
659
        if (s1_pressed()) {
1580
                        //sendMKData('d', 1, (unsigned char*) 0, 1);
660
                        //sendMKData('d', 1, (unsigned char*) 0, 1);
1581
            // request OSD Data from NC every 100ms
661
            // request OSD Data from NC every 100ms
1582
                        /*unsigned char ms = 10;
662
                        /*unsigned char ms = 10;
1583
            sendMKData('o', 1, &ms, 1);
663
            sendMKData('o', 1, &ms, 1);
1584
            _delay_ms(500);*/
664
            _delay_ms(500);*/
1585
                        config_menu();
665
                        config_menu();
1586
        }
666
        }
1587
                if (s2_pressed()) {
667
                if (s2_pressed()) {
1588
            uptime = 0;
668
            uptime = 0;
1589
            _delay_ms(100);
669
            _delay_ms(100);
1590
        }
670
        }
-
 
671
                if (seconds_since_last_data > 2) {
-
 
672
                        // re-request OSD Data from NC
-
 
673
                       
-
 
674
                        // re-enable TXD pin
-
 
675
                        usart1_EnableTXD();
-
 
676
                       
-
 
677
                        // every 100ms
-
 
678
                        unsigned char ms = 10;
-
 
679
            sendMKData('o', 1, &ms, 1);
-
 
680
                       
-
 
681
                        // disable TXD pin again
-
 
682
                        usart1_DisableTXD();
-
 
683
 
-
 
684
                        seconds_since_last_data = 0;
-
 
685
                }
1591
    }
686
    }
1592
#endif
687
#endif
1593
    return 0;
688
    return 0;
1594
}
689
}
1595
 
690