diff options
| -rw-r--r-- | ports/stm32/i2cslave.c | 12 | ||||
| -rw-r--r-- | ports/stm32/i2cslave.h | 24 | ||||
| -rw-r--r-- | ports/stm32/mboot/main.c | 14 |
3 files changed, 38 insertions, 12 deletions
diff --git a/ports/stm32/i2cslave.c b/ports/stm32/i2cslave.c index 44604db69..e60edf53b 100644 --- a/ports/stm32/i2cslave.c +++ b/ports/stm32/i2cslave.c @@ -45,10 +45,12 @@ void i2c_slave_irq_handler(i2c_slave_t *i2c) { 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); + // This callback must call i2c_slave_write_byte. + i2c_slave_process_tx_byte(i2c); } if (sr1 & I2C_SR1_RXNE) { - i2c_slave_process_rx_byte(i2c, i2c->DR); + // This callback must call i2c_slave_read_byte. + i2c_slave_process_rx_byte(i2c); } if (sr1 & I2C_SR1_STOPF) { // STOPF only set at end of RX mode (in TX mode AF is set on NACK) @@ -80,10 +82,12 @@ void i2c_slave_irq_handler(i2c_slave_t *i2c) { 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); + // This callback must call i2c_slave_write_byte. + i2c_slave_process_tx_byte(i2c); } if (isr & I2C_ISR_RXNE) { - i2c_slave_process_rx_byte(i2c, i2c->RXDR); + // This callback must call i2c_slave_read_byte. + i2c_slave_process_rx_byte(i2c); } if (isr & I2C_ISR_STOPF) { // STOPF only set for STOP condition, not a repeated START diff --git a/ports/stm32/i2cslave.h b/ports/stm32/i2cslave.h index a2108ab23..edead6cb2 100644 --- a/ports/stm32/i2cslave.h +++ b/ports/stm32/i2cslave.h @@ -28,6 +28,8 @@ #include STM32_HAL_H +#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32WB) + #if !defined(I2C2_BASE) // This MCU doesn't have I2C2_BASE, define it so that the i2c_idx calculation works. #define I2C2_BASE (I2C1_BASE + ((I2C3_BASE - I2C1_BASE) / 2)) @@ -78,13 +80,31 @@ static inline void i2c_slave_shutdown(i2c_slave_t *i2c, int irqn) { NVIC_DisableIRQ(irqn); } +static inline void i2c_slave_write_byte(i2c_slave_t *i2c, uint8_t value) { + #if defined(STM32F4) + i2c->DR = value; + #else + i2c->TXDR = value; + #endif +} + +static inline uint8_t i2c_slave_read_byte(i2c_slave_t *i2c) { + #if defined(STM32F4) + return i2c->DR; + #else + return i2c->RXDR; + #endif +} + void i2c_slave_irq_handler(i2c_slave_t *i2c); // These should be provided externally 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); +int i2c_slave_process_rx_byte(i2c_slave_t *i2c); 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_byte(i2c_slave_t *i2c); void i2c_slave_process_tx_end(i2c_slave_t *i2c); +#endif + #endif // MICROPY_INCLUDED_STM32_I2CSLAVE_H diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 59f2d8757..bd796c896 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -805,9 +805,9 @@ int i2c_slave_process_addr_match(i2c_slave_t *i2c, int rw) { return 0; // ACK } -int i2c_slave_process_rx_byte(i2c_slave_t *i2c, uint8_t val) { +int i2c_slave_process_rx_byte(i2c_slave_t *i2c) { if (i2c_obj.cmd_buf_pos < sizeof(i2c_obj.cmd_buf)) { - i2c_obj.cmd_buf[i2c_obj.cmd_buf_pos++] = val; + i2c_obj.cmd_buf[i2c_obj.cmd_buf_pos++] = i2c_slave_read_byte(i2c); } return 0; // ACK } @@ -909,15 +909,17 @@ void i2c_slave_process_rx_end(i2c_slave_t *i2c) { i2c_obj.cmd_arg_sent = false; } -uint8_t i2c_slave_process_tx_byte(i2c_slave_t *i2c) { +void i2c_slave_process_tx_byte(i2c_slave_t *i2c) { + uint8_t value; if (i2c_obj.cmd_send_arg) { i2c_obj.cmd_arg_sent = true; - return i2c_obj.cmd_arg; + value = i2c_obj.cmd_arg; } else if (i2c_obj.cmd_buf_pos < sizeof(i2c_obj.cmd_buf)) { - return i2c_obj.cmd_buf[i2c_obj.cmd_buf_pos++]; + value = i2c_obj.cmd_buf[i2c_obj.cmd_buf_pos++]; } else { - return 0; + value = 0; } + i2c_slave_write_byte(i2c, value); } void i2c_slave_process_tx_end(i2c_slave_t *i2c) { |
