Subversion Repositories Projects

Rev

Rev 728 | Rev 757 | 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
 
753 cascade 183
#if (NEW_ARTHORIZON == 1)
389 cascade 184
/* ##########################################################################
753 cascade 185
 * NEW artificial horizon     By AGRESSiVA --=-- COPTERTRONiC
389 cascade 186
 * ##########################################################################*/
753 cascade 187
// draw routine
188
int draw_noodles(int8_t pos_x, int8_t pos_y, int8_t num, int8_t old_num) {
189
	char noodle[5] = {0x78, 0x79, 0x7A, 0x7B, 0x7C};
190
	int8_t line,car;
191
 
192
	line = num / 5;
193
	car = num - (line * 5);
194
	if (num != old_num) {
195
		write_char_xy(15 - pos_x , pos_y + (old_num), 0);
196
		}
197
 
198
	if (num < 0) {car = -1* car; car = 4 - car; line--; num = num - 5;}
199
	write_char_xy(15 - pos_x , pos_y + line, noodle[car]);
200
 
201
return line;
202
}
203
 
204
/**
205
 * calculate the rails of artificial horizon
206
 * receive <nick> and <roll> values
207
 */
208
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
209
	static int8_t old_ticy = 1,old_ticx = 0;
210
	static int8_t old1 = 0,old2 = 0,old3 = 0,old4, old5 = 0, old6 = 0,old7 = 0,old8 = 0;
211
	int8_t ticy = 0, ticx = 0;
212
	uint8_t center_x = 15;
213
	uint8_t center_y = lastline - firstline;
214
	center_y = 7;
215
	write_char_xy(center_x - 7 ,center_y,226);
216
	write_char_xy(center_x + 6 ,center_y,226);
217
 
218
 
219
#if FCONLY
220
		ticy = -1*(roll / 10);	// rescale roll from FC debug data
221
		ticx = -1*(nick * 10);	// rescale nick from FC debug data
222
#else
223
		ticy = -1*(roll / 2);
224
		ticx = -1*(nick / 1);
225
#endif
226
 
227
if (ticy >= 30) ticy = 30;  // limit y
228
if (ticx >= 30) ticx = 30;	// limit x
229
 
230
	//write_ndigit_number_u (0 , 5 , ticy ,3, 1);
231
	//write_ndigit_number_u (0 , 6 , ticx ,3, 1);
232
 
233
	if ((ticy != old_ticy) || (ticx != old_ticx)) {
234
			old1 = draw_noodles(   4, 3,  (ticy /  2) + 20 + ticx, old1);
235
			old2 = draw_noodles(   3, 3,  (ticy /  3) + 20 + ticx, old2);
236
			old3 = draw_noodles(   2, 3,  (ticy /  6) + 20 + ticx, old3);
237
			old4 = draw_noodles(   1, 3,  (ticy / 14) + 20 + ticx, old4);
238
			old5 = draw_noodles( - 3, 3, -(ticy /  2) + 20 + ticx, old5);
239
			old6 = draw_noodles( - 2, 3, -(ticy /  3) + 20 + ticx, old6);
240
			old7 = draw_noodles( - 1, 3, -(ticy /  6) + 20 + ticx, old7);
241
			old8 = draw_noodles(   0, 3, -(ticy / 14) + 20 + ticx, old8);
242
			}
243
	// update old vars
244
	old_ticy = ticy;
245
	old_ticx = ticx;
246
}
247
 
248
#else
249
 
250
/* ##########################################################################
251
 * OLD artificial horizon
252
 * ##########################################################################*/
253
 
389 cascade 254
// remember last time displayed values
255
int8_t old_af_x = -1, old_af_y = -1;
256
 
257
/**
258
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
259
 * from line <firstline> to <listlines> for given <nick> and <roll> values
260
 */
261
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
262
	char noodle[5] = {225, 225, 226, 227, 227};
263
	uint8_t center_x = 15;
264
	uint8_t center_y = lastline - firstline;
265
	center_y = 7;
266
	write_char_xy(center_x,center_y,228);
267
	uint8_t cpos, nicky, rollx;
268
 
269
	// which line
270
	int8_t ypos =  nick / 20;
271
	// which character from the array?
272
	if (nick < 0) {
273
		cpos = -1*((nick - (ypos * 20))/4);
274
		ypos--;
275
	} else cpos = 4-((nick - (ypos * 20))/4);
276
	if (cpos > 4) cpos = 4;
277
 
278
	nicky = center_y - ypos;
279
	if (nicky > lastline) nicky = lastline;
280
	else if (nicky < firstline) nicky = firstline;
281
 
282
	// ensure roll-borders
283
	rollx = (roll / 8)+15;
284
	if (rollx < 2) rollx = 2;
285
	else if (rollx > 28) rollx = 28;
286
 
287
 
288
	// clear roll
289
	if (old_af_x != rollx && old_af_x >= 0) {
390 cascade 290
		write_char_xy(old_af_x, lastline, 0);
389 cascade 291
	}
292
 
293
	// clear nick
294
	if (old_af_y != nicky && old_af_y >= 0) {
390 cascade 295
		write_char_xy(center_x-1, old_af_y, 0);
296
		write_char_xy(center_x+1, old_af_y, 0);
389 cascade 297
	}
298
 
299
 
300
	// draw nick
390 cascade 301
	write_char_xy(center_x-1, nicky, noodle[cpos]);
302
	write_char_xy(center_x+1, nicky, noodle[cpos]);
389 cascade 303
 
304
	// draw roll
390 cascade 305
	write_char_xy(rollx, lastline, 229);
389 cascade 306
 
307
	// update old vars
308
	old_af_x = rollx;
309
	old_af_y = nicky;
310
}
311
 
312
#endif
753 cascade 313
 
314
#endif