0,0 → 1,676 |
/***************************************************************************** |
* Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de * |
* Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net * |
* based on the key handling by Peter Dannegger * |
* see www.mikrocontroller.net * |
* Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net * |
* Copyright (C) 2011 Harald Bongartz * |
* * |
* This program is free software; you can redistribute it and/or modify * |
* it under the terms of the GNU General Public License as published by * |
* the Free Software Foundation; either version 2 of the License. * |
* * |
* This program is distributed in the hope that it will be useful, * |
* but WITHOUT ANY WARRANTY; without even the implied warranty of * |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
* GNU General Public License for more details. * |
* * |
* You should have received a copy of the GNU General Public License * |
* along with this program; if not, write to the * |
* Free Software Foundation, Inc., * |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
* * |
* * |
* Credits to: * |
* Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN * |
* http://www.mikrokopter.de * |
* Gregor "killagreg" Stobrawa for his version of the MK code * |
* Thomas Kaiser "thkais" for the original project. See * |
* http://www.ft-fanpage.de/mikrokopter/ * |
* http://forum.mikrokopter.de/topic-4061-1.html * |
* Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code * |
* http://www.mylifesucks.de/oss/c-osd/ * |
* Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility* |
*****************************************************************************/ |
|
//############################################################################ |
//# HISTORY timer.c |
//# |
//# 09.03.2013 OG |
//# - add: timer2 (auch in timer.h) |
//############################################################################ |
|
|
#include "../cpu.h" |
#include <avr/io.h> |
#include <avr/interrupt.h> |
#include <avr/pgmspace.h> |
#include <string.h> |
#include <util/delay.h> |
#include <inttypes.h> |
|
|
#include "../main.h" |
#include "../timer/timer.h" |
#include "../eeprom/eeprom.h" |
#include "../lcd/lcd.h" |
#include "../uart/uart1.h" |
#include "../bluetooth/bluetooth.h" |
#include "../setup/setup.h" |
#include"../tracking/tracking.h" |
#include "../sound/pwmsine8bit.h" |
|
|
#if defined HWVERSION1_2W || defined HWVERSION1_2 |
#include "HAL_HW1_2.h" |
#endif |
|
#if defined HWVERSION1_3W || defined HWVERSION1_3 |
#include "HAL_HW1_3.h" |
#endif |
|
#ifdef HWVERSION3_9 |
#include "../HAL_HW3_9.h" |
#endif |
|
volatile uint16_t timer; |
volatile uint16_t timer2; |
volatile uint16_t abo_timer; |
volatile uint16_t sound_timer; |
volatile uint16_t soundpause_timer; |
volatile static unsigned int tim_main; |
|
uint8_t key_state = 0; // debounced and inverted key state: |
// bit = 1: key pressed |
uint8_t key_press = 0; // key press detect |
uint8_t key_long = 0; // key long press |
uint8_t key_rpt = 0; // key repeat |
uint8_t key_lrpt = 0; // key long press and repeat |
uint8_t key_rpts = 0; // key long press and speed repeat |
uint8_t repeat_speed = 0; |
|
uint16_t DisplayTime = 0; // Leuchtdauer |
volatile uint16_t IdleTimer = 0; // InaktivitÀtsTimer |
|
|
//uint8_t servo = 0; |
volatile uint16_t WarnCount = 0; // Zähler der LIPO Warnzeit |
volatile uint16_t WarnToggle = 0; // Togglezähler zum blinken |
volatile uint16_t WarnTime = 10; // Länge der LIPO Warnzeit 10 Sek. |
volatile uint16_t PoffTime = 30; // Länge der Wartezeit vor Abschalten 30 Sek. |
|
|
volatile uint8_t Display_on;// Flag Display on/off |
|
unsigned int BeepTime = 0; |
unsigned int BeepMuster = 0xffff; |
unsigned int BeepPrio = 0; |
|
volatile unsigned int CountMilliseconds = 0; |
|
// Size of Buffer for Converting unsigned int Value to ASCII |
#define STRING_BUFFER_SIZE 5 |
|
// Buffer for Converting unsigned int Value to ASCII |
char String_Buffer[STRING_BUFFER_SIZE]; |
|
|
//-------------------------------------------------------------- |
// |
void Timer0_Init (void) // System (100Hz) |
{ |
timer = 0; |
|
TCCR0A = (1 << WGM01); |
TCCR0B = (1 << CS02) | (1 << CS00); |
OCR0A = (F_CPU / (100L * 1024L)) ; |
|
TIMSK0 |= (1 << OCIE0A); // enable interrupt for OCR |
} |
//-------------------------------------------------------------- |
// |
//void Timer1_Init (void) // Timer 1-A |
//{ |
// // löschen |
// TCCR1A = 0; |
// TCCR1B = 0; |
// TIMSK1 = 0; |
// |
// // setzen |
// TCCR1A |= (1 << COM1A1) | (1 << WGM11); |
// TCCR1B |= (1 << CS11) | (1 << CS10) | (1 << WGM13) | (1 << WGM12); |
// |
// ICR1 = (F_CPU / 64) * 20 / 1000; |
// |
// OCR1A = 470; // ca. Servomitte |
//} |
|
|
|
|
//-------------------------------------------------------------- |
ISR(TIMER2_COMPA_vect) |
{ |
PORTD |= (1 << PD7); |
} |
ISR(TIMER2_COMPB_vect) |
{ |
PORTD &= ~(1 << PD7); |
} |
|
//-------------------------------------------------------------- |
|
////***************************************************************************** |
void Timer2_Init (void) |
{ |
if (Config.HWSound == 1) |
{ /*Sound PWM*/ |
TCCR2A = 0x00; //stop |
ASSR = 0x00; //set async mode |
TCNT2 = 0x00; //setup |
OCR2A = 0xff; |
//Fast PWM 0xFF BOTTOM MAX |
//Set OC2A on Compare Match |
//clkT2S/8 (From prescaler) |
TCCR2A |= (1 << WGM20) | (1 << WGM21) |(1 << COM2A1) | (1 << COM2A0); |
TCCR2B |= (1 << CS20); |
} |
else |
{ /* Displayhelligkeit*/ |
DDRD |= (1 << DDD7); // PD7 output |
TCCR2A |= (1 << WGM21) | (1 << WGM20) | (1 << COM2A1); // non invers |
TCCR2B |= (1 << CS20); // Prescaler 1/1 |
TIMSK2 |= (1 << OCIE2A) | (1 << OCIE2B); |
|
OCR2A = 255; |
} |
|
|
} |
//***************************************************************************** |
//-------------------------------------------------------------- |
void Timer3_Init (void) // Sound, Timer CTC |
{ |
|
TCCR3A = 0x00; //stop |
TCNT3H = 0xF8; //set count |
TCNT3L = 0x00; //set count |
OCR3AH = 0x07; //set compare |
OCR3AL = 0xFF; //set compare |
TCCR3A |= (1 << WGM31); |
TCCR3B |= (1 << CS30); |
TIMSK3 |= (1 << OCIE3A); //timer interrupt sources 2=t0 compare |
} |
|
|
ISR(TIMER3_COMPA_vect) // Sound |
{ |
//void timer0_comp_isr(void){ |
//was 8 KHz 125usec sampling rate |
//now 12 KHz 83usec sampling rate |
unsigned char oldfpart; |
signed char fullsamp; |
signed int tmp; |
|
TCNT3=0; |
// tics++; //8 bit... atomic |
|
if(generate){ |
|
DDRD |= (1<<DDD7); // Port aus Ausgang |
oldfpart=waveptfpart; //remember fractional part |
waveptfpart+=freqincfpart; //add frac part of freq inc to wave pointer |
if(waveptfpart < oldfpart){ //did it walk off the end? |
waveptipart++; //yes, bump integer part |
} |
waveptipart+=freqincipart; //add int part of freq increment to wave pointer |
fullsamp=sindat[waveptipart]; //get 8 bit sin sample from table (signed) |
tmp=fullsamp*iattenfac; //cvt 7 bit x 8 = 15 bit |
OCR2A=(tmp >> 8)+128; //cvt 15 bit signed to 8 bit unsigned |
} |
else |
|
DDRD &= ~(1 << DDD7); //Port auf Eingang, sperrt das Rauschen |
|
|
} |
|
|
|
//-------------------------------------------------------------- |
ISR(TIMER0_COMPA_vect) // Timer-Interrupt (100 Hz) |
{ |
static uint8_t ct0 = 0; |
static uint8_t ct1 = 0; |
static uint8_t k_time_l = 0; |
static uint8_t k_time_r = 0; |
static uint8_t k_time_lr = 0; |
static uint8_t k_time_rs = 0; |
uint8_t i; |
|
static unsigned char cnt_1ms = 1,cnt = 0; |
unsigned char beeper_ein = 0; |
// unsigned char pieper_ein = 0; |
|
// Key handling by Peter Dannegger |
// see www.mikrocontroller.net |
|
i = key_state ^ ~KEY_PIN; // key changed ? |
ct0 = ~(ct0 & i); // reset or count ct0 |
ct1 = ct0 ^ (ct1 & i); // reset or count ct1 |
i &= (ct0 & ct1); // count until roll over ? |
key_state ^= i; // then toggle debounced state |
key_press |= (key_state & i); // 0->1: key press detect |
|
// if (PKT_IdleBeep == 1) |
// { |
// IdleTimer ++; // nix zu tun? Timer hochzÀhlen |
// if (IdleTimer == 12000) // Warnhinweis |
// { |
// set_beep ( 200, 0x0080, BeepNormal); |
// IdleTimer = 0; |
// } |
// } |
|
if (!cnt--) |
{ |
cnt = 9; |
CountMilliseconds++; |
cnt_1ms++; |
} |
|
if (i!=0) |
{ // Displaylicht einschalten, und bzw. TimeoutzÀhlerreset wenn Taste gedrÌckt wurde |
if (((Config.HWBeeper==1)&&(PCB_Version == PKT39m))||((Config.HWBeeper==0)&&(PCB_Version == PKT39x))) // entweder Beeper oder Display ein/aus |
{ |
if (Display_on == 0) |
set_D_LIGHT(); |
|
|
Display_on = 1; // Flag Display on |
DisplayTime = 0; // Timer Reset |
IdleTimer = 0; // Idletimeout Reset |
} |
} |
|
if (Config.DisplayTimeout > 0) |
{ |
if (((Config.HWBeeper==1)&&(PCB_Version == PKT39m))||((Config.HWBeeper==0)&&(PCB_Version == PKT39x))) // entweder Beeper oder Display ein/aus |
{ |
if (Display_on == 1) |
{ |
DisplayTime++; |
if ((DisplayTime / 100) == Config.DisplayTimeout) // ISR läuft mit 100Hz |
{ // Displaylicht ausschalten |
clr_D_LIGHT(); |
Display_on = 0; // Flag Display off |
|
} |
} |
} |
} |
|
//-------------------------------------------------------------- |
#ifdef HWVERSION3_9 |
// LipoCheck(); // Lipo prüfen |
#endif |
|
//-------------------------------------------------------------- |
if (Config.HWBeeper==1) |
{ |
if (BeepTime) |
{ |
if (BeepTime > 10) |
BeepTime -= 10; |
else |
{ |
BeepTime = 0; |
|
} |
|
if (BeepTime & BeepMuster) |
beeper_ein = 1; |
else beeper_ein = 0; |
|
|
} |
else |
{ |
beeper_ein = 0; |
BeepMuster = 0xffff; |
BeepPrio = BeepNormal; |
} |
|
if (beeper_ein==1) |
set_BEEP(); |
else |
clr_BEEP(); |
} |
|
//Tonausgabe *********************************************************************************************** |
|
if (sound_timer > 0) // Ton spielen |
{ |
sound_timer --; |
} |
|
else |
{ |
// TIMSK2 &= ~_BV(TOIE2); // Interrupt sperren, verhindert Störgeräusche |
// TCCR2A = 0x00; //stop |
generate=0; // Sound aus |
tone_handler(); |
if (soundpause_timer > 0) |
{ |
soundpause_timer --; // Ton pause |
} |
} |
|
//*********************************************************************************************** |
//-------------------------------------------------------------- |
if ((key_state & LONG_MASK) == 0) // check long key function |
k_time_l = REPEAT_START; // start delay |
|
if (--k_time_l == 0) // long countdown |
key_long |= (key_state & LONG_MASK); |
|
//-------------------------------------------------------------- |
if ((key_state & REPEAT_MASK) == 0) // check repeat function |
k_time_r = 1; // kein delay |
|
if (--k_time_r == 0) |
{ |
k_time_r = REPEAT_NEXT; // repeat delay |
key_rpt |= (key_state & REPEAT_MASK); |
} |
|
//-------------------------------------------------------------- |
if ((key_state & LONG_REPEAT_MASK) == 0) // check repeat function |
k_time_lr = REPEAT_START; // start delay |
|
if (--k_time_lr == 0) |
{ |
k_time_lr = REPEAT_NEXT; // repeat delay |
key_lrpt |= (key_state & LONG_REPEAT_MASK); |
} |
|
//-------------------------------------------------------------- |
if ((key_state & LONG_REPEAT_SP_MASK) == 0) // check repeatX function |
k_time_rs = REPEAT_START; // start delay |
|
if (--k_time_rs == 0) // repeat countdown |
{ |
if (repeat_speed == 1) |
{ |
k_time_rs = REPEAT_SPEED_1; |
key_rpts |= (key_state & LONG_REPEAT_SP_MASK); |
} |
else if (repeat_speed == 2) |
{ |
k_time_rs = REPEAT_SPEED_2; |
key_rpts |= (key_state & LONG_REPEAT_SP_MASK); |
} |
else if (repeat_speed == 3) |
{ |
k_time_rs = REPEAT_SPEED_3; |
key_rpts |= (key_state & LONG_REPEAT_SP_MASK); |
} |
} |
|
if (timer > 0) |
timer --; |
|
if (timer2 > 0) |
timer2 --; |
|
if (abo_timer > 0) |
abo_timer --; |
|
//24.8.2012 |
// if (receiveNMEA==true) |
// { |
// if (bt_receiveNMEA()) Tracking_NMEA(); |
// else receiveNMEA = false; |
// |
// } |
|
} |
|
|
#ifdef HWVERSION3_9 |
|
void LipoCheck (void) // Lowbatpin des Spannungswandlers prüfen |
// LBO des LT1308 wechselt zum Ende der Batterielaufzeit häufig seinen Zustand in der Übergangsphase zum LowBat |
// Die Akkuspannung schwankt auch abhängig vom momentanen Stromverbrauch |
{ |
if (WarnToggle == 1) // Beim ersten Auftreten Warnung ausgeben, Rythmus 5/10 Sekunden |
{ |
|
set_beep ( 1000, 0x0020, BeepNormal); |
lcd_printp_at (0, 0, PSTR(" LIPO !!Warnung!! "), 2); |
} |
|
if (WarnToggle == WarnTime * 100) |
WarnToggle = 0; // erstmal bis hier warnen |
|
if (WarnToggle > 0) |
WarnToggle++; // weiter hochzählen |
|
if (PINC & (1 << LowBat)) // Kurzzeitige Unterspannung bearbeiten und Warnung ausgeben |
{ |
WarnCount = 0; |
// if (WarnCount > 0) |
// WarnCount--; // Bei LIPO OK erstmal runterzählen, LT1308 überlegt sich noch genauer ob nun ok oder nicht |
} |
|
if (!(PINC & (1 << LowBat)) ) // LT1308 hat Unterspannung erkannt |
{ |
WarnCount++; // solange LBO low ist Zähler hochzählen |
if (WarnCount == 10 && WarnToggle == 0) // mit "10" etwas unempfindlicher gegen kurze Impulse machen |
WarnToggle = 1; // Warnhinweis starten |
} |
|
if ((WarnCount) == PoffTime * 100) |
clr_V_On(); // Spannung abschalten |
} |
|
#endif |
|
|
|
|
//-------------------------------------------------------------- |
unsigned int SetDelay (unsigned int t) |
{ |
return(CountMilliseconds + t + 1); |
} |
|
|
//-------------------------------------------------------------- |
char CheckDelay(unsigned int t) |
{ |
return(((t - CountMilliseconds) & 0x8000) >> 9); |
} |
|
|
//-------------------------------------------------------------- |
void Delay_ms(unsigned int w) |
{ |
unsigned int akt; |
akt = SetDelay(w); |
while (!CheckDelay(akt)); |
} |
|
|
//-------------------------------------------------------------- |
// |
uint8_t get_key_press (uint8_t key_mask) |
{ |
uint8_t sreg = SREG; |
|
// disable all interrupts |
cli(); |
|
key_mask &= key_press; // read key(s) |
key_press ^= key_mask; // clear key(s) |
|
SREG = sreg; // restore status register |
|
return key_mask; |
} |
|
|
//-------------------------------------------------------------- |
// |
uint8_t get_key_short (uint8_t key_mask) |
{ |
uint8_t ret; |
uint8_t sreg = SREG; |
|
// disable all interrupts |
cli(); |
|
ret = get_key_press (~key_state & key_mask); |
|
SREG = sreg; // restore status register |
|
return ret; |
} |
|
|
//-------------------------------------------------------------- |
// |
uint8_t get_key_long (uint8_t key_mask) |
{ |
uint8_t sreg = SREG; |
|
// disable all interrupts |
cli(); |
|
key_mask &= key_long; // read key(s) |
key_long ^= key_mask; // clear key(s) |
|
SREG = sreg; // restore status register |
|
return get_key_press (get_key_rpt (key_mask)); |
} |
|
|
//-------------------------------------------------------------- |
// |
uint8_t get_key_rpt (uint8_t key_mask) |
{ |
uint8_t sreg = SREG; |
|
// disable all interrupts |
cli(); |
|
key_mask &= key_rpt; // read key(s) |
key_rpt ^= key_mask; // clear key(s) |
|
SREG = sreg; // restore status register |
|
return key_mask; |
} |
|
|
//-------------------------------------------------------------- |
// |
uint8_t get_key_long_rpt (uint8_t key_mask) |
{ |
uint8_t sreg = SREG; |
|
// disable all interrupts |
cli(); |
|
key_mask &= key_lrpt; // read key(s) |
key_lrpt ^= key_mask; // clear key(s) |
|
SREG = sreg; // restore status register |
|
return get_key_rpt (~key_press^key_mask); |
} |
|
|
//-------------------------------------------------------------- |
// |
uint8_t get_key_long_rpt_sp (uint8_t key_mask, uint8_t key_speed) |
{ |
uint8_t sreg = SREG; |
|
// disable all interrupts |
cli(); |
|
key_mask &= key_rpts; // read key(s) |
key_rpts ^= key_mask; // clear key(s) |
|
repeat_speed = key_speed; |
|
SREG = sreg; // restore status register |
|
return key_mask; |
} |
|
void set_beep ( uint16_t Time, uint16_t Muster, uint8_t Prio) |
{ |
if (Config.HWBeeper==1) |
{ |
if (Prio == BeepNormal) |
{ |
if (BeepPrio == BeepNormal) // nur setzen wenn keine hohe Prio schon aktiv ist |
{ |
BeepTime = Time; |
BeepMuster = Muster; |
} |
} |
|
if (Prio == BeepSevere) |
{ |
if (!BeepPrio == BeepSevere) |
{ |
BeepPrio = BeepSevere; // hohe Prio setzen |
BeepTime = Time; |
BeepMuster = Muster; |
} |
} |
|
if (Prio == BeepOff) |
{ |
BeepPrio = BeepNormal; // Beep hohe Prio aus |
BeepTime = 0; |
BeepMuster = 0; |
} |
} |
else |
{ |
|
if (Prio == BeepNormal) |
{ |
if (BeepPrio == BeepNormal) // nur setzen wenn keine hohe Prio schon aktiv ist |
{ |
playTone(900,Time/10,0); |
} |
} |
|
if (Prio == BeepSevere) |
{ |
if (!BeepPrio == BeepSevere) |
{ |
playTone(1200,Time/10,0); |
playTone(1100,Time/10,0); |
} |
} |
|
if (Prio == BeepOff) |
{ |
playTone(0,0,0); |
} |
|
} |
|
|
|
|
} |
|
|
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |