Skip to content

Commit 64e98c9

Browse files
author
Martin Fischer
committed
chore: add premlinenary CDC interfaces
1 parent c8ad6ca commit 64e98c9

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

micropython/usbd/cdc.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# MicroPython USB CDC module
2+
# MIT license; Copyright (c) 2022 Martin Fischer
3+
from .device import (
4+
USBInterface,
5+
get_usbdevice
6+
)
7+
from .utils import (
8+
endpoint_descriptor,
9+
EP_OUT_FLAG
10+
)
11+
from micropython import const
12+
import ustruct
13+
14+
_DEV_CLASS_MISC = const(0xef)
15+
_CS_DESC_TYPE = const(0x24) # CS Interface type communication descriptor
16+
_ITF_ASSOCIATION_DESC_TYPE = const(0xb) # Interface Association descriptor
17+
18+
# CDC control interface definitions
19+
_CDC_ITF_CONTROL_CLASS = const(2)
20+
_CDC_ITF_CONTROL_SUBCLASS = const(2) # Abstract Control Mode
21+
_CDC_ITF_CONTROL_PROT = const(0) # no protocol
22+
23+
# CDC data interface definitions
24+
_CDC_ITF_DATA_CLASS = const(0xa)
25+
_CDC_ITF_DATA_SUBCLASS = const(0)
26+
_CDC_ITF_DATA_PROT = const(0) # no protocol
27+
28+
29+
def setup_CDC_device():
30+
# CDC is a composite device, consisting of multiple interfaces
31+
# (CDC control and CDC data)
32+
# therefore we have to make sure that the association descriptor
33+
# is set and that it associates both interfaces to the logical cdc class
34+
usb_device = get_usbdevice()
35+
usb_device.device_class = _DEV_CLASS_MISC
36+
usb_device.device_subclass = 2
37+
usb_device.device_protocol = 1 # Itf association descriptor
38+
39+
40+
class CDCControlInterface(USBInterface):
41+
# Implements the CDC Control Interface
42+
43+
def __init__(self, interface_str):
44+
super().__init__(_CDC_ITF_CONTROL_CLASS, _CDC_ITF_CONTROL_SUBCLASS,
45+
_CDC_ITF_CONTROL_PROT)
46+
47+
def get_itf_descriptor(self, num_eps, itf_idx, str_idx):
48+
# CDC needs a Interface Association Descriptor (IAD)
49+
# first interface is zero, two interfaces in total
50+
desc = ustruct.pack("<BBBBBBBB", 8, _ITF_ASSOCIATION_DESC_TYPE, itf_idx, 2,
51+
_CDC_ITF_CONTROL_CLASS, _CDC_ITF_CONTROL_SUBCLASS,
52+
_CDC_ITF_CONTROL_PROT, 0) # "IAD"
53+
54+
itf, strs = super().get_itf_descriptor(num_eps, itf_idx, str_idx)
55+
desc += itf
56+
# Append the CDC class-specific interface descriptor
57+
# see also USB spec document CDC120-track, p20
58+
desc += ustruct.pack("<BBBH", 5, _CS_DESC_TYPE, 0, 0x0120) # "Header"
59+
desc += ustruct.pack("<BBBBB", 5, _CS_DESC_TYPE, 1, 0, 1) # "Call Management"
60+
desc += ustruct.pack("<BBBB", 4, _CS_DESC_TYPE, 2, 2) # "Abstract Control"
61+
desc += ustruct.pack("<BBBH", 5, _CS_DESC_TYPE, 6, itf_idx, 1) # "Union"
62+
return desc, strs
63+
64+
def get_endpoint_descriptors(self, ep_addr, str_idx):
65+
self.ep_in = endpoint_descriptor((ep_addr + 1) | EP_OUT_FLAG, "interrupt", 8, 16)
66+
return (self.ep_in, [], ((ep_addr+1) | EP_OUT_FLAG,))
67+
68+
69+
class CDCDataInterface(USBInterface):
70+
# Implements the CDC Data Interface
71+
72+
def __init__(self, interface_str):
73+
super().__init__(_CDC_ITF_DATA_CLASS, _CDC_ITF_DATA_SUBCLASS,
74+
_CDC_ITF_DATA_PROT)
75+
76+
def get_endpoint_descriptors(self, ep_addr, str_idx):
77+
# XXX OUT = 0x00 but is defined as 0x80?
78+
self.ep_in = (ep_addr + 2) | EP_OUT_FLAG
79+
self.ep_out = (ep_addr + 2) & ~EP_OUT_FLAG
80+
print("cdc in={} out={}".format(self.ep_in, self.ep_out))
81+
# one IN / OUT Endpoint
82+
e_out = endpoint_descriptor(self.ep_out, "bulk", 64, 0)
83+
e_in = endpoint_descriptor(self.ep_in, "bulk", 64, 0)
84+
desc = e_out + e_in
85+
return (desc, [], (self.ep_out, self.ep_in))
86+

0 commit comments

Comments
 (0)