Talking SMBus between RaspberryPi and ATMEGA 324PA - AVR not clock stretching
<p>I'm trying to get an ATMEGA 324PA to run as an SMBus slave.</p>

<p>I'm using the following code on the Pi:</p>

<pre><code>import smbus as smbus
i2c = smbus.SMBus(1)
i2c_addr = 0x30
result = i2c.read_block_data( i2c_addr, reg )
</code></pre>

<p>On the AVR, I'm using:</p>

<pre><code>#include &lt;avr/io.h&gt;
#include &lt;avr/interrupt.h&gt;
#include &lt;avr/sleep.h&gt;
#include "smb_slave.h"

#define SMB_COMMAND_RETURN_VENDOR_STRING    0x10

int main(void)
{
    // Set data direction of PORTB as output and turn off LEDs.
    DDRA = 0xff;
    PORTA = 0xff;

    // Initialize SMBus
    SMBusInit();
    SMBEnable();

    // Enable interrupts globally

    sei();
    for (;;)
    {
    }

    return 0;
}


void ProcessReceiveByte(SMBData *smb)
{
    smb-&gt;txBuffer[0] = ~PIND;
    smb-&gt;txLength = 1;
}

static void ReturnVendorString(SMBData *smb)
{
    unsigned char *vendor = (unsigned char*) "Vendor\0";
    unsigned char i;
    unsigned char temp;


    i = 0;
    // Copy vendor ID string from EEPROM.
    while ((temp = vendor[i]) != '\0')
    {
        i++;
        smb-&gt;txBuffer[i] = temp;
    }
    smb-&gt;txBuffer[0] = i; // Byte count.
    smb-&gt;txLength = i + 1; // Number of bytes to be transmitted including byte count.

    smb-&gt;state = SMB_STATE_WRITE_READ_REQUESTED;
    PORTA ^= 0x40; // debug
}

static void UndefinedCommand(SMBData *smb)
{
    // Handle undefined requests here.
    smb-&gt;error = TRUE;
    smb-&gt;state = SMB_STATE_IDLE;
}


void ProcessMessage(SMBData *smb)
{
    if (smb-&gt;state == SMB_STATE_WRITE_REQUESTED)
    {
        switch (smb-&gt;rxBuffer[0]) // Command code.
        {
            case SMB_COMMAND_RETURN_VENDOR_STRING:  // Block read, vendor ID.
                ReturnVendorString(smb);
                break;
            default:
                UndefinedCommand(smb);
                break;
        }
    }
    else
    {
        smb-&gt;state = SMB_STATE_IDLE;
    }
}
</code></pre>

<p>With a (gcc-adapted) version of: <a href="http://www.atmel.com/images/AVR316.zip" rel="nofollow">http://www.atmel.com/images/AVR316.zip</a> from <a href="http://www.atmel.com/devices/ATMEGA324A.aspx?tab=documents" rel="nofollow">http://www.atmel.com/devices/ATMEGA324A.aspx?tab=documents</a></p>

<p>Something's partially working, as my logic analyser shows:</p>

<p><a href="http://i.stack.imgur.com/MbQO7.png" rel="nofollow"><img src="http://i.stack.imgur.com/MbQO7.png" alt="enter image description here"></a></p>

<p>But I assume I'm doing something wrong as the AVR is not ACK'ing the READ, nor clock-stretching nor sending a response.</p>

<p>Where should I look next?</p>

<p>Can I have confidence in the Python smbus module on the RasPi?</p>

<hr>

<p>Could what I'm seeing be related to <a href="https://github.com/raspberrypi/linux/issues/254" rel="nofollow">https://github.com/raspberrypi/linux/issues/254</a> ?</p>

<p>I tried using SMBus from a Beaglebone instead (replacing the Raspberry Pi).</p>

<p>This worked perfectly, after I added some 10K pull-up resistors to the i2c bus.  (The Raspberry Pi has internal pull-ups on the i2c pins.)</p>

python raspberry-pi avr i2c smbus