From 7be4a23c0cccbcd9096d57235f32c5c2e02f6604 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 15 Jun 2018 14:15:31 +1000 Subject: [PATCH] stm32/i2cslave: Fix ordering of event callbacks in slave IRQ handler. It's possible (at least on F4 MCU's) to have RXNE and STOPF set at the same time during a call to the slave IRQ handler. In such cases RXNE should be handled before STOPF so that all bytes are processed before i2c_slave_process_rx_end() is called. --- ports/stm32/i2cslave.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ports/stm32/i2cslave.c b/ports/stm32/i2cslave.c index f8ff19cd6..473f0c8c5 100644 --- a/ports/stm32/i2cslave.c +++ b/ports/stm32/i2cslave.c @@ -44,6 +44,12 @@ void i2c_slave_ev_irq_handler(i2c_slave_t *i2c) { uint32_t sr2 = i2c->SR2; i2c_slave_process_addr_match((sr2 >> I2C_SR2_TRA_Pos) & 1); } + if (sr1 & I2C_SR1_TXE) { + i2c->DR = i2c_slave_process_tx_byte(); + } + if (sr1 & I2C_SR1_RXNE) { + i2c_slave_process_rx_byte(i2c->DR); + } if (sr1 & I2C_SR1_STOPF) { // STOPF only set at end of RX mode (in TX mode AF is set on NACK) // Read of SR1, write CR1 needed to clear STOPF bit @@ -52,12 +58,6 @@ void i2c_slave_ev_irq_handler(i2c_slave_t *i2c) { i2c_slave_process_rx_end(); i2c->CR1 |= I2C_CR1_ACK; } - if (sr1 & I2C_SR1_TXE) { - i2c->DR = i2c_slave_process_tx_byte(); - } - if (sr1 & I2C_SR1_RXNE) { - i2c_slave_process_rx_byte(i2c->DR); - } } #elif defined(STM32F7) @@ -79,6 +79,12 @@ void i2c_slave_ev_irq_handler(i2c_slave_t *i2c) { i2c->ICR = I2C_ICR_ADDRCF; i2c_slave_process_addr_match(0); } + if (isr & I2C_ISR_TXIS) { + i2c->TXDR = i2c_slave_process_tx_byte(); + } + if (isr & I2C_ISR_RXNE) { + i2c_slave_process_rx_byte(i2c->RXDR); + } if (isr & I2C_ISR_STOPF) { // STOPF only set for STOP condition, not a repeated START i2c->ICR = I2C_ICR_STOPCF; @@ -90,12 +96,6 @@ void i2c_slave_ev_irq_handler(i2c_slave_t *i2c) { } i2c->OAR1 |= I2C_OAR1_OA1EN; } - if (isr & I2C_ISR_TXIS) { - i2c->TXDR = i2c_slave_process_tx_byte(); - } - if (isr & I2C_ISR_RXNE) { - i2c_slave_process_rx_byte(i2c->RXDR); - } } #endif