Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1932 - 1
/*****************************************************************************
2
 *   Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de                  *
3
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
4
 *   Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
5
 *   Copyright (C) 2011 Harald Bongartz                                      *
6
 *   Copyright (C) 2012 Martin Runkel                                        *
7
 *                                                                           *
8
 *   This program is free software; you can redistribute it and/or modify    *
9
 *   it under the terms of the GNU General Public License as published by    *
10
 *   the Free Software Foundation; either version 2 of the License.          *
11
 *                                                                           *
12
 *   This program is distributed in the hope that it will be useful,         *
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
15
 *   GNU General Public License for more details.                            *
16
 *                                                                           *
17
 *   You should have received a copy of the GNU General Public License       *
18
 *   along with this program; if not, write to the                           *
19
 *   Free Software Foundation, Inc.,                                         *
20
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
21
 *                                                                           *
22
 *                                                                           *
23
 *   Credits to:                                                             *
24
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN  *
25
 *                          http://www.mikrokopter.de                        *
26
 *   Gregor "killagreg" Stobrawa for his version of the MK code              *
27
 *   Thomas Kaiser "thkais" for the original project. See                    *
28
 *                          http://www.ft-fanpage.de/mikrokopter/            *
29
 *                          http://forum.mikrokopter.de/topic-4061-1.html    *
30
 *   Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
31
 *                          http://www.mylifesucks.de/oss/c-osd/             *
32
 *   Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
33
 *****************************************************************************/
34
 
35
 
36
#include "../cpu.h"
37
#include <avr/io.h>
38
#include <avr/interrupt.h>
39
#include <avr/pgmspace.h>
40
 
41
#include <string.h>
42
#include <stdlib.h>
43
 
44
#include "../lcd/lcd.h"
45
#include "../timer/timer.h"
46
#include "../tracking/servo.h"
47
#include "../messages.h"
48
#include "../lipo/lipo.h"
49
#include "stick.h"
50
 
51
#define SERVO_CORRECT 3.125
52
 
53
 
54
#include <util/delay.h>
55
#include <inttypes.h>
56
#include <stdlib.h>
57
 
58
#include "../main.h"
59
#include "../uart/uart1.h"
60
#include "../uart/usart.h"
61
#include "../eeprom/eeprom.h"
62
 
63
 
64
#define LIMIT_MIN_MAX(value, min, max) {if(value <= min) value = min; else if(value >= max) value = max;}
65
 
66
	int16_t Pos_Stick[12];  // 1,5mS
67
	int16_t Pos_alt[5];  //
68
 
69
	uint8_t BalkenPos = 0;
70
	uint8_t Stick_Display = 0;
71
	uint8_t serialChannelRichtung = 0;
72
	uint8_t serialChannelConfig = 2;
73
 
74
 
75
//--------------------------------------------------------------
76
//
77
void joystick (void)
78
{
79
	// uint8_t chg = 0;
80
	// uint8_t Pos_Stick = 150;  // 1,5mS
81
	// uint8_t Pos_alt = 150;  //
82
 
83
	//int16_t Pos_Stick[12];  // 1,5mS
84
 
85
	uint8_t chg = 0;
86
	//uint8_t BalkenPos = 0;
87
	uint8_t Stick_Nr = 0;
88
	//uint8_t Stick_Display = 0;
89
	uint8_t i = 0;
90
 
91
	memset (Pos_Stick, 150, 3); // füllt  3+1 Byte vom Pos_Stick[12] mit 150
92
 
93
	//int16_t Pos_alt[5];  //
94
	int16_t Poti_Summe[5];  //
95
	memset (Poti_Summe, 0, 5); // füllt  3+1 Byte mit 0
96
	int16_t Poti_Neutral[5];  //
97
 
98
 
99
	// ADC- init
100
	Stick_Nr = 0;
101
	ADMUX = (1<<REFS0)|(0<<MUX0);  // Multiplexer selection Register: AVCC with external capacitor at AREF pin , ADC1
102
	ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[Stick_Nr] verwenden
103
 
104
	timer = 50;
105
	while (timer > 0);
106
 
107
	ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // ADC Enable, ADC Start, Prescaler 128
108
 
109
	// Stick-Neutralposition bestimmen
110
 
111
	while (ADCSRA & (1<<ADSC));  // wenn ADC fertig
112
 
113
		Poti_Neutral[Stick_Nr] = ((ADCW>>2)&0xff);
114
//CB		LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],108,148);
115
                LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],stick_min[Stick_Nr],stick_max[Stick_Nr]);
116
		Stick_Nr = 2 ;
117
		ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
118
			// Stick_Nr 1,2,3 = Potis, Stick_Nr 1= Lipo
119
			ADCSRA |= (1<<ADSC); // ADC Start
120
 
121
	while (ADCSRA & (1<<ADSC));  // wenn ADC fertig
122
 
123
			Poti_Neutral[Stick_Nr] = ((ADCW>>2)&0xff);
124
//CB			LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],108,148);
125
                        LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],stick_min[Stick_Nr],stick_max[Stick_Nr]);
126
			Stick_Nr = 0;
127
			ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
128
			// Stick_Nr 1,2,3 = Potis, Stick_Nr 1= Lipo
129
			ADCSRA |= (1<<ADSC); // ADC Start
130
 
131
 
132
 
133
 
134
	//OCR1A = 150 * SERVO_CORRECT;  // Servomitte
135
 
136
	lcd_cls ();
137
 
138
	// Kopfzeile und Rahmen zeichnen
139
 
140
	lcd_printp (PSTR(" serielle Potis 1-5 "), 2);
141
	//lcd_printp_at (7, 5, PSTR("%"), 0);
142
	//lcd_printp_at (16, 5, PSTR("mS"), 0);
143
 
144
    lcd_puts_at(0, 7, strGet(KEYLINE3), 0);
145
	lcd_printp_at (18, 7, PSTR("\x19O\x18"), 0);
146
 
147
 
148
	for (i=0 ; i< 5 ; i++)
149
	{
150
	BalkenPos = 12 + (i*8) ;
151
 
152
	lcd_rect(3,BalkenPos, 120, 6, 1);  			// +-150% Rahmen
153
	lcd_line(23,BalkenPos,23,(BalkenPos+6),1);  	// -100%
154
	lcd_line(43,BalkenPos,43,(BalkenPos+6),1);  	// -50%
155
	lcd_frect(62,BalkenPos, 2, 6, 1);  			// 0%
156
	lcd_line(83,BalkenPos,83,(BalkenPos+6),1);  	// +50%
157
	lcd_line(103,BalkenPos,103,(BalkenPos+6),1);  	// +100%
158
	}
159
 
160
	// Reset auf Mittelstellung
161
	Pos_Stick[0] = 150;
162
	Poti_Summe[0] = 0;
163
	Pos_Stick[2] = 150;
164
	Poti_Summe[2] = 0;
165
	Pos_Stick[4] = 150;
166
	Poti_Summe[4] = 0;
167
 
168
	chg = 255;
169
 
170
	do
171
	{
172
		if (!(ADCSRA & (1<<ADSC)))  // wenn ADC fertig
173
		{
174
 
175
			//Pos_Stick[Stick_Nr] = 150 + 128 - ((ADCW>>2)&0xff);
176
//CB                        if (serialChannelRichtung & (1<<Stick_Nr))
177
			if (stick_dir[Stick_Nr] & (1<<Stick_Nr))
178
			Pos_Stick[Stick_Nr] = Poti_Neutral[Stick_Nr] - ((ADCW>>2)&0xff);
179
			else
180
			Pos_Stick[Stick_Nr] = ((ADCW>>2)&0xff) - Poti_Neutral[Stick_Nr];
181
 
182
//			LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],-120,120);
183
			LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],stick_min[Stick_Nr],stick_max[Stick_Nr]);
184
 
185
			if ((Stick_Nr==0) || (Stick_Nr==2)) // nur die Potis 1,2 sind nicht neutralisierend
186
                          {
187
                            Poti_Summe[Stick_Nr] += (Pos_Stick[Stick_Nr]/8) * abs(Pos_Stick[Stick_Nr]/8);
188
                            LIMIT_MIN_MAX (Poti_Summe[Stick_Nr],-(120*128),(120*128));
189
                            Pos_Stick[Stick_Nr]= Poti_Summe[Stick_Nr] / 128; // nicht neutralisierend
190
                          }
191
			Pos_Stick[Stick_Nr] += 150;
192
//			LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
193
			LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],stick_min[Stick_Nr],stick_max[Stick_Nr]); // war 75 , 225
194
			if (Pos_Stick[Stick_Nr] != Pos_alt[Stick_Nr]) // nur bei Änderung
195
                          {
196
                           chg |= (1<<Stick_Nr) ;
197
                          //Pos_alt=Pos_Stick ; // verschoben
198
                          }
199
			Stick_Nr ++ ;
200
			//if (Stick_Nr==1) Stick_Nr=2; // Lipo überspringen
201
 
202
//CB			if (Stick_Nr==3) // Taster
203
			if (stick_typ[Stick_Nr]==1) // Taster
204
			{
205
			// if (get_key_press (1 << KEY_EXT))  Pos_Stick[Stick_Nr] = 225;
206
//CB				if (serialChannelRichtung & (1<<Stick_Nr))
207
	                        if (stick_dir[Stick_Nr] & (1<<Stick_Nr))
208
				{
209
                                  if (PINA & (1 << KEY_EXT))  Pos_Stick[Stick_Nr] = 30;
210
                                  else Pos_Stick[Stick_Nr] = 270;
211
				}
212
				else
213
				{
214
                                  if (PINA & (1 << KEY_EXT))  Pos_Stick[Stick_Nr] = 270;
215
                                  else Pos_Stick[Stick_Nr] = 30;
216
				}
217
 
218
				if (Pos_Stick[Stick_Nr] != Pos_alt[Stick_Nr])
219
				{
220
				chg |= (1<<Stick_Nr) ;
221
				}
222
 
223
			 Stick_Nr=0;
224
			}
225
 
226
			 /*
227
			 #ifndef ohne_Lipo // MartinR
228
			Stick_Nr = 1; // MartinR AD-Kanal 1 überspringen wegen Lipo Überwachung
229
			#endif
230
			*/
231
 
232
			ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
233
			// Stick_Nr 1,2,3 = Potis, Stick_Nr 0= Lipo
234
			ADCSRA |= (1<<ADSC); // ADC Start
235
 
236
			//serialPotis ();
237
 
238
		}
239
 
240
 
241
 
242
		if ((get_key_press (1 << KEY_PLUS) || get_key_long_rpt_sp ((1 << KEY_PLUS), 3)) && (Pos_Stick[4] < 271))
243
		{
244
			Pos_Stick[4] ++ ;
245
			//LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
246
			chg |= (1<<4) ;
247
		}
248
 
249
 
250
		else if ((get_key_press (1 << KEY_MINUS) || get_key_long_rpt_sp ((1 << KEY_MINUS), 3)) && (Pos_Stick[4] > 29))
251
		{
252
			Pos_Stick[4] -- ;
253
			//LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
254
			chg |= (1<<4) ;
255
		}
256
 
257
 
258
 
259
		else if (get_key_press (1 << KEY_ENTER))
260
		{
261
		/*
262
		 for (i=0 ; i< 4 ; i++)
263
			{
264
			BalkenPos = 12 + (i*8) ;
265
 
266
			lcd_frect (4, (BalkenPos+1), 118, 4, 0);  // Balken löschen
267
			lcd_frect(62, BalkenPos, 2, 6, 1);  // 0%
268
			}
269
		*/
270
			Pos_Stick[0] = 150;
271
			Poti_Summe[0] = 0;
272
			Pos_Stick[2] = 150;
273
			Poti_Summe[2] = 0;
274
			Pos_Stick[4] = 150;
275
			Poti_Summe[4] = 0;
276
			BeepTime = 200;
277
			BeepMuster = 0x0080;
278
			chg = 255;
279
		}
280
 
281
		if (chg)
282
		{
283
			if (chg & (1<<0)); // Stick 1
284
				{
285
				BalkenPos = 12 + (0*8) ;
286
				Stick_Display = 0;
287
				Balken_Zeichnen () ;
288
 
289
				Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
290
				}
291
			// Stick 2 = Lipo
292
			if (chg & (1<<1)); // Stick 2
293
				{
294
				BalkenPos = 12 + (1*8) ;
295
				Stick_Display = 1;
296
				if (serialChannelConfig & (0<<1))  Balken_Zeichnen () ; // nur wenn keine Lipo-Spannung
297
 
298
				Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
299
				}
300
 
301
 
302
			if (chg & (1<<2)); // Stick 3
303
				{
304
				BalkenPos = 12 + (2*8) ;
305
				Stick_Display = 2;
306
				Balken_Zeichnen () ;
307
 
308
				Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
309
				}
310
 
311
			if (chg & (1<<3)); // Stick 4 = Taster
312
				{
313
				BalkenPos = 12 + (3*8) ;
314
				Stick_Display = 3;
315
				Balken_Zeichnen () ;
316
 
317
				Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
318
				}
319
 
320
			if (chg & (1<<4)); // Stick 5 = Taster vom PKT
321
				{
322
				BalkenPos = 12 + (4*8) ;
323
				Stick_Display = 4;
324
				Balken_Zeichnen () ;
325
				//OCR1A = (((Pos_Stick[Stick_Display]-150)/1.6)+150) * SERVO_CORRECT;  // Servostellung , 1.6=0.8*0.5
326
 
327
				Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
328
				}
329
 
330
			chg = 0;
331
			serialPotis ();
332
		}
333
	}
334
	while (!get_key_press (1 << KEY_ESC));
335
	get_key_press(KEY_ALL);
336
 
337
	#ifdef HWVERSION3_9
338
	#ifndef ohne_Lipo // MartinR
339
        ADC_Init();             // ADC für Lipomessung wieder aktivieren
340
	#endif
341
	#endif
342
 
343
}
344
 
345
//--------------------------------------------------------------
346
//
347
void serialPotis (void)
348
{
349
	uint8_t i = 0;
350
 
351
	memset (buffer, 0, 12); // füllt die 12+1 Byte vom buffer mit 0
352
 
353
	for (i=0 ; i< 5 ; i++)
354
	{
355
	buffer[i] = Pos_Stick[i]-150 ;
356
	}
357
 
358
	SendOutData('y', ADDRESS_FC, 1, buffer, 12);
359
}
360
//--------------------------------------------------------------
361
//
362
void Balken_Zeichnen (void)
363
{
364
	// Balken löschen
365
 
366
		if ((Pos_Stick[Stick_Display] > Pos_alt[Stick_Display])&&(Pos_alt[Stick_Display] < 150)) // Balken links löschen
367
		lcd_frect ((63-((150 -Pos_alt[Stick_Display]) * 0.5)), (BalkenPos+1), (63-((150- Pos_Stick[Stick_Display]) * 0.5)), 4, 0);
368
		if ((Pos_Stick[Stick_Display] < Pos_alt[Stick_Display])&&(Pos_alt[Stick_Display] > 150)) // Balken rechts löschen
369
		lcd_frect ((63+((Pos_Stick[Stick_Display] - 150) * 0.5)), (BalkenPos+1), (63+((Pos_alt[Stick_Display] - 150) * 0.5)), 4, 0);
370
 
371
	// Balken zeichnen
372
		if (Pos_Stick[Stick_Display] >= 150)
373
			{
374
				lcd_frect (63, (BalkenPos+1), ((Pos_Stick[Stick_Display] - 150) * 0.5), 4, 1);
375
				//write_ndigit_number_u (4, 5, ((Pos_Stick[Stick_Display] - 150) * 1.25), 3, 0, 0);  // Pulse width in %
376
				lcd_frect(62, (BalkenPos), 2, 6, 1);  // 0%
377
			}
378
			else
379
			{
380
				lcd_frect (63 - ((150 - Pos_Stick[Stick_Display]) * 0.5), (BalkenPos+1), ((150 - Pos_Stick[Stick_Display]) * 0.5), 4, 1);
381
				//write_ndigit_number_u (4, 5, ((150 - Pos_Stick[Stick_Display]) * 1.25), 3, 0, 0);  // Pulse width in %
382
				lcd_frect(62, (BalkenPos), 2, 6, 1);  // 0%
383
			}
384
	// Raster zeichnen
385
			lcd_line(3,  BalkenPos,3,  (BalkenPos+6),1);  // -150%
386
			lcd_line(23, BalkenPos,23, (BalkenPos+6),1);  // -100%
387
			lcd_line(43, BalkenPos,43, (BalkenPos+6),1);  // -50%
388
			lcd_line(83, BalkenPos,83, (BalkenPos+6),1);  // +50%
389
			lcd_line(103,BalkenPos,103,(BalkenPos+6),1);  // +100%
390
			lcd_line(123,BalkenPos,123,(BalkenPos+6),1);  // +150%
391
}
392