9 Replies Latest reply on Oct 22, 2016 6:30 AM by user_1377889

    I2C Master sends wrong device address sometimes

    david.lynch

      I am new to Cypress, trying to get a UDB I2C master to work.  I have successfully fetched the device ID from my test I2c slave device, an ADXL345 accelerometer.  However I have two problems:

         

      1) Most of the time, the address that the I2C master puts on the bus right after the start bit is to address 1.  With enough resets of the debugger, the I2C master will occasionally get the correct 0x53 address on the bus.  When that happens, the slave responds correctly and data makes it into my buffer, and all return values are zero.

         

      2) Even if the address was correct in #1, the final stop bit of the 2nd cycle (the I2C read) will hang on this line in the I2C_MasterSendStop function: while(I2C_WAIT_STOP_COMPLETE(I2C_CSR_REG)).  I don't see the STOP bit on the scope either.  If I put in a breakpoint before the function and then single step, I see the STOP condition on the scope and it completes.

         

      For #1, what do I need to do to get the I2C Master ready to go to work on the correct address all of the time?

         

      For #2, do I need to check a flag before I call on the I2C_MasterSendStop function?

         

      Complete project attached.  Code snippet from main follows:

         
          

      #include <project.h>

          

      uint8 buffer[10];
      uint8 results[20];

          

      void ReadRegs(void)
      {
          uint8 i=0;
          
          results[i++] = I2C_MasterClearStatus();          // This was added but didn't help

          

          results[i++] = I2C_MasterSendStart( 0x53, 0 );  // start write

          

          results[i++] = I2C_MasterWriteByte( 0x0 );      // Register 0 

          

          //results[i++] = I2C_MasterSendStop();           // Commented out, switched to Restart but didn't matter

          

          results[i++] = I2C_MasterSendRestart( 0x53, 1 ); // Turnaround for next cycle
          
          buffer[0] = I2C_MasterReadByte( 1 );             // Read 1 byte

          

          results[i++] = I2C_MasterSendStop();             // stop - This never completes at full speed
          
          while (1)
          ;
      }

          

      int main()
      {
          CyGlobalIntEnable; /* Enable global interrupts. */

          

          /* Place your initialization/startup code here (e.g. MyInst_Start()) */
          
          I2C_Start();

          

          ReadRegs();
      }