Replies: 8 comments 22 replies
-
Awesome work @patfrench! I'm much in the same camp as you as I see WebUSB as the ultimate way to manage projects moving forward for me and I love the approach that @projectgus is taking. I dream of installing micropython off the main page onto my Pico W and writing a short python script to make a new WebUSB interface and to then plug it into any computer without anything but a web browser. As for your work, it's come so far from a few months ago! I was personally using the fork from KitronikLtd as well to get a basic test bed set up and as much as I like the work Angus is doing (I just realised he was an Australian as well!), this strategy works now. I also only speak English so I find it fun clicking on "connexion" but it gets the message across 😉 As for me personally, I intend to sit down one night when I'm inebriated enough and have a swing at making my own fork that haphazardly allows you to set USB descriptors in python. Not sure when that will happen but using this place will be nice to get a better plan going for how I will do that. Thanks again! |
Beta Was this translation helpful? Give feedback.
-
Hello, Thank you @Luckinber : oups "connection" in english of course Do you have any ideas to help me ? from usbd import CDC
from machine import UART
import usbd.device
import os
import time
uart1 = UART(1, 115200)
cdc = CDC()
cdc.init(timeout=0) # zero timeout makes this non-blocking, suitable for os.dupterm()
# pass static_drivers=True so that we get the static USB-CDC alongside,
# if it's available.
usbd.device.get().init(cdc, static_drivers=True)
print("Waiting for USB host to configure the interface...")
# wait for host enumerate as a CDC device...
while not cdc.is_open():
time.sleep_ms(100)
print("Waiting for CDC port to open...")
# cdc.is_open() returns true after enumeration finishes.
# cdc.dtr is not set until the host opens the port and asserts DTR
while not (cdc.is_open() and cdc.dtr):
time.sleep_ms(20)
print("CDC port is open")
#old_term = os.dupterm(cdc)
print("Run loop CDC => UART and UART => CDC.")
while True:
if cdc.read(256):
uart1.write(cdc.read(256))
if uart1.any():
cdc.write(uart1.read(256)) I have several problems:
Is my code correct ? My idea is to do like Thank you |
Beta Was this translation helpful? Give feedback.
-
hello @projectgus I have rebuilt everything and conducted more tests. Test 1 is OK, there are no more bugs:while True:
if cdc.read(256):
uart1.write(cdc.read(256))
if uart1.any():
cdc.write(uart1.read(256)) Test 2 gives me an error:I looked and didn't see an any() method while True:
if cdc.any():
uart1.write(cdc.read(256))
if uart1.any():
cdc.write(uart1.read(256))
Traceback (most recent call last):
File "<stdin>", line 37, in <module>
AttributeError: 'CDC' object has no attribute 'any' Test 3 also results in an error:while True:
select.select([cdc, uart1], [], [])
if cdc.read(256):
uart1.write(cdc.read(256))
if uart1.any():
cdc.write(uart1.read(256))
Traceback (most recent call last):
File "<stdin>", line 38, in <module>
TypeError: object with buffer protocol required
Regarding cdc_repl_example.py, it's great. If I ever have a TUD_VENDOR, then it will be compatible with MPYEditor. I could use Zadig to manually change the WinUSB driver, but in school settings, we can't install anything. To better understand, I went back to tinyusb in C and tried to understand it. Now, I understand your work better. I know that I'm missing in "tusb_config.h": #if MICROPY_HW_USB_MSC
#define CFG_TUD_MSC (1)
#else
#define CFG_TUD_MSC (0)
#endif
#define CFG_TUD_VENDOR (1)
#endif
#if CFG_TUD_VENDOR
#define EPNUM_VENDOR_IN 3
#define EPNUM_VENDOR_OUT 3
#endif In "mp_usbd_descriptor.c": const uint8_t mp_usbd_builtin_desc_cfg[MP_USBD_BUILTIN_DESC_CFG_LEN] = {
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_BUILTIN_MAX, USBD_STR_0, MP_USBD_BUILTIN_DESC_CFG_LEN,
0, USBD_MAX_POWER_MA),
#if CFG_TUD_CDC
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD,
USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
#endif
#if CFG_TUD_MSC
TUD_MSC_DESCRIPTOR(USBD_ITF_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
#endif
#if CFG_TUD_VENDOR
TUD_VENDOR_DESCRIPTOR(USBD_ITF_MSC, 5, EPNUM_VENDOR_OUT, 0x80 | EPNUM_VENDOR_IN, TUD_OPT_HIGH_SPEED ? 512 : 256)
#endif
}; In "mp_usbd.h": // Length of built-in configuration descriptor
#define MP_USBD_BUILTIN_DESC_CFG_LEN (TUD_CONFIG_DESC_LEN + \
(CFG_TUD_CDC ? (TUD_CDC_DESC_LEN) : 0) + \
(CFG_TUD_MSC ? (TUD_MSC_DESC_LEN) : 0)+ \
(CFG_TUD_VENDOR?(TUD_VENDOR_DESC_LEN):0) \
) And this part: //--------------------------------------------------------------------+
// BOS Descriptor
//--------------------------------------------------------------------+
/* Microsoft OS 2.0 registry property descriptor
Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx
device should create DeviceInterfaceGUIDs. It can be done by driver and
in case of real PnP solution device should expose MS "Microsoft OS 2.0
registry property descriptor". Such descriptor can insert any record
into Windows registry per device/configuration/interface. In our case it
will insert "DeviceInterfaceGUIDs" multistring property.
GUID is freshly generated and should be OK to use.
https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/
(Section Microsoft OS compatibility descriptors)
*/
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN)
#define MS_OS_20_DESC_LEN 0xB2
// BOS Descriptor is required for webUSB
uint8_t const desc_bos[] =
{
// total length, number of device caps
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2),
// Vendor Code, iLandingPage
TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1),
// Microsoft OS 2.0 descriptor
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT)
};
uint8_t const * tud_descriptor_bos_cb(void)
{
return desc_bos;
}
uint8_t const desc_ms_os_20[] =
{
// Set header: length, type, windows version, total length
U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN),
// Configuration subset header: length, type, configuration index, reserved, configuration total length
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A),
// Function Subset header: length, type, first interface, reserved, subset length
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_VENDOR, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08),
// MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID
U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible
// MS OS 2.0 Registry property descriptor: length, type
U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY),
U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00,
U16_TO_U8S_LE(0x0050), // wPropertyDataLength
//bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
'{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00, 'D', 0x00, '9', 0x00, '-', 0x00,
'0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00,
'8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00,
'8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
};
TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); I'm just starting out, and I'm far from being able to help you, but I'll keep going because I really want to have WebUSB support.
I'm not sure if it's possible, but I'd like to have full-speed communication between the PC and the microcontroller, and also be able to adjust the UART speed using the Vendor interface. I want full-speed communication because I intend to send Modbus commands from the browser. Thank you again. |
Beta Was this translation helpful? Give feedback.
-
Hello, I've kept looking and the problem may be with my machine (I'm going to try on another PC). Your code with x1 CDC (seen with chrome://usb-internals/) usbd.device.get().init(cdc1, builtin_drivers=True) Everything is OK Your code with x2 CDC (seen with chrome://usb-internals/) usbd.device.get().init(cdc1, cdc2,builtin_drivers=True) why doesn't windows see it ?????? and why does chrome see it ???? Thank you |
Beta Was this translation helpful? Give feedback.
-
The problem comes from my PC, on another PC I can see the 2 serial ports. |
Beta Was this translation helpful? Give feedback.
-
No, this is the missing piece that needs to be added in a follow-up PR. Nice multi-port setup, though!
RP2040 supports 16 USB endpoints. So I think that's 1 shared endpoint for control transfers, plus 2 for the built-in CDC port (if you're not using it set builtin_drivers=False and save the space), plus 6*2 for the CDC interfaces for a total of 15! |
Beta Was this translation helpful? Give feedback.
-
Hello @projectgus Something has gone wrong in cdc_repl_example.py Program does not wait for CDC connection (Line 32) Thank you for your help, |
Beta Was this translation helpful? Give feedback.
-
Hello @projectgus I really have a problem with cdc_repl_example on 2 different computers (windows 11 and windows 10) for it to work I have to put cdc.dtr import os
import time
import usb.device
from usb.device.cdc import CDCInterface
cdc = CDCInterface()
cdc.init(timeout=0) # zero timeout makes this non-blocking, suitable for os.dupterm()
# pass builtin_driver=True so that we get the built-in USB-CDC alongside,
# if it's available.
usb.device.get().init(cdc, builtin_driver=True)
print("Waiting for USB host to configure the interface...")
# wait for host enumerate as a CDC device...
while not (cdc.is_open() and cdc.dtr):
time.sleep_ms(100)
# Note: This example doesn't wait for the host to access the new CDC port,
# which could be done by polling cdc.dtr, as this will block the REPL
# from resuming while this code is still executing.
print("CDC port enumerated, duplicating REPL...")
old_term = os.dupterm(cdc) but the repl is in raw paste mode > (I had to press CTRL+B) thank you |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello everyone!
Let me present my adventure:
https://github.com/patfrench/patfrench.github.io/blob/main/README.md
I developed a MicroPython web editor when I discovered the project by "KitronikLtd" I wanted my project to be compatible with webusb and webbluetooth, so I had to update MicroPython to version 1.22.0 preview 5.
On Windows, a popup will appear, and all you need to do is follow the link to access MPYEditor or go directly to this page: https://patfrench.github.io/.
On Linux, you need to allow USB access, and there will be no popup.
Regarding the REPL and indentations, you will need to press ENTER multiple times instead of BACKSPACE (each ENTER will act as a BACKSPACE).
You will notice a TERMINAL; it is a PYSCRIPT component (python or micropython in browser). At the moment, it doesn't interact with MicroPython, but in the future, I would like to add some things.
MPYEditor is not perfect! There may be some bugs, but I did my best.
But I have another topic regarding boards supporting webusb, and in my opinion, @projectgus has the best approach when it comes to creating dynamic USB interfaces. His work is very comprehensive, but I would like it to be compatible with webusb.
I dream of a world where MicroPython ports default to webusb: a virtual com port and a port compatible with webusb.
See his comment here "#9497 (comment)" It is necessary to expose: tud_descriptor_bos_cb
When @projectgus says it, it seems so simple, but when I look at it 😰 😨
I think a new discussion on this topic would be interesting to help each other and even provide assistance.
@Luckinber @darkyellow @ArnaudV27
Thank you
Beta Was this translation helpful? Give feedback.
All reactions