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:
parent
6475cdb7d0
commit
137df81757
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue