pasko-zh / brzo_i2c

Brzo I2C is a fast I2C Implementation written in Assembly for the esp8266
GNU General Public License v3.0
244 stars 47 forks source link

gpio_init() will cause I2C bus busy (code: 1) #30

Closed mcr-ksh closed 6 years ago

mcr-ksh commented 6 years ago

When using gpio_init(); the library cannot be used anymore.

I will receive upon send error code = 1.

pasko-zh commented 6 years ago

Could you please give some more details about the issue? Maybe some code? Are you on the native or Arduino toolchain? etc... thanks

mcr-ksh commented 6 years ago

on Arduino toolchain.

issue #1: when using gpis_init() before the brzo code, brzo will not work. issue #2: when using brzo_i2c_setup the entire i2c bus is locked/blocked by the native Arduino Wire.cpp

Atm I have the problem that once I use brzo_i2c_setup(SDA,SCL) all further i2c communication using the Wire.read(), Wire.write() etc. is blocked.

If I have gpis_init() before brzo_i2c_setup() brzo i2c functions (read/write) won't work anymore. This is on wemos d1 lite and wemos d1 mini R2.

do the i2c_scan() before brzo_i2c_setup(SDA,SCL) and after.

i2c_scan(); brzo_i2c_setup(SDA,SCL); i2c_scan();

first there will be some devices and after the i2c_setup there won't be any. This must have something todo with putting the pin to OPEN_DRAIN and the brzo_i2c_reset_bus(). Im wondering on how I could revert back the chip so the Arduino function will work again until I call brzo_i2c_setup() again?

bool i2c_scan()
{
  bool found = false;

  Wire.begin();
  for (uint8_t n=8; n < 120; n++) 
  {
    Wire.beginTransmission(n);
    byte error = Wire.endTransmission();

    /* got device or error */
    if (error == 0)
    {
      Serial.print("I2C device found at address ");
      Serial.println(n, HEX);
      found = true;
    }
  }

  Serial.println(found);
  return found;
}

found will always be false.

Can I provide more info?

pasko-zh commented 6 years ago

Well... You cannot mix brzo_i2c and the wire library! This will never work was never intended to work. Also note that brzo_i2c is not designed as a drop-in replacement for the wire library, it uses a different approach with the notion of i2c transactions.

Thus, please have a look at

mcr-ksh commented 6 years ago

ok! understood. I was able to mix broth libraries by setting up using brzo_i2c_setup(), do the transaction and releasing the bus with release_i2c_brzo().

Unfortunately there are too many libraries that use Wire library so I cannot completely migrate to brzo. However, I like your work at a lot and thus prefer to mix it.

inline void release_i2c_brzo()
{
  uint16_t sda_bitmask = (uint16_t)(1 << SDA);
  uint16_t scl_bitmask = (uint16_t)(1 << SCL);
  int32_t a_set, a_temp1;

  asm volatile (
    "MOVI   %[r_set], 0x60000304;"
    "MOVI.N %[r_temp1], 30;"
    "S16I   %[r_scl_bitmask], %[r_set], 4;"
    "MEMW;"
    "S16I   %[r_sda_bitmask], %[r_set], 4;"
    "l_ksh_%=:"
    "addi   %[r_temp1], %[r_temp1], -1;"
    "NOP;"
    "BNEZ   %[r_temp1], l_ksh_%=;"

    : [r_set] "+r" (a_set), [r_temp1] "+r" (a_temp1)
    : [r_sda_bitmask] "r" (sda_bitmask), [r_scl_bitmask] "r" (scl_bitmask)
    : "memory"
  );  
}
pasko-zh commented 6 years ago

OK, thanks for the clarification. Thus, I will close this issue then.