Rev 2136 |
Blame |
Last modification |
View Log
| RSS feed
/*****************************************************************************
* 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
//#
//#
//# 08.08.2015 CB
//# - add: timer_nmea_timeout
//#
//# 29.06.2014 OG
//# - chg: ISR( TIMER0_COMPA_vect ) - LipoCheck() wieder hinzugefuegt
//# - chg: LipoCheck() - leichte optische Anpassung und lcd-Ausgabe an ISR angepasst
//# - add: #include "../lipo/lipo.h"
//#
//# 24.06.2014 OG
//# - add: timer_gauge
//# - add: #include "../pkt/pkt.h"
//#
//# 13.06.2014 OG
//# - del: IdleTimer entfernt da nicht verwendet
//# - chg: ISR(TIMER0_COMPA_vect) - "PKT aus nach" (via timer_pkt_off)
//# - chg: ISR(TIMER0_COMPA_vect) - "LCD aus nach" umgestellt von Sekunden
//# auf Minuten (via timer_lcd_off)
//# - chg: Code-Formattierung
//#
//# 31.05.2014 OG
//# - chg: 'timer_pktctrl' umbenannt zu 'timer_pktupdatecheck' (exklusiv fuer pkt.c)
//#
//# 25.04.2014 OG
//# - add: timer_get_displaydata
//#
//# 24.04.2014 OG
//# - add: timer1 (generischer Timer)
//# - add: timer3 (generischer Timer)
//# - add: timer_mk_timeout
//# - del: timer_get_erdata
//#
//# 29.03.2014 OG
//# - add: clear_key_all() - loescht ALLE Tasten egal ob short, long, repeat...
//#
//# 13.06.2013 cebra
//# - chg: Abfrage nach Hardwaresound bei Displaybeleuchtung entfällt
//#
//# 19.05.2013 OG
//# - add: timer_pktctrl - exclusive Verwendung von pkt.c
//#
//# 24.03.2013 OG
//# - add: UTCTime - inkrementiert wird UTCTime.seconds auf der Basis
//# von timer_pkt_uptime (modulo 100) aktuell initialisert von
//# der MK-NC Time durch OSD_MK_UTCTime()
//# - add: timer_get_tidata
//#
//# 21.03.2013 OG
//# - add: timer_pkt_uptime (auch in timer.h)
//# - add: timer_osd_refresh (auch in timer.h) -> verwendet in osd.c
//# - add: timer_get_bldata (auch in timer.h) -> verwendet in osd.c
//# - add: timer_get_erdata (auch in timer.h) -> verwendet in osd.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"
#include "../lipo/lipo.h"
#include "../pkt/pkt.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
//----------------------
// generische Timer
//----------------------
volatile uint16_t timer;
volatile uint16_t timer1;
volatile uint16_t timer2;
volatile uint16_t timer3;
//----------------------
// spezielle Timer
//----------------------
volatile uint16_t timer_pktupdatecheck; // verwendet von pkt.c (!EXKLUSIV!)
volatile uint16_t timer_osd_refresh; // verwendet in osd.c
volatile uint16_t timer_get_bldata; // verwendet in osd.c
volatile uint16_t timer_get_tidata; // verwendet in osd.c
volatile uint16_t timer_get_displaydata; // verwendet in osd.c
volatile uint16_t timer_mk_timeout; // verwendet u.a. in osd.c
volatile uint16_t timer_gauge; // verwendet in pkt.c fuer den rotierenden Wartekreisel
volatile uint16_t timer_nmea_timeout; // verwendet in nmea.c
volatile uint16_t abo_timer;
uint32_t timer_lcd_off = 0; // LCD aus nach... (der Zaehler muss 32Bit sein)
uint32_t timer_pkt_off = 0; // PKT aus nach... (der Zaehler muss 32Bit sein)
volatile uint16_t sound_timer;
volatile uint16_t soundpause_timer;
volatile static unsigned int tim_main;
volatile PKTdatetime_t UTCTime;
volatile uint32_t timer_pkt_uptime = 0; // OG: ja, 32 bit muss so sein!
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;
volatile uint8_t Display_on; // LCD Flag Display on/off
volatile uint16_t WarnCount = 0; // Zähler der LIPO Warnzeit
volatile uint16_t WarnToggle = 0; // Togglezähler zum blinken
volatile uint16_t WarnTime = 10; // Laenge der LIPO Warnzeit 10 Sek.
volatile uint16_t PoffTime = 15; // Laenge der Wartezeit vor abschalten 15 Sek.
//volatile uint16_t PoffTime = 30; // Laenge der Wartezeit vor abschalten 30 Sek.
unsigned int BeepTime = 0;
unsigned int BeepMuster = 0xffff;
unsigned int BeepPrio = 0;
volatile unsigned int CountMilliseconds = 0;
//--------------------------------------------------------------
// System (100Hz)
//--------------------------------------------------------------
void Timer0_Init( void )
{
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;
}
}
//--------------------------------------------------------------
// Sound, Timer CTC
//--------------------------------------------------------------
void Timer3_Init( void )
{
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
}
//--------------------------------------------------------------
//--------------------------------------------------------------
#ifdef USE_SOUND
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;
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
}
}
#endif
//--------------------------------------------------------------
// Timer-Interrupt (100 Hz)
//--------------------------------------------------------------
ISR( TIMER0_COMPA_vect )
{
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;
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( !cnt-- )
{
cnt = 9;
CountMilliseconds++;
cnt_1ms++;
}
//--------------------------------
// Key pressed -> Timer Reset
//--------------------------------
if( i!=0 ) // eine Taste wurde gedrueckt! -> Timer Rest und weiteres...
{
if( Display_on == 0 ) // ggf. Displaylicht einschalten
set_D_LIGHT();
Display_on = 1; // Flag Display on
timer_lcd_off = 0; // Timer Reset
timer_pkt_off = 0; // Timer Reset
}
//--------------------------------
// LCD off Timeout
// LCD ausschalten nach n Minuten
//--------------------------------
if( (Config.DisplayTimeout > 0) && (Display_on == 1) )
{
timer_lcd_off++;
if( (timer_lcd_off/(100*60)) == Config.DisplayTimeout ) // ISR laeuft mit 100Hz; umgerechnet auf Minuten
{
clr_D_LIGHT(); // Displaylicht ausschalten
Display_on = 0; // Flag Display off
}
}
//--------------------------------
// PKT off Timeout
// PKT ausschalten nach n Minuten
//--------------------------------
if( Config.PKTOffTimeout > 0 )
{
timer_pkt_off++;
if( (timer_pkt_off/(100*60)) == Config.PKTOffTimeout ) // ISR laeuft mit 100Hz; umgerechnet auf Minuten
{
WriteParameter(); // am Ende alle Parameter sichern
set_beep( 50, 0xffff, BeepNormal ); // ein Mini-Beep zum Abschied (laenger geht nicht, wahrscheinlich wegen der ISR)
clr_V_On(); // Spannung abschalten
}
}
//--------------------------------
// PKT bei Unterspannung abschalten
//--------------------------------
LipoCheck();
//--------------------------------
// Beeper
//--------------------------------
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();
}
//--------------------------------
// Sound
//--------------------------------
#ifdef USE_SOUND
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
}
}
#endif
//--------------------------------
// Tasten
//--------------------------------
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);
}
}
//--------------------------------
// generische Timer
//--------------------------------
if( timer > 0 ) timer --;
if( timer1 > 0 ) timer1 --;
if( timer2 > 0 ) timer2 --;
if( timer3 > 0 ) timer3 --;
//--------------------------------
// spezielle Timer
//--------------------------------
if( timer_osd_refresh > 0 ) timer_osd_refresh--; // Timer fuer OSD-Screenrefresh (verwendet von osd.c)
if( timer_get_bldata > 0 ) timer_get_bldata--; // Timer um BL-Daten zu holen (verwendet von osd.c)
if( timer_get_tidata > 0 ) timer_get_tidata--; // Timer um Datum/Zeit vom MK zu holen (verwendet von osd.c)
if( timer_get_displaydata > 0 ) timer_get_displaydata--; // Timer um Display vom MK zu holen (verwendet von osd.c)
if( timer_mk_timeout > 0 ) timer_mk_timeout--; // verwendet u.a. von osd.c
if( abo_timer > 0 ) abo_timer --; // Timer zum anfordern neuer Abo-Datenpakete wie OSD oder BL-Daten (verwendet u.a. von osd.c)
if( timer_pktupdatecheck > 0 ) timer_pktupdatecheck--; // Timer fuer pkt.c (PKT-Update-Check) - * FUER NICHTS ANDERES! *
if( timer_nmea_timeout > 0 ) timer_nmea_timeout--; // verwendet u.a. von osd.c
//--------------------------------
//--------------------------------
if( Gauge_active ) // Gauge_active -> pkt.c
{
if( timer_gauge > 0 ) timer_gauge--;
if( timer_gauge==0 ) PKT_Gauge_Next();
}
//--------------------------------
// PKT Uptime Timer
//--------------------------------
timer_pkt_uptime++;
if( timer_pkt_uptime % 100 == 0 ) // theoretisch muesste noch die Tagesgrenze (0 Uhr) implementiert werden...
UTCTime.seconds++;
} // end: ISR(TIMER0_COMPA_vect)
//--------------------------------------------------------------
// Lowbatpin des Spannungswandlers pruefen
// LBO des LT1308 wechselt zum Ende der Batterielaufzeit haeufig seinen Zustand in der Uebergangsphase zum LowBat
// Die Akkuspannung schwankt auch abhaengig vom momentanen Stromverbrauch
//--------------------------------------------------------------
void LipoCheck( void )
{
uint8_t lcd_xpos_save;
uint8_t lcd_ypos_save;
if( WarnToggle == 1 ) // Beim ersten Auftreten Warnung ausgeben, Rythmus 5/10 Sekunden
{
set_beep( 1000, 0x0020, BeepNormal);
lcd_xpos_save = lcd_xpos; // innerhalb einer ISR -> LCD Screenpos muss gesichert werden!
lcd_ypos_save = lcd_ypos;
//lcdx_cls_row( y, mode, yoffs )
lcdx_cls_row( 0, MINVERS ,0 ); // Zeile 0 komplett invers
lcd_printp_at( 0, 0, PSTR(" ** PKT LiPo! ** "), MINVERS); // und Warn-Text ausgeben
lcd_xpos = lcd_xpos_save; // lcd Screenpos wieder herstellen
lcd_ypos = lcd_ypos_save;
}
if( WarnToggle == WarnTime * 100 )
WarnToggle = 0; // erstmal bis hier warnen
if( WarnToggle > 0 )
WarnToggle++; // weiter hochzaehlen
if( PINC & (1 << LowBat) ) // Kurzzeitige Unterspannung bearbeiten und Warnung ausgeben
{
WarnCount = 0;
//if (WarnCount > 0)
// WarnCount--; // Bei LIPO OK erstmal runterzaehlen, LT1308 ueberlegt 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) )
{
set_beep( 50, 0xffff, BeepNormal ); // ein Mini-Beep zum Abschied (laenger geht nicht, wahrscheinlich wegen der ISR)
WriteParameter(); // am Ende alle Parameter sichern
clr_V_On(); // Spannung abschalten
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
//void LipoCheck_OLD( void )
//{
// 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 hochzaehlen
//
// if( PINC & (1 << LowBat) ) // Kurzzeitige Unterspannung bearbeiten und Warnung ausgeben
// {
// WarnCount = 0;
// //if (WarnCount > 0)
// // WarnCount--; // Bei LIPO OK erstmal runterzaehlen, LT1308 ueberlegt 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
// }
//}
//--------------------------------------------------------------
//--------------------------------------------------------------
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;
cli(); // disable all interrupts
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;
cli(); // disable all interrupts
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;
cli(); // disable all interrupts
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;
cli(); // disable all interrupts
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;
cli(); // disable all interrupts
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;
cli(); // disable all interrupts
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 clear_key_all( void )
{
key_rpt = 0; // clear key(s)
key_rpts = 0; // clear key(s)
key_lrpt = 0; // clear key(s)
key_long = 0; // clear key(s)
key_press = 0; // clear key(s)
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void set_beep( uint16_t Time, uint16_t Muster, uint8_t Prio)
{
if( Config.HWBeeper == 1 )
{
if( (Prio == BeepNormal) && (BeepPrio == BeepNormal) ) // BEEPER: nur setzen wenn keine hohe Prio schon aktiv ist
{
BeepTime = Time;
BeepMuster = Muster;
}
if( (Prio == BeepSevere) && (!BeepPrio == BeepSevere) ) // BEEPER: hohe Prio setzen
{
BeepPrio = BeepSevere;
BeepTime = Time;
BeepMuster = Muster;
}
if( Prio == BeepOff )
{
BeepPrio = BeepNormal; // BEEPER: Beep hohe Prio aus
BeepTime = 0;
BeepMuster = 0;
}
} // end: if( Config.HWBeeper==1 )
#ifdef USE_SOUND
else
{
if( (Prio == BeepNormal) && (BeepPrio == BeepNormal) ) // SOUND: nur setzen wenn keine hohe Prio schon aktiv ist
{
playTone(900,Time/10,0);
}
if( (Prio == BeepSevere) && (!BeepPrio == BeepSevere) )
{
playTone(1200,Time/10,0);
playTone(1100,Time/10,0);
}
if( Prio == BeepOff )
{
playTone(0,0,0);
}
}
#endif // end: #ifdef USE_SOUND
}