diff options
author | Wei-Ning Huang <wnhuang@google.com> | 2017-05-23 18:56:34 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-05-23 16:56:55 -0700 |
commit | 4c9e99b5e9a13ceca37b51c671323e94f0bd8fc6 (patch) | |
tree | bc0a9085f061a5a3a2693e899c529a188db0e7b3 /chip | |
parent | 4ce20f3f79d93f57f5c9974fdbe80316cb94f537 (diff) | |
download | chrome-ec-4c9e99b5e9a13ceca37b51c671323e94f0bd8fc6.tar.gz |
stm32f4: i2c: process stop condition after slave receiver executed
We need to process the stop condition after slaver receiver is executed,
or else we will lost the last byte of the transmission.
BRANCH=none
BUG=b:38510075
TEST=`make BOARD=rose -j`, AP suspend/resume should complete within 3 secs
Change-Id: I6390a908b6c05b875b8bb2c0a124292785110b20
Signed-off-by: Wei-Ning Huang <wnhuang@google.com>
Reviewed-on: https://chromium-review.googlesource.com/512463
Commit-Ready: Wei-Ning Huang <wnhuang@chromium.org>
Tested-by: Wei-Ning Huang <wnhuang@chromium.org>
Reviewed-by: Rong Chang <rongchang@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32/i2c-stm32f4.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/chip/stm32/i2c-stm32f4.c b/chip/stm32/i2c-stm32f4.c index a542088567..7c9414e444 100644 --- a/chip/stm32/i2c-stm32f4.c +++ b/chip/stm32/i2c-stm32f4.c @@ -910,28 +910,6 @@ static void i2c_event_handler(int port) disable_sleep(SLEEP_MASK_I2C_SLAVE); } - /* STOPF or AF */ - if (i2c_sr1 & (STM32_I2C_SR1_STOPF | STM32_I2C_SR1_AF)) { - /* Disable buffer interrupt */ - STM32_I2C_CR2(port) &= ~STM32_I2C_CR2_ITBUFEN; - -#ifdef CONFIG_BOARD_I2C_SLAVE_ADDR - if (rx_pending && addr == CONFIG_BOARD_I2C_SLAVE_ADDR) - i2c_process_board_command(0, addr, buf_idx); -#endif - rx_pending = 0; - tx_pending = 0; - - /* Clear AF */ - STM32_I2C_SR1(port) &= ~STM32_I2C_SR1_AF; - /* Clear STOPF: read SR1 and write CR1 */ - dummy = STM32_I2C_SR1(port); - STM32_I2C_CR1(port) = i2c_cr1 | STM32_I2C_CR1_PE; - - /* No longer inhibit deep sleep after stop condition */ - enable_sleep(SLEEP_MASK_I2C_SLAVE); - } - /* I2C in slave transmitter */ if (i2c_sr2 & STM32_I2C_SR2_TRA) { if (i2c_sr1 & (STM32_I2C_SR1_BTF | STM32_I2C_SR1_TXE)) { @@ -968,6 +946,28 @@ static void i2c_event_handler(int port) host_buffer[buf_idx++] = STM32_I2C_DR(port); } + /* STOPF or AF */ + if (i2c_sr1 & (STM32_I2C_SR1_STOPF | STM32_I2C_SR1_AF)) { + /* Disable buffer interrupt */ + STM32_I2C_CR2(port) &= ~STM32_I2C_CR2_ITBUFEN; + +#ifdef CONFIG_BOARD_I2C_SLAVE_ADDR + if (rx_pending && addr == CONFIG_BOARD_I2C_SLAVE_ADDR) + i2c_process_board_command(0, addr, buf_idx); +#endif + rx_pending = 0; + tx_pending = 0; + + /* Clear AF */ + STM32_I2C_SR1(port) &= ~STM32_I2C_SR1_AF; + /* Clear STOPF: read SR1 and write CR1 */ + dummy = STM32_I2C_SR1(port); + STM32_I2C_CR1(port) = i2c_cr1 | STM32_I2C_CR1_PE; + + /* No longer inhibit deep sleep after stop condition */ + enable_sleep(SLEEP_MASK_I2C_SLAVE); + } + /* Enable again */ if (!(i2c_cr1 & STM32_I2C_CR1_PE)) STM32_I2C_CR1(port) |= STM32_I2C_CR1_PE; |