arch/arm/src/sam34/sam_twi.c
/*******************************************************************************
 * Name: twi_interrupt
 *
 * Description:
 *   The TWI Interrupt Handler
 *
 *******************************************************************************/
twi_interrupt
Description:
The TWI Interrupt Handler
twi_interrupt Description : The TWI Interrupt Handler
static int twi_interrupt(struct twi_dev_s *priv)
{
  struct i2c_msg_s *msg;
  uint32_t sr;
  uint32_t imr;
  uint32_t pending;
  uint32_t regval;
  sr      = twi_getrel(priv, SAM_TWI_SR_OFFSET);
  imr     = twi_getrel(priv, SAM_TWI_IMR_OFFSET);
  pending = sr & imr;
  i2cllvdbg("TWI%d pending: %08x\n", priv->twi, pending);
  msg = priv->msg;
  if ((pending & TWI_INT_ERRORS) != 0)
    {
      i2clldbg("ERROR: TWI%d pending: %08x\n", priv->twi, pending);
      twi_wakeup(priv, -EIO);
    }
  else if ((pending & TWI_INT_RXRDY) != 0)
    {
      msg->buffer[priv->xfrd] = twi_getrel(priv, SAM_TWI_RHR_OFFSET);
      priv->xfrd++;
      if (priv->xfrd >= msg->length)
        {
          twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_RXRDY);
          twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP);
        }
      else if (priv->xfrd == (msg->length - 1))
        {
          twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP);
        }
    }
  else if ((pending & TWI_INT_TXRDY) != 0)
    {
      if (priv->xfrd >= msg->length)
        {
          twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXRDY);
          twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP);
          regval  = twi_getrel(priv, SAM_TWI_CR_OFFSET);
          regval |= TWI_CR_STOP;
          twi_putrel(priv, SAM_TWI_CR_OFFSET, regval);
        }
      else
        {
          twi_putrel(priv, SAM_TWI_THR_OFFSET, msg->buffer[priv->xfrd]);
          priv->xfrd++;
        }
    }
  else if ((pending & TWI_INT_TXCOMP) != 0)
    {
      twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXCOMP);
      if (priv->msgc > 1)
        {
          priv->msg++;
          priv->msgc--;
          twi_startmessage(priv, priv->msg);
        }
      else
        {
          twi_wakeup(priv, OK);
        }
    }
  return OK;
}
static int twi_interrupt ( struct twi_dev_s * priv ) { struct i2c_msg_s * msg ; uint32_t sr ; uint32_t imr ; uint32_t pending ; uint32_t regval ; sr = twi_getrel ( priv , SAM_TWI_SR_OFFSET ) ; imr = twi_getrel ( priv , SAM_TWI_IMR_OFFSET ) ; pending = sr & imr ; i2cllvdbg ( " \n " , priv -> twi , pending ) ; msg = priv -> msg ; if ( ( pending & TWI_INT_ERRORS ) != 0 ) { i2clldbg ( " \n " , priv -> twi , pending ) ; twi_wakeup ( priv , - EIO ) ; } else if ( ( pending & TWI_INT_RXRDY ) != 0 ) { msg -> buffer [ priv -> xfrd ] = twi_getrel ( priv , SAM_TWI_RHR_OFFSET ) ; priv -> xfrd ++ ; if ( priv -> xfrd >= msg -> length ) { twi_putrel ( priv , SAM_TWI_IDR_OFFSET , TWI_INT_RXRDY ) ; twi_putrel ( priv , SAM_TWI_IER_OFFSET , TWI_INT_TXCOMP ) ; } else if ( priv -> xfrd == ( msg -> length - 1 ) ) { twi_putrel ( priv , SAM_TWI_CR_OFFSET , TWI_CR_STOP ) ; } } else if ( ( pending & TWI_INT_TXRDY ) != 0 ) { if ( priv -> xfrd >= msg -> length ) { twi_putrel ( priv , SAM_TWI_IDR_OFFSET , TWI_INT_TXRDY ) ; twi_putrel ( priv , SAM_TWI_IER_OFFSET , TWI_INT_TXCOMP ) ; regval = twi_getrel ( priv , SAM_TWI_CR_OFFSET ) ; regval |= TWI_CR_STOP ; twi_putrel ( priv , SAM_TWI_CR_OFFSET , regval ) ; } else { twi_putrel ( priv , SAM_TWI_THR_OFFSET , msg -> buffer [ priv -> xfrd ] ) ; priv -> xfrd ++ ; } } else if ( ( pending & TWI_INT_TXCOMP ) != 0 ) { twi_putrel ( priv , SAM_TWI_IDR_OFFSET , TWI_INT_TXCOMP ) ; if ( priv -> msgc > 1 ) { priv -> msg ++ ; priv -> msgc -- ; twi_startmessage ( priv , priv -> msg ) ; } else { twi_wakeup ( priv , OK ) ; } } return OK ; }
Name: twi_interrupt
 Description:
   The TWI Interrupt Handler
Name : twi_interrupt Description : The TWI Interrupt Handler
/* Retrieve masked interrupt status */ /* Check for errors */ /* Wake up the thread with an I/O error indication */ /* Byte received */ /* Check for transfer complete */ /* The transfer is complete.  Disable the RXRDY interrupt and
           * enable the TXCOMP interrupt
           */ /* Not yet complete, but will the next be the last byte? */ /* Yes, set the stop signal */ /* Byte sent*/ /* Transfer finished? */ /* The transfer is complete.  Disable the TXRDY interrupt and
           * enable the TXCOMP interrupt
           */ /* Send the STOP condition */ /* No, there are more bytes remaining to be sent */ /* Transfer complete */ /* Is there another message to send? */ /* Yes... start the next message */ /* No.. we made it to the end of the message list with no errors.
           * Cancel any timeout and wake up the waiting thread with a
           * success indication.
           */