SpenceKonde / megaTinyCore

Arduino core for the tinyAVR 0/1/2-series - Ones's digit 2,4,5,7 (pincount, 8,14,20,24), tens digit 0, 1, or 2 (featureset), preceded by flash in kb. Library maintainers: porting help available!
Other
563 stars 148 forks source link

I2C Bus not working on 3217 with Adafruit MCP23017 Library #1107

Closed animalfactoryamplification closed 5 months ago

animalfactoryamplification commented 5 months ago

Been using this core to upload code to the 3217, everything including neopixel support works but the I2C line never turns on, using PB0 and PB1 as I2C lines, and have them pulled up with a 4k7 resistor. :(

hmeijdam commented 5 months ago

I2C bus works fine for me on a 3217. Just tested with this I2C scanner and it finds my slave device.

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>

void setup()
{
  Wire.begin();

  Serial.begin(115200);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}
animalfactoryamplification commented 5 months ago

Update:

It was the MCP23017 driver by Adafruit that wasn't working right, something to do with BusIO driver and how it was interfacing with the 3217. Wrote a driver using the Wire library and all working now!

SpenceKonde commented 2 months ago

Aaah, so Adafruit is now packing their own limited compatibility version of the basic libraries? B l o o d y h e l l.

I mean, I see why they would do it. The library arduino gives us is unfit for purpose.... but when they don't make their version work on new hardware, that kinda sucks.

(note that there is a very large difference between the stock shitshow that the official modern AVR core ships with (that version of the library is 1. incomplete (missing support for widely desired features, including the headline features for the new hardware), 2. Incomplete (it throws away information that the application acting as I2C slave would need to have in order to act like a normal I2C device (you know, the "register machine" model that's so familiar - ever wonder why arduino I2C slave projects you may have seen posted always use the I2C like lobotomized serial, instead of I2C? That would be because the stock library provides no facility through which the slave could implement the register-machine functionality, because it wouldn't know where to put the pointer because it doesn't know how many bytes the master read! (there's also an issue with how sleep is handled when acting as I2C slave) and 3. has several bugs in corner cases and 4. makes inefficient use of limited system resources). See our wire doc for more information on the backwards compatible extensions we have added to permit that (and a number of other significant features)