title: SMBus Communication with Silicon Labs C8051f320 and ADXL345
body: <p>I am Trying to Communicate from C8051F320 MCU to ADXL345 Accelerometer via SMBus</p>
  
  <p>8051 is Master
  ADXL345 is Slave</p>
  
  <p>to test my code i use a simple read of the ADXL345 <strong>device_ID</strong> at address <strong>0x00</strong></p>
  
  <p>but Sadly it is not Working</p>
  
  <p>Here is my Code</p>
  
  <pre><code>void SMBus_ISR (void) interrupt 7
   {
    bit FAIL = 0;                       // Used by the ISR to flag failed
                               // transfers
  
  
  
  
      if (SMB0CN_ARBLOST == 0)                   // Check for errors
       {
  
  // Normal operation
  switch (SMB0CN &amp; 0xF0)    //        // Status vector
    {
    // Master Transmitter/Receiver: START condition transmitted.
   case SMB_MTSTA:
  
    SMB0DAT = TARGET;          // Load address of the target slave
  
    SMB0CN_STA = 0;                   // Manually clear START bit
    ADDR_SEND = 1;
  
    break;
  
    // Master Transmitter: Data byte transmitted
    case SMB_MTDB:
  
  
    if (SMB0CN_ACK)                   // Slave ACK?
    {
    if (ADDR_SEND &amp;&amp; counter &lt; index)
    {
  
        //LED = ~LED;
          SMB0DAT = outgoing_str[counter];
          counter++;
  
  
    }
    else
       ADDR_SEND = 0;
       //SMB0CN_STO = 1;
       SMB_BUSY = 0;
       TARGET = SLAVE_ADDR_READ;
       SMB_Read();
    }
    else{
        LED =~LED;
      }
    break;
  
   // Master Receiver: byte received
   case SMB_MRDB:
    SMB_DATA_IN = SMB0DAT;     // Store received byte
    SMB_BUSY = 0;              // Free SMBus interface
    SMB0CN_ACK = 0;                   // Send NACK to indicate last byte
      if(SMB_DATA_IN&gt;0){
  
  
      LED2 = ~LED2;}
  
  
    break;
  
  
  
  } // end switch
  }
    else{
  
    FAIL = 1;
     }
  
    if (FAIL)                           // If the transfer failed,
    {
      SMB0CF &amp;= ~0x80;                 // Reset communication
      SMB0CF |= 0x80;
      SMB0CN_STA = 0;
      SMB0CN_STO = 0;
      SMB0CN_ACK = 0;
  
      SMB_BUSY = 0;                    // Free SMBus
  
      FAIL = 0;
  
  
    NUM_ERRORS++;                    // Indicate an error occurred
     }
  
  SMB0CN_SI = 0;                             // Clear interrupt flag
  }
  </code></pre>
  
  <p><strong>Here  are the SMBus Write and read Init Methods</strong></p>
  
  <pre><code>void SMB_Write (void)
  {
    while (SMB_BUSY);                   // Wait for SMBus to be free.
    SMB_BUSY = 1;                       // Claim SMBus (set to busy)
    SMB_RW = 0;                         // Mark this transfer as a WRITE
    SMB0CN_STA = 1;                            // Start transfer
  }
  
  void SMB_Read (void)
  {
   while (SMB_BUSY);                   // Wait for bus to be free.
   SMB_BUSY = 1;                       // Claim SMBus (set to busy)
   SMB_RW = 1;                         // Mark this transfer as a READ
  
   SMB0CN_STA = 1;                            // Start transfer
  
   while (SMB_BUSY);                   // Wait for transfer to complete
   }
  </code></pre>
  
  <p><strong>Other methods are taken from an example in the SDK so i guess they are OK</strong></p>