aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-01-06 16:29:18 +0000
committerbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-01-06 16:29:18 +0000
commit25238b87b5e39584590c3131e6695d0baf7a488f (patch)
tree1bad0492cbbc19c6dbbc534d0ef9a69e9292a581 /os/hal
parent32300b3913b8b038217342c263e295b99dfaa566 (diff)
downloadChibiOS-25238b87b5e39584590c3131e6695d0baf7a488f.tar.gz
ChibiOS-25238b87b5e39584590c3131e6695d0baf7a488f.tar.bz2
ChibiOS-25238b87b5e39584590c3131e6695d0baf7a488f.zip
I2C. Optimized interrupt handling strategy.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3749 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/platforms/STM32/i2c_lld.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c
index 9927016a7..40732c122 100644
--- a/os/hal/platforms/STM32/i2c_lld.c
+++ b/os/hal/platforms/STM32/i2c_lld.c
@@ -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;
}
/**