Subversion Repositories Projects

Rev

Rev 757 | Rev 761 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
389 cascade 1
/****************************************************************************
728 cascade 2
 *   Copyright (C) 2009-2010 by Claas Anders "CaScAdE" Rathje               *
389 cascade 3
 *   admiralcascade@gmail.com                                               *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
5
 *                                                                          *
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   *
8
 *   the Free Software Foundation; either version 2 of the License.         *
9
 *                                                                          *
10
 *   This program is distributed in the hope that it will be useful,        *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
13
 *   GNU General Public License for more details.                           *
14
 *                                                                          *
15
 *   You should have received a copy of the GNU General Public License      *
16
 *   along with this program; if not, write to the                          *
17
 *   Free Software Foundation, Inc.,                                        *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
19
 ****************************************************************************/
20
 
21
#include <avr/pgmspace.h> 
497 cascade 22
#include "main.h"
389 cascade 23
#include "osd_helpers.h"
24
#include "max7456_software_spi.h"
25
 
26
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
514 cascade 27
 
389 cascade 28
/* ##########################################################################
29
 * compass stuff
30
 * ##########################################################################*/
31
 
32
/**
33
 * convert the <heading> gotton from NC into an index
34
 */
35
uint8_t heading_conv(uint16_t heading) {
36
    if (heading > 23 && heading < 68) {
37
        //direction = "NE";
38
        return 0;
39
    } else if (heading > 67 && heading < 113) {
40
        //direction = "E ";
41
        return 1;
42
    } else if (heading > 112 && heading < 158) {
43
        //direction = "SE";
44
        return 2;
45
    } else if (heading > 157 && heading < 203) {
46
        //direction = "S ";
47
        return 3;
48
    } else if (heading > 202 && heading < 248) {
49
        //direction = "SW";
50
        return 4;
51
    } else if (heading > 247 && heading < 293) {
52
        //direction = "W ";
53
        return 5;
54
    } else if (heading > 292 && heading < 338) {
55
        //direction = "NW";
56
        return 6;
57
    }
58
    //direction = "N ";
59
    return 7;
60
}
61
 
62
/**
63
 * convert the <heading> gotton from NC into a more
64
 * precise index
65
 */
66
uint8_t heading_fine_conv(uint16_t heading) {
67
        heading = ((heading * 10) + 113) % 3600;
68
        return (heading / 225);
69
}
70
 
71
/**
72
 * draw a compass rose at <x>/<y> for <heading>
73
 */
74
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
75
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
489 woggle 76
    static char rose[48] PROGMEM = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
389 cascade 77
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
78
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
79
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
80
        // the center is char 19 (north), we add the current heading in 8th
81
        // which would be 22.5 degrees, but float would bloat up the code
82
        // and *10 / 225 would take ages... so we take the uncorrect way
83
    uint8_t front = 19 + (heading / 22);
84
    for (uint8_t i = 0; i < 9; i++) {
489 woggle 85
                write_char_xy(x++, y, pgm_read_byte(&rose[front - 4 + i]));
389 cascade 86
    }
87
}
88
 
89
/* ##########################################################################
90
 * battery index
91
 * ##########################################################################*/
92
/**
93
 * draw a battery symbol at <x>/<y> according to <voltage>
94
 */
453 cascade 95
void draw_battery(uint8_t x, uint8_t y, uint8_t min_voltage, uint8_t voltage, uint8_t max_voltage) {
96
        uint8_t percent = (100* (voltage - min_voltage) / (max_voltage - min_voltage));
389 cascade 97
        if (percent > 100) percent = 100;
453 cascade 98
        if (voltage < min_voltage) percent = 0;
389 cascade 99
        write_char_xy(x, y, 0x9d - (percent * 13 / 100));
100
        //write_ndigit_number_u(x, y-1, percent * 13 / 100, 100, 0);
101
}
102
 
103
/* ##########################################################################
104
 * variometer
105
 * ##########################################################################*/
106
/**
107
 * draw variometer arrows at <x>/<y> according to <variometer>
108
 */
109
void draw_variometer(uint8_t x, uint8_t y, int16_t variometer) {
110
        if (variometer == 0) {
111
                write_char_xy(x, y, 0xbb); // plain line
112
        } else if (variometer > 0) { // gain height
113
                switch (variometer / 5){
114
                        case 0:
115
                                //write_char_xy(x, y, 0xba); // smallest arrow up
116
                                write_char_xy(x, y, 0x70); // one arrow up
117
                                break;
118
                        case 1:
119
                                //write_char_xy(x, y, 0xb9); // small arrow up
120
                                write_char_xy(x, y, 0x71); // two arrows up
121
                                break;
122
                        case 2:
123
                                //write_char_xy(x, y, 0xb8); // large arrow up
124
                                write_char_xy(x, y, 0x72); // three arrows up
125
                                break;
126
                        default:
127
                                //write_char_xy(x, y, 0xb7); // largest arrow up
128
                                write_char_xy(x, y, 0x73); // three black arrows up
129
                }
130
        } else { // sink
131
                switch (variometer / -5){
132
                        case 0:
133
                                //write_char_xy(x, y, 0xbc); // smallest arrow down
134
                                write_char_xy(x, y, 0x77); // one arrow down
135
                                break;
136
                        case 1:
137
                                //write_char_xy(x, y, 0xbd); // small arrow down
138
                                write_char_xy(x, y, 0x76); // two arrows down
139
                                break;
140
                        case 2:
141
                                //write_char_xy(x, y, 0xbe); // large arrow down
142
                                write_char_xy(x, y, 0x75); // three arrows down
143
                                break;
144
                        default:
145
                                //write_char_xy(x, y, 0xbf); // largest arrow down
146
                                write_char_xy(x, y, 0x74); // three black arrows down
147
                }
148
        }
149
}
150
 
151
// big vario arrays 
489 woggle 152
const char vario_00[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xff};
153
const char vario_01[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc0};
154
const char vario_02[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc1};
155
const char vario_03[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0x00};
156
const char vario_04[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc0, 0x00};
157
const char vario_05[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc1, 0x00};
158
const char vario_06[5] PROGMEM = {0x00, 0x00, 0xc2, 0x00, 0x00};
159
const char vario_07[5] PROGMEM = {0x00, 0x00, 0xbb, 0x00, 0x00};
160
const char vario_08[5] PROGMEM = {0x00, 0x00, 0xc3, 0x00, 0x00};
161
const char vario_09[5] PROGMEM = {0x00, 0xc4, 0xc3, 0x00, 0x00};
162
const char vario_10[5] PROGMEM = {0x00, 0xc5, 0xc3, 0x00, 0x00};
163
const char vario_11[5] PROGMEM = {0x00, 0xff, 0xc3, 0x00, 0x00};
164
const char vario_12[5] PROGMEM = {0xc4, 0xff, 0xc3, 0x00, 0x00};
165
const char vario_13[5] PROGMEM = {0xc5, 0xff, 0xc3, 0x00, 0x00};
166
const char vario_14[5] PROGMEM = {0xff, 0xff, 0xc3, 0x00, 0x00};
167
const char* vario_pnt[15] PROGMEM = {vario_00, vario_01, vario_02, vario_03, vario_04,
389 cascade 168
                                vario_05, vario_06, vario_07, vario_08,
169
                                vario_09, vario_10, vario_11, vario_12,
170
                                vario_13, vario_14};
171
 
172
/**
173
 * draw a bigger vario with middle at <x>/<y> acording to <variometer>
174
 */
175
void draw_big_variometer(uint8_t x, uint8_t y, int16_t variometer) {   
176
        int16_t index = 7 + variometer;
177
        if (index > 14) index = 14;
178
        else if (index < 0) index = 0;
179
 
489 woggle 180
        write_string_pgm_down(x, y-2, (const char *) (pgm_read_word ( &(vario_pnt[index]))), 5);
389 cascade 181
}
182
 
183
/* ##########################################################################
753 cascade 184
 * NEW artificial horizon     By AGRESSiVA --=-- COPTERTRONiC
389 cascade 185
 * ##########################################################################*/
753 cascade 186
// draw routine 
187
int draw_noodles(int8_t pos_x, int8_t pos_y, int8_t num, int8_t old_num) {
758 cascade 188
        const char noodle[5] = {0x78, 0x79, 0x7A, 0x7B, 0x7C};
189
        int8_t line, car;
753 cascade 190
 
191
        line = num / 5;
192
        car = num - (line * 5);
193
        if (num != old_num) {
194
                write_char_xy(15 - pos_x , pos_y + (old_num), 0);
758 cascade 195
        }
753 cascade 196
 
197
        if (num < 0) {car = -1* car; car = 4 - car; line--; num = num - 5;}
198
        write_char_xy(15 - pos_x , pos_y + line, noodle[car]);
199
 
200
return line;
201
}
202
 
203
/**
204
 * calculate the rails of artificial horizon
205
 * receive <nick> and <roll> values
206
 */
757 cascade 207
void draw_agressiva_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
753 cascade 208
        static int8_t old_ticy = 1,old_ticx = 0;
209
        static int8_t old1 = 0,old2 = 0,old3 = 0,old4, old5 = 0, old6 = 0,old7 = 0,old8 = 0;
210
        int8_t ticy = 0, ticx = 0;
211
        uint8_t center_x = 15;
212
        uint8_t center_y = lastline - firstline;
213
        center_y = 7;
758 cascade 214
        write_char_xy(center_x - 7 ,center_y,226); // left bar
215
        write_char_xy(center_x + 6 ,center_y,226); // right bar
753 cascade 216
 
217
 
218
#if FCONLY
219
                ticy = -1*(roll / 10);  // rescale roll from FC debug data
220
                ticx = -1*(nick * 10);  // rescale nick from FC debug data
221
#else
222
                ticy = -1*(roll / 2);
223
                ticx = -1*(nick / 1);
224
#endif
225
 
226
if (ticy >= 30) ticy = 30;  // limit y
227
if (ticx >= 30) ticx = 30;      // limit x
228
 
229
        //write_ndigit_number_u (0 , 5 , ticy ,3, 1);
230
        //write_ndigit_number_u (0 , 6 , ticx ,3, 1);
231
 
758 cascade 232
        //if ((ticy != old_ticy) || (ticx != old_ticx)) { 
753 cascade 233
                        old1 = draw_noodles(   4, 3,  (ticy /  2) + 20 + ticx, old1);
234
                        old2 = draw_noodles(   3, 3,  (ticy /  3) + 20 + ticx, old2);
235
                        old3 = draw_noodles(   2, 3,  (ticy /  6) + 20 + ticx, old3);
236
                        old4 = draw_noodles(   1, 3,  (ticy / 14) + 20 + ticx, old4);
237
                        old5 = draw_noodles( - 3, 3, -(ticy /  2) + 20 + ticx, old5);
238
                        old6 = draw_noodles( - 2, 3, -(ticy /  3) + 20 + ticx, old6);
239
                        old7 = draw_noodles( - 1, 3, -(ticy /  6) + 20 + ticx, old7);
240
                        old8 = draw_noodles(   0, 3, -(ticy / 14) + 20 + ticx, old8);
758 cascade 241
                        //}
753 cascade 242
        // update old vars
243
        old_ticy = ticy;
244
        old_ticx = ticx;
245
}
246
 
247
 
248
/* ##########################################################################
249
 * OLD artificial horizon
250
 * ##########################################################################*/
251
 
389 cascade 252
// remember last time displayed values
253
int8_t old_af_x = -1, old_af_y = -1;
254
 
255
/**
256
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
257
 * from line <firstline> to <listlines> for given <nick> and <roll> values
258
 */
259
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
758 cascade 260
        const char noodle[5] = {225, 225, 226, 227, 227};
389 cascade 261
        uint8_t center_x = 15;
262
        uint8_t center_y = lastline - firstline;
263
        center_y = 7;
264
        write_char_xy(center_x,center_y,228);
265
        uint8_t cpos, nicky, rollx;
266
 
267
        // which line
268
        int8_t ypos =  nick / 20;
269
        // which character from the array?
270
        if (nick < 0) {
271
                cpos = -1*((nick - (ypos * 20))/4);
272
                ypos--;
273
        } else cpos = 4-((nick - (ypos * 20))/4);
274
        if (cpos > 4) cpos = 4;
275
 
276
        nicky = center_y - ypos;
277
        if (nicky > lastline) nicky = lastline;
278
        else if (nicky < firstline) nicky = firstline;
279
 
280
        // ensure roll-borders
281
        rollx = (roll / 8)+15;
282
        if (rollx < 2) rollx = 2;
283
        else if (rollx > 28) rollx = 28;
284
 
285
 
286
        // clear roll
287
        if (old_af_x != rollx && old_af_x >= 0) {
390 cascade 288
                write_char_xy(old_af_x, lastline, 0);
389 cascade 289
        }
290
 
291
        // clear nick
292
        if (old_af_y != nicky && old_af_y >= 0) {
390 cascade 293
                write_char_xy(center_x-1, old_af_y, 0);
294
                write_char_xy(center_x+1, old_af_y, 0);
389 cascade 295
        }
296
 
297
 
298
        // draw nick
390 cascade 299
        write_char_xy(center_x-1, nicky, noodle[cpos]);
300
        write_char_xy(center_x+1, nicky, noodle[cpos]);
389 cascade 301
 
302
        // draw roll
390 cascade 303
        write_char_xy(rollx, lastline, 229);
389 cascade 304
 
305
        // update old vars
306
        old_af_x = rollx;
307
        old_af_y = nicky;
308
}
309
 
753 cascade 310
 
311
#endif