Skip to content

Commit 2e6e530

Browse files
projectgusdpgeorge
authored andcommitted
shared/tinyusb: Further refactor static USB device implementation.
App the mp_ prefix to usbd_ symbols and files which are defined here and not in TinyUSB. rp2 only for now. This includes some groundwork for dynamic USB devices (defined in Python). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent eed4eb2 commit 2e6e530

File tree

13 files changed

+258
-192
lines changed

13 files changed

+258
-192
lines changed

ports/nrf/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ SRC_SHARED_C += $(addprefix shared/,\
242242
runtime/pyexec.c \
243243
runtime/sys_stdio_mphal.c \
244244
runtime/interrupt_char.c \
245-
runtime/tinyusb_helpers.c \
245+
tinyusb/mp_cdc_common.c \
246246
timeutils/timeutils.c \
247247
)
248248

ports/rp2/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ set(MICROPY_SOURCE_LIB
9494
${MICROPY_DIR}/shared/runtime/pyexec.c
9595
${MICROPY_DIR}/shared/runtime/stdout_helpers.c
9696
${MICROPY_DIR}/shared/runtime/sys_stdio_mphal.c
97-
${MICROPY_DIR}/shared/runtime/tinyusb_helpers.c
9897
${MICROPY_DIR}/shared/timeutils/timeutils.c
99-
${MICROPY_DIR}/shared/tinyusb/usbd.c
100-
${MICROPY_DIR}/shared/tinyusb/usbd_descriptor.c
98+
${MICROPY_DIR}/shared/tinyusb/mp_cdc_common.c
99+
${MICROPY_DIR}/shared/tinyusb/mp_usbd.c
100+
${MICROPY_DIR}/shared/tinyusb/mp_usbd_descriptor.c
101101
)
102102

103103
set(MICROPY_SOURCE_DRIVERS

ports/rp2/main.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#include "modrp2.h"
4444
#include "mpbthciport.h"
4545
#include "genhdr/mpversion.h"
46-
#include "usbd.h"
46+
#include "mp_usbd.h"
4747

4848
#include "pico/stdlib.h"
4949
#include "pico/binary_info.h"
@@ -88,7 +88,6 @@ int main(int argc, char **argv) {
8888
#if MICROPY_HW_ENABLE_USBDEV
8989
bi_decl(bi_program_feature("USB REPL"))
9090
tusb_init();
91-
usbd_reset_all(); // run now just in case usb initialization occurs early
9291
#endif
9392

9493
#if MICROPY_PY_THREAD
@@ -161,9 +160,6 @@ int main(int argc, char **argv) {
161160
machine_pin_init();
162161
rp2_pio_init();
163162
machine_i2s_init0();
164-
#if MICROPY_HW_ENABLE_USBDEV
165-
usbd_reset_all();
166-
#endif
167163

168164
#if MICROPY_PY_BLUETOOTH
169165
mp_bluetooth_hci_init();

ports/rp2/mpconfigport.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ extern void mp_thread_end_atomic_section(uint32_t);
217217
#define MICROPY_PY_LWIP_EXIT lwip_lock_release();
218218

219219
#if MICROPY_HW_ENABLE_USBDEV
220-
#define MICROPY_HW_USBDEV_TASK_HOOK extern void tud_task_ext(uint32_t, bool); tud_task_ext(0, false);
220+
#define MICROPY_HW_USBDEV_TASK_HOOK extern void usbd_task(void); usbd_task();
221221
#define MICROPY_VM_HOOK_COUNT (10)
222222
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
223223
#define MICROPY_VM_HOOK_POLL if (get_core_num() == 0 && --vm_hook_divisor == 0) { \

ports/rp2/usbd.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2022 Blake W. Felt
6+
* Copyright (c) 2022 Blake W. Felt & Angus Gratton
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -24,16 +24,21 @@
2424
* THE SOFTWARE.
2525
*/
2626

27-
#include "usbd.h"
27+
#include "mp_usbd.h"
2828
#include "string.h"
29+
#include "tusb.h"
2930
#include "pico/unique_id.h"
3031

31-
int usbd_serialnumber(uint8_t *buf) {
32+
void mp_usbd_port_get_serial_number(char *serial_buf) {
3233
pico_unique_board_id_t id;
33-
const int len = 8;
34-
3534
pico_get_unique_board_id(&id);
36-
memcpy(buf, id.id, len);
37-
38-
return len;
35+
// convert to hex
36+
int hexlen = sizeof(id.id) * 2;
37+
MP_STATIC_ASSERT(hexlen <= USBD_DESC_STR_MAX);
38+
for (int i = 0; i < hexlen; i += 2) {
39+
static const char *hexdig = "0123456789abcdef";
40+
serial_buf[i] = hexdig[id.id[i / 2] >> 4];
41+
serial_buf[i + 1] = hexdig[id.id[i / 2] & 0x0f];
42+
}
43+
serial_buf[hexlen] = 0;
3944
}
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2022 Blake W. Felt
6+
* Copyright (c) 2022 Blake W. Felt & Angus Gratton
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -24,9 +24,14 @@
2424
* THE SOFTWARE.
2525
*/
2626

27-
#include "py/runtime.h"
28-
#include "usbd.h"
27+
#include <stdlib.h>
2928

30-
void usbd_reset_all(void) {
31-
usbd_reset_descriptor();
29+
#ifndef NO_QSTR
30+
#include "tusb.h" // TinyUSB is not avaiable when running the string preprocessor
31+
#include "device/usbd.h"
32+
#include "device/usbd_pvt.h"
33+
#endif
34+
35+
void usbd_task(void) {
36+
tud_task_ext(0, false);
3237
}
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2022 Blake W. Felt
6+
* Copyright (c) 2022 Blake W. Felt & Angus Gratton
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -24,18 +24,16 @@
2424
* THE SOFTWARE.
2525
*/
2626

27-
#ifndef MICROPY_INCLUDED_SHARED_TINYUSB_USBD_H
28-
#define MICROPY_INCLUDED_SHARED_TINYUSB_USBD_H
27+
#ifndef MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_H
28+
#define MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_H
2929

3030
#include "py/obj.h"
3131

32-
// defined externally (needed per port)
32+
// Call instead of tud_task()
33+
void mp_usbd_task(void);
3334

34-
int usbd_serialnumber(uint8_t *buf);
35-
36-
// external use
37-
38-
void usbd_reset_all(void);
39-
void usbd_reset_descriptor(void);
35+
// Function to be implemented in port code.
36+
// Can write a string up to USBD_DESC_STR_MAX characters long, plus terminating byte.
37+
extern void mp_usbd_port_get_serial_number(char *buf);
4038

4139
#endif // MICROPY_INCLUDED_SHARED_TINYUSB_USBD_H
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Damien P. George
7+
* Copyright (c) 2022 Blake W. Felt & Angus Gratton
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "mpconfigport.h"
29+
#include "tusb.h"
30+
#include "mp_usbd.h"
31+
#include "mp_usbd_internal.h"
32+
33+
#define USBD_CDC_CMD_MAX_SIZE (8)
34+
#define USBD_CDC_IN_OUT_MAX_SIZE (64)
35+
36+
const tusb_desc_device_t mp_usbd_desc_device_static = {
37+
.bLength = sizeof(tusb_desc_device_t),
38+
.bDescriptorType = TUSB_DESC_DEVICE,
39+
.bcdUSB = 0x0200,
40+
.bDeviceClass = TUSB_CLASS_MISC,
41+
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
42+
.bDeviceProtocol = MISC_PROTOCOL_IAD,
43+
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
44+
.idVendor = MICROPY_HW_USB_VID,
45+
.idProduct = MICROPY_HW_USB_PID,
46+
.bcdDevice = 0x0100,
47+
.iManufacturer = USBD_STR_MANUF,
48+
.iProduct = USBD_STR_PRODUCT,
49+
.iSerialNumber = USBD_STR_SERIAL,
50+
.bNumConfigurations = 1,
51+
};
52+
53+
const uint8_t mp_usbd_desc_cfg_static[USBD_STATIC_DESC_LEN] = {
54+
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_STATIC_MAX, USBD_STR_0, USBD_STATIC_DESC_LEN,
55+
0, USBD_MAX_POWER_MA),
56+
57+
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD,
58+
USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
59+
#if CFG_TUD_MSC
60+
TUD_MSC_DESCRIPTOR(USBD_ITF_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
61+
#endif
62+
};
63+
64+
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
65+
char serial_buf[USBD_DESC_STR_MAX + 1]; // Includes terminating NUL byte
66+
static uint16_t desc_wstr[USBD_DESC_STR_MAX + 1]; // Includes prefix uint16_t
67+
const char *desc_str;
68+
uint16_t desc_len;
69+
70+
switch (index) {
71+
case 0:
72+
desc_wstr[1] = 0x0409; // supported language is English
73+
desc_len = 4;
74+
break;
75+
case USBD_STR_SERIAL:
76+
// TODO: make a port-specific serial number callback
77+
mp_usbd_port_get_serial_number(serial_buf);
78+
desc_str = serial_buf;
79+
break;
80+
case USBD_STR_MANUF:
81+
desc_str = MICROPY_HW_USB_MANUFACTURER_STRING;
82+
break;
83+
case USBD_STR_PRODUCT:
84+
desc_str = MICROPY_HW_USB_PRODUCT_FS_STRING;
85+
break;
86+
case USBD_STR_CDC:
87+
desc_str = MICROPY_HW_USB_CDC_INTERFACE_STRING;
88+
break;
89+
#if CFG_TUD_MSC
90+
case USBD_STR_MSC:
91+
desc_str = MICROPY_HW_USB_MSC_INTERFACE_STRING;
92+
break;
93+
#endif
94+
default:
95+
desc_str = NULL;
96+
}
97+
98+
if (index != 0) {
99+
if (desc_str == NULL) {
100+
return NULL; // Will STALL the endpoint
101+
}
102+
103+
// Convert from narrow string to wide string
104+
desc_len = 2;
105+
for (int i = 0; i < USBD_DESC_STR_MAX && desc_str[i] != 0; i++) {
106+
desc_wstr[1 + i] = desc_str[i];
107+
desc_len += 2;
108+
}
109+
}
110+
// first byte is length (including header), second byte is string type
111+
desc_wstr[0] = (TUSB_DESC_STRING << 8) | desc_len;
112+
113+
return desc_wstr;
114+
}
115+
116+
117+
const uint8_t *tud_descriptor_device_cb(void) {
118+
return (const void *)&mp_usbd_desc_device_static;
119+
}
120+
121+
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
122+
(void)index;
123+
return mp_usbd_desc_cfg_static;
124+
}

shared/tinyusb/mp_usbd_internal.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2022 Angus Gratton
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+
#ifndef MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_INTERNAL_H
27+
#define MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_INTERNAL_H
28+
#include "tusb.h"
29+
30+
// Static USB device descriptor values
31+
extern const tusb_desc_device_t mp_usbd_desc_device_static;
32+
extern const uint8_t mp_usbd_desc_cfg_static[USBD_STATIC_DESC_LEN];
33+
34+
#endif // MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_INTERNAL_H

0 commit comments

Comments
 (0)