view cp2102/decode_usb_desc.c @ 89:cddf60418f98

cp2102-decode-ee-desc: decode endpoint descriptors
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 27 Sep 2023 20:00:56 +0000
parents ea7b411aad27
children 3bde280f0986
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]);
}

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);
	/* decoding of string descriptors remains to be implemented */
	exit(0);
}