9 years, 5 months ago.

I2C Slave capability

I'm trying to get A FRDM-K64 board to work in I2C Slave mode. I have connected one to a bus pirate, using pins I2C_SDA and I2C_SCL. I have the following code (based on the demo in the documentation) running on the board:

#include <mbed.h>

I2CSlave slave( I2C_SDA, I2C_SCL );
const int SLAVE_ADDRESS = 0x02;

int main( void )
{
    char incoming[10]; // incoming data buffer
    slave.frequency( 100000 );
    slave.address(SLAVE_ADDRESS);

    printf("Setup I2C...\n\r");

    while(1) {
        int status = slave.receive();
        switch( status ) {
            case I2CSlave::NoData:
                // nothing happening here...
                break;
            case I2CSlave::WriteAddressed:
                // something is writing to this address
                slave.read( incoming, 1 );
                printf("data rx\n");
                break;
            default:
                // some other operation is happening
                printf("i2c op: %d\n", status );
                break;

        }
    }
}

I have set the Bus Pirate to I2C mode, 100kHz. When I send a message START -> ADDRESS -> DATA_BYTE -> STOP, I simply gets NACKs. I have tried assorted addresses without success. I sort-of expect it should enter detect an attempt to write to it, then read the next byte before returning to wait for further status changes. Have I missed some critical bit of setup?

Alan

Question relating to:

The Freedom-K64F is an ultra-low-cost development platform for Kinetis K64, K63, and K24 MCUs.

I have found that the slave.address() line does not appear to be setting the address correctly. In the i2c_api.c file for this target, the function i2c_slave_address() appears to be calling I2C_HAL_SetUpperAddress7bit() instead of I2C_HAL_SetAddress7bit(). This gets me a step toward receiving commands on my slave - it is now ACKing the traffic correctly, just not reading subsequent bytes.

posted by Alan Bowman 14 Nov 2014

I have made some further progress - in the same file, there is a function i2c_slave_read(). It appeared to be setting the peripheral into transmit mode. Changing the setup line to kI2CReceive instead of kI2CSend is a dramatic improvement.

posted by Alan Bowman 14 Nov 2014
Be the first to answer this question.