summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorWei-Ning Huang <wnhuang@google.com>2017-05-23 18:56:34 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-05-23 16:56:55 -0700
commit4c9e99b5e9a13ceca37b51c671323e94f0bd8fc6 (patch)
treebc0a9085f061a5a3a2693e899c529a188db0e7b3 /chip
parent4ce20f3f79d93f57f5c9974fdbe80316cb94f537 (diff)
downloadchrome-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.c44
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;