summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/i2cslave.c12
-rw-r--r--ports/stm32/i2cslave.h24
-rw-r--r--ports/stm32/mboot/main.c14
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) {