diff --git a/radio/src/keys.cpp b/radio/src/keys.cpp index 00ce73711..4c0580b06 100644 --- a/radio/src/keys.cpp +++ b/radio/src/keys.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -20,8 +20,27 @@ #include "opentx.h" +#define KEY_LONG_DELAY 32 // long key press minimum duration (x10ms), must be less than KEY_REPEAT_DELAY +#define KEY_REPEAT_DELAY 40 // press longer than this enables repeat (but does not fire it yet) +#define KEY_REPEAT_TRIGGER 48 // repeat trigger, used in combination with m_state to produce decreasing times between repeat events +#define KEY_REPEAT_PAUSE_DELAY 64 + +#ifdef SIMU + #define FILTERBITS 1 // defines how many bits are used for debounce +#else + #define FILTERBITS 4 // defines how many bits are used for debounce +#endif + +#define KSTATE_OFF 0 +#define KSTATE_RPTDELAY 95 +#define KSTATE_START 97 +#define KSTATE_PAUSE 98 +#define KSTATE_KILLED 99 + + event_t s_evt; struct t_inactivity inactivity = {0}; +Key keys[NUM_KEYS]; #if defined(CPUARM) event_t getEvent(bool trim) @@ -47,11 +66,9 @@ event_t getEvent() } #endif -#define KEY_LONG_DELAY 32 - -Key keys[NUM_KEYS]; void Key::input(bool val) { + // store new value in the bits that hold the key state history (used for debounce) uint8_t t_vals = m_vals ; t_vals <<= 1 ; if (val) t_vals |= 1; @@ -59,32 +76,39 @@ void Key::input(bool val) m_cnt++; - if (m_state && m_vals==0) { + if (m_state && m_vals == 0) { + // key is released if (m_state != KSTATE_KILLED) { + // TRACE("key %d BREAK", key()); putEvent(EVT_KEY_BREAK(key())); } - m_cnt = 0; m_state = KSTATE_OFF; + m_cnt = 0; + return; } + switch (m_state) { case KSTATE_OFF: - if (m_vals == FFVAL) { + if (m_vals == ((1<= 48) { //3 6 12 24 48 pulses in every 480ms + if (m_cnt >= KEY_REPEAT_TRIGGER) { //3 6 12 24 48 pulses in every 480ms m_state >>= 1; - m_cnt = 0; + m_cnt = 0; } // no break case 1: if ((m_cnt & (m_state-1)) == 0) { + // this produces repeat events that at first repeat slowly and then increase in speed + // TRACE("key %d REPEAT", key()); putEvent(EVT_KEY_REPT(key())); } break; - case KSTATE_PAUSE: //pause - if (m_cnt >= 64) { + case KSTATE_PAUSE: //pause repeat events + if (m_cnt >= KEY_REPEAT_PAUSE_DELAY) { m_state = 8; - m_cnt = 0; + m_cnt = 0; } break; @@ -117,17 +143,32 @@ void Key::input(bool val) } } +void Key::pauseEvents() +{ + m_state = KSTATE_PAUSE; + m_cnt = 0; +} + +void Key::killEvents() +{ + // TRACE("key %d killed", key()); + m_state = KSTATE_KILLED; +} + + uint8_t Key::key() const { return (this - keys); } +// Introduce a slight delay in the key repeat sequence void pauseEvents(event_t event) { event = EVT_KEY_MASK(event); if (event < (int)DIM(keys)) keys[event].pauseEvents(); } +// Disables any further event generation (BREAK and REPEAT) for this key, until the key is released void killEvents(event_t event) { #if defined(ROTARY_ENCODERS) diff --git a/radio/src/keys.h b/radio/src/keys.h index d7a7048c9..5475a7aed 100644 --- a/radio/src/keys.h +++ b/radio/src/keys.h @@ -41,15 +41,16 @@ #define EVT_ENTRY_UP 0xbe #endif -#define EVT_KEY_BREAK(key) ((key)|_MSK_KEY_BREAK) -#define EVT_KEY_FIRST(key) ((key)|_MSK_KEY_FIRST) -#define EVT_KEY_REPT(key) ((key)|_MSK_KEY_REPT) -#define EVT_KEY_LONG(key) ((key)|_MSK_KEY_LONG) +// normal order of events is: FIRST, LONG, REPEAT, REPEAT, ..., BREAK +#define EVT_KEY_FIRST(key) ((key)|_MSK_KEY_FIRST) // fired when key is pressed +#define EVT_KEY_LONG(key) ((key)|_MSK_KEY_LONG) // fired when key is held pressed for a while +#define EVT_KEY_REPT(key) ((key)|_MSK_KEY_REPT) // fired when key is held pressed long enough, fires multiple times with increasing speed +#define EVT_KEY_BREAK(key) ((key)|_MSK_KEY_BREAK) // fired when key is released (short or long), but only if the event was not killed -#define IS_KEY_BREAK(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_BREAK) #define IS_KEY_FIRST(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_FIRST) #define IS_KEY_LONG(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_LONG) #define IS_KEY_REPT(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_REPT) +#define IS_KEY_BREAK(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_BREAK) #if (defined(PCBHORUS) || defined(PCBFLAMENCO) || defined(PCBTARANIS)) && defined(ROTARY_ENCODER_NAVIGATION) typedef uint16_t event_t; @@ -79,34 +80,19 @@ class Key { -#define FILTERBITS 4 - -#ifdef SIMU - #define FFVAL 1 -#else - #define FFVAL ((1< 0; } - void pauseEvents() { m_state = KSTATE_PAUSE; m_cnt = 0; } - void killEvents() { m_state = KSTATE_KILLED; } + bool state() const { return m_vals > 0; } + void pauseEvents(); + void killEvents(); uint8_t key() const; }; extern Key keys[NUM_KEYS]; - extern event_t s_evt; #define putEvent(evt) s_evt = evt