AnsweredAssumed Answered

ADSP-21469 TWI (I2C) problem

Question asked by misterdsp on Feb 23, 2012
Latest reply on Feb 27, 2012 by Mitesh

Before the code runs, TWIMSTAT is 0. When the code runs, it gets stuck in the TWI_TXWHILE state, the transmit FIFO is full, and TWIMSTAT is 0x1C0 = TWIBUSY + TWISCLSEN + TWISDASEN. On an oscilloscope, I observe both SDA and SCL are high. I don't see anything wrong with the SRU setup, and the hardware is using DPI pins 6 and 7. So why are the TWISCLSEN and TWISDASEN bits set?

 

 

=================== code begin =====================

#include <sysreg.h>

#include <signal.h>

#include <cdef21469.h>

#include <def21469.h>

#include <21469.h>

#include <math.h>

#include <sru.h>

#include <filter.h>

#include <stdio.h>

#include <processor_include.h>

 

 

// TWI clock = 10MHz / 100 = 100KHz

#define TWICLKHI 50

#define TWICLKLO 50

 

 

enum TWISTATE

{

  TWI_IDLE           = 0,  /**< TWI is idle. */

  TWI_TXWHILE        = 1,  /**< TWI byte sent, wait for Ack. */

  TWI_EXIT           = 2,  /**< TWI all data sent or received, wait for completion. */

};

typedef enum TWISTATE TWISTATE;

 

 

unsigned char    TWI_Buffer[256];

TWISTATE         TWI_State;

unsigned char *  TWI_Data;

int              TWI_bytes;

int              twi_count;

int              twi_error;

 

 

void TWI_TX(unsigned char ** data, int * nbytes);

 

 

 

 

void main()

{

  initPLL();

 

 

  ////////////////////////////////////////////////////////////////

  // TWI (I2C). Clock on DPI pin 6; data on DPI pin 7           //

  ////////////////////////////////////////////////////////////////

 

 

  SRU(LOW,DPI_PB07_I);

  SRU(TWI_DATA_PBEN_O,DPI_PBEN07_I);

  SRU(DPI_PB07_O,TWI_DATA_I);

 

 

  SRU(LOW,DPI_PB06_I);

  SRU2(TWI_CLK_PBEN_O,DPI_PBEN06_I);

  SRU(DPI_PB06_O,TWI_CLK_I);

 

  twi_error = 0;

  twi_count = 0;

 

 

  /* Init. */

  *pTWIDIV = (TWICLKHI << 8) | TWICLKLO;

  // Pclk = 225MHz clock -> 10MHz reference

  *pTWIMITR = TWIEN | 0x17;

 

 

  while(1)

  {

    if(TWI_State == TWI_IDLE)

    {

      TWI_Data    = TWI_Buffer;

      TWI_Data[0] = 0x24;

      TWI_Data[1] = 0x00;

      TWI_Data[2] = 0x43;

      TWI_bytes   = 2;

      twi_count++;

    }

 

 

    /* Service the TWI (I2C) port. */

    TWI_TX(&TWI_Data, &TWI_bytes);

  }

}

 

 

 

 

void TWI_TX(unsigned char ** data, int * nbytes)

{

          /* Is there a TWI error? */

  if(*pTWIIRPTL&TWIMERR)

  {

    /* Write to the bits to clear them. */

            *pTWIIRPTL |= (TWIMCOM+TWIMERR+TWITXINT+TWIRXINT);

    *pTWIMSTAT |= (TWILOST+TWIANAK+TWIDNAK+TWIRERR+TWIWERR);

    twi_error++;

    TWI_State = TWI_IDLE;

    return;

  }

 

 

  switch(TWI_State)

  {

    default:

    case TWI_IDLE:

    {

      /* Look for a non zero I2C address. */

      if(**data != 0)

      {

        // set the I2C write address

        *pTWIMADDR = (**data)>>1;

        (*data)++;

 

 

        // data must be available when turning TWI on

        *pTXTWI8 = **data;

 

 

        // enable tx transfer

        *pTWIMCTL = TWIMEN | ((*nbytes)<<6);

        TWI_State = TWI_TXWHILE;

      }

      break;

    }

    case TWI_TXWHILE:

    {

      /* Write if FIFO is not full. */

      if(((*pTWIFIFOSTAT)&TWITXS) != TWITXS)

      {

        (*nbytes)--;

        if(*nbytes>0)

        {

          (*data)++;

          *pTXTWI8 = **data;

        }

        else

        {

          TWI_State = TWI_EXIT;

        }

      }

      break;

    }

    case TWI_EXIT:

    {

      if(*pTWIIRPTL & TWIMCOM)

      {

        *pTWIIRPTL |= TWIMCOM;

        twi_count++;

        TWI_State = TWI_IDLE;

      }

      break;

    }

  }

}

=================== code end =====================

Outcomes