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>
This commit is contained in:
Damien George 2020-06-26 23:56:45 +10:00
parent 6475cdb7d0
commit 137df81757
3 changed files with 21 additions and 17 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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)
/******************************************************************************/