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:
barthess 2012-01-06 16:29:18 +00:00
parent 32300b3913
commit 25238b87b5
1 changed files with 12 additions and 3 deletions

View File

@ -305,16 +305,21 @@ static uint32_t i2c_get_event(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)) {
case I2C_EV5_MASTER_MODE_SELECT:
i2cp->i2c->DR = i2cp->addr;
break;
case I2C_EV6_MASTER_REC_MODE_SELECTED:
i2cp->i2c->CR2 &= ~I2C_CR2_ITEVTEN;
dmaStreamEnable(i2cp->dmarx);
/* LAST bit needs only during receive phase. */
i2cp->i2c->CR2 |= I2C_CR2_LAST;
i2cp->i2c->CR2 |= I2C_CR2_LAST; /* need in receiver mode */
break;
case I2C_EV6_MASTER_TRA_MODE_SELECTED:
i2cp->i2c->CR2 &= ~I2C_CR2_ITEVTEN;
dmaStreamEnable(i2cp->dmatx);
break;
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);
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_STOP;
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);
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;
}
/**