Skip to content

Commit 81cd7ca

Browse files
martinjaegerkartben
authored andcommitted
drivers: input: input_adc_keys: add debouncing to avoid false events
The previous implementation already reported a key-press event after reading an ADC value close to the threshold for the first time. This may lead to false events if the ADC takes a reading just during the transition from one button state to another (especially if a somewhat large capacitor is used to avoid noise). A key-press state must be same for at least two samples in order to avoid such issues, which is what this commit implements. Signed-off-by: Martin Jäger <martin@libre.solar>
1 parent 07e1de3 commit 81cd7ca

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

drivers/input/input_adc_keys.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct adc_keys_code_config {
2323
};
2424

2525
struct adc_keys_key_state {
26+
bool orig_state;
2627
bool last_state;
2728
bool curr_state;
2829
};
@@ -99,7 +100,18 @@ static inline void adc_keys_process(const struct device *dev)
99100
LOG_DBG("sample=%d mV, closest=%d mV, diff=%d mV", sample_mv, closest_mv, closest_diff);
100101

101102
/*
102-
* Update cached key states according to the closest key press threshold.
103+
* Update cached key states and init current states with false
104+
*/
105+
106+
for (uint8_t i = 0; i < cfg->key_cnt; i++) {
107+
key_state = &cfg->key_state[i];
108+
109+
key_state->last_state = key_state->curr_state;
110+
key_state->curr_state = false;
111+
}
112+
113+
/*
114+
* Update current key states according to the closest key press threshold.
103115
*
104116
* Note that multiple keys may have the same press threshold, which is
105117
* the mixed voltage that these keys are simultaneously pressed.
@@ -119,25 +131,20 @@ static inline void adc_keys_process(const struct device *dev)
119131
}
120132

121133
/*
122-
* Report the key event if the key state has changed.
134+
* Report the key event if the key state changed for at least two continuous cycles.
123135
*/
124136

125137
for (uint8_t i = 0; i < cfg->key_cnt; i++) {
126138
key_state = &cfg->key_state[i];
127139
key_code = cfg->key_code[i];
128140

129-
if (key_state->last_state != key_state->curr_state) {
141+
if (key_state->orig_state != key_state->curr_state &&
142+
key_state->last_state == key_state->curr_state) {
130143
LOG_DBG("Report event %s %d, code=%d", dev->name, key_state->curr_state,
131144
key_code);
132145
input_report_key(dev, key_code, key_state->curr_state, true, K_FOREVER);
133-
key_state->last_state = key_state->curr_state;
146+
key_state->orig_state = key_state->curr_state;
134147
}
135-
136-
/*
137-
* Reset the state so that it can be updated in the next
138-
* iteration.
139-
*/
140-
key_state->curr_state = false;
141148
}
142149
}
143150

0 commit comments

Comments
 (0)