summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Adolfsson <sadolfsson@google.com>2018-05-07 00:13:09 +0200
committerchrome-bot <chrome-bot@chromium.org>2018-05-11 09:30:31 -0700
commit1ddb719bd0521ccaeaeddce656c0468192ffc360 (patch)
tree66593026a597f283dc93365abd99e0d04de14f6c
parente89486c9b6751b375fe823a2555c64760dcf832d (diff)
downloadchrome-ec-1ddb719bd0521ccaeaeddce656c0468192ffc360.tar.gz
npcx: CEC: Add resend-logic to CEC driver
According to the CEC specification, a resend must be attempted at least once and up to five times after NAK. This fix does it five times. Signed-off-by: Stefan Adolfsson <sadolfsson@chromium.org> BUG=b:76467407 BRANCH=none TEST=Write CEC message without sink. Verify with logical analyzer that it resends 5 times. CQ-DEPEND=CL:1030221 Change-Id: Id296e12b6657b9e7ca0453a2deb06e8aaf17f839 Reviewed-on: https://chromium-review.googlesource.com/1030222 Commit-Ready: Stefan Adolfsson <sadolfsson@chromium.org> Tested-by: Stefan Adolfsson <sadolfsson@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--chip/npcx/cec.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/chip/npcx/cec.c b/chip/npcx/cec.c
index f52e4ff76d..ac597860a5 100644
--- a/chip/npcx/cec.c
+++ b/chip/npcx/cec.c
@@ -33,8 +33,15 @@
/* CEC broadcast address. Also the highest possible CEC address */
#define CEC_BROADCAST_ADDR 15
+/*
+ * The CEC specification requires at least one and a maximum of
+ * five resends attempts
+ */
+#define CEC_MAX_RESENDS 5
+
/* Free time timing (us). */
#define NOMINAL_BIT_TIME APB1_TICKS(2400)
+#define FREE_TIME_RS (3 * (NOMINAL_BIT_TIME)) /* Resend */
#define FREE_TIME_NI (5 * (NOMINAL_BIT_TIME)) /* New initiator */
/* Start bit timing (us) */
@@ -107,6 +114,8 @@ struct cec_tx {
struct cec_msg_transfer msgt;
/* Message length */
uint8_t len;
+ /* Number of resends attempted in current send */
+ uint8_t resends;
/* Acknowledge received from sink? */
uint8_t ack;
};
@@ -181,7 +190,10 @@ void enter_state(enum cec_state new_state)
break;
case CEC_STATE_INITIATOR_FREE_TIME:
gpio = 1;
- timeout = FREE_TIME_NI;
+ if (cec_tx.resends)
+ timeout = FREE_TIME_RS;
+ else
+ timeout = FREE_TIME_NI;
break;
case CEC_STATE_INITIATOR_START_LOW:
cec_tx.msgt.bit = 0;
@@ -301,12 +313,20 @@ static void cec_event_timeout(void)
} else {
/* Transfer completed successfully */
cec_tx.len = 0;
+ cec_tx.resends = 0;
enter_state(CEC_STATE_IDLE);
}
} else {
- /* Transfer failed */
- cec_tx.len = 0;
- enter_state(CEC_STATE_IDLE);
+ if (cec_tx.resends < CEC_MAX_RESENDS) {
+ /* Resend */
+ cec_tx.resends++;
+ enter_state(CEC_STATE_INITIATOR_FREE_TIME);
+ } else {
+ /* Transfer failed */
+ cec_tx.len = 0;
+ cec_tx.resends = 0;
+ enter_state(CEC_STATE_IDLE);
+ }
}
break;
case CEC_STATE_INITIATOR_DATA_LOW: