adafruit / Adafruit_CircuitPython_seesaw

seesaw helper IC driver for circuitPython
MIT License
62 stars 36 forks source link

FT232H Connected to Neopixel Driver gives an Invalid hardware ID #127

Open scirelli opened 9 months ago

scirelli commented 9 months ago

I have a FT232h connected to a Neopixel Driver board. They are connected via the FT232H STEMMA to the NeoPixel Drivers STEMMA connector.

Example code I'm testing with.

Error being raised:

Traceback (most recent call last):

  File "./i2c_neopixel.py", line 32, in <module>

    ss = seesaw.Seesaw(i2c, addr=0x60)

         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "./.venv/lib/python3.11/site-packages/adafruit_seesaw/seesaw.py", line 161, in __init__

    raise RuntimeError(

RuntimeError: Seesaw hardware ID returned 0x67 is not correct! Please check your wiring.

The guide has me installing adafruit-circuitpython-seesaw I see where the error is being raise on lines 152-164. pip install adafruit-circuitpython-seesaw

Is a new chip being used on the NeoPixel driver board, and the code hasn't been updated?

There are some other examples that setup the I2C with

i2c = board.STEMMA_I2C()

I modified the example code I was using to test the FT232H and NeoPixel driver to use the above but that gives me this error:

Traceback (most recent call last):
  File "./i2c_neopixel.py", line 32, in <module>
    i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller
          ^^^^^^^^^^^^^^^^
AttributeError: module 'board' has no attribute 'STEMMA_I2C'

===== Update ===== I took a look at the chip on the Neopixel driver board with a magnifying glass. It is an Attiny, the code on the chip is T1616-N. I edited this line in the source to change the ID to 0x43, not 0x67 because of this bug. The neopixels started to change colors, a rainbow pattern then died with this exception:

Traceback (most recent call last):
  File "/Users/kls602/Projects/ATMoF/FT232H/./i2c_neopixel.py", line 46, in <module>
    pixels[i] = colorwheel(rc_index & 255)
    ~~~~~~^^^
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/adafruit_pixelbuf.py", line 312, in __setitem__
    self.show()
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/adafruit_pixelbuf.py", line 204, in show
    return self._transmit(self._post_brightness_buffer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/adafruit_seesaw/neopixel.py", line 106, in _transmit
    self._seesaw.write(_NEOPIXEL_BASE, _NEOPIXEL_BUF, self.output_buffer)
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/adafruit_seesaw/seesaw.py", line 521, in write
    i2c.write(full_buffer)
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/adafruit_bus_device/i2c_device.py", line 100, in write
    self.i2c.writeto(self.device_address, buf, start=start, end=end)
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/busio.py", line 206, in writeto
    return self._i2c.writeto(address, memoryview(buffer)[start:end], stop=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/adafruit_blinka/microcontroller/ftdi_mpsse/mpsse/i2c.py", line 46, in writeto
    port.write(buffer[start:end], relax=stop)
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/pyftdi/i2c.py", line 114, in write
    return self._controller.write(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/pyftdi/i2c.py", line 735, in write
    self._do_write(out)
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/pyftdi/i2c.py", line 1155, in _do_write
    self._send_check_ack(cmd)
  File "/Users/kls602/Projects/ATMoF/FT232H/.venv/lib/python3.11/site-packages/pyftdi/i2c.py", line 1064, in _send_check_ack
    raise I2cNackError('NACK from slave')
pyftdi.i2c.I2cNackError: NACK from slave

~This looks like a bug in the example code. I will edit it and create a new issue and PR.~ Maybe not really a bug in the example, what I had to do to stop the error was to reduce the frequency:

i2c = busio.I2C(board.SCL, board.SDA, frequency=10000)  # The default is 100,000

~I will create a PR to add another chip ID for the Attiny1616 if that is a valid fix?~

scirelli commented 9 months ago

@ladyada where do you get the chip ids from? I'd like to update the list, if 0x43 is a valid chip id. Thanks!

caternuson commented 9 months ago

It's baked into the firmware.

For ATtiny based seesaws (neodriver is one of these), the firmware is here: https://github.com/adafruit/Adafruit_seesawPeripheral and HW_ID is set via preproc logic: https://github.com/adafruit/Adafruit_seesawPeripheral/blob/313090f3a3839e1e5f8f0d7a81c6a6262f89f571/Adafruit_seesawPeripheral_request.h#L1-L15

For SAMD based seesaws, the firmware is here: https://github.com/adafruit/seesaw

The value itself comes from querying the Status function register for HW_ID: https://learn.adafruit.com/adafruit-seesaw-atsamd09-breakout/status

0x43 is not a valid chip id. Something else is happening and will need to be investigated. It may also be something specific to the FT232H.

scirelli commented 9 months ago

Is this something I can help with? I'm now sure what I can do. I have the FT232H hooked up to a Mac, and even though I edited in the wrong hardware id, it's working and I can run the neopixel example code now. I had to reduce the frequency for it to work though.

caternuson commented 9 months ago

I had to reduce the frequency for it to work though.

That's actually probably the best fix for getting it working with the FT232H. There is potentially a small amount of clock stretching happening with the seesaw chip, and the FT232H may or may not be handling that well. Slowing down the I2C frequency is a good work around.

With the slowed down clock, the id is probably reading correctly now as well. Can verify via REPL:

>>> import board, busio
>>> from adafruit_seesaw import seesaw, neopixel
>>> i2c = busio.I2C(board.SCL, board.SDA, frequency=10000)
>>> ss = seesaw.Seesaw(i2c, addr=0x60)
>>> ss.chip_id
135
>>> hex(_)
'0x87'
>>>
scirelli commented 9 months ago

I had to reduce the frequency for it to work though.

That's actually probably the best fix for getting it working with the FT232H. There is potentially a small amount of clock stretching happening with the seesaw chip, and the FT232H may or may not be handling that well. Slowing down the I2C frequency is a good work around.

With the slowed down clock, the id is probably reading correctly now as well. Can verify via REPL:

>>> import board, busio
>>> from adafruit_seesaw import seesaw, neopixel
>>> i2c = busio.I2C(board.SCL, board.SDA, frequency=10000)
>>> ss = seesaw.Seesaw(i2c, addr=0x60)
>>> ss.chip_id
135
>>> hex(_)
'0x87'
>>>

Yes, now it does read the correct chip id! I'll close that other PR with a note.

scirelli commented 9 months ago

Can we add a note to the example code that the frequency may need to be slowed down? I can do it if you point me to where it lives.