aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George2020-06-26 23:56:45 +1000
committerDamien George2020-06-26 23:56:45 +1000
commit137df817575e06b7bd765fb230a99d108f1d4f61 (patch)
tree6c73d731a1113e01fbfa33ff08298fbcb0cb79d2
parent6475cdb7d06cc1a7bf273e66d0bbfc9aef890622 (diff)
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 <damien@micropython.org>
-rw-r--r--ports/stm32/i2cslave.c18
-rw-r--r--ports/stm32/i2cslave.h9
-rw-r--r--ports/stm32/mboot/main.c11
3 files changed, 21 insertions, 17 deletions
diff --git a/ports/stm32/i2cslave.c b/ports/stm32/i2cslave.c
index 149e105ee..a575c5308 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 f335c9291..4a51bf378 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 b3e63ccc2..87618e7f4 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)
/******************************************************************************/