From 137df817575e06b7bd765fb230a99d108f1d4f61 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 26 Jun 2020 23:56:45 +1000 Subject: [PATCH] stm32/i2cslave: Pass I2C instance to callbacks to support multi I2Cs. By passing through the I2C instance to the application callbacks, the application can implement multiple I2C slave devices on different peripherals (eg I2C1 and I2C2). This commit also adds a proper rw argument to i2c_slave_process_addr_match for F7/H7/WB MCUs, and enables the i2c_slave_process_tx_end callback. Mboot is also updated for these changes. Signed-off-by: Damien George --- ports/stm32/i2cslave.c | 18 +++++++++--------- ports/stm32/i2cslave.h | 9 +++++---- ports/stm32/mboot/main.c | 11 +++++++---- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/ports/stm32/i2cslave.c b/ports/stm32/i2cslave.c index 149e105ee8..a575c53085 100644 --- a/ports/stm32/i2cslave.c +++ b/ports/stm32/i2cslave.c @@ -42,20 +42,20 @@ void i2c_slave_ev_irq_handler(i2c_slave_t *i2c) { // Read of SR1, SR2 needed to clear ADDR bit sr1 = i2c->SR1; uint32_t sr2 = i2c->SR2; - i2c_slave_process_addr_match((sr2 >> I2C_SR2_TRA_Pos) & 1); + i2c_slave_process_addr_match(i2c, (sr2 >> I2C_SR2_TRA_Pos) & 1); } if (sr1 & I2C_SR1_TXE) { - i2c->DR = i2c_slave_process_tx_byte(); + i2c->DR = i2c_slave_process_tx_byte(i2c); } if (sr1 & I2C_SR1_RXNE) { - i2c_slave_process_rx_byte(i2c->DR); + i2c_slave_process_rx_byte(i2c, 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 sr1 = i2c->SR1; i2c->CR1 &= ~I2C_CR1_ACK; - i2c_slave_process_rx_end(); + i2c_slave_process_rx_end(i2c); i2c->CR1 |= I2C_CR1_ACK; } } @@ -77,22 +77,22 @@ void i2c_slave_ev_irq_handler(i2c_slave_t *i2c) { // Set TXE so that TXDR is flushed and ready for the first byte i2c->ISR = I2C_ISR_TXE; i2c->ICR = I2C_ICR_ADDRCF; - i2c_slave_process_addr_match(0); + i2c_slave_process_addr_match(i2c, (i2c->ISR >> I2C_ISR_DIR_Pos) & 1); } if (isr & I2C_ISR_TXIS) { - i2c->TXDR = i2c_slave_process_tx_byte(); + i2c->TXDR = i2c_slave_process_tx_byte(i2c); } if (isr & I2C_ISR_RXNE) { - i2c_slave_process_rx_byte(i2c->RXDR); + i2c_slave_process_rx_byte(i2c, i2c->RXDR); } if (isr & I2C_ISR_STOPF) { // STOPF only set for STOP condition, not a repeated START i2c->ICR = I2C_ICR_STOPCF; i2c->OAR1 &= ~I2C_OAR1_OA1EN; if (i2c->ISR & I2C_ISR_DIR) { - // i2c_slave_process_tx_end(); + i2c_slave_process_tx_end(i2c); } else { - i2c_slave_process_rx_end(); + i2c_slave_process_rx_end(i2c); } i2c->OAR1 |= I2C_OAR1_OA1EN; } diff --git a/ports/stm32/i2cslave.h b/ports/stm32/i2cslave.h index f335c92912..4a51bf378e 100644 --- a/ports/stm32/i2cslave.h +++ b/ports/stm32/i2cslave.h @@ -67,9 +67,10 @@ static inline void i2c_slave_shutdown(i2c_slave_t *i2c, int irqn) { void i2c_slave_ev_irq_handler(i2c_slave_t *i2c); // These should be provided externally -int i2c_slave_process_addr_match(int rw); -int i2c_slave_process_rx_byte(uint8_t val); -void i2c_slave_process_rx_end(void); -uint8_t i2c_slave_process_tx_byte(void); +int i2c_slave_process_addr_match(i2c_slave_t *i2c, int rw); +int i2c_slave_process_rx_byte(i2c_slave_t *i2c, uint8_t val); +void i2c_slave_process_rx_end(i2c_slave_t *i2c); +uint8_t i2c_slave_process_tx_byte(i2c_slave_t *i2c); +void i2c_slave_process_tx_end(i2c_slave_t *i2c); #endif // MICROPY_INCLUDED_STM32_I2CSLAVE_H diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index b3e63ccc26..87618e7f41 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -664,7 +664,7 @@ void i2c_init(int addr) { i2c_slave_init(MBOOT_I2Cx, I2Cx_EV_IRQn, IRQ_PRI_I2C, addr); } -int i2c_slave_process_addr_match(int rw) { +int i2c_slave_process_addr_match(i2c_slave_t *i2c, int rw) { if (i2c_obj.cmd_arg_sent) { i2c_obj.cmd_send_arg = false; } @@ -672,14 +672,14 @@ int i2c_slave_process_addr_match(int rw) { return 0; // ACK } -int i2c_slave_process_rx_byte(uint8_t val) { +int i2c_slave_process_rx_byte(i2c_slave_t *i2c, uint8_t val) { if (i2c_obj.cmd_buf_pos < sizeof(i2c_obj.cmd_buf)) { i2c_obj.cmd_buf[i2c_obj.cmd_buf_pos++] = val; } return 0; // ACK } -void i2c_slave_process_rx_end(void) { +void i2c_slave_process_rx_end(i2c_slave_t *i2c) { if (i2c_obj.cmd_buf_pos == 0) { return; } @@ -764,7 +764,7 @@ void i2c_slave_process_rx_end(void) { i2c_obj.cmd_arg_sent = false; } -uint8_t i2c_slave_process_tx_byte(void) { +uint8_t i2c_slave_process_tx_byte(i2c_slave_t *i2c) { if (i2c_obj.cmd_send_arg) { i2c_obj.cmd_arg_sent = true; return i2c_obj.cmd_arg; @@ -775,6 +775,9 @@ uint8_t i2c_slave_process_tx_byte(void) { } } +void i2c_slave_process_tx_end(i2c_slave_t *i2c) { +} + #endif // defined(MBOOT_I2C_SCL) /******************************************************************************/