Skip to content

Commit 40f6d53

Browse files
committed
Add missing file
1 parent 0da83a9 commit 40f6d53

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed

supervisor/shared/usb/usb_device.c

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 hathach for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "py/runtime.h"
28+
#include "supervisor/port.h"
29+
#include "supervisor/usb.h"
30+
#include "shared/runtime/interrupt_char.h"
31+
32+
#if CIRCUITPY_STATUS_BAR
33+
#include "supervisor/shared/status_bar.h"
34+
#endif
35+
36+
#if CIRCUITPY_USB_CDC
37+
#include "shared-module/usb_cdc/__init__.h"
38+
#include "lib/tinyusb/src/class/cdc/cdc_device.h"
39+
#endif
40+
41+
#if CIRCUITPY_USB_VIDEO
42+
#include "shared-module/usb_video/__init__.h"
43+
#endif
44+
45+
#include "tusb.h"
46+
47+
#if CIRCUITPY_USB_VENDOR
48+
#include "usb_vendor_descriptors.h"
49+
50+
// The WebUSB support being conditionally added to this file is based on the
51+
// tinyusb demo examples/device/webusb_serial.
52+
53+
static bool web_serial_connected = false;
54+
55+
#define URL "www.tinyusb.org/examples/webusb-serial"
56+
57+
const tusb_desc_webusb_url_t desc_webusb_url =
58+
{
59+
.bLength = 3 + sizeof(URL) - 1,
60+
.bDescriptorType = 3, // WEBUSB URL type
61+
.bScheme = 1, // 0: http, 1: https
62+
.url = URL
63+
};
64+
65+
#endif
66+
67+
void usb_disconnect(void) {
68+
tud_disconnect();
69+
}
70+
71+
// Invoked when device is mounted
72+
void tud_mount_cb(void) {
73+
#if CIRCUITPY_USB_MSC
74+
usb_msc_mount();
75+
#endif
76+
}
77+
78+
// Invoked when device is unmounted
79+
void tud_umount_cb(void) {
80+
#if CIRCUITPY_USB_MSC
81+
usb_msc_umount();
82+
#endif
83+
}
84+
85+
// Invoked when usb bus is suspended
86+
// remote_wakeup_en : if host allows us to perform remote wakeup
87+
// USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus
88+
void tud_suspend_cb(bool remote_wakeup_en) {
89+
}
90+
91+
// Invoked when usb bus is resumed
92+
void tud_resume_cb(void) {
93+
}
94+
95+
// Invoked when cdc when line state changed e.g connected/disconnected
96+
// Use to reset to DFU when disconnect with 1200 bps
97+
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
98+
(void)itf; // interface ID, not used
99+
100+
// DTR = false is counted as disconnected
101+
if (!dtr) {
102+
cdc_line_coding_t coding;
103+
// Use whichever CDC is itf 0.
104+
tud_cdc_get_line_coding(&coding);
105+
106+
if (coding.bit_rate == 1200) {
107+
reset_to_bootloader();
108+
}
109+
} else {
110+
#if CIRCUITPY_STATUS_BAR
111+
// We are connected, let's request a title bar update.
112+
supervisor_status_bar_request_update(true);
113+
#endif
114+
}
115+
}
116+
117+
#if CIRCUITPY_USB_VENDOR
118+
// --------------------------------------------------------------------+
119+
// WebUSB use vendor class
120+
// --------------------------------------------------------------------+
121+
122+
bool tud_vendor_connected(void) {
123+
return web_serial_connected;
124+
}
125+
126+
// Invoked when a control transfer occurred on an interface of this class
127+
// Driver response accordingly to the request and the transfer stage (setup/data/ack)
128+
// return false to stall control endpoint (e.g unsupported request)
129+
bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) {
130+
// nothing to with DATA & ACK stage
131+
if (stage != CONTROL_STAGE_SETUP) {
132+
return true;
133+
}
134+
135+
switch (request->bRequest)
136+
{
137+
case VENDOR_REQUEST_WEBUSB:
138+
// match vendor request in BOS descriptor
139+
// Get landing page url
140+
return tud_control_xfer(rhport, request, (void *)&desc_webusb_url, desc_webusb_url.bLength);
141+
142+
case VENDOR_REQUEST_MICROSOFT:
143+
if (request->wIndex == 7) {
144+
// Get Microsoft OS 2.0 compatible descriptor
145+
// let's just hope the target architecture always has the same endianness
146+
uint16_t total_len;
147+
memcpy(&total_len, vendor_ms_os_20_descriptor() + 8, 2);
148+
149+
return tud_control_xfer(rhport, request, (void *)vendor_ms_os_20_descriptor(), total_len);
150+
} else {
151+
return false;
152+
}
153+
154+
case 0x22:
155+
// Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to
156+
// connect and disconnect.
157+
web_serial_connected = (request->wValue != 0);
158+
159+
// response with status OK
160+
return tud_control_status(rhport, request);
161+
162+
default:
163+
// stall unknown request
164+
return false;
165+
}
166+
167+
return true;
168+
}
169+
#endif // CIRCUITPY_USB_VENDOR
170+
171+
172+
#if MICROPY_KBD_EXCEPTION && CIRCUITPY_USB_CDC
173+
174+
// The CDC RX buffer impacts monitoring for ctrl-c. TinyUSB will only ask for
175+
// more from CDC if the free space in the buffer is greater than the endpoint
176+
// size. Setting CFG_TUD_CDC_RX_BUFSIZE to the endpoint size and then sending
177+
// any character will prevent ctrl-c from working. Require at least a 64
178+
// character buffer.
179+
#if CFG_TUD_CDC_RX_BUFSIZE < CFG_TUD_CDC_EP_BUFSIZE + 64
180+
#error "CFG_TUD_CDC_RX_BUFSIZE must be 64 bytes bigger than endpoint size."
181+
#endif
182+
183+
/**
184+
* Callback invoked when received an "wanted" char.
185+
* @param itf Interface index (for multiple cdc interfaces)
186+
* @param wanted_char The wanted char (set previously)
187+
*/
188+
void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) {
189+
// Workaround for using shared/runtime/interrupt_char.c
190+
// Compare mp_interrupt_char with wanted_char and ignore if not matched
191+
if (mp_interrupt_char == wanted_char) {
192+
tud_cdc_n_read_flush(itf); // flush read fifo
193+
mp_sched_keyboard_interrupt();
194+
}
195+
}
196+
197+
void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) {
198+
if (usb_cdc_console_enabled() && mp_interrupt_char != -1 && itf == 0 && duration_ms > 0) {
199+
mp_sched_keyboard_interrupt();
200+
}
201+
}
202+
203+
#endif

0 commit comments

Comments
 (0)