wip: descriptor building
This commit is contained in:
parent
6b18a51d57
commit
64e0958916
@ -346,7 +346,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int k=0; k<4; k++) {
|
||||
raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff;
|
||||
raw_id[4 * i + (3 -k)] = (*(id_addresses[i]) >> k * 8) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,6 @@ endif
|
||||
|
||||
INTERNAL_LIBM = 1
|
||||
|
||||
USB_SERIAL_NUMBER_LENGTH = 32
|
||||
|
||||
# Number of USB endpoint pairs.
|
||||
USB_NUM_EP = 8
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
USB_SERIAL_NUMBER_LENGTH = 10
|
||||
USB_HIGHSPEED = 1
|
||||
USB_RENUMBER_ENDPOINTS = 0
|
||||
USB_CDC_EP_NUM_NOTIFICATION = 3
|
||||
|
@ -6,9 +6,6 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
|
||||
# Internal math library is substantially smaller than toolchain one
|
||||
INTERNAL_LIBM = 1
|
||||
|
||||
# Chip supplied serial number, in bytes
|
||||
USB_SERIAL_NUMBER_LENGTH = 12
|
||||
|
||||
# Longints can be implemented as mpz, as longlong, or not
|
||||
LONGINT_IMPL = MPZ
|
||||
|
||||
|
@ -9,9 +9,6 @@ INTERNAL_LIBM = 1
|
||||
# Number of USB endpoint pairs.
|
||||
USB_NUM_EP = 16
|
||||
|
||||
# Chip supplied serial number, in bytes
|
||||
USB_SERIAL_NUMBER_LENGTH = 30
|
||||
|
||||
# Longints can be implemented as mpz, as longlong, or not
|
||||
LONGINT_IMPL = MPZ
|
||||
|
||||
|
@ -14,7 +14,6 @@ endif
|
||||
|
||||
INTERNAL_LIBM = 1
|
||||
|
||||
USB_SERIAL_NUMBER_LENGTH = 32
|
||||
USB_HIGHSPEED = 1
|
||||
|
||||
# Number of USB endpoint pairs.
|
||||
|
@ -9,8 +9,6 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
|
||||
|
||||
INTERNAL_LIBM = 1
|
||||
|
||||
USB_SERIAL_NUMBER_LENGTH = 16
|
||||
|
||||
# Number of USB endpoint pairs.
|
||||
USB_NUM_EP = 8
|
||||
|
||||
|
@ -47,8 +47,6 @@ CIRCUITPY_AUDIOMIXER ?= 0
|
||||
|
||||
INTERNAL_LIBM = 1
|
||||
|
||||
USB_SERIAL_NUMBER_LENGTH = 16
|
||||
|
||||
# Number of USB endpoint pairs.
|
||||
USB_NUM_EP = 8
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
MPY_TOOL_LONGINT_IMPL ?= -mlongint-impl=mpz
|
||||
LONGINT_IMPL ?= MPZ
|
||||
INTERNAL_LIBM ?= 1
|
||||
USB_SERIAL_NUMBER_LENGTH ?= 24
|
||||
|
||||
ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F405xx STM32F407xx))
|
||||
CIRCUITPY_CANIO = 1
|
||||
|
@ -58,7 +58,7 @@ static const uint8_t storage_usb_msc_descriptor_template[] = {
|
||||
// MSC Endpoint IN Descriptor
|
||||
0x07, // 9 bLength
|
||||
0x05, // 10 bDescriptorType (Endpoint)
|
||||
0xFF, // 11 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x8 | number]
|
||||
0xFF, // 11 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number]
|
||||
#define MSC_IN_ENDPOINT_INDEX 11
|
||||
0x02, // 12 bmAttributes (Bulk)
|
||||
0x40, 0x00, // 13,14 wMaxPacketSize 64
|
||||
@ -81,12 +81,21 @@ size_t storage_usb_descriptor_length(void) {
|
||||
return sizeof(usb_msc_descriptor);
|
||||
}
|
||||
|
||||
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t interface_number, uint8_t in_endpoint, uint8_t out_endpoint, uint8_t interface_string) {
|
||||
static const char[] storage_interface_name = USB_INTERFACE_NAME " Mass Storage";
|
||||
|
||||
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string) {
|
||||
memcpy(descriptor_buf, storage_usb_msc_descriptor_template, sizeof(storage_usb_msc_descriptor_template));
|
||||
descriptor_buf[MSC_INTERFACE_INDEX] = interface_number;
|
||||
descriptor_buf[MSC_INTERFACE_STRING_INDEX] = interface_string;
|
||||
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = in_endpoint_address;
|
||||
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = 0x80 | out_endpoint_address;
|
||||
descriptor_buf[MSC_INTERFACE_INDEX] = *current_interface;
|
||||
(*current_interface)++;
|
||||
|
||||
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : *current_endpoint;
|
||||
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = 0x80 | (USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : *current_endpoint);
|
||||
(*current_endpoint)++:
|
||||
|
||||
usb_add_interface_string(*current_interface_string,);
|
||||
descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string;
|
||||
(*current_interface_string)++;
|
||||
|
||||
return sizeof(storage_usb_msc_descriptor_template);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,6 @@ extern bool storage_usb_enabled;
|
||||
|
||||
void storage_init(void);
|
||||
size_t storage_usb_descriptor_length(void);
|
||||
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t interface, uint8_t in_endpoint, uint8_t out_endpoint, uint8_tt interface_string);
|
||||
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string);
|
||||
|
||||
#endif // SHARED_MODULE_STORAGE___INIT___H
|
||||
|
@ -140,21 +140,48 @@ size_t usb_cdc_descriptor_length(void) {
|
||||
return sizeof(usb_cdc_descriptor_template);
|
||||
}
|
||||
|
||||
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8 comm_interface, uint8_t data_interface, uint8_t control_in_endpoint, uint8_t data_in_endpoint, uint8_t data_out_endpoint, uint8_t comm_interface_string, uint8_t data_interface_string) {
|
||||
static const char[] repl_cdc_comm_interface_name = USB_INTERFACE_NAME " CDC control";
|
||||
static const char[] data_cdc_comm_interface_name = USB_INTERFACE_NAME " CDC2 control";
|
||||
static const char[] repl_cdc_data_interface_name = USB_INTERFACE_NAME " CDC data";
|
||||
static const char[] data_cdc_data_interface_name = USB_INTERFACE_NAME " CDC2 data";
|
||||
|
||||
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string, bool repl) {
|
||||
memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template));
|
||||
descriptor_buf[CDC_FIRST_INTERFACE_INDEX] = comm_interface;
|
||||
descriptor_buf[CDC_COMM_INTERFACE_INDEX] = comm_interface;
|
||||
descriptor_buf[CDC_CALL_MANAGEMENT_DATA_INTERFACE_INDEX] = data_interface;
|
||||
descriptor_buf[CDC_UNION_MASTER_INTERFACE_INDEX] = comm_interface;
|
||||
descriptor_buf[CDC_UNION_SLAVE_INTERFACE_INDEX] = data_interface;
|
||||
descriptor_buf[CDC_DATA_INTERFACE_INDEX] = data_interface;
|
||||
|
||||
descriptor_buf[CDC_CONTROL_IN_ENDPOINT_INDEX] = control_in_endpoint;
|
||||
descriptor_buf[CDC_DATA_OUT_ENDPOINT_INDEX] = data_out_endpoint;
|
||||
descriptor_buf[CDC_DATA_IN_ENDPOINT_INDEX] = data_in_endpoint;
|
||||
// Store comm interface number.
|
||||
descriptor_buf[CDC_FIRST_INTERFACE_INDEX] = *current_interface;
|
||||
descriptor_buf[CDC_COMM_INTERFACE_INDEX] = *current_interface;
|
||||
descriptor_buf[CDC_UNION_MASTER_INTERFACE_INDEX] = *current_interface;
|
||||
(*current_interface)++;
|
||||
|
||||
descriptor_buf[CDC_COMM_INTERFACE_STRING_INDEX] = comm_interface_string;
|
||||
descriptor_buf[CDC_DATA_INTERFACE_STRING_INDEX] = data_interface_string;
|
||||
// Now store data interface number.
|
||||
descriptor_buf[CDC_CALL_MANAGEMENT_DATA_INTERFACE_INDEX] = *current_interface;
|
||||
descriptor_buf[CDC_UNION_SLAVE_INTERFACE_INDEX] = *current_interface;
|
||||
descriptor_buf[CDC_DATA_INTERFACE_INDEX] = *current_interface;
|
||||
|
||||
descriptor_buf[CDC_CONTROL_IN_ENDPOINT_INDEX] = repl
|
||||
? (USB_CDC_EP_NUM_NOTIFICATION ? USB_CDC_EP_NUM_NOTIFICATION : *current_endpoint)
|
||||
: (USB_CDC2_EP_NUM_NOTIFICATION ? USB_CDC2_EP_NUM_NOTIFICATION : *current_endpoint);
|
||||
(*current_endpoint)++;
|
||||
|
||||
descriptor_buf[CDC_DATA_OUT_ENDPOINT_INDEX] = repl
|
||||
? (USB_CDC_EP_NUM_DATA_OUT ? USB_CDC_EP_NUM_DATA_OUT : *current_endpoint)
|
||||
: (USB_CDC2_EP_NUM_DATA_OUT ? USB_CDC2_EP_NUM_DATA_OUT : *current_endpoint);
|
||||
|
||||
descriptor_buf[CDC_DATA_IN_ENDPOINT_INDEX] = repl
|
||||
? (USB_CDC_EP_NUM_DATA_IN ? USB_CDC_EP_NUM_DATA_IN : *current_endpoint)
|
||||
: (USB_CDC2_EP_NUM_DATA_IN ? USB_CDC2_EP_NUM_DATA_IN : *current_endpoint);
|
||||
(*current_endpoint)++;
|
||||
|
||||
usb_add_interface_string(*current_interface_string,
|
||||
repl ? repl_cdc_comm_interface_name : data_cdc_comm_interface_name);
|
||||
descriptor_buf[CDC_COMM_INTERFACE_STRING_INDEX] = *current_interface_string;
|
||||
(*current_interface_string)++;
|
||||
|
||||
usb_add_interface_string(*current_interface_string,
|
||||
repl ? repl_cdc_data_interface_name : data_cdc_data_interface_name);
|
||||
descriptor_buf[CDC_DATA_INTERFACE_STRING_INDEX] = *current_interface_string;
|
||||
(*current_interface_string)++;
|
||||
|
||||
return sizeof(usb_midi_descriptor_template);
|
||||
}
|
||||
|
@ -34,6 +34,6 @@ extern bool usb_cdc_data_enabled;
|
||||
|
||||
void usb_cdc_init(void);
|
||||
size_t usb_cdc_descriptor_length(void);
|
||||
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8 comm_interface, uint8_t data_interface, uint8_t control_in_endpoint, uint8_t data_in_endpoint, uint8_t data_out_endpoint, uint8_t comm_interface_string, uint8_t data_interface_string);
|
||||
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string, bool repl);
|
||||
|
||||
#endif /* SHARED_MODULE_USB_CDC___INIT___H */
|
||||
|
@ -24,4 +24,51 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Nothing needed here. Tables of HID devices are generated in autogen_usb_descriptor.c at compile-time.
|
||||
static const uint8_t usb_hid_descriptor_template[] = {
|
||||
0x09, // 0 bLength
|
||||
0x21, // 1 bDescriptorType (HID)
|
||||
0x11, 0x01, // 2 bcdHID 1.11
|
||||
0x00, // 3 bCountryCode
|
||||
0x01, // 4 bNumDescriptors
|
||||
0x22, // 5 bDescriptorType[0] (HID)
|
||||
0xFF, 0xFF, // 6,7 wDescriptorLength[0] [SET AT RUNTIME: lo, hi]
|
||||
#define HID_DESCRIPTOR_LENGTH_INDEX 6
|
||||
|
||||
0x07, // 8 bLength
|
||||
0x05, // 9 bDescriptorType (Endpoint)
|
||||
0xFF, // 10 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | endpoint]
|
||||
#define HID_IN_ENDPOINT_INDEX 10
|
||||
0x03, // 11 bmAttributes (Interrupt)
|
||||
0x40, 0x00, // 12,13 wMaxPacketSize 64
|
||||
0x08, // 14 bInterval 8 (unit depends on device speed)
|
||||
|
||||
0x07, // 15 bLength
|
||||
0x05, // 16 bDescriptorType (Endpoint)
|
||||
0xFF, // 17 bEndpointAddress (OUT/H2D) [SET AT RUNTIME]
|
||||
#define HID_OUT_ENDPOINT_INDEX 17
|
||||
0x03, // 18 bmAttributes (Interrupt)
|
||||
0x40, 0x00, // 19,20 wMaxPacketSize 64
|
||||
0x08, // 21 bInterval 8 (unit depends on device speed)
|
||||
};
|
||||
|
||||
// Is the HID device enabled?
|
||||
bool usb_hid_enabled;
|
||||
|
||||
size_t usb_hid_descriptor_length(void) {
|
||||
return sizeof(usb_hid_descriptor);
|
||||
}
|
||||
|
||||
static const char[] usb_hid_interface_name = USB_INTERFACE_NAME " Mass Storage";
|
||||
|
||||
size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string, uint16_t report_descriptor_length) {
|
||||
memcpy(descriptor_buf, usb_hid_descriptor_template, sizeof(usb_hid_descriptor_template));
|
||||
|
||||
descriptor_buf[HID_DESCRIPTOR_LENGTH_INDEX] = report_descriptor_length & 0xFF;
|
||||
descriptor_buf[HID_DESCRIPTOR_LENGTH_INDEX + 1] = (report_descriptor_length >> 8);
|
||||
|
||||
descriptor_buf[HID_IN_ENDPOINT_INDEX] = USB_HID_EP_NUM_IN ? USB_HID_EP_NUM_IN : *current_endpoint;
|
||||
descriptor_buf[HID_OUT_ENDPOINT_INDEX] = 0x80 | (USB_HID_EP_NUM_OUT ? USB_HID_EP_NUM_OUT : *current_endpoint);
|
||||
(*current_endpoint)++:
|
||||
|
||||
return sizeof(usb_hid_descriptor_template);
|
||||
}
|
||||
|
@ -163,21 +163,41 @@ size_t usb_midi_descriptor_length(void) {
|
||||
return sizeof(usb_midi_descriptor_template);
|
||||
}
|
||||
|
||||
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf,
|
||||
uint8_t audio_control_interface, uint8_t midi_streaming_interface, uint8_t midi_streaming_in_endpoint, uint8_t midi_streaming_out_endpoint, uint8_t audio_control_interface_string, uint8_t midi_streaming_interface_string, uint8_t in_jack_string, uint8_t out_jack_string) {
|
||||
static const char[] midi_streaming_interface_name = USB_INTERFACE_NAME " MIDI";
|
||||
static const char[] midi_audio_control_interface_name = USB_INTERFACE_NAME " Audio";
|
||||
static const char[] midi_in_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]";
|
||||
static const char[] midi_out_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]";
|
||||
|
||||
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string) {
|
||||
memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template));
|
||||
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = audio_control_interface_number;
|
||||
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = audio_control_interface_string;
|
||||
|
||||
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = midi_streaming_in_endpoint;
|
||||
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = 0x80 | midi_streaming_out_endpoint;
|
||||
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = *current_interface;
|
||||
(*current_interface)++;
|
||||
|
||||
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX] = midi_streaming_interface_number;
|
||||
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = midi_streaming_interface_number;
|
||||
descriptor_buf[MIDI_STREAMING_INTERFACE_STRING_INDEX] = midi_streaming_interface_string;
|
||||
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = USB_MIDI_EP_NUM_IN ? USB_MIDI_EP_NUM_IN : *current_endpoint;
|
||||
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] =
|
||||
0x80 | (USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : *current_endpoint);
|
||||
(*current_endpoint)++;
|
||||
|
||||
descriptor_buf[MIDI_IN_JACK_STRING_INDEX] = in_jack_string;
|
||||
descriptor_buf[MIDI_OUT_JACK_STRING_INDEX] = out_jack_string;
|
||||
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX] = *current_interface;
|
||||
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = *current_interface;
|
||||
(*current_interface)++;
|
||||
|
||||
usb_add_interface_string(*current_interface, midi_streaming_interface_name);
|
||||
descriptor_buf[MIDI_STREAMING_INTERFACE_STRING_INDEX] = *current_interface;
|
||||
(*current_interface_string)++;
|
||||
|
||||
usb_add_interface_string(*current_interface, midi_audio_control_interface_name);
|
||||
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = *current_interface;
|
||||
(*current_interface_string)++;
|
||||
|
||||
usb_add_interface_string(*current_interface, midi_in_jack_name);
|
||||
descriptor_buf[MIDI_IN_JACK_STRING_INDEX] = *current_interface;
|
||||
(*current_interface_string)++;
|
||||
|
||||
usb_add_interface_string(*current_interface, midi_out_jack_name);
|
||||
descriptor_buf[MIDI_OUT_JACK_STRING_INDEX] = *current_interface;
|
||||
(*current_interface_string)++;
|
||||
|
||||
return sizeof(usb_midi_descriptor_template);
|
||||
}
|
||||
|
@ -33,6 +33,6 @@ void usb_midi_init(void);
|
||||
void usb_midi_usb_init(void);
|
||||
|
||||
size_t usb_midi_descriptor_length(void);
|
||||
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t audio_control_interface, uint8_t midi_streaming_interface, uint8_t midi_streaming_in_endpoint, uint8_t midi_streaming_out_endpoint, uint8_t audio_control_interface_string, uint8_t midi_streaming_interface_string, uint8_t in_jack_string, uint8_t out_jack_string);
|
||||
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string);
|
||||
|
||||
#endif /* SHARED_MODULE_USB_MIDI___INIT___H */
|
||||
|
@ -51,27 +51,6 @@ extern const tusb_desc_webusb_url_t desc_webusb_url;
|
||||
static bool web_serial_connected = false;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Serial number as hex characters. This writes directly to the USB
|
||||
// descriptor.
|
||||
extern uint16_t usb_serial_number[1 + COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2];
|
||||
|
||||
void load_serial_number(void) {
|
||||
// create serial number based on device unique id
|
||||
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
|
||||
common_hal_mcu_processor_get_uid(raw_id);
|
||||
|
||||
usb_serial_number[0] = 0x300 | sizeof(usb_serial_number);
|
||||
for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf;
|
||||
// Strings are UTF-16-LE encoded.
|
||||
usb_serial_number[1 + i * 2 + j] = nibble_to_hex_upper[nibble];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool usb_enabled(void) {
|
||||
return tusb_inited();
|
||||
}
|
||||
@ -80,8 +59,13 @@ MP_WEAK void post_usb_init(void) {
|
||||
}
|
||||
|
||||
void usb_init(void) {
|
||||
usb_build_device_descriptor();
|
||||
usb_build_configuration_descriptor();
|
||||
usb_build_hid_descriptor();
|
||||
usb_build_string_descriptors();
|
||||
|
||||
|
||||
init_usb_hardware();
|
||||
load_serial_number();
|
||||
|
||||
tusb_init();
|
||||
|
||||
|
@ -46,9 +46,22 @@
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
// ******* TODO PROTECT AGAINST GC.
|
||||
static uint8_t *device_descriptor;
|
||||
static uint8_t *config_descriptor;
|
||||
|
||||
// Table for collecting interface strings (interface names) as descriptor is built.
|
||||
#define MAX_INTERFACE_STRINGS 16
|
||||
// slot 0 is not used.
|
||||
static char * collected_interface_strings[];
|
||||
static uint16_t current_interface_string;
|
||||
|
||||
static const char[] manufacturer_name = USB_MANUFACTURER;
|
||||
static const char[] product_name = USB_PRODUCT;
|
||||
|
||||
// Serial number string is UID length * 2 (2 nibbles per byte) + 1 byte for null termination.
|
||||
static char serial_number_hex_string[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2 + 1];
|
||||
|
||||
static const uint8_t device_descriptor_template[] = {
|
||||
0x12, // 0 bLength
|
||||
0x01, // 1 bDescriptorType (Device)
|
||||
@ -87,8 +100,27 @@ static const uint8_t configuration_descriptor_template[] = {
|
||||
0x32, // 8 bMaxPower 100mA
|
||||
};
|
||||
|
||||
void build_usb_device_descriptor(uint16_t vid, uint16_t pid, uint8_t manufacturer_string_index, uint8_t product_string_index, uint8_t serial_number_string_index) {
|
||||
void usb_desc_init(void) {
|
||||
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
|
||||
common_hal_mcu_processor_get_uid(raw_id);
|
||||
|
||||
for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf;
|
||||
serial_number_hex_string[i * 2 + (1 - j)] = nibble_to_hex_upper[nibble];
|
||||
}
|
||||
}
|
||||
|
||||
// Null-terminate the string.
|
||||
serial_number_hex_string[sizeof(serial_number_hex_string)] = '\0';
|
||||
|
||||
// Set to zero when allocated; we depend on that.
|
||||
collected_interface_strings = m_malloc(MAX_INTERFACE_STRINGS + 1, false);
|
||||
current_interface_string = 1;
|
||||
}
|
||||
|
||||
|
||||
void usb_build_device_descriptor(uint16_t vid, uint16_t pid, uint8_t *current_interface_string) {
|
||||
device_descriptor = m_malloc(sizeof(device_descriptor_template), false);
|
||||
memcpy(device_descriptor, device_descriptor_template, sizeof(device_descriptor_template));
|
||||
|
||||
@ -96,12 +128,21 @@ void build_usb_device_descriptor(uint16_t vid, uint16_t pid, uint8_t manufacture
|
||||
device_descriptor[DEVICE_VID_HI_INDEX] = vid >> 8;
|
||||
device_descriptor[DEVICE_PID_LO_INDEX] = pid & 0xFF;
|
||||
device_descriptor[DEVICE_PID_HI_INDEX] = pid >> 8;
|
||||
device_descriptor[DEVICE_MANUFACTURER_STRING_INDEX] = manufacturer_string_index;
|
||||
device_descriptor[DEVICE_PRODUCT_STRING_INDEX] = product_string_index;
|
||||
device_descriptor[DEVICE_SERIAL_NUMBER_STRING_INDEX] = serial_number_string_index;
|
||||
|
||||
usb_add_interface_string(*current_interface_string, manufacturer_name);
|
||||
device_descriptor[DEVICE_MANUFACTURER_STRING_INDEX] = *current_interface_string;
|
||||
(*current_interface_string)++;
|
||||
|
||||
usb_add_interface_string(*current_interface_string, product_name);
|
||||
device_descriptor[DEVICE_PRODUCT_STRING_INDEX] = *current_interface_string;
|
||||
(*current_interface_string)++;
|
||||
|
||||
usb_add_interface_string(*current_interface_string, serial_number_hex_string);
|
||||
device_descriptor[DEVICE_SERIAL_NUMBER_STRING_INDEX] = *current_interface_string;
|
||||
(*current_interface_string)++;
|
||||
}
|
||||
|
||||
void build_usb_configuration_descriptor(uint16_t total_length, uint8_t num_interfaces) {
|
||||
void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_interfaces) {
|
||||
size_t total_descriptor_length = sizeof(configuration_descriptor_template);
|
||||
|
||||
// CDC should be first, for compatibility with Adafruit Windows 7 drivers.
|
||||
@ -143,19 +184,22 @@ void build_usb_configuration_descriptor(uint16_t total_length, uint8_t num_inter
|
||||
configuration_descriptor[CONFIG_TOTAL_LENGTH_HI_INDEX] = (total_descriptor_length >> 8) & 0xFF;
|
||||
|
||||
// Number interfaces and endpoints.
|
||||
// Endpoint 0 is already used for USB control.
|
||||
// Endpoint 0 is already used for USB control, so start with 1.
|
||||
uint8_t current_interface = 0;
|
||||
uint8_t current_endpoint = 1;
|
||||
uint16_t current_interface_string = 1;
|
||||
|
||||
uint8_t *descriptor_buf_remaining = configuration_descriptor + sizeof(configuration_descriptor_template);
|
||||
|
||||
#if CIRCUITPY_USB_CDC
|
||||
if (usb_cdc_repl_enabled) {
|
||||
// Concatenate and fix up the CDC REPL descriptor.
|
||||
descriptor_buf_remaining += usb_cdc_add_descriptor(
|
||||
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string, true);
|
||||
}
|
||||
if (usb_cdc_data_enabled) {
|
||||
// Concatenate and fix up the CDC data descriptor.
|
||||
descriptor_buf_remaining += usb_cdc_add_descriptor(
|
||||
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -163,13 +207,7 @@ void build_usb_configuration_descriptor(uint16_t total_length, uint8_t num_inter
|
||||
if (storage_usb_enabled) {
|
||||
// Concatenate and fix up the MSC descriptor.
|
||||
descriptor_buf_remaining += storage_usb_add_descriptor(
|
||||
descriptor_buf_remaining, current_interface,
|
||||
current_endpoint, // in
|
||||
current_endpoint, // out
|
||||
current_interface_string_index);
|
||||
current_interface++;
|
||||
current_endpoint++;
|
||||
current_interface_string++;
|
||||
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -177,26 +215,14 @@ void build_usb_configuration_descriptor(uint16_t total_length, uint8_t num_inter
|
||||
if (usb_midi_enabled) {
|
||||
// Concatenate and fix up the MIDI descriptor.
|
||||
descriptor_buf_remaining += usb_midi_add_descriptor(
|
||||
descriptor_buf_remaining,
|
||||
current_interface, // audio control
|
||||
current_interface + 1, // MIDI streaming
|
||||
current_endpoint, // in
|
||||
current_endpoint, // out
|
||||
current_interface_string, // audio control
|
||||
current_interface_string + 1 // MIDI streaming
|
||||
current_interface_string + 2 // in jack
|
||||
current_interface_string + 3 // out jack
|
||||
);
|
||||
current_interface += 2; // two interfaces: audio control and MIDI streaming
|
||||
current_endpoint++; // MIDI streaming only (no audio data)
|
||||
current_interface_string += 4; // two interface names: audio control and MIDI streaming
|
||||
|
||||
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
if (usb_hid_enabled) {
|
||||
// Concatenate and fix up the HID descriptor (not the report descriptors).
|
||||
descriptor_buf_remaining += usb_hid_add_descriptor(
|
||||
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -210,13 +236,33 @@ void build_usb_configuration_descriptor(uint16_t total_length, uint8_t num_inter
|
||||
|
||||
}
|
||||
|
||||
// Invoked when received GET DEVICE DESCRIPTOR
|
||||
void usb_add_interface_string(uint8_t interface_string_index, const char[] str) {
|
||||
if (interface_string_index > MAX_INTERFACE_STRINGS) {
|
||||
mp_raise_SystemError("Too many USB interface names");
|
||||
}
|
||||
// 2 bytes for String Descriptor header, then 2 bytes for each character
|
||||
const size_t str_len = strlen(str);
|
||||
uint8_t descriptor_size = 2 + (str_len * 2);
|
||||
uint16_t *string_descriptor = (uint16_t *) m_malloc(descriptor_size, false);
|
||||
string_descriptor[0] = 0x0300 | descriptor_size;
|
||||
// Convert to le16
|
||||
for (i = 0; i <= str_len; i++) {
|
||||
string_descriptor[i + 1] = str[i];
|
||||
}
|
||||
|
||||
collected_interface_strings[interface_string_index] = string_descriptor;
|
||||
}
|
||||
|
||||
|
||||
void usb_
|
||||
|
||||
// Invoked when GET DEVICE DESCRIPTOR is received.
|
||||
// Application return pointer to descriptor
|
||||
uint8_t const *tud_descriptor_device_cb(void) {
|
||||
return usb_descriptor_dev;
|
||||
}
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
// Invoked when GET CONFIGURATION DESCRIPTOR is received.
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
@ -225,7 +271,7 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
}
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
// Invoked when GET HID REPORT DESCRIPTOR is received.
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
|
||||
@ -234,9 +280,11 @@ uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Invoked when received GET STRING DESCRIPTOR request
|
||||
// Invoked when GET STRING DESCRIPTOR request is received.
|
||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
uint8_t const max_index = sizeof(string_descriptor_arr) / sizeof(string_descriptor_arr[0]);
|
||||
return (index < max_index) ? string_descriptor_arr[index] : NULL;
|
||||
if (index > MAX_INTERFACE_STRINGS) {
|
||||
return NULL;
|
||||
}
|
||||
return collected_interface_strings[index];
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ else
|
||||
supervisor/usb.c \
|
||||
supervisor/shared/usb/usb_desc.c \
|
||||
supervisor/shared/usb/usb.c \
|
||||
$(BUILD)/autogen_usb_descriptor.c \
|
||||
|
||||
ifeq ($(CIRCUITPY_USB_CDC), 1)
|
||||
SRC_SUPERVISOR += \
|
||||
@ -159,61 +158,24 @@ USB_HIGHSPEED ?= 0
|
||||
USB_CDC_EP_NUM_NOTIFICATION ?= 0
|
||||
USB_CDC_EP_NUM_DATA_OUT ?= 0
|
||||
USB_CDC_EP_NUM_DATA_IN ?= 0
|
||||
|
||||
USB_CDC2_EP_NUM_NOTIFICATION ?= 0
|
||||
USB_CDC2_EP_NUM_DATA_OUT ?= 0
|
||||
USB_CDC2_EP_NUM_DATA_IN ?= 0
|
||||
|
||||
USB_MSC_EP_NUM_OUT ?= 0
|
||||
USB_MSC_EP_NUM_IN ?= 0
|
||||
|
||||
USB_HID_EP_NUM_OUT ?= 0
|
||||
USB_HID_EP_NUM_IN ?= 0
|
||||
|
||||
USB_MIDI_EP_NUM_OUT ?= 0
|
||||
USB_MIDI_EP_NUM_IN ?= 0
|
||||
|
||||
USB_NUM_EP ?= 0
|
||||
|
||||
USB_DESCRIPTOR_ARGS = \
|
||||
--manufacturer $(USB_MANUFACTURER)\
|
||||
--product $(USB_PRODUCT)\
|
||||
--vid $(USB_VID)\
|
||||
--pid $(USB_PID)\
|
||||
--serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\
|
||||
--interface_name_prefix $(USB_INTERFACE_NAME)\
|
||||
--devices "$(USB_DEVICES)"\
|
||||
--hid_devices "$(USB_HID_DEVICES)"\
|
||||
--max_ep $(USB_NUM_EP) \
|
||||
--cdc_ep_num_notification $(USB_CDC_EP_NUM_NOTIFICATION)\
|
||||
--cdc_ep_num_data_out $(USB_CDC_EP_NUM_DATA_OUT)\
|
||||
--cdc_ep_num_data_in $(USB_CDC_EP_NUM_DATA_IN)\
|
||||
--msc_ep_num_out $(USB_MSC_EP_NUM_OUT)\
|
||||
--msc_ep_num_in $(USB_MSC_EP_NUM_IN)\
|
||||
--hid_ep_num_out $(USB_HID_EP_NUM_OUT)\
|
||||
--hid_ep_num_in $(USB_HID_EP_NUM_IN)\
|
||||
--midi_ep_num_out $(USB_MIDI_EP_NUM_OUT)\
|
||||
--midi_ep_num_in $(USB_MIDI_EP_NUM_IN)\
|
||||
--output_c_file $(BUILD)/autogen_usb_descriptor.c\
|
||||
--output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h
|
||||
|
||||
ifeq ($(CIRCUITPY_USB_VENDOR), 1)
|
||||
USB_DESCRIPTOR_ARGS += \
|
||||
--vendor_ep_num_out 0 --vendor_ep_num_in 0 \
|
||||
--webusb_url $(USB_WEBUSB_URL)
|
||||
endif
|
||||
|
||||
ifeq ($(USB_RENUMBER_ENDPOINTS), 0)
|
||||
USB_DESCRIPTOR_ARGS += --no-renumber_endpoints
|
||||
endif
|
||||
|
||||
ifeq ($(USB_HIGHSPEED), 1)
|
||||
USB_DESCRIPTOR_ARGS += --highspeed
|
||||
endif
|
||||
|
||||
$(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h
|
||||
|
||||
$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: autogen_usb_descriptor.intermediate
|
||||
|
||||
.INTERMEDIATE: autogen_usb_descriptor.intermediate
|
||||
|
||||
autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD)
|
||||
$(STEPECHO) "GEN $@"
|
||||
$(Q)install -d $(BUILD)/genhdr
|
||||
$(Q)$(PYTHON3) ../../tools/gen_usb_descriptor.py $(USB_DESCRIPTOR_ARGS)
|
||||
|
||||
CIRCUITPY_DISPLAY_FONT ?= "../../tools/fonts/ter-u12n.bdf"
|
||||
|
||||
$(BUILD)/autogen_display_resources.c: ../../tools/gen_display_resources.py $(HEADER_BUILD)/qstrdefs.generated.h Makefile | $(HEADER_BUILD)
|
||||
|
@ -53,6 +53,11 @@ bool usb_enabled(void);
|
||||
void usb_init(void);
|
||||
void usb_disconnect(void);
|
||||
|
||||
void usb_add_interface_string(uint8_t interface_string_index, const char[] str);
|
||||
void usb_desc_init(void);
|
||||
void usb_build_device_descriptor(uint16_t vid, uint16_t pid, uint8_t *current_interface_string);
|
||||
void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_interfaces);
|
||||
|
||||
// Propagate plug/unplug events to the MSC logic.
|
||||
#if CIRCUITPY_USB_MSC
|
||||
void usb_msc_mount(void);
|
||||
|
Loading…
Reference in New Issue
Block a user