adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.07k stars 1.2k forks source link

Incorrect I2C pins for SAMD51 #1997

Closed wallarug closed 5 years ago

wallarug commented 5 years ago

As per Discord Chat.

Hi,

I noticed on my ItsyBitsy M4 (SAMD21G19A) that CircuitPython seems to allow a huge number of non-compliant combinations for I2C and UART configurations for SAMD51.

I was just wondering if the datasheet for the SAMD51 is wrong or CircuitPython.

EG: D3 (PB23) and MOSI (PB22) is said to be supported uart but really you cannot use the TX pin. (not on PAD[0])

EG: MOSI (PA00) and SCK (PA01) is said to be a valid I2C connection but doesn't work at all. (Not supported by SAMD51 - see datasheet).

Attached is what the test script outputs.

CircuitPython code.py

import board
import busio
from microcontroller import Pin

def is_hardware_I2C(scl, sda):
    try:
        p = busio.I2C(scl, sda)
        p.deinit()
        return True
    except ValueError:
        return False
    except RuntimeError:
        return True

def get_unique_pins():
    exclude = ['NEOPIXEL', 'APA102_MOSI', 'APA102_SCK']
    pins = [pin for pin in [
        getattr(board, p) for p in dir(board) if p not in exclude]
            if isinstance(pin, Pin)]
    unique = []
    for p in pins:
        if p not in unique:
            unique.append(p)
    return unique

for scl_pin in get_unique_pins():
    for sda_pin in get_unique_pins():
        if scl_pin is sda_pin:
            continue
        else:
            if is_hardware_I2C(scl_pin, sda_pin):
                print("SCL pin:", scl_pin, "\t SDA pin:", sda_pin)
            else:
                pass

It looks like busio.I2C doesn't do it's checks correctly. Same goes for busio.UART.

SAMD51 Datasheet. image

d51-i2c.txt d51-uart.txt

tannewt commented 5 years ago

Assume CircuitPython is wrong. UART was just fixed in #1989. Please file a fix for I2C if you have time. Let me know if you have questions about it.

wallarug commented 5 years ago

No worries @tannewt . I'll give it a test run in the next version bump of CircuitPython and report back.

wallarug commented 5 years ago

@tannewt

Following up on this.

Does CPY support software I2C? We have got I2C working on PA08/PA09 but the datasheet clearly says that only:

PA16/17 PA12/13 PA22/23

Any ideas?

deshipu commented 5 years ago

CircuitPython does support software i2c, but you have to explicitly use bitbangio instead of busio.

wallarug commented 5 years ago

Follow up Question: How come busio works on the pins mentioned before PA08/PA09 when datasheet says it shouldn't for SAMD51G19A?

deshipu commented 5 years ago

Maybe it only seems like it works, and there are some weird corner cases or rare hardware errors that we can't see, so the datasheet says they are not supported? Or maybe the datasheet lies?

dhalbert commented 5 years ago

I have seen before on the SAMD21 that some pins were excluded from I2C even though they worked. In that case it was because of under-spec current sinking on those pins. The I2C pins had higher current capability than most of the other pins. In practice the under-spec pins work fine. The might be flaky on very long runs, but we have never seen that.

However, on the SAMD51, PA08 and PA09 are supposed to have higher sink ability: Quoting from the datasheet: 3. These pins are High Sink pins and have different properties than regular pins: PA08, PA09, PA12, PA13, PA16, PA17, PA22, PA23, PD08, PD09. So that's not the issue on the SMAD51.

But PA08 and PA09 are powered by VDDIOB, not VDDIO. Note that PA08 and PA09 are spec'd for I2C in the 100-pin and 128-pin packages. So this may be due again to some slight-out-of-spec issue, such as noise or total current sinking, in the 64 and 48-pin packages. It's not necessarily that they don't function, just that they don't meet the rather rigid I2C specifications.

It could be due, for instance, to total current draw available from multiple pins sharing the same power supply. In other words, it might be a worst case situation, which most users won't encounter.

wallarug commented 5 years ago

So based on your above comment @dhalbert it is likely that in most cases they will work (as they appear to be working for me both in CircuitPython and Arduino) but could experience issues.

I understand what you are saying about how much power they can sink and the different supplies. I just found it strange that they (1) worked and (2) datasheet said otherwise.

I have the same case on PA00 / PA01 --> working I2C even though they are not in datasheet.

The only reason I even tried them out is because they are supported on SAMD21.

dhalbert commented 5 years ago

@wallarug Yes, the datasheet is saying in an opaque way you shouldn't, as opposed to you can't, or "we don't guarantee it".

AND, I found a previous discussion of this exact issue: https://forums.adafruit.com/viewtopic.php?f=63&t=139056. Also see https://www.avrfreaks.net/forum/solved-samd21-i2c-slave-mode-data-write-failure (linked from the forums thread).

wallarug commented 5 years ago

Great information! Thanks @dhalbert .

There are no issues with I2C and CircuitPython (in fact - it is good that you can use more combinations).

I would still like to keep this issue open so that I can test the UART pins thing mentioned at the top by @tannewt and report back when I run my next build.

Thank you everyone! 💯

tannewt commented 5 years ago

@wallarug Any update? Still need this open?

wallarug commented 5 years ago

Hey Scott,

Happy to have this one closed off. I'm going to PR some changes this weekend for the other issue.