The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Dependents:   hello SerialTestv11 SerialTestv12 Sierpinski ... more

Issue: Unexpected return values of I2CSlave read/write functions (Closed: Fixed)

Instead of returning "0" on success and "non-0" on failure as documented,
I2CSlave::read returns the number of bytes read ... minus one
and
I2CSlave::write returns the number of bytes written

I2CSlave.h:

    /** Read from an I2C master.
     *
     *  @param data pointer to the byte array to read data in to
     *  @param length maximum number of bytes to read
     *
     *  @returns
     *       0 on success,
     *   non-0 otherwise
     */
    int read(char *data, int length);

    /** Write to an I2C master.
     *
     *  @param data pointer to the byte array to be transmitted
     *  @param length the number of bytes to transmite
     *
     *  @returns
     *       0 on success,
     *   non-0 otherwise
     */
    int write(const char *data, int length);

I2CSlave.cpp

int I2CSlave::read(char *data, int length) {
    return i2c_slave_read(&_i2c, data, length);
}
int I2CSlave::write(const char *data, int length) {
    return i2c_slave_write(&_i2c, data, length);
}

i2c_api.c
BTW: Here the clearing of the serial interrupt i2c_clear_SI(obj); is necessary (see https://mbed.org/users/mbed_official/code/mbed/issues/1). It stops the slave keeping the SCL line low, which would inhibit the master from creating a START or STOP condition.

int i2c_slave_read(i2c_t *obj, char *data, int length) {
    int count = 0;
    int status;

    do {
        i2c_clear_SI(obj);
        i2c_wait_SI(obj);
        status = i2c_status(obj);
        if((status == 0x80) || (status == 0x90)) {
            data[count] = I2C_DAT(obj) & 0xFF;
        }
        count++;
    } while (((status == 0x80) || (status == 0x90) ||
            (status == 0x060) || (status == 0x70)) && (count < length));

    if(status != 0xA0) {
        i2c_stop(obj);
    }

    i2c_clear_SI(obj);

    return (count - 1);
}

int i2c_slave_write(i2c_t *obj, const char *data, int length) {
    int count = 0;
    int status;

    if(length <= 0) {
        return(0);
    }

    do {
        status = i2c_do_write(obj, data[count]);
        count++;
    } while ((count < length) && (status == 0xB8));

    if((status != 0xC0) && (status != 0xC8)) {
        i2c_stop(obj);
    }

    i2c_clear_SI(obj);

    return(count);
}