Merge pull request #1269 from pkendall64/crsf-max-output
[ExpressLRS.git] / src / lib / SCREEN / FiveWayButton / FiveWayButton.cpp
blobaf1803ef62111d4d8326cb386c5b7487c69d6884
1 #ifdef HAS_FIVE_WAY_BUTTON
2 #include "FiveWayButton.h"
4 #define KEY_DEBOUNCE_TIME 500
5 #define KEY_LONG_RPESS_TIME 1000
6 #define KEY_CHECK_OVER_TIME 2000
9 uint32_t key_debounce_start = 0;
11 int key = INPUT_KEY_NO_PRESS;
14 #ifdef GPIO_PIN_JOYSTICK
15 #define UP 0;
16 #define DOWN 1;
17 #define LEFT 2;
18 #define RIGHT 3;
19 #define ENTER 4;
20 #define IDLE 5;
22 static int16_t joyAdcValues[] = JOY_ADC_VALUES;
24 // Returns minimum difference between any pair
25 int findMinDiff(int16_t arr[], int n)
27 // Initialize difference as infinite
28 int diff = 1000;
30 // Find the min diff by comparing difference
31 // of all possible pairs in given array
32 for (int i=0; i<n-1; i++)
33 for (int j=i+1; j<n; j++)
34 if (abs(arr[i] - arr[j]) < diff)
35 diff = abs(arr[i] - arr[j]);
37 // Return min diff
38 return diff;
41 bool checkValue(int direction){
42 int value = analogRead(GPIO_PIN_JOYSTICK);
43 if(value < (joyAdcValues[direction] + 50) && value > (joyAdcValues[direction] - 50)){
44 return true;
45 } else {
46 return false;
50 int checkKey()
52 int fuzz = (findMinDiff(joyAdcValues, 6) /2 );
53 int value = analogRead(GPIO_PIN_JOYSTICK);
55 if(value < (joyAdcValues[0] + fuzz) && value > (joyAdcValues[0] - fuzz))
56 return INPUT_KEY_UP_PRESS;
57 else if(value < (joyAdcValues[1] + fuzz) && value > (joyAdcValues[1] - fuzz))
58 return INPUT_KEY_DOWN_PRESS;
59 else if(value < (joyAdcValues[2] + fuzz) && value > (joyAdcValues[2] - fuzz))
60 return INPUT_KEY_LEFT_PRESS;
61 else if(value < (joyAdcValues[3] + fuzz) && value > (joyAdcValues[3] - fuzz))
62 return INPUT_KEY_RIGHT_PRESS;
63 else if(value < (joyAdcValues[4] + fuzz) && value > (joyAdcValues[4] - fuzz))
64 return INPUT_KEY_OK_PRESS;
65 else
66 return INPUT_KEY_NO_PRESS;
68 #endif
70 void FiveWayButton::init()
72 #ifndef JOY_ADC_VALUES
73 pinMode(GPIO_PIN_FIVE_WAY_INPUT1, INPUT|PULLUP );
74 pinMode(GPIO_PIN_FIVE_WAY_INPUT2, INPUT|PULLUP );
75 pinMode(GPIO_PIN_FIVE_WAY_INPUT3, INPUT|PULLUP );
76 #endif
78 key_state = INPUT_KEY_NO_PRESS;
79 keyPressed = false;
80 isLongPressed = false;
83 void FiveWayButton::handle()
85 if(keyPressed)
87 #ifndef JOY_ADC_VALUES
88 int key_down = digitalRead(GPIO_PIN_FIVE_WAY_INPUT1) << 2 | digitalRead(GPIO_PIN_FIVE_WAY_INPUT2) << 1 | digitalRead(GPIO_PIN_FIVE_WAY_INPUT3);
89 #else
90 // Hack, we know that INPUT_KEY_NO_PRESS = 7 so for analog we would have to have it equal idle
91 int key_down = checkKey();
92 #endif
95 if(key_down == INPUT_KEY_NO_PRESS)
97 //key released
98 if(isLongPressed)
100 clearKeyState();
102 else
104 key_state = key;
105 if((millis() - key_debounce_start) > KEY_DEBOUNCE_TIME)
107 keyPressed = false;
111 else
113 if((millis() - key_debounce_start) > KEY_LONG_RPESS_TIME)
115 isLongPressed = true;
119 else
121 #ifndef JOY_ADC_VALUES
122 key = digitalRead(GPIO_PIN_FIVE_WAY_INPUT1) << 2 | digitalRead(GPIO_PIN_FIVE_WAY_INPUT2) << 1 | digitalRead(GPIO_PIN_FIVE_WAY_INPUT3);
123 #else
124 key = checkKey();
125 #endif
127 if(key != INPUT_KEY_NO_PRESS)
129 keyPressed = true;
130 isLongPressed = false;
131 key_debounce_start = millis();
136 void FiveWayButton::getKeyState(int *keyValue, bool *keyLongPressed)
138 *keyValue = key_state;
139 *keyLongPressed = isLongPressed;
140 if(key_state != INPUT_KEY_NO_PRESS)
142 clearKeyState();
146 void FiveWayButton::clearKeyState()
148 keyPressed = false;
149 isLongPressed = false;
150 key_state = INPUT_KEY_NO_PRESS;
152 #endif