i2c line busy after i2c_master_stop()

permal
Posts: 384
Joined: Sun May 14, 2017 5:36 pm

i2c line busy after i2c_master_stop()

Postby permal » Sun Aug 27, 2017 9:27 am

Hi,

I've been reading values from a BME280 continuously for the last week over I2C without any glitches, but yesterday when I wanted to implement the MCP23017 I/O expander I discovered an error in my code that prevented it from ever calling i2c_master_stop() at the end of the command sequence.

So, I fixed that but in doing so the entire i2C communication broke down and i2c_master_cmd_begin() now always returns ESP_ERR_TIMEOUT.

I've compared my code with how the IED I2C example does things and I see no difference in how commands are built. Apart from potentially OR:ing error codes together, am I building the command wrong in some way? I2CCommandLink is a scoped-based resource that is implicitly cast to a i2c_cmd_handle_t when needed.

Code: Select all

                    I2CCommandLink link(*this);

                    // Set R/W bit to 0 for write.
                    uint8_t write_address = address << 1;
                    // Set R/W bit to 1 for read.
                    uint8_t read_address = (address << 1) | 0x1;

                    // Generate start condition
                    auto res = i2c_master_start(link);
                    // Write the slave write address followed by the register address.
                    res |= i2c_master_write_byte(link, write_address, true);
                    res |= i2c_master_write_byte(link, slave_register, true);
                    // Generate another start condition
                    res = i2c_master_start(link);

                    // Write the read address, then read the desired amount,
                    // ending the read with a NACK (0) to signal the slave to stop sending data.
                    res |= i2c_master_write_byte(link, read_address, true);
                    res |= i2c_master_read(link, data.data(), data.size(), 0);

                    // Complete the read with a stop condition.
                    res |= i2c_master_stop(link); // Removing this line makes things work?!?!?!!?!?
                    res |= i2c_master_cmd_begin(port, link, Task::to_tick(timeout));

permal
Posts: 384
Joined: Sun May 14, 2017 5:36 pm

Re: i2c line busy after i2c_master_stop()

Postby permal » Sun Aug 27, 2017 10:04 am

Hm, interesting how a monolog with yourself can make you see things that you've missed previosuly.

So it seems that I had switched the value of a NACK (had it to 0) and switching it to 1 freed up the bus, but the real problem was me misunderstanding the usage of i2c_master_read(). It seems you must only read to size-1 then use i2c_master_read_byte() to read the last byte if you want to end with a NACK. I suppose it comes down to how the i2c protocols function(?)

So, the i2c_master_read() in my code above becomes this instead:

Code: Select all

                    if (data.size() > 1)
                    {
                        res |= i2c_master_read(link, data.data(), data.size() - 1, ACK);
                    }
                    res |= i2c_master_read_byte(link, data.data() + data.size() - 1, NACK);
Alternatively you could do this instead, but perhaps that uses up more resources in the command link?

Code: Select all

                  int i = 0;
                  for (; i < data.size()-1; ++i)
                  {
                      res |= i2c_master_read_byte(link, data.data() + i, 0);
                  }
                  res |= i2c_master_read_byte(link, data.data() + i, 1);

User avatar
rudi ;-)
Posts: 1730
Joined: Fri Nov 13, 2015 3:25 pm

Re: i2c line busy after i2c_master_stop()

Postby rudi ;-) » Sun Aug 27, 2017 10:03 pm

permal wrote: Hm, interesting how a monolog with yourself can make you see things that you've missed previosuly.
OT:
i've started to learn on this way esp8266 and deepen the esp32 knowledge step by step

:mrgreen:
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪

Who is online

Users browsing this forum: Bing [Bot] and 147 guests