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
This commit is contained in:
patacongo 2011-09-09 19:50:18 +00:00
parent 202e109d6b
commit 4b09cfc3a9
2 changed files with 54 additions and 54 deletions

View File

@ -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 */

View File

@ -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)
{