summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorTing Shen <phoenixshen@google.com>2019-10-17 17:56:03 +0800
committerCommit Bot <commit-bot@chromium.org>2019-10-21 07:25:18 +0000
commite36da133d89c675592c2ade4c0cbc80035db3fde (patch)
tree7d4da407d971bcc888bb6b7400b3ef8d43ae5848 /chip
parent0152ee73ab98d29c252243547fd89e8713ca4e62 (diff)
downloadchrome-ec-e36da133d89c675592c2ade4c0cbc80035db3fde.tar.gz
stm32f0: handle i2c reload mode properly
Fixed a bug that RELOAD bit not cleared properly when there's two consecutive chip_i2c_xfer() calls, where the first call only contains "write" transaction, and the second call contains a "read" transaction. BUG=b:138095176 TEST=Case 1 - write and read in two separate i2c_xfer call: `ectool i2cxfer 1 0x55 8 0x64` On Krane, this should print the string "L16D2P31" in hex. Case 2 - no write and read 1 byte: `i2cscan` in ec console. BRANCH=kukui Change-Id: I57c1909058606b458801b3b35f54c16c1309c594 Signed-off-by: Ting Shen <phoenixshen@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1866222 Reviewed-by: Alexandru M Stan <amstan@chromium.org> Reviewed-by: Eric Yilun Lin <yllin@chromium.org> Commit-Queue: Ting Shen <phoenixshen@chromium.org> Tested-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/stm32/i2c-stm32f0.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/chip/stm32/i2c-stm32f0.c b/chip/stm32/i2c-stm32f0.c
index c612e922c5..49be4833c5 100644
--- a/chip/stm32/i2c-stm32f0.c
+++ b/chip/stm32/i2c-stm32f0.c
@@ -447,8 +447,25 @@ int chip_i2c_xfer(const int port, const uint16_t slave_addr_flags,
/* Clear status */
if (xfer_start) {
+ uint32_t cr2 = STM32_I2C_CR2(port);
+
STM32_I2C_ICR(port) = STM32_I2C_ICR_ALL;
STM32_I2C_CR2(port) = 0;
+ if (cr2 & STM32_I2C_CR2_RELOAD) {
+ /*
+ * If I2C_XFER_START flag is on and we've set RELOAD=1
+ * in previous chip_i2c_xfer() call. Then we are
+ * probably in the middle of an i2c transaction.
+ *
+ * In this case, we need to clear the RELOAD bit and
+ * wait for Transfer Complete (TC) flag, to make sure
+ * the chip is not expecting another NBYTES data, And
+ * send repeated-start correctly.
+ */
+ rv = wait_isr(port, STM32_I2C_ISR_TC);
+ if (rv)
+ goto xfer_exit;
+ }
}
if (out_bytes || !in_bytes) {