QUELLCODE / C
usb_descriptor_test.c
pico/tests/usb_descriptor_test.c
1/*2 * OpenAss: nur privater, experimenteller Gebrauch; auf eigene Verantwortung.3 * Niemals Unternehmensrechner, Produktivsysteme, Industrieanlagen oder4 * sicherheitskritische Systeme anschließen oder bedienen.5 * Haftungshinweis und gesetzliche Grenzen: ../../DISCLAIMER.txt.6 */7// Optional integration test compiled against a real TinyUSB source checkout.8#include <assert.h>9#include <stdio.h>10#include <string.h>11#include "pico/unique_id.h"12#include "tusb.h"13#include "usb_descriptors.h"1415void pico_get_unique_board_id_string(char *out, size_t capacity) {16 assert(capacity >= 17u);17 memcpy(out, "0123456789ABCDEF", 17u);18}1920static size_t input_bits(const uint8_t *descriptor) {21 // Walk through two closing collections, decoding standard HID short items.22 size_t position = 0;23 size_t bits = 0;24 uint32_t report_size = 0, report_count = 0;25 unsigned depth = 0;26 bool started = false;27 do {28 uint8_t prefix = descriptor[position++];29 assert(prefix != 0xfeu);30 unsigned size = prefix & 3u;31 if (size == 3u) size = 4u;32 uint32_t value = 0;33 for (unsigned byte = 0; byte < size; ++byte) value |= (uint32_t)descriptor[position++] << (byte * 8u);34 unsigned type = (prefix >> 2u) & 3u;35 unsigned tag = prefix >> 4u;36 if (type == 1u && tag == 7u) report_size = value;37 if (type == 1u && tag == 9u) report_count = value;38 if (type == 0u && tag == 8u) bits += report_size * report_count;39 if (type == 0u && tag == 10u) { ++depth; started = true; }40 if (type == 0u && tag == 12u) { assert(depth); --depth; }41 assert(position < 256u);42 } while (!started || depth);43 return bits;44}4546int main(void) {47 const tusb_desc_device_t *device = (const tusb_desc_device_t *)tud_descriptor_device_cb();48 assert(device->bNumConfigurations == 1 && device->bMaxPacketSize0 == 64);49 assert(device->idVendor == 0xcafe && device->idProduct == 0xb001);50 const uint8_t *config = tud_descriptor_configuration_cb(0);51 assert(config && config[4] == 3u && tud_descriptor_configuration_cb(1) == NULL);52 uint16_t length = (uint16_t)(config[2] | ((uint16_t)config[3] << 8u));53 uint8_t expected_protocol[] = {HID_ITF_PROTOCOL_KEYBOARD, HID_ITF_PROTOCOL_NONE, HID_ITF_PROTOCOL_MOUSE};54 unsigned interface_count = 0, endpoint_count = 0;55 for (size_t at = 0; at < length; at += config[at]) {56 assert(config[at] >= 2u && at + config[at] <= length);57 if (config[at + 1u] == TUSB_DESC_INTERFACE) {58 assert(interface_count < 3u && config[at + 5u] == TUSB_CLASS_HID);59 assert(config[at + 7u] == expected_protocol[interface_count++]);60 }61 if (config[at + 1u] == TUSB_DESC_ENDPOINT) {62 assert(config[at + 2u] == 0x81u + endpoint_count++ && config[at + 6u] == 1u);63 }64 }65 assert(interface_count == 3u && endpoint_count == 3u);66 assert(input_bits(tud_hid_descriptor_report_cb(HB_HID_KEYBOARD)) == 64u);67 assert(input_bits(tud_hid_descriptor_report_cb(HB_HID_ABSOLUTE)) == 40u);68 assert(input_bits(tud_hid_descriptor_report_cb(HB_HID_RELATIVE)) == 40u);69 assert(tud_hid_descriptor_report_cb(HB_HID_COUNT) == NULL);70 assert((tud_descriptor_string_cb(0, 0)[0] & 0xffu) == 4u);71 assert(tud_descriptor_string_cb(0, 0)[1] == 0x0409u);72 const uint16_t *serial = tud_descriptor_string_cb(3, 0);73 assert((serial[0] & 0xffu) == 34u && serial[1] == '0' && serial[16] == 'F');74 assert(tud_descriptor_string_cb(99, 0) == NULL);75 puts("USB descriptor integration tests passed against real TinyUSB headers.");76 return 0;77}