Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1734 - 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.h"
45
#include "timer.h"
46
#include "servo.h"
47
#include "messages.h"
48
#include "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 "uart1.h"
60
#include "usart.h"
61
 
62
 
63
#define LIMIT_MIN_MAX(value, min, max) {if(value <= min) value = min; else if(value >= max) value = max;}
64
 
65
        int16_t Pos_Stick[12];  // 1,5mS 
66
        int16_t Pos_alt[5];  //
67
 
68
        uint8_t BalkenPos = 0;
69
        uint8_t Stick_Display = 0;
70
        uint8_t serialChannelRichtung = 0;
71
        uint8_t serialChannelConfig = 2;
72
 
73
 
74
//--------------------------------------------------------------
75
//
76
void joystick (void)
77
{
78
        // uint8_t chg = 0;
79
        // uint8_t Pos_Stick = 150;  // 1,5mS
80
        // uint8_t Pos_alt = 150;  // 
81
 
82
        //int16_t Pos_Stick[12];  // 1,5mS
83
 
84
        uint8_t chg = 0;
85
        //uint8_t BalkenPos = 0;
86
        uint8_t Stick_Nr = 0;
87
        //uint8_t Stick_Display = 0;
88
        uint8_t i = 0;
89
 
90
        memset (Pos_Stick, 150, 3); // füllt  3+1 Byte vom Pos_Stick[12] mit 150
91
 
92
        //int16_t Pos_alt[5];  // 
93
        int16_t Poti_Summe[5];  // 
94
        memset (Poti_Summe, 0, 5); // füllt  3+1 Byte mit 0
95
        int16_t Poti_Neutral[5];  // 
96
 
97
 
98
        // ADC- init
99
        Stick_Nr = 0;
100
        ADMUX = (1<<REFS0)|(0<<MUX0);  // Multiplexer selection Register: AVCC with external capacitor at AREF pin , ADC1
101
        ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[Stick_Nr] verwenden
102
 
103
        timer = 50;
104
        while (timer > 0);
105
 
106
        ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // ADC Enable, ADC Start, Prescaler 128
107
 
108
        // Stick-Neutralposition bestimmen
109
 
110
        while (ADCSRA & (1<<ADSC));  // wenn ADC fertig
111
 
112
                Poti_Neutral[Stick_Nr] = ((ADCW>>2)&0xff);
113
                LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],108,148);
114
                Stick_Nr = 2 ;
115
                ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
116
                        // Stick_Nr 1,2,3 = Potis, Stick_Nr 1= Lipo
117
                        ADCSRA |= (1<<ADSC); // ADC Start
118
 
119
        while (ADCSRA & (1<<ADSC));  // wenn ADC fertig
120
 
121
                        Poti_Neutral[Stick_Nr] = ((ADCW>>2)&0xff);
122
                        LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],108,148);
123
                        Stick_Nr = 0;
124
                        ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
125
                        // Stick_Nr 1,2,3 = Potis, Stick_Nr 1= Lipo
126
                        ADCSRA |= (1<<ADSC); // ADC Start
127
 
128
 
129
 
130
 
131
        //OCR1A = 150 * SERVO_CORRECT;  // Servomitte
132
 
133
        lcd_cls ();
134
 
135
        // Kopfzeile und Rahmen zeichnen
136
 
137
        lcd_printp (PSTR(" serielle Potis 1-5 "), 2);
138
        //lcd_printp_at (7, 5, PSTR("%"), 0);
139
        //lcd_printp_at (16, 5, PSTR("mS"), 0);
140
 
141
    lcd_puts_at(0, 7, strGet(KEYLINE3), 0);
142
        lcd_printp_at (18, 7, PSTR("\x19O\x18"), 0);
143
 
144
 
145
        for (i=0 ; i< 5 ; i++)
146
        {
147
        BalkenPos = 12 + (i*8) ;
148
 
149
        lcd_rect(3,BalkenPos, 120, 6, 1);                       // +-150% Rahmen
150
        lcd_line(23,BalkenPos,23,(BalkenPos+6),1);      // -100%
151
        lcd_line(43,BalkenPos,43,(BalkenPos+6),1);      // -50%
152
        lcd_frect(62,BalkenPos, 2, 6, 1);                       // 0%
153
        lcd_line(83,BalkenPos,83,(BalkenPos+6),1);      // +50%
154
        lcd_line(103,BalkenPos,103,(BalkenPos+6),1);    // +100%
155
        }
156
 
157
        // Reset auf Mittelstellung
158
        Pos_Stick[0] = 150;
159
        Poti_Summe[0] = 0;
160
        Pos_Stick[2] = 150;
161
        Poti_Summe[2] = 0;
162
        Pos_Stick[4] = 150;
163
        Poti_Summe[4] = 0;
164
 
165
        chg = 255;
166
 
167
        do
168
        {
169
                if (!(ADCSRA & (1<<ADSC)))  // wenn ADC fertig
170
                {
171
 
172
                        //Pos_Stick[Stick_Nr] = 150 + 128 - ((ADCW>>2)&0xff);
173
                        if (serialChannelRichtung & (1<<Stick_Nr))
174
                        Pos_Stick[Stick_Nr] = Poti_Neutral[Stick_Nr] - ((ADCW>>2)&0xff);
175
                        else
176
                        Pos_Stick[Stick_Nr] = ((ADCW>>2)&0xff) - Poti_Neutral[Stick_Nr];
177
 
178
                        LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],-120,120);
179
                        if ((Stick_Nr==0) || (Stick_Nr==2)) // nur die Potis 1,2 sind nicht neutralisierend
180
                        {
181
                        Poti_Summe[Stick_Nr] += (Pos_Stick[Stick_Nr]/8) * abs(Pos_Stick[Stick_Nr]/8);
182
                        LIMIT_MIN_MAX (Poti_Summe[Stick_Nr],-(120*128),(120*128));
183
                        Pos_Stick[Stick_Nr]= Poti_Summe[Stick_Nr] / 128; // nicht neutralisierend
184
                        }
185
                        Pos_Stick[Stick_Nr] += 150;
186
                        LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
187
                        if (Pos_Stick[Stick_Nr] != Pos_alt[Stick_Nr]) // nur bei Änderung
188
                        {
189
                         chg |= (1<<Stick_Nr) ;
190
                        //Pos_alt=Pos_Stick ; // verschoben
191
                        }
192
                        Stick_Nr ++ ;
193
                        //if (Stick_Nr==1) Stick_Nr=2; // Lipo überspringen
194
 
195
                        if (Stick_Nr==3) // Taster
196
                        {
197
                        // if (get_key_press (1 << KEY_EXT))  Pos_Stick[Stick_Nr] = 225;
198
                                if (serialChannelRichtung & (1<<Stick_Nr))
199
                                {
200
                                if (PINA & (1 << KEY_EXT))  Pos_Stick[Stick_Nr] = 30;
201
                                else Pos_Stick[Stick_Nr] = 270;
202
                                }
203
                                else
204
                                {
205
                                if (PINA & (1 << KEY_EXT))  Pos_Stick[Stick_Nr] = 270;
206
                                else Pos_Stick[Stick_Nr] = 30;
207
                                }
208
 
209
                                if (Pos_Stick[Stick_Nr] != Pos_alt[Stick_Nr])
210
                                {
211
                                chg |= (1<<Stick_Nr) ;
212
                                }
213
 
214
                         Stick_Nr=0;
215
                        }
216
 
217
                         /*
218
                         #ifndef ohne_Lipo // MartinR
219
                        Stick_Nr = 1; // MartinR AD-Kanal 1 überspringen wegen Lipo Überwachung
220
                        #endif
221
                        */
222
 
223
                        ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
224
                        // Stick_Nr 1,2,3 = Potis, Stick_Nr 0= Lipo
225
                        ADCSRA |= (1<<ADSC); // ADC Start
226
 
227
                        //serialPotis ();
228
 
229
                }
230
 
231
 
232
 
233
                if ((get_key_press (1 << KEY_PLUS) || get_key_long_rpt_sp ((1 << KEY_PLUS), 3)) && (Pos_Stick[4] < 271))
234
                {
235
                        Pos_Stick[4] ++ ;
236
                        //LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
237
                        chg |= (1<<4) ;
238
                }      
239
 
240
 
241
                else if ((get_key_press (1 << KEY_MINUS) || get_key_long_rpt_sp ((1 << KEY_MINUS), 3)) && (Pos_Stick[4] > 29))
242
                {
243
                        Pos_Stick[4] -- ;
244
                        //LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
245
                        chg |= (1<<4) ;
246
                }      
247
 
248
 
249
 
250
                else if (get_key_press (1 << KEY_ENTER))
251
                {
252
                /*
253
                 for (i=0 ; i< 4 ; i++)
254
                        {
255
                        BalkenPos = 12 + (i*8) ;
256
 
257
                        lcd_frect (4, (BalkenPos+1), 118, 4, 0);  // Balken löschen
258
                        lcd_frect(62, BalkenPos, 2, 6, 1);  // 0%
259
                        }
260
                */     
261
                        Pos_Stick[0] = 150;
262
                        Poti_Summe[0] = 0;
263
                        Pos_Stick[2] = 150;
264
                        Poti_Summe[2] = 0;
265
                        Pos_Stick[4] = 150;
266
                        Poti_Summe[4] = 0;
267
                        BeepTime = 200;
268
                        BeepMuster = 0x0080;
269
                        chg = 255;
270
                }
271
 
272
                if (chg)
273
                {
274
                        if (chg & (1<<0)); // Stick 1
275
                                {
276
                                BalkenPos = 12 + (0*8) ;
277
                                Stick_Display = 0;
278
                                Balken_Zeichnen () ;
279
 
280
                                Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
281
                                }
282
                        // Stick 2 = Lipo
283
                        if (chg & (1<<1)); // Stick 2
284
                                {
285
                                BalkenPos = 12 + (1*8) ;
286
                                Stick_Display = 1;
287
                                if (serialChannelConfig & (0<<1))  Balken_Zeichnen () ; // nur wenn keine Lipo-Spannung
288
 
289
                                Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
290
                                }
291
 
292
 
293
                        if (chg & (1<<2)); // Stick 3
294
                                {
295
                                BalkenPos = 12 + (2*8) ;
296
                                Stick_Display = 2;
297
                                Balken_Zeichnen () ;
298
 
299
                                Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
300
                                }
301
 
302
                        if (chg & (1<<3)); // Stick 4 = Taster
303
                                {
304
                                BalkenPos = 12 + (3*8) ;
305
                                Stick_Display = 3;
306
                                Balken_Zeichnen () ;
307
 
308
                                Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
309
                                }
310
 
311
                        if (chg & (1<<4)); // Stick 5 = Taster vom PKT
312
                                {
313
                                BalkenPos = 12 + (4*8) ;
314
                                Stick_Display = 4;
315
                                Balken_Zeichnen () ;
316
                                //OCR1A = (((Pos_Stick[Stick_Display]-150)/1.6)+150) * SERVO_CORRECT;  // Servostellung , 1.6=0.8*0.5
317
 
318
                                Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
319
                                }
320
 
321
                        chg = 0;
322
                        serialPotis ();
323
                }
324
        }
325
        while (!get_key_press (1 << KEY_ESC));
326
        get_key_press(KEY_ALL);
327
 
328
        #ifdef HWVERSION3_9 
329
        #ifndef ohne_Lipo // MartinR
330
        ADC_Init();             // ADC für Lipomessung wieder aktivieren
331
        #endif
332
        #endif
333
 
334
}
335
 
336
//--------------------------------------------------------------
337
//
338
void serialPotis (void)
339
{
340
        uint8_t i = 0;
341
 
342
        memset (buffer, 0, 12); // füllt die 12+1 Byte vom buffer mit 0
343
 
344
        for (i=0 ; i< 5 ; i++)
345
        {
346
        buffer[i] = Pos_Stick[i]-150 ;
347
        }
348
 
349
        SendOutData('y', ADDRESS_FC, 1, buffer, 12);
350
}
351
//--------------------------------------------------------------
352
//
353
void Balken_Zeichnen (void)
354
{
355
        // Balken löschen
356
 
357
                if ((Pos_Stick[Stick_Display] > Pos_alt[Stick_Display])&&(Pos_alt[Stick_Display] < 150)) // Balken links löschen
358
                lcd_frect ((63-((150 -Pos_alt[Stick_Display]) * 0.5)), (BalkenPos+1), (63-((150- Pos_Stick[Stick_Display]) * 0.5)), 4, 0);
359
                if ((Pos_Stick[Stick_Display] < Pos_alt[Stick_Display])&&(Pos_alt[Stick_Display] > 150)) // Balken rechts löschen
360
                lcd_frect ((63+((Pos_Stick[Stick_Display] - 150) * 0.5)), (BalkenPos+1), (63+((Pos_alt[Stick_Display] - 150) * 0.5)), 4, 0);
361
 
362
        // Balken zeichnen
363
                if (Pos_Stick[Stick_Display] >= 150)
364
                        {
365
                                lcd_frect (63, (BalkenPos+1), ((Pos_Stick[Stick_Display] - 150) * 0.5), 4, 1);
366
                                //write_ndigit_number_u (4, 5, ((Pos_Stick[Stick_Display] - 150) * 1.25), 3, 0, 0);  // Pulse width in %
367
                                lcd_frect(62, (BalkenPos), 2, 6, 1);  // 0%
368
                        }
369
                        else
370
                        {
371
                                lcd_frect (63 - ((150 - Pos_Stick[Stick_Display]) * 0.5), (BalkenPos+1), ((150 - Pos_Stick[Stick_Display]) * 0.5), 4, 1);
372
                                //write_ndigit_number_u (4, 5, ((150 - Pos_Stick[Stick_Display]) * 1.25), 3, 0, 0);  // Pulse width in %
373
                                lcd_frect(62, (BalkenPos), 2, 6, 1);  // 0%
374
                        }
375
        // Raster zeichnen              
376
                        lcd_line(3,  BalkenPos,3,  (BalkenPos+6),1);  // -150%
377
                        lcd_line(23, BalkenPos,23, (BalkenPos+6),1);  // -100%
378
                        lcd_line(43, BalkenPos,43, (BalkenPos+6),1);  // -50%
379
                        lcd_line(83, BalkenPos,83, (BalkenPos+6),1);  // +50%
380
                        lcd_line(103,BalkenPos,103,(BalkenPos+6),1);  // +100%
381
                        lcd_line(123,BalkenPos,123,(BalkenPos+6),1);  // +150%  
382
}
383