Subversion Repositories Projects

Rev

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

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