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) {    // Wert bestimmt die max. Beschleunigung/Wiederholrate
            cli();                                              // kann jedoch nicht kleiner 10ms sein
                key_repeat_next -= 2;
                sei();
          }
        }
  }
}