electronicayciencia / EasyMCP2221

The most complete python module to interface with MCP2221.
https://easymcp2221.readthedocs.io/
MIT License
15 stars 3 forks source link

Get assigned serial port name #11

Closed agustinjgomez closed 5 days ago

agustinjgomez commented 2 weeks ago

Hello, I want to know if there is a way to detect the serial port name assigned by the system to the mcp2221. I used to work with some ftdi modules whose library have that feature. It would make easier to use both interfaces, i2c and uart, in the same python script. Now I have to detect which port was assigned by checking the device manager (windows) and changing the port name in the script.

Is it possible to add that feature to the library or any hints on how to manage that? Thanks in advance

agustinjgomez commented 2 weeks ago

I got this workaround but would like to hear if there is something already included or posible to include to the library.

import serial.tools.list_ports;
comports=  serial.tools.list_ports.comports()
found = None
for com in comports:
    if ("VID:PID=04D8:00DD" in com.hwid):
        found = com.name

print(found)
if (found):
    PORT_NAME=found
agustinjgomez commented 1 week ago

I was wondering where can I get the serial number to identify for the case of N connected devices. I noticed that the serial number that serial.tools.listports returns does not match the serial number EasyMCP2221 returns. However I found in the Microchip Tool MCP2221 Utility the following checkbox. image

Then, after enabling and saving that option and reconnecting the device, the serial.tools.listports does match.

image

electronicayciencia commented 1 week ago

Hello.

That's interesting! I also got stuck with the serial numbers.

I wrote a small script for experimentation:

# Try to match COM (CDC interface) with GPIO (HID interface)
import serial.tools.list_ports
coms=serial.tools.list_ports.comports()

import hid
hidhandler = hid.device()
hids = hid.enumerate(0x04D8, 0x00DD)

hidhandler.open_path(hids[0]["path"])

In this example you can differentiate both Devices by the serial number:

>>> coms[0].serial_number
'7&34CCB19E&1&4'
>>> coms[1].serial_number
'7&34CCB19E&1&3'

But I was unable to get the same serial number using HID enumerate.

[{'path': b'\\\\?\\HID#VID_04D8&PID_00DD&MI_02#9&14392a42&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}',
  'vendor_id': 1240,
  'product_id': 221,
  'serial_number': '',
  'release_number': 256,
  'manufacturer_string': 'Microchip Technology Inc.',
  'product_string': 'MCP2221 USB-I2C/UART Combo',
  'usage_page': 65280,
  'usage': 1,
  'interface_number': 2},
 {'path': b'\\\\?\\HID#VID_04D8&PID_00DD&MI_02#9&18d24698&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}',
  'vendor_id': 1240,
  'product_id': 221,
  'serial_number': '',
  'release_number': 256,
  'manufacturer_string': 'Microchip Technology Inc.',
  'product_string': 'MCP2221 USB-I2C/UART Combo',
  'usage_page': 65280,
  'usage': 1,
  'interface_number': 2}]

CDC enumeration is not currently implemented in the library. But I think it won't be difficult.

image

Thank you.

electronicayciencia commented 1 week ago

Please, review enable_cdc_serial and Hint.

agustinjgomez commented 1 week ago

Many thanks! I tried the following code based in yours and works perfectly. For now its working in both cases, i.e. previously enabled and disabled.

import EasyMCP2221
import serial.tools.list_ports
mcp = EasyMCP2221.Device()

if (mcp.read_flash_info()['CHIP_SETTINGS']['cdcsnen'] != 'enabled'):
    mcp.enable_cdc_serial()
    mcp.save_config()
    mcp.reset()
sernum = mcp.read_flash_info()['USB_SERIAL']
vidpid = "04D8:00DD"

com = next(serial.tools.list_ports.grep(sernum),      None) #or \
      #next(serial.tools.list_ports.grep(vidpid), None) #vidpid commented out to test serial number
print(com.name)

Do you know if after a reset() should I wait or the code waits by itself the needed time? You mention a 5sec timeout of the enumeration process.

electronicayciencia commented 1 week ago

Do you know if after a reset() should I wait or the code waits by itself the needed time? You mention a 5sec timeout of the enumeration process.

The reset function waits 0.5 seconds to complete. After that, it tries to re-open the device for the next 5 seconds. If past 5 seconds the chips does not respond, it throws an exception.

agustinjgomez commented 6 days ago

Thank you. That means the code will work. I hope you can release a new version soon, so I can install it through pip without cloning the repo. You can close the issue.

electronicayciencia commented 5 days ago

v1.8.0 just released.

Buena suerte y hasta la próxima.