Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1470 - 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
 
51
#if defined HWVERSION1_2W || defined HWVERSION1_2
52
#include "HAL_HW1_2.h"
53
#endif
54
 
55
#if defined HWVERSION1_3W || defined HWVERSION1_3
56
#include "HAL_HW1_3.h"
57
#endif
58
 
59
#ifdef HWVERSION3_9
60
#include "HAL_HW3_9.h"
61
#endif
62
 
63
volatile uint16_t timer;
64
volatile uint16_t abo_timer;
65
volatile static unsigned int tim_main;
66
 
67
uint8_t key_state = 0;          // debounced and inverted key state:
68
                                                        // bit = 1: key pressed
69
uint8_t key_press = 0;          // key press detect
70
uint8_t key_long = 0;           // key long press
71
uint8_t key_rpt = 0;            // key repeat
72
uint8_t key_lrpt = 0;           // key long press and repeat
73
uint8_t key_rpts = 0;           // key long press and speed repeat
74
uint8_t repeat_speed = 0;
75
 
76
uint16_t DisplayTime = 0;       // Leuchtdauer
77
volatile uint16_t IdleTimer = 0;                // InaktivitätsTimer
78
 
79
uint16_t WarnCount = 0;         // Zähler der LIPO Warnzeit
80
uint16_t WarnToggle = 0;        // Togglezähler zum blinken
81
uint16_t WarnTime = 10;         // Länge der LIPO Warnzeit 10 Sek.
82
uint16_t PoffTime = 30;         // Länge der Wartezeit vor Abschalten 30 Sek.
83
//uint8_t       servo = 0;
84
 
85
 
86
volatile uint8_t Display_on;// Flag Display on/off
87
 
88
unsigned int BeepTime = 0;
89
unsigned int BeepMuster = 0xffff;
90
 
91
volatile unsigned int CountMilliseconds = 0;
92
 
93
// Size of Buffer for Converting unsigned int Value to ASCII
94
#define STRING_BUFFER_SIZE 5
95
 
96
// Buffer for Converting unsigned int Value to ASCII
97
char String_Buffer[STRING_BUFFER_SIZE];
98
 
99
 
100
//--------------------------------------------------------------
101
//
102
void Timer1_Init (void) // Timer 1-A
103
{
104
        // löschen
105
        TCCR1A = 0;
106
        TCCR1B = 0;
107
        TIMSK1 = 0;
108
 
109
        // setzen
110
        TCCR1A |=   (1 << COM1A1) | (1 << WGM11);
111
        TCCR1B |=   (1 << CS11)   | (1 << CS10)   | (1 << WGM13)  | (1 << WGM12);
112
 
113
        ICR1 = (F_CPU / 64) * 20 / 1000;
114
 
115
        OCR1A = 470;  // ca. Servomitte
116
}
117
 
118
 
119
//--------------------------------------------------------------
120
void Timer2_Init (void) // Displayhelligkeit
121
{
122
        DDRD   |= (1 << DDD7);                                                                          // PD7 output
123
        TCCR2A |= (1 << WGM21)  | (1 << WGM20)  | (1 << COM2A1);        // non invers
124
        TCCR2B |= (1 << CS20);                                                                          // Prescaler 1/1
125
        TIMSK2 |= (1 << OCIE2A) | (1 << OCIE2B);
126
 
127
        OCR2A = 255;
128
}
129
 
130
 
131
#if defined HWVERSION1_2 || defined HWVERSION1_2W
132
//--------------------------------------------------------------
133
ISR(TIMER2_COMPA_vect)
134
{
135
        PORTD &= ~(1 << PD7);
136
        PORTC &= ~(1 << PC0);
137
        PORTC &= ~(1 << PC1);
138
}
139
ISR(TIMER2_COMPB_vect)
140
{
141
        PORTD |= (1 << PD7);
142
        PORTC |= (1 << PC0);
143
        PORTC |= (1 << PC1);
144
}
145
#endif
146
#if defined HWVERSION1_3 || defined HWVERSION1_3W
147
//--------------------------------------------------------------
148
ISR(TIMER2_COMPA_vect)
149
{
150
        PORTD &= ~(1 << PD7);
151
        PORTD &= ~(1 << PD6);
152
        PORTC &= ~(1 << PC2);
153
}
154
ISR(TIMER2_COMPB_vect)
155
{
156
        PORTD |= (1 << PD7);
157
        PORTD |= (1 << PD6);
158
        PORTC |= (1 << PC2);
159
}
160
#endif
161
#ifdef HWVERSION3_9
162
//--------------------------------------------------------------
163
ISR(TIMER2_COMPA_vect)
164
{
165
        PORTD |= (1 << PD7);
166
}
167
ISR(TIMER2_COMPB_vect)
168
{
169
        PORTD &= ~(1 << PD7);
170
}
171
#endif
172
 
173
 
174
//--------------------------------------------------------------
175
void Timer0_Init (void)  // System (100Hz)
176
{
177
        timer = 0;
178
 
179
        TCCR0A = (1 << WGM01);
180
        TCCR0B = (1 << CS02) | (1 << CS00);
181
        OCR0A = (F_CPU / (100L * 1024L)) ;
182
 
183
        TIMSK0 |= (1 << OCIE0A);        // enable interrupt for OCR
184
}
185
 
186
 
187
//--------------------------------------------------------------
188
ISR(TIMER0_COMPA_vect)  // Timer-Interrupt (100 Hz)
189
{
190
        static uint8_t ct0 = 0;
191
        static uint8_t ct1 = 0;
192
        static uint8_t k_time_l = 0;
193
        static uint8_t k_time_r = 0;
194
        static uint8_t k_time_lr = 0;
195
        static uint8_t k_time_rs = 0;
196
        uint8_t i;
197
 
198
        static unsigned char cnt_1ms = 1,cnt = 0;
199
        unsigned char beeper_ein = 0;
200
//      unsigned char pieper_ein = 0;
201
 
202
        // Key handling by Peter Dannegger
203
        // see www.mikrocontroller.net
204
 
205
        i = key_state ^ ~KEY_PIN;               // key changed ?
206
        ct0 = ~(ct0 & i);                               // reset or count ct0
207
        ct1 = ct0 ^ (ct1 & i);                  // reset or count ct1
208
        i &= (ct0 & ct1);                               // count until roll over ?
209
        key_state ^= i;                                 // then toggle debounced state
210
        key_press |= (key_state & i);   // 0->1: key press detect
211
 
212
        if (PKT_IdleBeep == 1)
213
        {
214
                IdleTimer ++;                                   // nix zu tun? Timer hochzählen
215
                if (IdleTimer == 12000)                 // Warnhinweis
216
                {
217
                        BeepTime = 200;
218
                        BeepMuster = 0x0080;
219
                        IdleTimer = 0;
220
                }
221
        }
222
 
223
        if (!cnt--)
224
        {
225
                cnt = 9;
226
                CountMilliseconds++;
227
                cnt_1ms++;
228
        }
229
 
230
        if (i!=0)
231
        {                                               // Displaylicht einschalten, und bzw. Timeoutzählerreset wenn Taste gedrückt wurde
232
                if (Display_on == 0)
233
                  set_D_LIGHT();
234
 
235
 
236
                Display_on = 1;         // Flag Display on
237
                DisplayTime = 0;        // Timer Reset
238
                IdleTimer = 0;          // Idletimeout Reset
239
 
240
        }
241
 
242
        if (DisplayTimeout > 0)
243
        {
244
                if (Display_on == 1)
245
                {
246
                        DisplayTime++;
247
                        if ((DisplayTime / 100) == DisplayTimeout)      // ISR läuft mit 100Hz
248
                        {                                                                                       // Displaylicht ausschalten
249
                            clr_D_LIGHT();
250
                            Display_on = 0;                                                     // Flag Display off
251
 
252
                        }
253
                }
254
        }
255
 
256
//--------------------------------------------------------------
257
#ifdef HWVERSION3_9
258
        LipoCheck();    // Lipo prüfen
259
#endif
260
 
261
//--------------------------------------------------------------
262
        if (BeepTime)
263
        {
264
                if (BeepTime > 10)
265
                        BeepTime -= 10;
266
                else
267
                        BeepTime = 0;
268
 
269
                if (BeepTime & BeepMuster)
270
                        beeper_ein = 1;
271
                else
272
                        beeper_ein = 0;
273
        }
274
        else
275
        {
276
                beeper_ein = 0;
277
                BeepMuster = 0xffff;
278
        }
279
 
280
        if (beeper_ein)
281
                set_BEEP();
282
        else
283
                clr_BEEP();
284
 
285
 
286
//--------------------------------------------------------------
287
        if ((key_state & LONG_MASK) == 0)                       // check long key function
288
                k_time_l = REPEAT_START;                                // start delay
289
 
290
        if (--k_time_l == 0)                                            // long countdown
291
                key_long |= (key_state & LONG_MASK);
292
 
293
//--------------------------------------------------------------
294
        if ((key_state & REPEAT_MASK) == 0)                     // check repeat function
295
                k_time_r = 1;                                                   // kein delay
296
 
297
        if (--k_time_r == 0)
298
        {
299
                k_time_r = REPEAT_NEXT;                                 // repeat delay
300
                key_rpt |= (key_state & REPEAT_MASK);
301
        }
302
 
303
//--------------------------------------------------------------
304
        if ((key_state & LONG_REPEAT_MASK) == 0)        // check repeat function
305
                k_time_lr = REPEAT_START;                               // start delay
306
 
307
        if (--k_time_lr == 0)
308
        {
309
                k_time_lr = REPEAT_NEXT;                                // repeat delay
310
                key_lrpt |= (key_state & LONG_REPEAT_MASK);
311
        }
312
 
313
//--------------------------------------------------------------
314
        if ((key_state & LONG_REPEAT_SP_MASK) == 0)     // check repeatX function
315
                k_time_rs = REPEAT_START;                               // start delay
316
 
317
        if (--k_time_rs == 0)                                           // repeat countdown
318
        {
319
                if (repeat_speed == 1)
320
                {
321
                        k_time_rs = REPEAT_SPEED_1;
322
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
323
                }
324
                else if (repeat_speed == 2)
325
                {
326
                        k_time_rs = REPEAT_SPEED_2;
327
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
328
                }
329
                else if (repeat_speed == 3)
330
                {
331
                        k_time_rs = REPEAT_SPEED_3;
332
                        key_rpts |= (key_state & LONG_REPEAT_SP_MASK);
333
                }
334
        }
335
 
336
        if (timer > 0)
337
                timer --;
338
 
339
        if (abo_timer > 0)
340
                abo_timer --;
341
 
342
 
343
}
344
 
345
 
346
//--------------------------------------------------------------
347
#ifdef HWVERSION3_9
348
 
349
void LipoCheck (void)   // Lowbatpin des Spannungswandlers prüfen
350
                        // LBO des LT1308 wechselt zum Ende der Batterielaufzeit häufig seinen Zustand in der Ãœbergangsphase zum LowBat
351
                        // Die Akkuspannung schwankt auch abhängig vom momentanen Stromverbrauch
352
{
353
        if (WarnToggle == 1)    // Beim ersten Auftreten Warnung ausgeben, Rythmus 5/10 Sekunden
354
        {
355
                BeepTime = 1000;
356
                BeepMuster = 0x0020;
357
                lcd_printp_at (0, 0, PSTR("  LIPO  !!Warnung!!  "), 2);
358
        }
359
 
360
        if (WarnToggle == WarnTime * 100)
361
                WarnToggle = 0;  // erstmal bis hier warnen
362
 
363
        if (WarnToggle > 0)
364
                WarnToggle++;  // weiter hochzählen
365
 
366
        if (PINC & (1 << LowBat))       // Kurzzeitige Unterspannung bearbeiten und Warnung ausgeben
367
        {
368
                WarnCount = 0;
369
//              if (WarnCount > 0)
370
//                      WarnCount--;  // Bei LIPO OK erstmal runterzählen, LT1308 überlegt sich noch genauer ob nun ok oder nicht
371
        }
372
 
373
        if (!(PINC & (1 << LowBat)) )  // LT1308 hat Unterspannung erkannt
374
        {
375
                WarnCount++;  // solange LBO low ist Zähler hochzählen
376
                if (WarnCount == 10 && WarnToggle == 0)  // mit "10" etwas unempfindlicher gegen kurze Impulse machen
377
                        WarnToggle = 1;  // Warnhinweis starten
378
        }
379
 
380
        if ((WarnCount) == PoffTime * 100)
381
                clr_V_On();  // Spannung abschalten
382
}
383
 
384
#endif
385
 
386
 
387
//--------------------------------------------------------------
388
unsigned int SetDelay (unsigned int t)
389
{
390
        return(CountMilliseconds + t + 1);
391
}
392
 
393
 
394
//--------------------------------------------------------------
395
char CheckDelay(unsigned int t)
396
{
397
        return(((t - CountMilliseconds) & 0x8000) >> 9);
398
}
399
 
400
 
401
//--------------------------------------------------------------
402
void Delay_ms(unsigned int w)
403
{
404
        unsigned int akt;
405
        akt = SetDelay(w);
406
        while (!CheckDelay(akt));
407
}
408
 
409
 
410
//--------------------------------------------------------------
411
//
412
uint8_t get_key_press (uint8_t key_mask)
413
{
414
        uint8_t sreg = SREG;
415
 
416
        // disable all interrupts
417
        cli();
418
 
419
        key_mask &= key_press;  // read key(s)
420
        key_press ^= key_mask;  // clear key(s)
421
 
422
        SREG = sreg;    // restore status register
423
 
424
        return key_mask;
425
}
426
 
427
 
428
//--------------------------------------------------------------
429
//
430
uint8_t get_key_short (uint8_t key_mask)
431
{
432
        uint8_t ret;
433
        uint8_t sreg = SREG;
434
 
435
        // disable all interrupts
436
        cli();
437
 
438
        ret = get_key_press (~key_state & key_mask);
439
 
440
        SREG = sreg;    // restore status register
441
 
442
        return ret;
443
}
444
 
445
 
446
//--------------------------------------------------------------
447
//
448
uint8_t get_key_long (uint8_t key_mask)
449
{
450
        uint8_t sreg = SREG;
451
 
452
        // disable all interrupts
453
        cli();
454
 
455
        key_mask &= key_long;   // read key(s)
456
        key_long ^= key_mask;   // clear key(s)
457
 
458
        SREG = sreg;    // restore status register
459
 
460
  return get_key_press (get_key_rpt (key_mask));
461
}
462
 
463
 
464
//--------------------------------------------------------------
465
//
466
uint8_t get_key_rpt (uint8_t key_mask)
467
{
468
        uint8_t sreg = SREG;
469
 
470
        // disable all interrupts
471
        cli();
472
 
473
        key_mask &= key_rpt;    // read key(s)
474
        key_rpt ^= key_mask;    // clear key(s)
475
 
476
        SREG = sreg;    // restore status register
477
 
478
        return key_mask;
479
}
480
 
481
 
482
//--------------------------------------------------------------
483
//
484
uint8_t get_key_long_rpt (uint8_t key_mask)
485
{
486
        uint8_t sreg = SREG;
487
 
488
        // disable all interrupts
489
        cli();
490
 
491
        key_mask &= key_lrpt;   // read key(s)
492
        key_lrpt ^= key_mask;   // clear key(s)
493
 
494
        SREG = sreg;    // restore status register
495
 
496
        return get_key_rpt (~key_press^key_mask);
497
}
498
 
499
 
500
//--------------------------------------------------------------
501
//
502
uint8_t get_key_long_rpt_sp (uint8_t key_mask, uint8_t key_speed)
503
{
504
        uint8_t sreg = SREG;
505
 
506
        // disable all interrupts
507
        cli();
508
 
509
        key_mask &= key_rpts;   // read key(s)
510
        key_rpts ^= key_mask;   // clear key(s)
511
 
512
        repeat_speed = key_speed;
513
 
514
        SREG = sreg;    // restore status register
515
 
516
        return key_mask;
517
}
518
 
519