mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-14 08:36:39 +00:00
npcx: CEC: Add software debouncing
If pulses shorter than the CEC specification allows are detected, ignore the bus for a while. This avoids CPU stress if there is a misbehaving device sending short pulses on the CEC bus. Signed-off-by: Stefan Adolfsson <sadolfsson@chromium.org> BUG=b:76467407 BRANCH=none TEST=none CQ-DEPEND=CL:1030228 Change-Id: I55819f9437a00799718e235c30f256508465bf4c Reviewed-on: https://chromium-review.googlesource.com/1030229 Commit-Ready: Stefan Adolfsson <sadolfsson@chromium.org> Tested-by: Stefan Adolfsson <sadolfsson@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
394ede0e6e
commit
edac0b1924
@@ -89,6 +89,19 @@
|
||||
#define DATA_HIGH(data) DATA_TIME(HIGH, data)
|
||||
#define DATA_LOW(data) DATA_TIME(LOW, data)
|
||||
|
||||
/*
|
||||
* Number of short pulses seen before the debounce logic goes into ignoring
|
||||
* the bus for DEBOUNCE_WAIT_LONG instead of DEBOUNCE_WAIT_SHORT
|
||||
*/
|
||||
#define DEBOUNCE_CUTOFF 3
|
||||
|
||||
/* The limit how short a start-bit can be to trigger debounce logic */
|
||||
#define DEBOUNCE_LIMIT APB1_TICKS(200)
|
||||
/* The time we ignore the bus for the first three debounce cases */
|
||||
#define DEBOUNCE_WAIT_SHORT APB1_TICKS(100)
|
||||
/* The time we ignore the bus after the three initial debounce cases */
|
||||
#define DEBOUNCE_WAIT_LONG APB1_TICKS(500)
|
||||
|
||||
/*
|
||||
* The variance in timing we allow outside of the CEC specification for
|
||||
* incoming signals. Our measurements aren't 100% accurate either, so this
|
||||
@@ -142,6 +155,7 @@ enum cec_state {
|
||||
CEC_STATE_INITIATOR_ACK_VERIFY,
|
||||
CEC_STATE_FOLLOWER_START_LOW,
|
||||
CEC_STATE_FOLLOWER_START_HIGH,
|
||||
CEC_STATE_FOLLOWER_DEBOUNCE,
|
||||
CEC_STATE_FOLLOWER_HEADER_INIT_LOW,
|
||||
CEC_STATE_FOLLOWER_HEADER_INIT_HIGH,
|
||||
CEC_STATE_FOLLOWER_HEADER_DEST_LOW,
|
||||
@@ -203,6 +217,8 @@ struct cec_rx {
|
||||
* pulse duration
|
||||
*/
|
||||
int low_time;
|
||||
/* Number of too short pulses seen in a row */
|
||||
int debounce_count;
|
||||
};
|
||||
|
||||
/* Transfer buffer and states */
|
||||
@@ -550,9 +566,18 @@ void enter_state(enum cec_state new_state)
|
||||
timeout = CAP_START_LOW;
|
||||
break;
|
||||
case CEC_STATE_FOLLOWER_START_HIGH:
|
||||
cec_rx.debounce_count = 0;
|
||||
cap_edge = CAP_EDGE_FALLING;
|
||||
timeout = CAP_START_HIGH;
|
||||
break;
|
||||
case CEC_STATE_FOLLOWER_DEBOUNCE:
|
||||
if (cec_rx.debounce_count >= DEBOUNCE_CUTOFF) {
|
||||
timeout = DEBOUNCE_WAIT_LONG;
|
||||
} else {
|
||||
timeout = DEBOUNCE_WAIT_SHORT;
|
||||
cec_rx.debounce_count++;
|
||||
}
|
||||
break;
|
||||
case CEC_STATE_FOLLOWER_HEADER_INIT_LOW:
|
||||
case CEC_STATE_FOLLOWER_HEADER_DEST_LOW:
|
||||
case CEC_STATE_FOLLOWER_EOM_LOW:
|
||||
@@ -723,6 +748,7 @@ static void cec_event_timeout(void)
|
||||
break;
|
||||
case CEC_STATE_FOLLOWER_START_LOW:
|
||||
case CEC_STATE_FOLLOWER_START_HIGH:
|
||||
case CEC_STATE_FOLLOWER_DEBOUNCE:
|
||||
case CEC_STATE_FOLLOWER_HEADER_INIT_LOW:
|
||||
case CEC_STATE_FOLLOWER_HEADER_INIT_HIGH:
|
||||
case CEC_STATE_FOLLOWER_HEADER_DEST_LOW:
|
||||
@@ -765,6 +791,9 @@ static void cec_event_cap(void)
|
||||
if (VALID_LOW(START_BIT, t)) {
|
||||
cec_rx.low_time = t;
|
||||
enter_state(CEC_STATE_FOLLOWER_START_HIGH);
|
||||
} else if (t < DEBOUNCE_LIMIT) {
|
||||
/* Wait a bit if start-pulses are really short */
|
||||
enter_state(CEC_STATE_FOLLOWER_DEBOUNCE);
|
||||
} else {
|
||||
enter_state(CEC_STATE_IDLE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user