adafruit / circuitpython

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

RasPi Pico: Often (but not always) Errno 19 on i2c writes #4235

Closed ajs256 closed 3 years ago

ajs256 commented 3 years ago

I'm sometimes getting "OSError: [Errno 19] Unsupported operation" when attempting to write to an i2c device (a SparkFun Serial LCD) using a RasPi Pico.

code.py:

import board
import busio

i2c = busio.I2C(board.GP17, board.GP16)

while not i2c.try_lock():
    print("i2c not locked, retrying...")

print(i2c.scan())
i2c.writeto(114, "|-") # Clear
i2c.writeto(114, "Hello world!") # Show some text. Error happens here.

The error appears to be happening on line 11, according to the output. Am I trying to send an illegal character? Or is it a bug in CircuitPython?

EDIT: Oh. I suppose I should say that I am running Adafruit CircuitPython 6.2.0-beta.2 on 2021-02-11; Raspberry Pi Pico with rp2040. I don't know why I didn't say that in my initial comment!

dhalbert commented 3 years ago

There are issues with some I2C devices. The I2C peripherals on the RP2040 do not allow zero-length writes, which are the typical way to do scanning. We are working on a workaround for that.

If you remove the i2c.scan(), does the problem go away?

ajs256 commented 3 years ago

Hmm. I commented out the scan call, and I now get the same error every time! I don't think the scan() is what's causing it.

dhalbert commented 3 years ago

Could you try some other I2C device? What is the part number of the serial LCD you are using?

ajs256 commented 3 years ago

The LCD is SparkFun ID LCD-14073, running firmware version 1.4. That one is now discontinued, but LCD-16397 and LCD-16396 are the same apart from the addition of a QT/Qwiic connector if you want to test yourself. Give me a bit to scrounge up another device.

ajs256 commented 3 years ago

I don't get the error at all using a 8x8 bicolor LED matrix backpack (Adafruit PID 902). I am using the adafruit_ht16k33 library and not writing raw bytes though.

ajs256 commented 3 years ago

Just tested it using the absolute newest build as of https://github.com/adafruit/circuitpython/commit/b19e7c914844634306745ff6858f52df308f85ff, and the error still happens.

ajs256 commented 3 years ago

Tested again as of https://github.com/adafruit/circuitpython/commit/15615effc2f8a9f991ace105f8a9f7bb51982059, and it still happens.

Sorry, but because I do not have an SWD debugger or a logic analyzer, I cannot help with anything requiring that.

ajs256 commented 3 years ago

Tested using bus_device, and it appears to hang when attempting to init the device, unless I pass in probe=False. Then it gives me the OSError I was getting before. Here's the code I'm using:

import board
import busio
from adafruit_bus_device import i2c_device

i2c = busio.I2C(board.GP17, board.GP16)

while not i2c.try_lock():
    pass # Interestingly, it doesn't work without locking the bus. bus_device examples don't seem to require this. 
print("i2c locked.")

lcd = i2c_device.I2CDevice(i2c, 114, False)
print("Device initted.")

lcd.write("|-") # Clear display
lcd.write("Hello, world!") # Print text
print("Text shown.")
dhalbert commented 3 years ago

Try using bitbangio.I2C() on absolute latest. I am still working on getting busio.I2C() to work.

ajs256 commented 3 years ago

bitbangio.I2C works perfectly, thank you.

ajs256 commented 3 years ago

Well... not exactly perfectly. I have to pass in probe=False, or else it just infinitely hangs.

dhalbert commented 3 years ago

Moving to a 6.x.x milestone since there's now a workaround.

dhalbert commented 3 years ago

This is now fixed by #4499 and #4508.

ajs256 commented 3 years ago

This doesn't appear to be fixed in

Adafruit CircuitPython 6.2.0 on 2021-04-05; Raspberry Pi Pico with rp2040

I still need to use bitbangio, otherwise I occasionally get OSError: [Errno 19] Unsupported operation when writing a string to an I2CDevice.

dhalbert commented 3 years ago

Which device(s) in particular? I tested a bunch.

ajs256 commented 3 years ago

The SparkFun SerLCD, which is ATmega328-based, and the firmware is open source here.

dhalbert commented 3 years ago

Could you open a specific issue for that device? It must depend on how I2C peripheral is implemented there. There are further minor fixes to I2C that are in the works upstream, but I'm not sure they would fix this. Does it work some of the time with the native I2C?

ajs256 commented 3 years ago

Could you open a specific issue for that device?

Give me a bit to get a minimal example working.

Does it work some of the time with the native I2C?

Sometimes with busio.I2C and all the time with bitbangio.I2C.

ajs256 commented 3 years ago

Just opened #4621.