Skip to content

i2c: Wire only works with some pins. (Need to use Wire1 instead.) #169

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

Closed
skybrian opened this issue May 26, 2021 · 3 comments · Fixed by #182
Closed

i2c: Wire only works with some pins. (Need to use Wire1 instead.) #169

skybrian opened this issue May 26, 2021 · 3 comments · Fixed by #182

Comments

@skybrian
Copy link
Contributor

If you use setSDA() and setSCL() on Wire then it apparently only works for pins labeled "I2C0" on the Pico pinout diagram. I had the bad luck of choosing pins labeled "I2C1" and it silently didn't work. For those pins you need to use Wire1.

This seems awkward, but if it can't be helped, maybe stating this more explicitly on the i2c page might help others avoid this gotcha?

@earlephilhower
Copy link
Owner

...silently didn't work...

Crud, I thought I had added warnings when a setXXX() failed when in debug mode, but it looks like I didn't get around to it.

It's just the way the Pico HW muxes are set up. Only certain pins are allowed for each peripheral copy (I2C, SPI, and UART) as well as per actual pinout (i.e. you can't swap SDA/SCL pins). You really need a copy of the Pico pinout sheet like you linked.

@skybrian
Copy link
Contributor Author

I seem not to be building in DEBUG mode and didn't think about using it, since I'm coming from the official Mbed-based board support where I don't think it's an option. It looks handy! (I switched to get support for USB MIDI.)

I knew that only certain pins work for i2c but the official Mbed-based board (which uses a constructor rather than setter methods) seems to automatically choose the right instance to use, or maybe I just got lucky.

I suppose theoretically you could make Wire and Wire1 automagically swap instances if you are only using one of them, or get it backwards?

@earlephilhower
Copy link
Owner

My preference is to keep them both separate and usable. The thing is, you're limited to specific pins anyway (i.e. can't ever do SCK on GPIO0), so there is always some knowledge needed. Exposing both HW sets lets you do things like run 2 separate apps doing I2C (maybe some kind of safety critical thing where you read some data from one I2C bus, compute on it, then fire it to the other I2C bus to be acted upon).

For now, even DEBUG mode doesn't warn you when the set call fails (it does return false but that's pretty much ignored).

I think the right thing to do, then would be to do a complete panic() (i.e. dump and halt) in all modes, debug or not. I'll throw in a PR to that effect for the 3 peripherals later tonight.

earlephilhower added a commit that referenced this issue May 29, 2021
Fixes #169

Trying to change pinout while running, or to an illegal configuration,
will now immediately panic() with an error message.  Such an attempt
is a pretty big problem since pinouts are hardware related/static.

Prior code would fail silently and return false, but nobody checked
the setXXX return values, anyway.
earlephilhower added a commit that referenced this issue May 29, 2021
Fixes #169

Trying to change pinout while running, or to an illegal configuration,
will now immediately panic() with an error message.  Such an attempt
is a pretty big problem since pinouts are hardware related/static.

Prior code would fail silently and return false, but nobody checked
the setXXX return values, anyway.
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

Successfully merging a pull request may close this issue.

2 participants