Open min-hs opened 4 weeks ago
There are PIO SPI examples here: https://github.com/raspberrypi/pico-examples/tree/master/spi, but it seems like you are well along in your PIO SPI implementation.
I'm guessing that you had to choose the pins you did due to limitations of the placement of the bonding wires between the chips. Is that correct?
While this solution works as an alternative, we thought about the possibility of creating a new CHIP_VARIANT for rp2 CHIP_FAMILY.
I am not sure what you mean by this. The PIO SPI could be separated out, and then the W5500 functionality could be done mostly in a library and in device-independent code. For instance, see https://github.com/adafruit/Adafruit_CircuitPython_Wiznet5k
Yes, that's right. We are currently using PIO SPI due to wiring issues between the RP2040 and W5500.
I've currently made some similar to wiznet5k to control the W5500 with PIO SPI instead of busio.SPI, but I'm having trouble getting it to work with different socketpools, dhcp, dns, and other protocols.
Also, if I do this, I would like to discuss with you how to utilize the W55RP20 library from adafruit to make it available to users in the future. https://github.com/WIZnet-ioNIC/WIZnet-ioNIC-Circuitpython
I'm sure I'm oversimplifying several things, but bitbangio
works with these pins (even ssl
), so it seems like if PIO could make the pins look like SPI, the existing adafruit_circuitpython_wiznet5k
driver library should work?
I think the q would be the SPI speed for bitbangio.
Yes, I was mainly suggesting PIO SPI as a possible transparent alternate to SPI (or bitbangio SPI), not sure if that's possible.
BTW, I have these boards and could do some speed comparisons, but could use direction on code (and URL or what to serve) to test effectively.
I don't have time to look at this in detail at the moment, but here's what I was thinking of:
busio.SPI
, so that it can be just passed in to the Wiznet driver. PIO SPI could even be a separate library totally.Re: (1.), I get as far as AttributeError: 'StateMachine' object has no attribute 'try_lock'
when trying the PIO SPI with the existing driver on the W55RP20, which I interpret to mean that the PIO SPI implementation could possibly be beefed up to be compatible enough for the existing driver. But perhaps min-hs has already been down that road.
(1) I think it would be great to have it as a separate library, or you could create a separate class called ioNIC in the existing adafruit_wiznet5k driver.
(2) Currently in that repo, the W5500 is controlled by SPI using busio. The W55RP20 can't use hardware SPI due to pin issues, so we use rp2pio to drive the W5500 since it uses SPI PIO.
(3) It is not a better driver, but it is also a packaged chip that integrates RP2040 and W5500, and it is a solution that many users have responded to.
@anecdata Is the error on the rp2pio internal statemachine side in the link below? https://github.com/WIZnet-ioNIC/WIZnet-ioNIC-Circuitpython
@min-hs I tried the WIZnet-ioNIC code and example and of course that worked fine. The exception was when I tried to naively use the statemachine as SPI with the existing circuitpython WIZnet library.
But conceivably to Dan's point and yours, someone who knows what they are doing could construct a more SPI-compatible class or library using the statemachine. I didn't get far enough or do a thorough audit of the methods needed (read, write, etc), but try_lock
and unlock
do seem to be needed.
Thank you so much for your help. @anecdata I'm not sure how I'm supposed to use try_lock and unlock, can you give me an example or explanation of how to use them?
(2) Currently in that repo, the W5500 is controlled by SPI using busio. The W55RP20 can't use hardware SPI due to pin issues, so we use rp2pio to drive the W5500 since it uses SPI PIO.
Yes, I am saying you could refactor the library so it's using an SPI interface in the abstract, instead of knowing that it must use the "soft" SPI provided by your PIO program. The driver does not need to know that it has to use PIO SPI. My understanding is that you are using it the same way you would use it if it were an external chip. Only the transport has changed slightly.
I'm not sure how I'm supposed to use try_lock and unlock, can you give me an example or explanation of how to use them?
See try_lock()
and unlock()
in https://docs.circuitpython.org/en/latest/shared-bindings/bitbangio/index.html#bitbangio.SPI. The SPI
obect supports a lock so that it can't be used concurrently for more than one device without the two users cooperating around the lock. There is some discussion of that in this writeup of CircuitPython SPI: https://learn.adafruit.com/circuitpython-basics-i2c-and-spi/spi-devices
Something that I was discussing about this on Discord:
Both busio.SPI
and rp2pio.StateMachine
have read
and write
methods, they have different behaviors: SPI discards the "unwanted" side, while StateMachine retains it in a (small) FIFO. Thus, for a PIO SPI implementation to be compatible with busio.SPI, it will have to implement read
and write
both in terms of write_readinto
, likely with some kind of dummy buffer of the right length for the unneeded half of the data. Without this, the first few bytes sent to write
will work, but they'll stop being output once the 4-entry rxfifo fills (PIO program stalled at the push
instruction) and then write will block once the 4-entry txfifo fills.
Our engineers have made initial progress in developing a driver for the W55RP20, but we've encountered a few difficulties that we would like to address with your team. Below is a brief overview of the situation:
The W55RP20 is a SiP project that integrates the RP2040 and W5500 in one chip. Internally, the dies are connected via general GPIO pins, not the typical SPI pins. As a result, a PIO program is needed to configure these pins for SPI communication.
Our engineers then decided to start from scratch, writing a PIO program and general code to initialize the W5500 through registers. They were able to create a basic loopback server in standalone mode. While this solution works as an alternative, we thought about the possibility of creating a new CHIP_VARIANT for rp2 CHIP_FAMILY. Given our limited resources, we thought of collaboration with Adafruit to further develop the driver.
The link below is to a WIZNet PIO example we created. https://github.com/WIZnet-ioNIC/WIZnet-ioNIC-Circuitpython