mirror of https://github.com/rusefi/ChibiOS.git
I2C. Optimized interrupt handling strategy.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3749 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
32300b3913
commit
25238b87b5
|
@ -305,16 +305,21 @@ static uint32_t i2c_get_event(I2CDriver *i2cp) {
|
||||||
*/
|
*/
|
||||||
static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
|
static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
|
||||||
|
|
||||||
|
/* Interrupts disabled just before dmaStreamEnable() because there is no
|
||||||
|
* need of interrupts until next transaction begin. All work
|
||||||
|
* will be done by DMA. */
|
||||||
|
|
||||||
switch (i2c_get_event(i2cp)) {
|
switch (i2c_get_event(i2cp)) {
|
||||||
case I2C_EV5_MASTER_MODE_SELECT:
|
case I2C_EV5_MASTER_MODE_SELECT:
|
||||||
i2cp->i2c->DR = i2cp->addr;
|
i2cp->i2c->DR = i2cp->addr;
|
||||||
break;
|
break;
|
||||||
case I2C_EV6_MASTER_REC_MODE_SELECTED:
|
case I2C_EV6_MASTER_REC_MODE_SELECTED:
|
||||||
|
i2cp->i2c->CR2 &= ~I2C_CR2_ITEVTEN;
|
||||||
dmaStreamEnable(i2cp->dmarx);
|
dmaStreamEnable(i2cp->dmarx);
|
||||||
/* LAST bit needs only during receive phase. */
|
i2cp->i2c->CR2 |= I2C_CR2_LAST; /* need in receiver mode */
|
||||||
i2cp->i2c->CR2 |= I2C_CR2_LAST;
|
|
||||||
break;
|
break;
|
||||||
case I2C_EV6_MASTER_TRA_MODE_SELECTED:
|
case I2C_EV6_MASTER_TRA_MODE_SELECTED:
|
||||||
|
i2cp->i2c->CR2 &= ~I2C_CR2_ITEVTEN;
|
||||||
dmaStreamEnable(i2cp->dmatx);
|
dmaStreamEnable(i2cp->dmatx);
|
||||||
break;
|
break;
|
||||||
case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
|
case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
|
||||||
|
@ -356,7 +361,7 @@ static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags) {
|
||||||
dmaStreamDisable(i2cp->dmarx);
|
dmaStreamDisable(i2cp->dmarx);
|
||||||
dmaStreamClearInterrupt(i2cp->dmarx);
|
dmaStreamClearInterrupt(i2cp->dmarx);
|
||||||
|
|
||||||
i2cp->i2c->CR2 &= ~(I2C_CR2_LAST | I2C_CR2_ITEVTEN);
|
i2cp->i2c->CR2 &= ~I2C_CR2_LAST;
|
||||||
i2cp->i2c->CR1 &= ~I2C_CR1_ACK;
|
i2cp->i2c->CR1 &= ~I2C_CR1_ACK;
|
||||||
i2cp->i2c->CR1 |= I2C_CR1_STOP;
|
i2cp->i2c->CR1 |= I2C_CR1_STOP;
|
||||||
wakeup_isr(i2cp, RDY_OK);
|
wakeup_isr(i2cp, RDY_OK);
|
||||||
|
@ -382,6 +387,10 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
|
||||||
|
|
||||||
dmaStreamDisable(i2cp->dmatx);
|
dmaStreamDisable(i2cp->dmatx);
|
||||||
dmaStreamClearInterrupt(i2cp->dmatx);
|
dmaStreamClearInterrupt(i2cp->dmatx);
|
||||||
|
/* Enable interrupts to catch BTF event meaning transmission part complete.
|
||||||
|
* Interrupt handler will decide to generate STOP or to begin receiving part
|
||||||
|
* of rw transaction itself. */
|
||||||
|
i2cp->i2c->CR2 |= I2C_CR2_ITEVTEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue