Discover the Millennia eV port by its STM32 USB-CDC VID/PID#108
Merged
Conversation
Problem: MillenniaEv25Device could only be constructed with an explicit portPath; doInitializeDevice opened SerialPort(portPath=...) and never fell back to VID/PID discovery, so a caller (e.g. the MillenniaUI app) had to know the OS port name up front. The class did not set classIdVendor/classIdProduct, so nothing identified the device by its USB descriptor. Solution: Set classIdVendor = 0x0483 / classIdProduct = 0x5740 (the STM32 Virtual COM Port identity the lab eV25s enumerates as) and have doInitializeDevice discover the port by that identity when no portPath is given, mirroring FieldMasterDevice: it builds SerialPort(idVendor, idProduct, serialNumber) -> matchAnyPort over pyserial's comports(), and raises a clear UnableToInitialize naming the identity when nothing matches. An explicit portPath still wins; a serialNumber narrows discovery when several STM32 CDC ports are present. serialNumber is passed only when it actually narrows, so matchPorts stays on its vid/pid path and never regex-matches a possibly-None descriptor serial. The generic-STM32-VCP caveat is documented in the code. DebugMillenniaEv25Device is unaffected: it overrides doInitializeDevice and keeps its own fake identity. testMillennia.py passes (14 passed, 6 skipped). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
MillenniaEv25Devicecould only be constructed with an explicitportPath—doInitializeDeviceopenedSerialPort(portPath=...)and never fell back to VID/PID discovery. A caller (e.g. the MillenniaUI app) had to know the OS port name up front, and the class set noclassIdVendor/classIdProductto identify the device.Solution
classIdVendor = 0x0483/classIdProduct = 0x5740— the STM32 Virtual COM Port identity the lab eV25s enumerates as (confirmed on the bench).doInitializeDevicenow discovers the port by that identity when noportPathis given, mirroringFieldMasterDevice: it buildsSerialPort(idVendor, idProduct, serialNumber)→matchAnyPortover pyserial'scomports(), and raises a clearUnableToInitializenaming the identity when nothing matches.Precedence for the UI:
MillenniaDevice(portPath=...)→ uses that exact port (still wins).MillenniaDevice()→ auto-discovers by0x0483:0x5740.MillenniaDevice(serialNumber="3239")→ discovery narrowed by USB descriptor serial (for hosts with more than one STM32 CDC port).serialNumberis forwarded only when it actually narrows, somatchPortsstays on its vid/pid path and never regex-matches a possibly-Nonedescriptor serial.Caveat (documented in code)
0x0483:0x5740is STMicro's generic STM32 VCP identity, shared by many unrelated STM32 boards. On a host with another STM32 CDC device, discovery could bind to the wrong port — pinportPath(or passserialNumber) there.Tests
DebugMillenniaEv25Deviceis unaffected (it overridesdoInitializeDeviceand keeps its own fake identity). Smoke-checked: identity resolves, discovery raises cleanly with no hardware, debug device initializes.testMillennia.py: 14 passed, 6 skipped.🤖 Generated with Claude Code