diff options
author | Ting Shen <phoenixshen@google.com> | 2019-10-17 17:56:03 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-21 07:25:18 +0000 |
commit | e36da133d89c675592c2ade4c0cbc80035db3fde (patch) | |
tree | 7d4da407d971bcc888bb6b7400b3ef8d43ae5848 | |
parent | 0152ee73ab98d29c252243547fd89e8713ca4e62 (diff) | |
download | chrome-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>
-rw-r--r-- | chip/stm32/i2c-stm32f0.c | 17 |
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) { |