I2C read bug RRS feed

  • Question

  • I think I have discovered a major bug in the Azure Sphere I2C libraries.

    I'm trying to interface to an I2C device from my Avnet Azure Sphere.

    i2cFd = I2CMaster_Open(AVNET_MT3620_SK_ISU2_I2C); int result = I2CMaster_SetBusSpeed(i2cFd, I2C_BUS_SPEED_STANDARD); result = I2CMaster_SetTimeout(i2cFd, 100); result = I2CMaster_SetDefaultTargetAddress(i2cFd, i2cAddress);

    const uint8_t readLength = 9;
        const uint8_t address = 0xD0;
        uint8_t b1[20];
        uint8_t b2[20];
        uint8_t b3[20];
        uint8_t b4[20];
        uint8_t b5[20];
        uint8_t b6[20];

        I2CMaster_WriteThenRead(i2cFd, i2cAddress, &address, 1, b1, readLength);
        I2CMaster_WriteThenRead(i2cFd, i2cAddress, &address, 1, b2, readLength);
        I2CMaster_WriteThenRead(i2cFd, i2cAddress, &address, 1, b3, readLength);
        I2CMaster_WriteThenRead(i2cFd, i2cAddress, &address, 1, b4, readLength);
        I2CMaster_WriteThenRead(i2cFd, i2cAddress, &address, 1, b5, readLength);
        I2CMaster_WriteThenRead(i2cFd, i2cAddress, &address, 1, b6, readLength);

    Log_Debug("\nb1[0] = %x, b2[0] = %x, b3[0] = %x, b4[0] = %x, b5[0] = %x, b6[0] = %x\n", b1[0], b2[0], b3[0], b4[0], b5[0], b6[0]);

    When readLength is <= 8, the code works as expected, the content of the output buffers is good, and the following is printed to the console (register d0 is a chip ID which is read-only and should always be 0x61):

    b1[0] = 61, b2[0] = 61, b3[0] = 61, b4[0] = 61, b5[0] = 61, b6[0] = 61

    However if readLength > 8, I get the following console output:

    b1[0] = 80, b2[0] = 0, b3[0] = 0, b4[0] = 0, b5[0] = 0, b6[0] = 0

    and my output buffers contain an extra byte before the expected data.

    In other words, buffer[0] is rubbish, and my read data is from buffer[1] onwards.

    If I mix up the readLengths with a combination of values <=8 and > 8, then I discover that the first read of 9 or more bytes is good but subsequent reads of 9 or more bytes are bad with the additional byte at the start, until the next read of 8 or less bytes which is good.


    Im using Azure Sphere 19.07 on an Avnet Starter Kit board with an external I2C device with address 0x77.

    My current workaround is to read larger lengths in blocks of 8 (or less) bytes.

    Sunday, September 29, 2019 1:27 PM


All replies

  • I can confirm the same behaviour with a different I2C device. I put an oscilloscope on the I2C signal and it the data appears to be correct, but the MT3620 is returning the duplicated first byte.Correct I2C data being returned from device

    Incorrect data returned

    • Edited by FredMurphy Wednesday, October 2, 2019 10:24 AM
    Wednesday, October 2, 2019 10:18 AM
  • Thank you both for reporting this! We are looking into this and get back to you soon.
    Wednesday, October 2, 2019 11:10 AM
  • For completeness, here's my workaround code for reading more than 8 bytes:

    int32_t retVal = I2CMaster_Write(i2cFd, dev_id, &reg_addr, 1);
    if (retVal < 0) {
        return -1;
    uint16_t i = 0;
        there seems to be a bug where bad data is returned when reading more than 8 bytes at a time
        so read in blocks of 8 bytes for now
    for (i = 0; i < len; i += 8)
        uint8_t readLength = len - i;
        if (readLength > 8)
            readLength = 8;
        retVal = I2CMaster_Read(i2cFd, dev_id, &reg_data[i], readLength);
        if (retVal < 0) {
            return -1;
    Also in my case, I don't think I was receiving a duplicate of the first expected byte in position 0.

    • Edited by Jeremy_K Wednesday, October 2, 2019 11:15 AM
    Wednesday, October 2, 2019 11:13 AM
  • Can you reproduce this when using I2CMaster_Read Function ?
    Wednesday, October 2, 2019 11:23 AM
  • The same issue occurs whether using I2CMaster_Write followed by I2CMaster_Read or a single I2CMaster_WriteThenRead

    I do not know of any problems with the I2C write functionality, only the reading.

    • Edited by Jeremy_K Wednesday, October 2, 2019 11:30 AM
    Wednesday, October 2, 2019 11:29 AM
  • Thanks for checking it Jeremy. I am at the moment trying to repro your issue. Can I also kindly as you to test ISU0, ISU1, ISU3 and ISU4 to check if the issue is persistent?

    See : https://docs.microsoft.com/en-us/azure-sphere/app-development/app-manifest

    • I2cMaster: BETA feature List of I2C master interfaces that are used by the application. For the MT3620 development board, the possible values are "ISU0" through "ISU4".

    I guess you only tested ISU2, that's why I ask.


    Monday, October 7, 2019 1:51 PM
  • You are correct, I have only tested ISU2 so far.

    I am testing with an Avnet Azure Sphere starter kit, which does not expose ISU3 or ISU4. In order to use I2C on ISU0 or ISU1, I'll need to add some jiggery-pokery between my Click Board and the starter kit, I'm not sure I have time at present to run those tests.

    Have you been able to reproduce my issue? Other users have confirmed the bug exists with other I2C devices on the same ISU2 peripheral.

    Tuesday, October 8, 2019 4:54 AM
  • Thanks Jeremy,

    I am trying to find time to repro this and already requested that Product Group takes a look at it. Please bear with us.

    Tuesday, October 8, 2019 1:41 PM
  • I have now updated my Azure Sphere to 19.09 and installed the latest SDK preview.

    I can confirm the issue is still present with Target API Set 3+Beta1909.

    Thursday, October 10, 2019 10:26 AM
  • Thanks Jeremy,

    We were able to repro this issue and are already investigating the Root Cause. Will keep updating the Status of the investigation on this thread.

    Once more, thank you so much for reporting it Jeremy and Fred!

    Thursday, October 17, 2019 10:52 PM
  • :)

    This is not a bug, but incomplete documentation ...
    Mediatek: Hardware SPI for this chipset ( and other ) 
    support 8 bytes for one time transaction...



    look members description:

    VMUINT32 data_length; The data length. Please note: this length should not exceed 8. 

    • Proposed as answer by WizIO.bg Friday, October 18, 2019 3:24 PM
    • Edited by WizIO.bg Friday, October 18, 2019 3:43 PM
    • Unproposed as answer by Jeremy_K Friday, October 18, 2019 8:51 PM
    Friday, October 18, 2019 3:24 PM
  • Sorry I don't agree that this should solely be fixed in documentation.

    The API should not necessarily be restricted by hardware limitations. If a new Azure Sphere device is released, for example, you want the API to be as compatible as possible.

    In my view, if there is a hardware limit of 8 bytes then the appropriate fix is for the Azure Sphere libraries to abstract that away and make multiple reads under the hood.

    Friday, October 18, 2019 8:57 PM
  • Microsoft I2C API function is "copy" of Mediatek HAL I2C driver
    This API is not posix read() write() and is not java or C# ...
    Example: Arduino Wire class use I2C HAL functions and ring buffers to make that you want
    Friday, October 18, 2019 9:20 PM
  • according to Microsoft, you're right :)

    ssize_t I2CMaster_Write(int fd, I2C_DeviceAddress address, const uint8_t *data, size_t length);
    ... This function provides the same functionality as the POSIX write() function ...
    Sunday, October 20, 2019 9:12 AM
  • Thanks Jeremy,

    We were able to repro this issue and are already investigating the Root Cause. Will keep updating the Status of the investigation on this thread.

    Once more, thank you so much for reporting it Jeremy and Fred!

    Any news here?
    Wednesday, November 13, 2019 10:06 PM
  • Hello Jeremy, all.

    We have fixed this issue and it will be deployed on Retail Eval Feed 19.11. Please wait for that release and let us know if you stop seeing the additional byte at the start when readLength > 8.

    Thank you again for reporting this issue!

    FYI: Here are the instructions to set-up Retail Eval feed:

    Friday, November 15, 2019 8:08 PM