5 years, 8 months ago.

Fail to write to I2C after arbitrary amount of time

Hi, I am trying to write some code to read data over I2C. I have been successful in receiving data, and the program runs for a good amount of time (about 90 minutes on average) before the I2C write function returns NACK, and continues to do so after that.

The device I am using is a UBlox M8 module. I have the device rebooting once this error occurs (lines 22-27) and it works for now, but I'd really like to understand why this is happening.

I ran it over the weekend (about 60 hours) and it rebooted 36 times.

Thanks!

Minimal example

Serial serial(USBRX, USBTX, 19200);
I2C i2c(I2C_SDA, I2C_SCL);

const uint8_t slaveAddr = 0x42;

void read(void const *args) {
    I2C* i2c = (I2C*)args;
    char buf[128];
    Thread::wait(100);

    const char I2C_ADDR = slaveAddr << 1; // Address of I2C slave to read
    const char COUNT_REG[] = { 0xFD };   // Count register address - how many bytes are available to read
    const char DATA_REG[] = { 0xFF };    // Data register address - the data stream

    // Set read register to COUNT_REG to open I2C stream
    bool success = !i2c->write(I2C_ADDR, COUNT_REG, sizeof(COUNT_REG));

    while (success) {
        success = !i2c->write(I2C_ADDR, COUNT_REG, sizeof(COUNT_REG), true) && 
              !i2c->read(I2C_ADDR, buf, 2);

        if (!success) {
            serial.printf("Write/read failed...\r\n");
			Thread::wait(500);
			NVIC_SystemReset();
        }

        int bytesAvailable = (unsigned short)(buf[0] << 8 | buf[1]);

        if (bytesAvailable) {
            serial.printf("\r\nbytesAvailable  %i\r\n", bytesAvailable);

            while (bytesAvailable && success) {
                int bytesToRead = (bytesAvailable < (unsigned) sizeof(buf)) ? bytesAvailable : sizeof(buf);

                success = !i2c->write(I2C_ADDR, DATA_REG, sizeof(DATA_REG), true) && 
                        !i2c->read(I2C_ADDR, buf, bytesToRead);

                if (success) {
                    for (int i = 0; i < bytesToRead; i++) {
                        serial.printf("%02X", buf[i]);
                    }

                    bytesAvailable -= bytesToRead;
                } else {
                    serial.printf("Couldn't read even though bytes available = %d\r\n", bytesAvailable);
                }
            }

            serial.printf("\r\n");
        }
        Thread::wait(100);
    }
}

int main() {
	Thread readThread;
    readThread.start(callback(read, (void *)&i2c));

    while (1)
    {
        led = !led;
        Thread::wait(500);
    }

    return 0;
}

@team-ublox: could you please provide Steven with necessary information to debug the crash that he is observing on the Ublox device? Thanks!

posted by Naveen Kaje 20 Aug 2018

For @team-ublox reference, I am running a NINA-B112 connected to a SAM-M8Q-0-10

posted by Steven Crake 22 Aug 2018

The article you have shared here is very awesome. I really like and appreciate your work. The points you have mentioned in this article are useful. I must try to follow these points and also share others. http://happywheelsaz.com/

posted by happy wheels 24 Aug 2018
Be the first to answer this question.

Assigned to u-blox 5 years, 8 months ago.

This means that the question has been accepted and is being worked on.