Subversion Repositories Projects

Rev

Blame | Last modification | View Log | RSS feed


/************************************************************************/
/*                                                                                                                                                                                                                                                                                      */
/*                                                                                      Debouncing 8 Keys                                                                                                                               */
/*                                                                                      Sampling 4 Times                                                                                                                                */
/*                                                                                      With Repeat Function                                                                                                            */
/*                                                                                                                                                                                                                                                                                      */
/*                                                      Author: Peter Dannegger                                                                                                                                 */
/*                                                                                      danni@specs.de                                                                                                                                  */
/*                                                                                                                                                                                                                                                                                      */
/*               Ergänzt: gebad, beschschleunigende Tastenwiederholung                                          */
/*                                                                                                                                                                                                                                                                                      */
/************************************************************************/

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "keys.h"
#include "config.h"

ISR( TIMER0_OVF_vect )                                                                                                  // every 10ms
{
        static uint8_t  ct0, ct1, rpt, timer0_1, timer0_2, timer0_3, timer0_4;
        static uint16_t timer0_5 = TIMER0_5;
        uint8_t i, key_pin;

        TCNT0 = 256 - (F_CPU / 1024 * 10e-3) + 0.5;     // preload for 10ms 8bit-Timer

        key_pin = (KEY_MP_PIN & ( (1<<KEY_MINUS) | (1<<KEY_PLUS)));
        key_pin |= (KEY_ENTER_PIN & (1<<KEY_ENTER)) >> 2;// move enter bit to sw_enter bit
        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 (key_press & REPEAT_MASK) {                                                          // da bei mir alle Tasten in REPEAT_MASK
                light_count = 0;                                                                                                                // wenn keine Taste gedrückt beginnt Zähler für Hintergrundbeleuchtung aus
                timer0_5 = TIMER0_5;
        }
        if( (key_state & REPEAT_MASK) == 0 ) {                          // check repeat function
                 rpt = REPEAT_START;                                                                                            // start delay
                 key_repeat_next = REPEAT_NEXT;                                                 // Wert bestimmt Tasten-Beschleunigung/-Wiederholrate beginnt, mit 200ms
                 key_counter = REPEAT_ACC_N;                                                            // wenn V_REPEAT, nach dem angegebenen Zeichen beschleunigen
        }
        if( --rpt == 0 ){
                rpt = key_repeat_next;                                                                                  // repeat delay
                key_rpt |= key_state & REPEAT_MASK;
        }
        if ( --timer0_1 == 0) {
                timer0_1 = TIMER0_1;
                task_timer0_1 = 1;             
        }
        if ( --timer0_2 == 0) {
                timer0_2 = TIMER0_2;
                task_timer0_2 = 1;             
        }
        if ( --timer0_3 == 0) {
                timer0_3 = TIMER0_3;
                task_timer0_3 = 1;
        }
        if ( --timer0_4 == 0) {
                timer0_4 = TIMER0_4;
                task_timer0_4 = 1;             
        }
        if ( --timer0_5 == 0) {
                timer0_5 = TIMER0_5;
                task_timer0_5 = 1;             
        }
}

///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed. Each pressed key is reported
// only once
//
uint8_t Get_Key_Press( uint8_t key_mask )
{
        cli();                                                                                                                                                          // read and clear atomic !
        key_mask &= key_press;                                                                                          // read key(s)
        key_press ^= key_mask;                                                                                          // clear key(s)
        sei();
        return key_mask;
}

///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed long enough such that the
// key repeat functionality kicks in. After a small setup delay
// the key is reported beeing pressed in subsequent calls
// to this function. This simulates the user repeatedly
// pressing and releasing the key.
//
uint8_t Get_Key_Rpt( uint8_t key_mask )
{
        cli();                                                                                                                                                          // read and clear atomic !
        key_mask &= key_rpt;                                                                                                    // read key(s)
        key_rpt ^= key_mask;                                                                                                    // clear key(s)
        sei();
        return key_mask;
}

///////////////////////////////////////////////////////////////////
//
uint8_t Get_Key_Short( uint8_t key_mask )
{
        cli();                                                                                                                                                          // read key state and key press atomic !
        return Get_Key_Press( ~key_state & key_mask );
}

///////////////////////////////////////////////////////////////////
//
uint8_t Get_Key_Long( uint8_t key_mask )
{
        return Get_Key_Press( Get_Key_Rpt( key_mask ));
}

void Key_Speedup_rpt( uint8_t speedup )
{
        if (speedup) {
                if (key_counter > 0) {                                          // nach x Zeichen wird Wiederholrate kontinuierlich erhöht
                        cli();
                        key_counter--;
                        sei();
                }
                else {
                        if (key_repeat_next > 3) {                      // jetzt beschleunigen, Wert bestimmt die max. Beschleunigung/Wiederholrate
                                cli();                                                                                          // kann jedoch nicht kleiner 10ms sein
                                key_repeat_next -= 2;                                   // noch etwas schneller
                                sei();
                        }
                }
        }
}