FreeCalypso > hg > fc-usbser-tools
view cp2102/decode_usb_desc.c @ 104:866eae65dbea
LICENSE: same as other FreeCalypso tools
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 Sep 2023 18:20:04 +0000 |
parents | f4a7ac90cf39 |
children |
line wrap: on
line source
/* * This program reads a CP2102 EEPROM image from an Intel HEX file * and decodes the USB descriptors portion thereof. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include "cp210x_defs.h" u_char eeprom[SIZE_EEPROM]; static void print_device_desc(desc) u_char *desc; { printf(" bLength: %u", desc[0]); if (desc[0] != 18) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" bDescriptorType: 0x%02X", desc[1]); if (desc[1] != 0x01) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" bcdUSB: 0x%02X%02X\n", desc[3], desc[2]); printf(" bDeviceClass: 0x%02X\n", desc[4]); printf(" bDeviceSubClass: 0x%02X\n", desc[5]); printf(" bDeviceProtocol: 0x%02X\n", desc[6]); printf(" bMaxPacketSize0: %u\n", desc[7]); printf(" idVendor: 0x%02X%02X\n", desc[9], desc[8]); printf(" idProduct: 0x%02X%02X\n", desc[11], desc[10]); printf(" bcdDevice: 0x%02X%02X\n", desc[13], desc[12]); printf(" iManufacturer: %u\n", desc[14]); printf(" iProduct: %u\n", desc[15]); printf(" iSerialNumber: %u\n", desc[16]); printf(" bNumConfigurations: %u\n", desc[17]); } static void print_config_desc(desc) u_char *desc; { printf(" bLength: %u", desc[0]); if (desc[0] != 9) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" bDescriptorType: 0x%02X", desc[1]); if (desc[1] != 0x02) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" wTotalLength: %u\n", desc[2] | (desc[3] << 8)); printf(" bNumInterfaces: %u\n", desc[4]); printf(" bConfigurationValue: 0x%02X\n", desc[5]); printf(" iConfiguration: %u\n", desc[6]); printf(" bmAttributes: 0x%02X\n", desc[7]); printf(" bMaxPower: 0x%02X (%u mA)\n", desc[8], desc[8] * 2); } static void print_interf_desc(desc) u_char *desc; { printf(" bLength: %u", desc[0]); if (desc[0] != 9) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" bDescriptorType: 0x%02X", desc[1]); if (desc[1] != 0x04) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" bInterfaceNumber: %u\n", desc[2]); printf(" bAlternateSetting: 0x%02X\n", desc[3]); printf(" bNumEndpoints: %u\n", desc[4]); printf(" bInterfaceClass: 0x%02X\n", desc[5]); printf(" bInterfaceSubClass: 0x%02X\n", desc[6]); printf(" bInterfaceProtocol: 0x%02X\n", desc[7]); printf(" iInterface: %u\n", desc[8]); } static void print_endpoint_desc(desc) u_char *desc; { printf(" bLength: %u", desc[0]); if (desc[0] != 7) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" bDescriptorType: 0x%02X", desc[1]); if (desc[1] != 0x05) fputs(" (WRONG!)", stdout); putchar('\n'); printf(" bEndpointAddress: 0x%02X\n", desc[2]); printf(" bmAttributes: 0x%02X\n", desc[3]); printf(" wMaxPacketSize: %u\n", desc[4] | (desc[5] << 8)); printf(" bInterval: %u\n", desc[6]); } static void print_string_desc_0(desc) u_char *desc; { printf(" bLength: %u", desc[0]); if (desc[0] > 8) fputs(" (too long!)", stdout); else if (desc[0] < 2) fputs(" (too short!)", stdout); else if (desc[0] & 1) fputs(" (odd bogon!)", stdout); putchar('\n'); printf(" bDescriptorType: 0x%02X", desc[1]); if (desc[1] != 0x03) fputs(" (WRONG!)", stdout); putchar('\n'); if (desc[0] < 4) return; printf(" wLANGID[0]: 0x%04X\n", desc[2] | (desc[3] << 8)); if (desc[0] < 6) return; printf(" wLANGID[1]: 0x%04X\n", desc[4] | (desc[5] << 8)); if (desc[0] < 8) return; printf(" wLANGID[2]: 0x%04X\n", desc[6] | (desc[7] << 8)); } static void print_string_desc(headline, desc, maxlen) char *headline; u_char *desc; unsigned maxlen; { u_char *sp, *endp; unsigned uni; if (desc[0] < 2 || desc[0] > maxlen || desc[0] & 1 || desc[1] != 0x03) { printf("%s INVALID\n", headline); return; } printf("%s \"", headline); endp = desc + desc[0]; for (sp = desc + 2; sp < endp; sp += 2) { uni = sp[0] | (sp[1] << 8); if (uni < 0x20 || uni > 0x7E) { printf("\\u%04X", uni); continue; } if (uni == '"' || uni == '\\') putchar('\\'); putchar(uni); } putchar('"'); putchar('\n'); } main(argc, argv) char **argv; { if (argc != 2) { fprintf(stderr, "usage: %s ihex-file\n", argv[0]); exit(1); } read_intel_hex(argv[1]); printf("USB device descriptor at 0x3988:\n"); print_device_desc(eeprom + 0x388); printf("USB configuration descriptor at 0x399A:\n"); print_config_desc(eeprom + 0x39A); printf("USB interface descriptor at 0x39A3:\n"); print_interf_desc(eeprom + 0x3A3); printf("USB endpoint descriptor at 0x39AC:\n"); print_endpoint_desc(eeprom + 0x3AC); printf("USB endpoint descriptor at 0x39B3:\n"); print_endpoint_desc(eeprom + 0x3B3); printf("USB string descriptor 0 at 0x3800:\n"); print_string_desc_0(eeprom + 0x200); print_string_desc("Manuf string: ", eeprom + 0x3C3, 60); print_string_desc("Product string:", eeprom + 0x208, 254); print_string_desc("Serial# string:", eeprom + 0x307, 128); exit(0); }