summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-09-09 19:50:18 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-09-09 19:50:18 +0000
commitb90f21b46e4efed68ba80a6ecc8b536de2a2fd5a (patch)
tree4c5694a1a551bf2cd366971d1ff991460efb3e4b
parent578a23b761f0020c31fe604c172de27b27476dce (diff)
downloadpx4-nuttx-b90f21b46e4efed68ba80a6ecc8b536de2a2fd5a.tar.gz
px4-nuttx-b90f21b46e4efed68ba80a6ecc8b536de2a2fd5a.tar.bz2
px4-nuttx-b90f21b46e4efed68ba80a6ecc8b536de2a2fd5a.zip
Only enable I2C interrupts when a transfer is started
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3945 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_i2c.h2
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_i2c.c106
2 files changed, 54 insertions, 54 deletions
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
index 2049ac1f4..b637dc507 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
@@ -107,6 +107,8 @@
#define I2C_CR2_DMAEN (1 << 11) /* Bit 11: DMA Requests Enable */
#define I2C_CR2_LAST (1 << 12) /* Bit 12: DMA Last Transfer */
+#define I2C_CR2_ALLINTS (I2C_CR2_ITERREN|I2C_CR2_ITEVFEN|I2C_CR2_ITBUFEN)
+
/* Own address register 1 */
#define I2C_OAR1_ADD0 (1 << 0) /* Bit 0: Interface Address */
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.c b/nuttx/arch/arm/src/stm32/stm32_i2c.c
index ae1e124d7..ec78b0a6c 100644
--- a/nuttx/arch/arm/src/stm32/stm32_i2c.c
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.c
@@ -109,6 +109,21 @@
# define CONFIG_STM32_I2CTIMEOMS 0 /* User provided seconds */
#endif
+/* Debug ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_I2C
+# define i2cdbg dbg
+# ifdef CONFIG_DEBUG_I2CINTS
+# define intdbg lldbg
+# else
+# define intdbg(x...)
+# endif
+#else
+# undef CONFIG_DEBUG_I2CINTS
+# define i2cdbg(x...)
+# define intdbg(x...)
+#endif
+
/************************************************************************************
* Private Types
************************************************************************************/
@@ -220,9 +235,17 @@ int inline stm32_i2c_sem_waitisr(FAR struct i2c_dev_s *dev)
FAR struct stm32_i2c_priv_s *priv = ((struct stm32_i2c_inst_s *)dev)->priv;
struct timespec abstime;
irqstate_t flags;
+ uint32_t regval;
int ret;
flags = irqsave();
+
+ /* Enable I2C interrupts */
+
+ regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET);
+ regval |= (I2C_CR2_ITERREN | I2C_CR2_ITEVFEN);
+ stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval);
+
do
{
/* Get the current time */
@@ -250,6 +273,11 @@ int inline stm32_i2c_sem_waitisr(FAR struct i2c_dev_s *dev)
}
while (ret != OK && errno == EINTR);
+ /* Disable I2C interrupts */
+
+ regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET);
+ regval &= ~I2C_CR2_ALLINTS;
+ stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval);
irqrestore(flags);
return ret;
}
@@ -437,21 +465,18 @@ static inline void stm32_i2c_enablefsmc(uint32_t ahbenr)
* Interrupt Service Routines
************************************************************************************/
-//DEBUG TO BE CLEANED
-//#define NON_ISR
-
static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
{
uint32_t status = stm32_i2c_getstatus(priv);
-#ifdef NON_ISR
+#ifdef CONFIG_DEBUG_I2CINTS
static uint32_t isr_count = 0;
static uint32_t old_status = 0xFFFF;
isr_count++;
if (old_status != status)
{
- printf("status = %8x, count=%d\n", status, isr_count); fflush(stdout);
+ intdbg("status = %8x, count=%d\n", status, isr_count); fflush(stdout);
old_status = status;
}
#endif
@@ -501,9 +526,8 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
if (--priv->dcnt >= 0)
{
/* Send a byte */
-#ifdef NON_ISR
- printf("Send byte: %2x\n", *priv->ptr);
-#endif
+
+ intdbg("Send byte: %2x\n", *priv->ptr);
stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, *priv->ptr++);
}
}
@@ -521,15 +545,12 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
{
/* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */
-#ifdef NON_ISR
- printf("dcnt=%d\n", priv->dcnt);
-#endif
+ intdbg("dcnt=%d\n", priv->dcnt);
if (--priv->dcnt >= 0)
{
*priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET);
-#ifdef NON_ISR
- printf("Received: %2x\n", *(priv->ptr-1) );
-#endif
+ intdbg("Received: %2x\n", *(priv->ptr-1) );
+
/* Disable acknowledge when last byte is to be received */
if (priv->dcnt == 1)
@@ -556,9 +577,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
if (priv->dcnt<=0 && (status & I2C_SR1_BTF))
{
-#ifdef NON_ISR
- printf("BTF\n");
-#endif
+ intdbg("BTF\n");
stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); /* ACK ISR */
/* Do we need to terminate or restart after this byte */
@@ -590,9 +609,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
}
else if (priv->msgv)
{
-#ifdef NON_ISR
- printf("stop2: status = %8x\n", status);
-#endif
+ intdbg("stop2: status = %8x\n", status);
stm32_i2c_sendstop(priv);
if (priv->isr_wait)
{
@@ -674,7 +691,7 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
return ERROR;
}
- /* attach ISRs */
+ /* Attach ISRs */
irq_attach(STM32_IRQ_I2C1EV, stm32_i2c1_isr);
irq_attach(STM32_IRQ_I2C1ER, stm32_i2c1_isr);
@@ -719,17 +736,11 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
return ERROR;
}
- /* Set peripheral frequency, where it must be at least 2 MHz
- * for 100 kHz or 4 MHz for 400 kHz. Enable interrupt generation.
+ /* Set peripheral frequency, where it must be at least 2 MHz for 100 kHz
+ * or 4 MHz for 400 kHz. This also disables all I2C interrupts.
*/
- stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET,
-#ifndef NON_ISR
- I2C_CR2_ITERREN | I2C_CR2_ITEVFEN | // I2C_CR2_ITBUFEN |
-#endif
- (STM32_PCLK1_FREQUENCY / 1000000)
- );
-
+ stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, (STM32_PCLK1_FREQUENCY / 1000000));
stm32_i2c_setclock(priv, 100000);
/* Enable I2C */
@@ -824,7 +835,7 @@ int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int
ahbenr = stm32_i2c_disablefsmc(inst->priv);
- /* wait as stop might still be in progress
+ /* Wait as stop might still be in progress
*
* \todo GET RID OF THIS PERFORMANCE LOSS and for() loop
*/
@@ -839,27 +850,20 @@ int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int
inst->priv->msgv = msgs;
inst->priv->msgc = count;
- /* Set clock (on change it toggles I2C_CR1_PE !) */
+ /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) */
stm32_i2c_setclock(inst->priv, inst->frequency);
- /* Trigger start condition, then the process moves into the ISR */
+ /* Clear any pending error interrupts */
+
+ stm32_i2c_putreg(inst->priv, STM32_I2C_SR1_OFFSET, 0);
+
+ /* Trigger start condition, then the process moves into the ISR. I2C
+ * interrupts will be enabled within stm32_i2c_waitisr().
+ */
stm32_i2c_sendstart(inst->priv);
-#ifdef NON_ISR
- do
- {
- do
- {
- stm32_i2c_isr(&stm32_i2c1_priv);
- status = inst->priv->status;
- }
- while (status & (I2C_SR2_BUSY << 16));
- }
- while( sem_trywait( &((struct stm32_i2c_inst_s *)dev)->priv->sem_isr ) != 0 );
-#else
-#if 1
/* Wait for an ISR, if there was a timeout, fetch latest status to get
* the BUSY flag.
*/
@@ -883,14 +887,8 @@ int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int
status = inst->priv->status & 0xffff;
}
-#else
- do
- {
- printf("%x, %d\n", inst->priv->status, isr_count );
- }
- while( sem_trywait( &inst->priv->sem_isr ) != 0 );
-#endif
-#endif
+
+ /* Check for error status conditions */
if (status & I2C_SR1_BERR)
{