Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wire.Begin(4,0) doesn't seem to work: Can GPIO0 mux with I2C clock(SCL)? #1236

Closed
terryjmyers opened this issue Mar 19, 2018 · 6 comments
Closed

Comments

@terryjmyers
Copy link
Contributor

Hardware:

Board: ESP32-WROVER (bare module in small batch burn fixture)
Core Installation/update date: Some time in Jan 2018 (2 months ago)
IDE name: vstudio
Flash Frequency: 240Mhz(irrelevant)
Upload Speed: 926500 (irrelevant)

I want to use GPIO4 for SDA and GPIO0 for SCL. GPIO4 for SDA works fine (even up to 400Khz), tested by simplying assigning SCL to some other pin. However I'm unable to use GPIO0 as SCL. Of course I'm aware that GPIO0 is a boot strap pin, but this shouldn't matter if you are using it as an output (same with GPIO2. Besides, GPIO0 has an inbuilt Pull up resistor anyway so it makes sense for a SCL line.

Additional information:

  1. The bus has an MCP4725 and an ADS1115, both of which respond fine on any other "normal" GPIO pins with either 100Khz or 400Khz.
  2. I'm using external 1K pull up resistors as my capacitance is a bit high as I'm still in a breadboard and my bus lines are at least 12in long.
  3. With an OScope I'm able to see the transmission on "other" GPIO pin combination without any problem at both 100khz and 400khz speeds. e.g. I've tested: [SDA, SCL], [4,22], [21/22], [25/26], just to make sure it wasn't user error.
  4. I'm using GPIO2 (which is of course another boot strap pin with inbuilt pulldown) successfully as a PWM output to control a fan speed PWM line (generic 26Khz 4-pin fan control).

Is GPIO0 unable to mux itself into the clock line? Am I doing something wrong? I also realize this may be hard to reproduce as most dev boards don't give access to GPIO0. My sketch is quite extensive so its probably just easier for anyone to open an example sketch provided with any reliable I2C IC library( e.g. AdaFruit_mcp4725, AdaFruit_ads111x), and simply changing the Wire.Begin() in the librariers *.cpp file to Wire.Begin(4,0).

Thanks! Any assistance or verification of what I'm seeing would be much appreciated. Good luck breaking out GPIO0 :).

@terryjmyers terryjmyers changed the title Wire.Begin(4,0) doesn't work. Pin 0 can't be used for SCL Wire.Begin(4,0) doesn't work. GPIO0 doesn't seem to want to mux with I2C clock(SCL) Mar 19, 2018
@terryjmyers terryjmyers changed the title Wire.Begin(4,0) doesn't work. GPIO0 doesn't seem to want to mux with I2C clock(SCL) Wire.Begin(4,0) doesn't seem to work: Can GPIO0 mux with I2C clock(SCL)? Mar 19, 2018
@stickbreaker
Copy link
Contributor

@terryjmyers check through all of your libraries that use Wire(). It is standard practice in Arduino libraries to have a call to Wire.begin(); inside the initialization code for EACH library. The way this repo's TwoWire:: class is written is that any call of Wire.begin(); will restore the pin configurations to the default values of Wire.begin(SDA,SCL); Where SDA and SCL are defined for each different board. The most common values are SDA=21, SCL=22. So if any library re-inits Wire() and custom values are overwritten back to Wire.begin(21,22);.

I made a fix for my repo, but I haven't merged it yet. To fix it, in Wire.cpp at TwoWire::begin() replace the two if(pin) at the top of the function with this code.

  if(sdaPin < 0) { // default param passed
    if(num == 0) {
      if(sda==-1) sdaPin = SDA; //use Default Pin
      else sdaPin = sda; // reuse prior pin
      } 
    else {
      if(sda==-1) {
        log_e("no Default SDA Pin for Second Peripheral");
        return; //no Default pin for Second Peripheral
        }        
      else sdaPin = sda; // reuse prior pin
      }
    }

  if(sclPin < 0) { // default param passed
    if(num == 0) {
      if(scl==-1) sclPin = SCL; // use Default pin
      else sclPin = scl; // reuse prior pin
      }
    else {
      if(scl==-1){
        log_e("no Default SCL Pin for Second Peripheral");
        return; //no Default pin for Second Peripheral
        }
      else sclPin = scl; // reuse prior pin
      }
    }

Chuck.

@terryjmyers
Copy link
Contributor Author

@stickbreaker
Thanks for your reply. I'm using all of my own libraries for the ADS1115 and the MCP4725 that are on the bus, and I've made sure I only have one Wire.begin(...) in my main program. I like to write my own so I fully understand how the chips functions and understand what the code does and doesn't do so I can optimize for my own project. For example I'm using FreeRTOS so everything is asyncronous. Therefore my ADS1115 library simply has a function to trigger the conversion and a separate to quick check if its done, and another just to get the result, instead of triggering it and waiting with blocking code (ref https://github.com/terryjmyers/ADS1115-Lite).
Anyway I slapped your code in however as I expected it didn't really solve my problem. I'm calling Wire.begin as:
Wire.begin(4,0,400000), which by definition won't trigger the if...then statements because the sclPin and sdaPin are not -1 (default when the Wire library constructor is called).

Anyway I did again verify that my library is functional and I have full control over my peripherals no matter what combination of GPIO pins I choose for SCL and SDA, however I simply cannot get GPIO0 to function as SCL.

@stickbreaker
Copy link
Contributor

are you using the the same library you referenced ADS1115-Lite
because: how about line 18

Chuck.

@stickbreaker
Copy link
Contributor

stickbreaker commented Mar 20, 2018

@terryjmyers What circuit do you have attached to GPIO 0?
How is your USB-Serial converter connected?

Check out this page on standard boot loader configurations ESP32 Boot Mode Selection

The reason I point this out is, because the 'recommended' connection directly connects DTR from the usb-serial converter to GPIO0?

Chuck.

@copercini
Copy link
Contributor

Fixed with I2C core RC1, boot strapping pin problem

@milamber-ls
Copy link

it seems I have the same issue at espidf. how was that fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants