I had a similar need a few months back, and created a Pi Pico adapter. It initially didn't support GPIO, but the code was so simple, I have now added it and uploaded it to
GitHub. Maybe it's an option if the FTDI device isn't essential.
The steps are:
(1) Buy some Pi Pico's, and hold down the button on them while inserting the USB connection, then release the button, and you'll be in boot mode, you'll see a drive letter appear, like a USB flash drive.
(2) Drag-and-drop the executable from the pre_built_binary folder at the GitHub page.
(3) After a few seconds, the code will be uploaded, and you'll know it is running successfully, because the green LED on the Pi Pico will permanently blink very rapidly.
Now you can wire it up as shown in the attached diagram.
To use it, either open a serial console terminal, and type things such as shown in the serial-console-example.jpg screenshot, or, alternatively, download the easyadapter.py file from the
GitHub page python_pc_interface folder, and then type the following from a command line:
pip install pyserial
The, run Python, and you can control I2C using commands like:
import easyadapter as ea
firstAdapter = ea.EasyAdapter()
secondAdapter = ea.EasyAdapter()
firstAdapter.init(0)
secondAdapter.init(1)
buffer = firstAdapter.i2c_read(0x5a, 4)
data = [0xaa, 0xbb, 0xcc]
secondAdapter.i2c_write(0x5b, data[0], data[1:])
The above example assumes that two Pico boards are connected, and that you want to use the I2C interface on the first Pico board, to read four bytes from address 0x5a, and use the second Pico board to write three bytes to address 0x5b. Notice that with the write operation, the i2c_write function expects the first data byte to be separate, because that's often convenient for using the first byte as a register address.
To distinguish between different Pi Pico boards, use the BOARD_ID pins shown in the connection diagram (GPIO pins 4,3,2). They float high, and that's an ID value of 0 as used in the firstAdapter.init(0) Python code above. If you short GPIO2 to ground, then that's an ID value of 1.
To control GPIO from Python, the code would look like the following, to set GPIO6 to logic level 1:
firstAdapter.io_write(6,1)
To read the GPIO level:
val = firstAdapter.io_read(6)
The io_read and io_write functions automatically convert the GPIO pin to an input or an output respectively.
Main downside with this project is that it's still very fresh, there are bound to be errors. On the plus side, Pi Pico boards are so popular, and the code is so tiny, that if there's an issue, I'm sure myself, or others could help if there's any major issue.
The extent of my testing is reading and writing a couple of simple I2C devices, and controlling a couple of GPIO pins (reading and writing them), with two Pico boards.
Another limitation currently, is that you can't read/write more than a couple of hundred bytes at a time (so if you're reading/writing flash memory for instance, then you'll need to ensure the operations are split up into suitable chunks).