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
 *   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
//############################################################################
37
//# HISTORY  timer.c
38
//#
39
//# 09.03.2013 OG
40
//# - add: timer2 (auch in timer.h)
41
//############################################################################
42
 
43
 
44
#include "../cpu.h"
45
#include <avr/io.h>
46
#include <avr/interrupt.h>
47
#include <avr/pgmspace.h>
48
#include <string.h>
49
#include <util/delay.h>
50
#include <inttypes.h>
51
 
52
 
53
#include "../main.h"
54
#include "../timer/timer.h"
55
#include "../eeprom/eeprom.h"
56
#include "../lcd/lcd.h"
57
#include "../uart/uart1.h"
58
#include "../bluetooth/bluetooth.h"
59
#include "../setup/setup.h"
60
#include"../tracking/tracking.h"
61
#include "../sound/pwmsine8bit.h"
62
 
63
 
64
#if defined HWVERSION1_2W || defined HWVERSION1_2
65
#include "HAL_HW1_2.h"
66
#endif
67
 
68
#if defined HWVERSION1_3W || defined HWVERSION1_3
69
#include "HAL_HW1_3.h"
70
#endif
71
 
72
#ifdef HWVERSION3_9
73
#include "../HAL_HW3_9.h"
74
#endif
75
 
76
volatile uint16_t timer;
77
volatile uint16_t timer2;
78
volatile uint16_t abo_timer;
79
volatile uint16_t sound_timer;
80
volatile uint16_t soundpause_timer;
81
volatile static unsigned int tim_main;
82
 
83
uint8_t key_state = 0;          // debounced and inverted key state:
84
                                                        // bit = 1: key pressed
85
uint8_t key_press = 0;          // key press detect
86
uint8_t key_long = 0;           // key long press
87
uint8_t key_rpt = 0;            // key repeat
88
uint8_t key_lrpt = 0;           // key long press and repeat
89
uint8_t key_rpts = 0;           // key long press and speed repeat
90
uint8_t repeat_speed = 0;
91
 
92
uint16_t DisplayTime = 0;       // Leuchtdauer
93
volatile uint16_t IdleTimer = 0;                // InaktivitÀtsTimer
94
 
95
 
96
//uint8_t       servo = 0;
97
volatile uint16_t WarnCount = 0;         // Zähler der LIPO Warnzeit
98
volatile uint16_t WarnToggle = 0;        // Togglezähler zum blinken
99
volatile uint16_t WarnTime = 10;         // Länge der LIPO Warnzeit 10 Sek.
100
volatile uint16_t PoffTime = 30;         // Länge der Wartezeit vor Abschalten 30 Sek.
101
 
102
 
103
volatile uint8_t Display_on;// Flag Display on/off
104
 
105
unsigned int BeepTime = 0;
106
unsigned int BeepMuster = 0xffff;
107
unsigned int BeepPrio = 0;
108
 
109
volatile unsigned int CountMilliseconds = 0;
110
 
111
// Size of Buffer for Converting unsigned int Value to ASCII
112
#define STRING_BUFFER_SIZE 5
113
 
114
// Buffer for Converting unsigned int Value to ASCII
115
char String_Buffer[STRING_BUFFER_SIZE];
116
 
117
 
118
//--------------------------------------------------------------
119
//
120
void Timer0_Init (void)  // System (100Hz)
121
{
122
        timer = 0;
123
 
124
        TCCR0A = (1 << WGM01);
125
        TCCR0B = (1 << CS02) | (1 << CS00);
126
        OCR0A = (F_CPU / (100L * 1024L)) ;
127
 
128
        TIMSK0 |= (1 << OCIE0A);        // enable interrupt for OCR
129
}
130
//--------------------------------------------------------------
131
//
132
//void Timer1_Init (void) // Timer 1-A
133
//{
134
//      // löschen
135
//      TCCR1A = 0;
136
//      TCCR1B = 0;
137
//      TIMSK1 = 0;
138
//
139
//      // setzen
140
//      TCCR1A |=   (1 << COM1A1) | (1 << WGM11);
141
//      TCCR1B |=   (1 << CS11)   | (1 << CS10)   | (1 << WGM13)  | (1 << WGM12);
142
//
143
//      ICR1 = (F_CPU / 64) * 20 / 1000;
144
//
145
//      OCR1A = 470;  // ca. Servomitte
146
//}
147
 
148
 
149
 
150
 
151
//--------------------------------------------------------------
152
ISR(TIMER2_COMPA_vect)
153
{
154
        PORTD |= (1 << PD7);
155
}
156
ISR(TIMER2_COMPB_vect)
157
{
158
        PORTD &= ~(1 << PD7);
159
}
160
 
161
//--------------------------------------------------------------
162
 
163
////*****************************************************************************
164
void Timer2_Init (void)
165
{
166
  if (Config.HWSound == 1)
167
    {                                                   /*Sound PWM*/
168
      TCCR2A = 0x00; //stop
169
      ASSR  = 0x00; //set async mode
170
      TCNT2 = 0x00; //setup
171
      OCR2A  = 0xff;
172
      //Fast PWM 0xFF BOTTOM MAX
173
      //Set OC2A on Compare Match
174
      //clkT2S/8 (From prescaler)
175
      TCCR2A |=   (1 << WGM20) | (1 << WGM21) |(1 << COM2A1) | (1 << COM2A0);
176
      TCCR2B |=   (1 << CS20);
177
    }
178
  else
179
    {                                                   /* Displayhelligkeit*/
180
      DDRD   |= (1 << DDD7);                                                                          // PD7 output
181
      TCCR2A |= (1 << WGM21)  | (1 << WGM20)  | (1 << COM2A1);        // non invers
182
      TCCR2B |= (1 << CS20);                                                                          // Prescaler 1/1
183
      TIMSK2 |= (1 << OCIE2A) | (1 << OCIE2B);
184
 
185
      OCR2A = 255;
186
    }
187
 
188
 
189
}
190
//*****************************************************************************
191
//--------------------------------------------------------------
192
void Timer3_Init (void)  // Sound, Timer CTC
193
{
194
 
195
  TCCR3A = 0x00; //stop
196
  TCNT3H = 0xF8; //set count
197
  TCNT3L = 0x00; //set count
198
  OCR3AH = 0x07; //set compare
199
  OCR3AL = 0xFF; //set compare
200
  TCCR3A |=   (1 << WGM31);
201
  TCCR3B |=   (1 << CS30);
202
  TIMSK3 |= (1 << OCIE3A); //timer interrupt sources  2=t0 compare
203
}
204
 
205
 
206
ISR(TIMER3_COMPA_vect)  // Sound
207
{
208
//void timer0_comp_isr(void){
209
//was 8 KHz 125usec  sampling rate
210
//now 12 KHz 83usec  sampling rate
211
unsigned char oldfpart;
212
signed char fullsamp;
213
signed int tmp;
214
 
215
  TCNT3=0;
216
//  tics++; //8 bit... atomic
217
 
218
  if(generate){
219
 
220
    DDRD |= (1<<DDD7);            // Port aus Ausgang
221
    oldfpart=waveptfpart;         //remember fractional part
222
    waveptfpart+=freqincfpart;    //add frac part of freq inc to wave pointer
223
    if(waveptfpart < oldfpart){   //did it walk off the end?
224
      waveptipart++;              //yes, bump integer part
225
    }
226
    waveptipart+=freqincipart;    //add int part of freq increment to wave pointer
227
    fullsamp=sindat[waveptipart]; //get 8 bit sin sample from table (signed)
228
        tmp=fullsamp*iattenfac;       //cvt 7 bit x 8 = 15 bit
229
          OCR2A=(tmp >> 8)+128;        //cvt 15 bit signed to 8 bit unsigned
230
  }
231
  else
232
 
233
      DDRD &= ~(1 << DDD7);       //Port auf Eingang, sperrt das Rauschen
234
 
235
 
236
}
237
 
238
 
239
 
240
//--------------------------------------------------------------
241
ISR(TIMER0_COMPA_vect)  // Timer-Interrupt (100 Hz)
242
{
243
        static uint8_t ct0 = 0;
244
        static uint8_t ct1 = 0;
245
        static uint8_t k_time_l = 0;
246
        static uint8_t k_time_r = 0;
247
        static uint8_t k_time_lr = 0;
248
        static uint8_t k_time_rs = 0;
249
        uint8_t i;
250
 
251
        static unsigned char cnt_1ms = 1,cnt = 0;
252
        unsigned char beeper_ein = 0;
253
//      unsigned char pieper_ein = 0;
254
 
255
        // Key handling by Peter Dannegger
256
        // see www.mikrocontroller.net
257
 
258
        i = key_state ^ ~KEY_PIN;               // key changed ?
259
        ct0 = ~(ct0 & i);                               // reset or count ct0
260
        ct1 = ct0 ^ (ct1 & i);                  // reset or count ct1
261
        i &= (ct0 & ct1);                               // count until roll over ?
262
        key_state ^= i;                                 // then toggle debounced state
263
        key_press |= (key_state & i);   // 0->1: key press detect
264
 
265
//      if (PKT_IdleBeep == 1)
266
//      {
267
//              IdleTimer ++;                                   // nix zu tun? Timer hochzÀhlen
268
//              if (IdleTimer == 12000)                 // Warnhinweis
269
//              {
270
//                      set_beep ( 200, 0x0080, BeepNormal);
271
//                      IdleTimer = 0;
272
//              }
273
//      }
274
 
275
        if (!cnt--)
276
        {
277
                cnt = 9;
278
                CountMilliseconds++;
279
                cnt_1ms++;
280
        }
281
 
282
        if (i!=0)
283
        {                                               // Displaylicht einschalten, und bzw. TimeoutzÀhlerreset wenn Taste gedrÃŒckt wurde
284
            if (((Config.HWBeeper==1)&&(PCB_Version == PKT39m))||((Config.HWBeeper==0)&&(PCB_Version == PKT39x)))                              // entweder Beeper oder Display ein/aus
285
              {
286
                if (Display_on == 0)
287
                  set_D_LIGHT();
288
 
289
 
290
                Display_on = 1;         // Flag Display on
291
                DisplayTime = 0;        // Timer Reset
292
                IdleTimer = 0;          // Idletimeout Reset
293
              }
294
        }
295
 
296
        if (Config.DisplayTimeout > 0)
297
        {
298
            if (((Config.HWBeeper==1)&&(PCB_Version == PKT39m))||((Config.HWBeeper==0)&&(PCB_Version == PKT39x)))                                // entweder Beeper oder Display ein/aus
299
              {
300
                if (Display_on == 1)
301
                {
302
                        DisplayTime++;
303
                        if ((DisplayTime / 100) == Config.DisplayTimeout)       // ISR läuft mit 100Hz
304
                        {                                               // Displaylicht ausschalten
305
                            clr_D_LIGHT();
306
                            Display_on = 0;                             // Flag Display off
307
 
308
                        }
309
                }
310
              }
311
        }
312
 
313
//--------------------------------------------------------------
314
#ifdef HWVERSION3_9
315
//      LipoCheck();    // Lipo prüfen
316
#endif
317
 
318
//--------------------------------------------------------------
319
        if (Config.HWBeeper==1)
320
          {
321
            if (BeepTime)
322
            {
323
                    if (BeepTime > 10)
324
                            BeepTime -= 10;
325
                    else
326
                      {
327
                            BeepTime = 0;
328
 
329
                      }
330
 
331
                    if (BeepTime & BeepMuster)
332
                            beeper_ein = 1;
333
                    else    beeper_ein = 0;
334
 
335
 
336
            }
337
            else
338
            {
339
                    beeper_ein = 0;
340
                    BeepMuster = 0xffff;
341
                    BeepPrio = BeepNormal;
342
            }
343
 
344
            if (beeper_ein==1)
345
                    set_BEEP();
346
            else
347
                    clr_BEEP();
348
          }
349
 
350
        //Tonausgabe ***********************************************************************************************
351
 
352
        if (sound_timer > 0)            // Ton spielen
353
        {
354
          sound_timer --;
355
        }
356
 
357
        else
358
          {
359
//            TIMSK2 &= ~_BV(TOIE2);      // Interrupt sperren, verhindert Störgeräusche
360
//            TCCR2A = 0x00; //stop
361
            generate=0;                 // Sound aus
362
            tone_handler();
363
            if (soundpause_timer > 0)
364
            {
365
              soundpause_timer --;        // Ton pause
366
            }
367
          }
368
 
369
        //***********************************************************************************************
370
//--------------------------------------------------------------
371
        if ((key_state & LONG_MASK) == 0)                       // check long key function
372
                k_time_l = REPEAT_START;                                // start delay
373
 
374
        if (--k_time_l == 0)                                            // long countdown
375
                key_long |= (key_state & LONG_MASK);
376
 
377
//--------------------------------------------------------------
378
        if ((key_state & REPEAT_MASK) == 0)                     // check repeat function
379
                k_time_r = 1;                                                   // kein delay
380
 
381
        if (--k_time_r == 0)
382
        {
383
                k_time_r = REPEAT_NEXT;                                 // repeat delay
384
                key_rpt |= (key_state & REPEAT_MASK);
385
        }
386
 
387
//--------------------------------------------------------------
388
        if ((key_state & LONG_REPEAT_MASK) == 0)        // check repeat function
389
                k_time_lr = REPEAT_START;                               // start delay
390
 
391
        if (--k_time_lr == 0)
392
        {
393
                k_time_lr = REPEAT_NEXT;                                // repeat delay
394
                key_lrpt |= (key_state & LONG_REPEAT_MASK);
395
        }
396
 
397
//--------------------------------------------------------------
398
        if ((key_state & LONG_REPEAT_SP_MASK) == 0)     // check repeatX function
399
                k_time_rs = REPEAT_START;                               // start delay
400
 
401
        if (--k_time_rs == 0)                                           // repeat countdown
402
        {
403
                if (repeat_speed == 1)
404
                {
405
                        k_time_rs = REPEAT_SPEED_1;
406
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
407
                }
408
                else if (repeat_speed == 2)
409
                {
410
                        k_time_rs = REPEAT_SPEED_2;
411
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
412
                }
413
                else if (repeat_speed == 3)
414
                {
415
                        k_time_rs = REPEAT_SPEED_3;
416
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
417
                }
418
        }
419
 
420
        if (timer > 0)
421
                timer --;
422
 
423
        if (timer2 > 0)
424
                timer2 --;
425
 
426
        if (abo_timer > 0)
427
                abo_timer --;
428
 
429
        //24.8.2012
430
//              if (receiveNMEA==true)
431
//                {
432
//                  if (bt_receiveNMEA()) Tracking_NMEA();
433
//                  else receiveNMEA = false;
434
//
435
//                }
436
 
437
}
438
 
439
 
440
#ifdef HWVERSION3_9
441
 
442
void LipoCheck (void)   // Lowbatpin des Spannungswandlers prüfen
443
                        // LBO des LT1308 wechselt zum Ende der Batterielaufzeit häufig seinen Zustand in der Ãœbergangsphase zum LowBat
444
                        // Die Akkuspannung schwankt auch abhängig vom momentanen Stromverbrauch
445
{
446
        if (WarnToggle == 1)    // Beim ersten Auftreten Warnung ausgeben, Rythmus 5/10 Sekunden
447
        {
448
 
449
                set_beep ( 1000, 0x0020, BeepNormal);
450
                lcd_printp_at (0, 0, PSTR("  LIPO  !!Warnung!!  "), 2);
451
        }
452
 
453
        if (WarnToggle == WarnTime * 100)
454
                WarnToggle = 0;  // erstmal bis hier warnen
455
 
456
        if (WarnToggle > 0)
457
                WarnToggle++;  // weiter hochzählen
458
 
459
        if (PINC & (1 << LowBat))       // Kurzzeitige Unterspannung bearbeiten und Warnung ausgeben
460
        {
461
                WarnCount = 0;
462
//              if (WarnCount > 0)
463
//                      WarnCount--;  // Bei LIPO OK erstmal runterzählen, LT1308 überlegt sich noch genauer ob nun ok oder nicht
464
        }
465
 
466
        if (!(PINC & (1 << LowBat)) )  // LT1308 hat Unterspannung erkannt
467
        {
468
                WarnCount++;  // solange LBO low ist Zähler hochzählen
469
                if (WarnCount == 10 && WarnToggle == 0)  // mit "10" etwas unempfindlicher gegen kurze Impulse machen
470
                        WarnToggle = 1;  // Warnhinweis starten
471
        }
472
 
473
        if ((WarnCount) == PoffTime * 100)
474
                clr_V_On();  // Spannung abschalten
475
}
476
 
477
#endif
478
 
479
 
480
 
481
 
482
//--------------------------------------------------------------
483
unsigned int SetDelay (unsigned int t)
484
{
485
        return(CountMilliseconds + t + 1);
486
}
487
 
488
 
489
//--------------------------------------------------------------
490
char CheckDelay(unsigned int t)
491
{
492
        return(((t - CountMilliseconds) & 0x8000) >> 9);
493
}
494
 
495
 
496
//--------------------------------------------------------------
497
void Delay_ms(unsigned int w)
498
{
499
        unsigned int akt;
500
        akt = SetDelay(w);
501
        while (!CheckDelay(akt));
502
}
503
 
504
 
505
//--------------------------------------------------------------
506
//
507
uint8_t get_key_press (uint8_t key_mask)
508
{
509
        uint8_t sreg = SREG;
510
 
511
        // disable all interrupts
512
        cli();
513
 
514
        key_mask &= key_press;  // read key(s)
515
        key_press ^= key_mask;  // clear key(s)
516
 
517
        SREG = sreg;    // restore status register
518
 
519
        return key_mask;
520
}
521
 
522
 
523
//--------------------------------------------------------------
524
//
525
uint8_t get_key_short (uint8_t key_mask)
526
{
527
        uint8_t ret;
528
        uint8_t sreg = SREG;
529
 
530
        // disable all interrupts
531
        cli();
532
 
533
        ret = get_key_press (~key_state & key_mask);
534
 
535
        SREG = sreg;    // restore status register
536
 
537
        return ret;
538
}
539
 
540
 
541
//--------------------------------------------------------------
542
//
543
uint8_t get_key_long (uint8_t key_mask)
544
{
545
        uint8_t sreg = SREG;
546
 
547
        // disable all interrupts
548
        cli();
549
 
550
        key_mask &= key_long;   // read key(s)
551
        key_long ^= key_mask;   // clear key(s)
552
 
553
        SREG = sreg;    // restore status register
554
 
555
  return get_key_press (get_key_rpt (key_mask));
556
}
557
 
558
 
559
//--------------------------------------------------------------
560
//
561
uint8_t get_key_rpt (uint8_t key_mask)
562
{
563
        uint8_t sreg = SREG;
564
 
565
        // disable all interrupts
566
        cli();
567
 
568
        key_mask &= key_rpt;    // read key(s)
569
        key_rpt ^= key_mask;    // clear key(s)
570
 
571
        SREG = sreg;    // restore status register
572
 
573
        return key_mask;
574
}
575
 
576
 
577
//--------------------------------------------------------------
578
//
579
uint8_t get_key_long_rpt (uint8_t key_mask)
580
{
581
        uint8_t sreg = SREG;
582
 
583
        // disable all interrupts
584
        cli();
585
 
586
        key_mask &= key_lrpt;   // read key(s)
587
        key_lrpt ^= key_mask;   // clear key(s)
588
 
589
        SREG = sreg;    // restore status register
590
 
591
        return get_key_rpt (~key_press^key_mask);
592
}
593
 
594
 
595
//--------------------------------------------------------------
596
//
597
uint8_t get_key_long_rpt_sp (uint8_t key_mask, uint8_t key_speed)
598
{
599
        uint8_t sreg = SREG;
600
 
601
        // disable all interrupts
602
        cli();
603
 
604
        key_mask &= key_rpts;   // read key(s)
605
        key_rpts ^= key_mask;   // clear key(s)
606
 
607
        repeat_speed = key_speed;
608
 
609
        SREG = sreg;    // restore status register
610
 
611
        return key_mask;
612
}
613
 
614
void set_beep ( uint16_t Time, uint16_t Muster, uint8_t Prio)
615
{
616
   if (Config.HWBeeper==1)
617
     {
618
      if (Prio == BeepNormal)
619
        {
620
          if (BeepPrio == BeepNormal)        // nur setzen wenn keine hohe Prio schon aktiv ist
621
            {
622
            BeepTime = Time;
623
            BeepMuster = Muster;
624
            }
625
        }
626
 
627
      if (Prio == BeepSevere)
628
        {
629
          if (!BeepPrio == BeepSevere)
630
            {
631
              BeepPrio = BeepSevere;             // hohe Prio setzen
632
              BeepTime = Time;
633
              BeepMuster = Muster;
634
            }
635
        }
636
 
637
      if (Prio == BeepOff)
638
        {
639
          BeepPrio = BeepNormal;             // Beep hohe Prio aus
640
          BeepTime = 0;
641
          BeepMuster = 0;
642
        }
643
     }
644
   else
645
     {
646
 
647
       if (Prio == BeepNormal)
648
         {
649
           if (BeepPrio == BeepNormal)        // nur setzen wenn keine hohe Prio schon aktiv ist
650
             {
651
               playTone(900,Time/10,0);
652
             }
653
         }
654
 
655
       if (Prio == BeepSevere)
656
         {
657
           if (!BeepPrio == BeepSevere)
658
             {
659
               playTone(1200,Time/10,0);
660
               playTone(1100,Time/10,0);
661
             }
662
         }
663
 
664
       if (Prio == BeepOff)
665
         {
666
           playTone(0,0,0);
667
         }
668
 
669
     }
670
 
671
 
672
 
673
 
674
}
675
 
676