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
 *   based on the key handling by Peter Dannegger                            *
5
 *     see www.mikrocontroller.net                                           *
6
 *   Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
7
 *   Copyright (C) 2011 Harald Bongartz                                      *
8
 *                                                                           *
9
 *   This program is free software; you can redistribute it and/or modify    *
10
 *   it under the terms of the GNU General Public License as published by    *
11
 *   the Free Software Foundation; either version 2 of the License.          *
12
 *                                                                           *
13
 *   This program is distributed in the hope that it will be useful,         *
14
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
15
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
16
 *   GNU General Public License for more details.                            *
17
 *                                                                           *
18
 *   You should have received a copy of the GNU General Public License       *
19
 *   along with this program; if not, write to the                           *
20
 *   Free Software Foundation, Inc.,                                         *
21
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
22
 *                                                                           *
23
 *                                                                           *
24
 *   Credits to:                                                             *
25
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN  *
26
 *                          http://www.mikrokopter.de                        *
27
 *   Gregor "killagreg" Stobrawa for his version of the MK code              *
28
 *   Thomas Kaiser "thkais" for the original project. See                    *
29
 *                          http://www.ft-fanpage.de/mikrokopter/            *
30
 *                          http://forum.mikrokopter.de/topic-4061-1.html    *
31
 *   Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
32
 *                          http://www.mylifesucks.de/oss/c-osd/             *
33
 *   Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
34
 *****************************************************************************/
35
 
36
#include "cpu.h"
37
#include <avr/io.h>
38
#include <avr/interrupt.h>
39
#include <avr/pgmspace.h>
40
#include <string.h>
41
#include <util/delay.h>
42
#include <inttypes.h>
43
 
44
 
45
#include "main.h"
46
#include "timer.h"
47
#include "eeprom.h"
48
#include "lcd.h"
49
#include "uart1.h"
50
#include "bluetooth.h"
51
#include "setup.h"
52
 
53
 
54
#if defined HWVERSION1_2W || defined HWVERSION1_2
55
#include "HAL_HW1_2.h"
56
#endif
57
 
58
#if defined HWVERSION1_3W || defined HWVERSION1_3
59
#include "HAL_HW1_3.h"
60
#endif
61
 
62
#ifdef HWVERSION3_9
63
#include "HAL_HW3_9.h"
64
#endif
65
 
66
volatile uint16_t timer;
67
volatile uint16_t abo_timer;
68
volatile static unsigned int tim_main;
69
 
70
uint8_t key_state = 0;          // debounced and inverted key state:
71
                                                        // bit = 1: key pressed
72
uint8_t key_press = 0;          // key press detect
73
uint8_t key_long = 0;           // key long press
74
uint8_t key_rpt = 0;            // key repeat
75
uint8_t key_lrpt = 0;           // key long press and repeat
76
uint8_t key_rpts = 0;           // key long press and speed repeat
77
uint8_t repeat_speed = 0;
78
 
79
uint16_t DisplayTime = 0;       // Leuchtdauer
80
volatile uint16_t IdleTimer = 0;                // InaktivitätsTimer
81
 
82
uint16_t WarnCount = 0;         // Zähler der LIPO Warnzeit
83
uint16_t WarnToggle = 0;        // Togglezähler zum blinken
84
uint16_t WarnTime = 10;         // Länge der LIPO Warnzeit 10 Sek.
85
uint16_t PoffTime = 30;         // Länge der Wartezeit vor Abschalten 30 Sek.
86
//uint8_t       servo = 0;
87
 
88
 
89
 
90
volatile uint8_t Display_on;// Flag Display on/off
91
 
92
unsigned int BeepTime = 0;
93
unsigned int BeepMuster = 0xffff;
94
unsigned int BeepPrio = 0;
95
 
96
volatile unsigned int CountMilliseconds = 0;
97
 
98
// Size of Buffer for Converting unsigned int Value to ASCII
99
#define STRING_BUFFER_SIZE 5
100
 
101
// Buffer for Converting unsigned int Value to ASCII
102
char String_Buffer[STRING_BUFFER_SIZE];
103
 
104
 
105
//--------------------------------------------------------------
106
//
107
void Timer1_Init (void) // Timer 1-A
108
{
109
        // löschen
110
        TCCR1A = 0;
111
        TCCR1B = 0;
112
        TIMSK1 = 0;
113
 
114
        // setzen
115
        TCCR1A |=   (1 << COM1A1) | (1 << WGM11);
116
        TCCR1B |=   (1 << CS11)   | (1 << CS10)   | (1 << WGM13)  | (1 << WGM12);
117
 
118
        ICR1 = (F_CPU / 64) * 20 / 1000;
119
 
120
        OCR1A = 470;  // ca. Servomitte
121
}
122
 
123
 
124
//--------------------------------------------------------------
125
void Timer2_Init (void) // Displayhelligkeit
126
{
127
        DDRD   |= (1 << DDD7);                                                                          // PD7 output
128
        TCCR2A |= (1 << WGM21)  | (1 << WGM20)  | (1 << COM2A1);        // non invers
129
        TCCR2B |= (1 << CS20);                                                                          // Prescaler 1/1
130
        TIMSK2 |= (1 << OCIE2A) | (1 << OCIE2B);
131
 
132
        OCR2A = 255;
133
}
134
 
135
 
136
#if defined HWVERSION1_2 || defined HWVERSION1_2W
137
//--------------------------------------------------------------
138
ISR(TIMER2_COMPA_vect)
139
{
140
        PORTD &= ~(1 << PD7);
141
        PORTC &= ~(1 << PC0);
142
        PORTC &= ~(1 << PC1);
143
}
144
ISR(TIMER2_COMPB_vect)
145
{
146
        PORTD |= (1 << PD7);
147
        PORTC |= (1 << PC0);
148
        PORTC |= (1 << PC1);
149
}
150
#endif
151
#if defined HWVERSION1_3 || defined HWVERSION1_3W
152
//--------------------------------------------------------------
153
ISR(TIMER2_COMPA_vect)
154
{
155
        PORTD &= ~(1 << PD7);
156
        PORTD &= ~(1 << PD6);
157
        PORTC &= ~(1 << PC2);
158
}
159
ISR(TIMER2_COMPB_vect)
160
{
161
        PORTD |= (1 << PD7);
162
        PORTD |= (1 << PD6);
163
        PORTC |= (1 << PC2);
164
}
165
#endif
166
#ifdef HWVERSION3_9
167
//--------------------------------------------------------------
168
ISR(TIMER2_COMPA_vect)
169
{
170
        PORTD |= (1 << PIND7); // MartinR: von PD auf PIND geändert
171
}
172
ISR(TIMER2_COMPB_vect)
173
{
174
        PORTD &= ~(1 << PIND7); // MartinR: von PD auf PIND geändert
175
}
176
#endif
177
 
178
 
179
//--------------------------------------------------------------
180
void Timer0_Init (void)  // System (100Hz)
181
{
182
        timer = 0;
183
 
184
        TCCR0A = (1 << WGM01);
185
        TCCR0B = (1 << CS02) | (1 << CS00);
186
        OCR0A = (F_CPU / (100L * 1024L)) ;
187
 
188
        TIMSK0 |= (1 << OCIE0A);        // enable interrupt for OCR
189
}
190
 
191
 
192
//--------------------------------------------------------------
193
ISR(TIMER0_COMPA_vect)  // Timer-Interrupt (100 Hz)
194
{
195
        static uint8_t ct0 = 0;
196
        static uint8_t ct1 = 0;
197
        static uint8_t k_time_l = 0;
198
        static uint8_t k_time_r = 0;
199
        static uint8_t k_time_lr = 0;
200
        static uint8_t k_time_rs = 0;
201
        uint8_t i;
202
 
203
        static unsigned char cnt_1ms = 1,cnt = 0;
204
        unsigned char beeper_ein = 0;
205
//      unsigned char pieper_ein = 0;
206
 
207
        // Key handling by Peter Dannegger
208
        // see www.mikrocontroller.net
209
 
210
        i = key_state ^ ~KEY_PIN;               // key changed ?
211
        ct0 = ~(ct0 & i);                               // reset or count ct0
212
        ct1 = ct0 ^ (ct1 & i);                  // reset or count ct1
213
        i &= (ct0 & ct1);                               // count until roll over ?
214
        key_state ^= i;                                 // then toggle debounced state
215
        key_press |= (key_state & i);   // 0->1: key press detect
216
 
217
        if (PKT_IdleBeep == 1)
218
        {
219
                IdleTimer ++;                                   // nix zu tun? Timer hochzählen
220
                if (IdleTimer == 12000)                 // Warnhinweis
221
                {
222
                        set_beep ( 200, 0x0080, BeepNormal);
223
                        IdleTimer = 0;
224
                }
225
        }
226
 
227
        if (!cnt--)
228
        {
229
                cnt = 9;
230
                CountMilliseconds++;
231
                cnt_1ms++;
232
        }
233
 
234
        if (i!=0)
235
        {                                               // Displaylicht einschalten, und bzw. Timeoutzählerreset wenn Taste gedrückt wurde
236
                if (Display_on == 0)
237
                  set_D_LIGHT();
238
 
239
 
240
                Display_on = 1;         // Flag Display on
241
                DisplayTime = 0;        // Timer Reset
242
                IdleTimer = 0;          // Idletimeout Reset
243
 
244
        }
245
 
246
        if (DisplayTimeout > 0)
247
        {
248
                if (Display_on == 1)
249
                {
250
                        DisplayTime++;
251
                        if ((DisplayTime / 100) == DisplayTimeout)      // ISR läuft mit 100Hz
252
                        {                                                                                       // Displaylicht ausschalten
253
                            clr_D_LIGHT();
254
                            Display_on = 0;                                                     // Flag Display off
255
 
256
                        }
257
                }
258
        }
259
 
260
//--------------------------------------------------------------
261
#ifdef HWVERSION3_9
262
        if (ADCSRA & ADIE) LipoCheck(); // Lipo prüfen // MartinR nicht wenn Stick aktiv
263
        //LipoCheck();  // Lipo prüfen // MartinR: soe war es
264
#endif
265
 
266
//--------------------------------------------------------------
267
        if (BeepTime)
268
        {
269
                if (BeepTime > 10)
270
                        BeepTime -= 10;
271
                else
272
                  {
273
                        BeepTime = 0;
274
 
275
                  }
276
 
277
                if (BeepTime & BeepMuster)
278
                        beeper_ein = 1;
279
                else    beeper_ein = 0;
280
 
281
 
282
        }
283
        else
284
        {
285
                beeper_ein = 0;
286
                BeepMuster = 0xffff;
287
                BeepPrio = BeepNormal;
288
        }
289
 
290
        if (beeper_ein==1)
291
                set_BEEP();
292
        else
293
                clr_BEEP();
294
 
295
 
296
//--------------------------------------------------------------
297
        if ((key_state & LONG_MASK) == 0)                       // check long key function
298
                k_time_l = REPEAT_START;                                // start delay
299
 
300
        if (--k_time_l == 0)                                            // long countdown
301
                key_long |= (key_state & LONG_MASK);
302
 
303
//--------------------------------------------------------------
304
        if ((key_state & REPEAT_MASK) == 0)                     // check repeat function
305
                k_time_r = 1;                                                   // kein delay
306
 
307
        if (--k_time_r == 0)
308
        {
309
                k_time_r = REPEAT_NEXT;                                 // repeat delay
310
                key_rpt |= (key_state & REPEAT_MASK);
311
        }
312
 
313
//--------------------------------------------------------------
314
        if ((key_state & LONG_REPEAT_MASK) == 0)        // check repeat function
315
                k_time_lr = REPEAT_START;                               // start delay
316
 
317
        if (--k_time_lr == 0)
318
        {
319
                k_time_lr = REPEAT_NEXT;                                // repeat delay
320
                key_lrpt |= (key_state & LONG_REPEAT_MASK);
321
        }
322
 
323
//--------------------------------------------------------------
324
        if ((key_state & LONG_REPEAT_SP_MASK) == 0)     // check repeatX function
325
                k_time_rs = REPEAT_START;                               // start delay
326
 
327
        if (--k_time_rs == 0)                                           // repeat countdown
328
        {
329
                if (repeat_speed == 1)
330
                {
331
                        k_time_rs = REPEAT_SPEED_1;
332
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
333
                }
334
                else if (repeat_speed == 2)
335
                {
336
                        k_time_rs = REPEAT_SPEED_2;
337
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
338
                }
339
                else if (repeat_speed == 3)
340
                {
341
                        k_time_rs = REPEAT_SPEED_3;
342
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
343
                }
344
        }
345
 
346
        if (timer > 0)
347
                timer --;
348
 
349
        if (abo_timer > 0)
350
                abo_timer --;
351
 
352
//      if (receiveNMEA==true)
353
//        {
354
//          if (bt_receiveNMEA()) Tracking_NMEA();
355
//
356
//        }
357
 
358
 
359
}
360
 
361
 
362
//--------------------------------------------------------------
363
#ifdef HWVERSION3_9
364
 
365
void LipoCheck (void)   // Lowbatpin des Spannungswandlers prüfen
366
                        // LBO des LT1308 wechselt zum Ende der Batterielaufzeit häufig seinen Zustand in der Ãœbergangsphase zum LowBat
367
                        // Die Akkuspannung schwankt auch abhängig vom momentanen Stromverbrauch
368
{
369
        if (WarnToggle == 1)    // Beim ersten Auftreten Warnung ausgeben, Rythmus 5/10 Sekunden
370
        {
371
 
372
                set_beep ( 1000, 0x0020, BeepNormal);
373
                lcd_printp_at (0, 0, PSTR("  LIPO  !!Warnung!!  "), 2);
374
        }
375
 
376
        if (WarnToggle == WarnTime * 100)
377
                WarnToggle = 0;  // erstmal bis hier warnen
378
 
379
        if (WarnToggle > 0)
380
                WarnToggle++;  // weiter hochzählen
381
 
382
        if (PINC & (1 << LowBat))       // Kurzzeitige Unterspannung bearbeiten und Warnung ausgeben
383
        {
384
                WarnCount = 0;
385
//              if (WarnCount > 0)
386
//                      WarnCount--;  // Bei LIPO OK erstmal runterzählen, LT1308 überlegt sich noch genauer ob nun ok oder nicht
387
        }
388
 
389
        if (!(PINC & (1 << LowBat)) )  // LT1308 hat Unterspannung erkannt
390
        {
391
                WarnCount++;  // solange LBO low ist Zähler hochzählen
392
                if (WarnCount == 10 && WarnToggle == 0)  // mit "10" etwas unempfindlicher gegen kurze Impulse machen
393
                        WarnToggle = 1;  // Warnhinweis starten
394
        }
395
 
396
        if ((WarnCount) == PoffTime * 100)
397
                clr_V_On();  // Spannung abschalten
398
}
399
 
400
#endif
401
 
402
 
403
//--------------------------------------------------------------
404
unsigned int SetDelay (unsigned int t)
405
{
406
        return(CountMilliseconds + t + 1);
407
}
408
 
409
 
410
//--------------------------------------------------------------
411
char CheckDelay(unsigned int t)
412
{
413
        return(((t - CountMilliseconds) & 0x8000) >> 9);
414
}
415
 
416
 
417
//--------------------------------------------------------------
418
void Delay_ms(unsigned int w)
419
{
420
        unsigned int akt;
421
        akt = SetDelay(w);
422
        while (!CheckDelay(akt));
423
}
424
 
425
 
426
//--------------------------------------------------------------
427
//
428
uint8_t get_key_press (uint8_t key_mask)
429
{
430
        uint8_t sreg = SREG;
431
 
432
        // disable all interrupts
433
        cli();
434
 
435
        key_mask &= key_press;  // read key(s)
436
        key_press ^= key_mask;  // clear key(s)
437
 
438
        SREG = sreg;    // restore status register
439
 
440
        return key_mask;
441
}
442
 
443
 
444
//--------------------------------------------------------------
445
//
446
uint8_t get_key_short (uint8_t key_mask)
447
{
448
        uint8_t ret;
449
        uint8_t sreg = SREG;
450
 
451
        // disable all interrupts
452
        cli();
453
 
454
        ret = get_key_press (~key_state & key_mask);
455
 
456
        SREG = sreg;    // restore status register
457
 
458
        return ret;
459
}
460
 
461
 
462
//--------------------------------------------------------------
463
//
464
uint8_t get_key_long (uint8_t key_mask)
465
{
466
        uint8_t sreg = SREG;
467
 
468
        // disable all interrupts
469
        cli();
470
 
471
        key_mask &= key_long;   // read key(s)
472
        key_long ^= key_mask;   // clear key(s)
473
 
474
        SREG = sreg;    // restore status register
475
 
476
  return get_key_press (get_key_rpt (key_mask));
477
}
478
 
479
 
480
//--------------------------------------------------------------
481
//
482
uint8_t get_key_rpt (uint8_t key_mask)
483
{
484
        uint8_t sreg = SREG;
485
 
486
        // disable all interrupts
487
        cli();
488
 
489
        key_mask &= key_rpt;    // read key(s)
490
        key_rpt ^= key_mask;    // clear key(s)
491
 
492
        SREG = sreg;    // restore status register
493
 
494
        return key_mask;
495
}
496
 
497
 
498
//--------------------------------------------------------------
499
//
500
uint8_t get_key_long_rpt (uint8_t key_mask)
501
{
502
        uint8_t sreg = SREG;
503
 
504
        // disable all interrupts
505
        cli();
506
 
507
        key_mask &= key_lrpt;   // read key(s)
508
        key_lrpt ^= key_mask;   // clear key(s)
509
 
510
        SREG = sreg;    // restore status register
511
 
512
        return get_key_rpt (~key_press^key_mask);
513
}
514
 
515
 
516
//--------------------------------------------------------------
517
//
518
uint8_t get_key_long_rpt_sp (uint8_t key_mask, uint8_t key_speed)
519
{
520
        uint8_t sreg = SREG;
521
 
522
        // disable all interrupts
523
        cli();
524
 
525
        key_mask &= key_rpts;   // read key(s)
526
        key_rpts ^= key_mask;   // clear key(s)
527
 
528
        repeat_speed = key_speed;
529
 
530
        SREG = sreg;    // restore status register
531
 
532
        return key_mask;
533
}
534
 
535
void set_beep ( uint16_t Time, uint16_t Muster, uint8_t Prio)
536
{
537
 
538
  if (Prio == BeepNormal)
539
    {
540
      if (BeepPrio == BeepNormal)        // nur setzen wenn keine hohe Prio schon aktiv ist
541
        {
542
        BeepTime = Time;
543
        BeepMuster = Muster;
544
        }
545
    }
546
 
547
  if (Prio == BeepSevere)
548
    {
549
      if (!BeepPrio == BeepSevere)
550
        {
551
          BeepPrio = BeepSevere;             // hohe Prio setzen
552
          BeepTime = Time;
553
          BeepMuster = Muster;
554
        }
555
    }
556
 
557
  if (Prio == BeepOff)
558
    {
559
      BeepPrio = BeepNormal;             // Beep hohe Prio aus
560
      BeepTime = 0;
561
      BeepMuster = 0;
562
    }
563
 
564
 
565
}
566
 
567