/* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /** USB cable definitions and utilities * @file * @author King Kévin * @date 2019 */ /* standard libraries */ #include // standard integer types #include // string utilities /* STM32 (including CM3) libraries */ #include // Cortex M3 utilities #include // assert definitions #include // general purpose input output library /* own libraries */ #include "global.h" // board definitions #include "print.h" // printing utilities #include "usb_cables.h" // own definitions /* USB connectors */ /** USB type A connector (host side) */ static const struct usb_pin_t usb_host_a_pins[] = { { .name = "shield", .port = GPIOD, .pin = GPIO0, .type = USB_PIN_TYPE_SHIELD, }, { .name = "VBUS", .port = GPIOC, .pin = GPIO12, .type = USB_PIN_TYPE_POWER, }, { .name = "D-", .port = GPIOA, .pin = GPIO15, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "D+", .port = GPIOG, .pin = GPIO6, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND", .port = GPIOG, .pin = GPIO2, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSRX-", .port = GPIOD, .pin = GPIO14, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRX+", .port = GPIOG, .pin = GPIO4, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND_DRAIN", .port = GPIOG, .pin = GPIO8, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSTX-", .port = GPIOC, .pin = GPIO10, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTX+", .port = GPIOC, .pin = GPIO11, .type = USB_PIN_TYPE_DIFFERENTIAL, }, }; /** USB-C connector ("host" side) */ static const struct usb_pin_t usb_host_c_pins[] = { { .name = "shield", .port = GPIOG, .pin = GPIO13, .type = USB_PIN_TYPE_SHIELD, }, { .name = "GND-A1", .port = GPIOD, .pin = GPIO15, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSTXp1", .port = GPIOG, .pin = GPIO3, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTXn1", .port = GPIOG, .pin = GPIO5, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "VBUS-A4", .port = GPIOG, .pin = GPIO7, .type = USB_PIN_TYPE_POWER, }, { .name = "CC1", .port = GPIOC, .pin = GPIO6, .type = USB_PIN_TYPE_IDENTIFICATION, }, { .name = "Dp1", .port = GPIOC, .pin = GPIO8, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "Dn1", .port = GPIOA, .pin = GPIO8, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SBU1", .port = GPIOA, .pin = GPIO10, .type = USB_PIN_TYPE_OTHER, }, { .name = "VBUS-A9", .port = GPIOG, .pin = GPIO11, .type = USB_PIN_TYPE_POWER, }, { .name = "SSRXn2", .port = GPIOA, .pin = GPIO9, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRXp2", .port = GPIOC, .pin = GPIO9, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND-A12", .port = GPIOC, .pin = GPIO7, .type = USB_PIN_TYPE_GROUND, }, { .name = "GND-B12", .port = GPIOG, .pin = GPIO12, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSRXp1", .port = GPIOG, .pin = GPIO14, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRXn1", .port = GPIOG, .pin = GPIO10, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "VBUS-B9", .port = GPIOG, .pin = GPIO9, .type = USB_PIN_TYPE_POWER, }, { .name = "SBU2", .port = GPIOG, .pin = GPIO15, .type = USB_PIN_TYPE_OTHER, }, { .name = "Dn2", .port = GPIOD, .pin = GPIO7, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "Dp2", .port = GPIOD, .pin = GPIO6, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "CC2", .port = GPIOD, .pin = GPIO1, .type = USB_PIN_TYPE_IDENTIFICATION, }, { .name = "VBUS-B4", .port = GPIOD, .pin = GPIO5, .type = USB_PIN_TYPE_POWER, }, { .name = "SSTXn2", .port = GPIOD, .pin = GPIO4, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTXp2", .port = GPIOD, .pin = GPIO2, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND-B1", .port = GPIOD, .pin = GPIO3, .type = USB_PIN_TYPE_GROUND, }, }; /** USB type A connector (device) * @note type A should be a host side connector, but it is sometimes used on the device side, or to provide additional power on Y cables */ static const struct usb_pin_t usb_device_a_pins[] = { { .name = "shield", .port = GPIOB, .pin = GPIO3, .type = USB_PIN_TYPE_SHIELD, }, { .name = "VBUS", .port = GPIOE, .pin = GPIO3, .type = USB_PIN_TYPE_POWER, }, { .name = "D-", .port = GPIOE, .pin = GPIO1, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "D+", .port = GPIOB, .pin = GPIO9, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND", .port = GPIOB, .pin = GPIO5, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSRX-", .port = GPIOB, .pin = GPIO4, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRX+", .port = GPIOB, .pin = GPIO8, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND_DRAIN", .port = GPIOE, .pin = GPIO0, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSTX-", .port = GPIOC, .pin = GPIO13, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTX+", .port = GPIOE, .pin = GPIO2, .type = USB_PIN_TYPE_DIFFERENTIAL, }, }; /** USB type B connector (device side) */ static const struct usb_pin_t usb_device_b_pins[] = { { .name = "shield", .port = GPIOF, .pin = GPIO1, .type = USB_PIN_TYPE_SHIELD, }, { .name = "VBUS", .port = GPIOC, .pin = GPIO3, .type = USB_PIN_TYPE_POWER, }, { .name = "D-", .port = GPIOA, .pin = GPIO0, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "D+", .port = GPIOA, .pin = GPIO4, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND", .port = GPIOC, .pin = GPIO0, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSTX-", .port = GPIOA, .pin = GPIO2, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTX+", .port = GPIOA, .pin = GPIO1, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND_DRAIN", .port = GPIOF, .pin = GPIO6, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSRX-", .port = GPIOC, .pin = GPIO2, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRX+", .port = GPIOC, .pin = GPIO1, .type = USB_PIN_TYPE_DIFFERENTIAL, }, }; /** USB mini-B connector (device side) * @note this connector does not support USB 3.x */ static const struct usb_pin_t usb_device_minib_pins[] = { { .name = "shield", .port = GPIOC, .pin = GPIO14, .type = USB_PIN_TYPE_SHIELD, }, { .name = "VBUS", .port = GPIOE, .pin = GPIO4, .type = USB_PIN_TYPE_POWER, }, { .name = "D-", .port = GPIOE, .pin = GPIO5, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "D+", .port = GPIOE, .pin = GPIO6, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "ID", .port = GPIOF, .pin = GPIO0, .type = USB_PIN_TYPE_IDENTIFICATION, }, { .name = "GND", .port = GPIOC, .pin = GPIO15, .type = USB_PIN_TYPE_GROUND, }, }; /** USB micro-B connector (device side) */ static const struct usb_pin_t usb_device_microb_pins[] = { { .name = "shield", .port = GPIOD, .pin = GPIO12, .type = USB_PIN_TYPE_SHIELD, }, { .name = "VBUS", .port = GPIOD, .pin = GPIO11, .type = USB_PIN_TYPE_POWER, }, { .name = "D-", .port = GPIOD, .pin = GPIO10, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "D+", .port = GPIOD, .pin = GPIO9, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "ID", .port = GPIOD, .pin = GPIO8, .type = USB_PIN_TYPE_IDENTIFICATION, }, { .name = "GND", .port = GPIOB, .pin = GPIO15, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSTX-", .port = GPIOB, .pin = GPIO14, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTX+", .port = GPIOB, .pin = GPIO13, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND_DRAIN", .port = GPIOB, .pin = GPIO11, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSRX-", .port = GPIOB, .pin = GPIO10, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRX+", .port = GPIOB, .pin = GPIO12, .type = USB_PIN_TYPE_DIFFERENTIAL, }, }; /** USB-C connector ("device" side) */ static const struct usb_pin_t usb_device_c_pins[] = { { .name = "shield", .port = GPIOE, .pin = GPIO11, .type = USB_PIN_TYPE_SHIELD, }, { .name = "GND-A1", .port = GPIOF, .pin = GPIO13, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSTXp1", .port = GPIOF, .pin = GPIO12, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTXn1", .port = GPIOF, .pin = GPIO11, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "VBUS-A4", .port = GPIOB, .pin = GPIO2, .type = USB_PIN_TYPE_POWER, }, { .name = "CC1", .port = GPIOB, .pin = GPIO1, .type = USB_PIN_TYPE_IDENTIFICATION, }, { .name = "Dp1", .port = GPIOB, .pin = GPIO0, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "Dn1", .port = GPIOC, .pin = GPIO5, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SBU1", .port = GPIOC, .pin = GPIO4, .type = USB_PIN_TYPE_OTHER, }, { .name = "VBUS-A9", .port = GPIOA, .pin = GPIO7, .type = USB_PIN_TYPE_POWER, }, { .name = "SSRXn2", .port = GPIOA, .pin = GPIO6, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRXp2", .port = GPIOA, .pin = GPIO5, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND-A12", .port = GPIOA, .pin = GPIO3, .type = USB_PIN_TYPE_GROUND, }, { .name = "GND-B12", .port = GPIOE, .pin = GPIO10, .type = USB_PIN_TYPE_GROUND, }, { .name = "SSRXp1", .port = GPIOE, .pin = GPIO12, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSRXn1", .port = GPIOE, .pin = GPIO9, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "VBUS-B9", .port = GPIOE, .pin = GPIO8, .type = USB_PIN_TYPE_POWER, }, { .name = "SBU2", .port = GPIOE, .pin = GPIO13, .type = USB_PIN_TYPE_OTHER, }, { .name = "Dn2", .port = GPIOE, .pin = GPIO7, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "Dp2", .port = GPIOG, .pin = GPIO1, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "CC2", .port = GPIOE, .pin = GPIO14, .type = USB_PIN_TYPE_IDENTIFICATION, }, { .name = "VBUS-B4", .port = GPIOG, .pin = GPIO0, .type = USB_PIN_TYPE_POWER, }, { .name = "SSTXn2", .port = GPIOF, .pin = GPIO15, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "SSTXp2", .port = GPIOE, .pin = GPIO15, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "GND-B1", .port = GPIOF, .pin = GPIO14, .type = USB_PIN_TYPE_GROUND, }, }; /** Apple lightning connector (device side) * @note this is not strictly a USB connector */ static const struct usb_pin_t lighnting_device_pins[] = { { .name = "GND", .port = GPIOF, .pin = GPIO10, .type = USB_PIN_TYPE_GROUND, }, { .name = "L0p", .port = GPIOF, .pin = GPIO9, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "L0n", .port = GPIOF, .pin = GPIO8, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "ID0", .port = GPIOF, .pin = GPIO7, .type = USB_PIN_TYPE_IDENTIFICATION, }, { .name = "PWR", .port = GPIOF, .pin = GPIO5, .type = USB_PIN_TYPE_POWER, }, { .name = "L1n", .port = GPIOF, .pin = GPIO2, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "L1p", .port = GPIOF, .pin = GPIO3, .type = USB_PIN_TYPE_DIFFERENTIAL, }, { .name = "ID1", .port = GPIOF, .pin = GPIO4, .type = USB_PIN_TYPE_IDENTIFICATION, }, }; /** list of all connectors */ static const struct usb_connector_t usb_host_a_connector = { .name = "A", .host = true, .pins_nb = LENGTH(usb_host_a_pins), .pins = usb_host_a_pins, }; static const struct usb_connector_t usb_host_c_connector = { .name = "C", .host = true, .pins_nb = LENGTH(usb_host_c_pins), .pins = usb_host_c_pins, }; static const struct usb_connector_t usb_device_a_connector = { .name = "A", .host = false, .pins_nb = LENGTH(usb_device_a_pins), .pins = usb_device_a_pins, }; static const struct usb_connector_t usb_device_b_connector = { .name = "B", .host = false, .pins_nb = LENGTH(usb_device_b_pins), .pins = usb_device_b_pins, }; static const struct usb_connector_t usb_device_minib_connector = { .name = "mini-B", .host = false, .pins_nb = LENGTH(usb_device_minib_pins), .pins = usb_device_minib_pins, }; static const struct usb_connector_t usb_device_microb_connector = { .name = "micro-B", .host = false, .pins_nb = LENGTH(usb_device_microb_pins), .pins = usb_device_microb_pins, }; static const struct usb_connector_t usb_device_c_connector = { .name = "C", .host = false, .pins_nb = LENGTH(usb_device_c_pins), .pins = usb_device_c_pins, }; static const struct usb_connector_t lightning_device_connector = { .name = "lightning", .host = false, .pins_nb = LENGTH(lighnting_device_pins), .pins = lighnting_device_pins, }; const struct usb_connector_t* usb_connectors[] = { &usb_host_a_connector, &usb_host_c_connector, &usb_device_a_connector, &usb_device_b_connector, &usb_device_minib_connector, &usb_device_microb_connector, &usb_device_c_connector, &lightning_device_connector, }; /** USB cable definitions */ static const struct usb_connector_t* usb_a_a_connectors[] = { &usb_host_a_connector, &usb_device_a_connector, }; static const struct usb_pin_t* usb_a_a_power_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_a_pins[1]}, // VBUS {&usb_host_a_pins[4], &usb_device_a_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_a_usb2_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_a_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_a_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_a_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_a_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_a_usb2_shielded_pins[][2] = { {&usb_host_a_pins[0], &usb_device_a_pins[0]}, // shield {&usb_host_a_pins[1], &usb_device_a_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_a_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_a_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_a_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_a_usb3_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_a_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_a_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_a_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_a_pins[4]}, // GND {&usb_host_a_pins[5], &usb_device_a_pins[5]}, // SSRX-, SSTX- {&usb_host_a_pins[6], &usb_device_a_pins[6]}, // SSRX+, SSTX+ {&usb_host_a_pins[7], &usb_device_a_pins[7]}, // GND_DRAIN {&usb_host_a_pins[8], &usb_device_a_pins[8]}, // SSTX-, SSRX- {&usb_host_a_pins[9], &usb_device_a_pins[9]}, // SSTX+, SSRX+ }; static const struct usb_pin_t* usb_a_a_usb3_shielded_pins[][2] = { {&usb_host_a_pins[0], &usb_device_a_pins[0]}, // shield {&usb_host_a_pins[1], &usb_device_a_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_a_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_a_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_a_pins[4]}, // GND {&usb_host_a_pins[5], &usb_device_a_pins[5]}, // SSRX-, SSTX- {&usb_host_a_pins[6], &usb_device_a_pins[6]}, // SSRX+, SSTX+ {&usb_host_a_pins[7], &usb_device_a_pins[7]}, // GND_DRAIN {&usb_host_a_pins[8], &usb_device_a_pins[8]}, // SSTX-, SSRX- {&usb_host_a_pins[9], &usb_device_a_pins[9]}, // SSTX+, SSRX+ }; static const struct usb_connector_t* usb_a_host_b_connectors[] = { &usb_host_a_connector, &usb_device_b_connector, }; static const struct usb_pin_t* usb_a_host_b_power_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_host_a_pins[4], &usb_device_b_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_host_b_usb2_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_b_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_host_b_usb2_shielded_pins[][2] = { {&usb_host_a_pins[0], &usb_device_b_pins[0]}, // shield {&usb_host_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_b_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_host_b_usb3_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_b_pins[4]}, // GND {&usb_host_a_pins[5], &usb_device_b_pins[5]}, // SSRX-, SSTX- {&usb_host_a_pins[6], &usb_device_b_pins[6]}, // SSRX+, SSTX+ {&usb_host_a_pins[7], &usb_device_b_pins[7]}, // GND_DRAIN {&usb_host_a_pins[8], &usb_device_b_pins[8]}, // SSTX-, SSRX- {&usb_host_a_pins[9], &usb_device_b_pins[9]}, // SSTX+, SSRX+ }; static const struct usb_pin_t* usb_a_host_b_usb3_shielded_pins[][2] = { {&usb_host_a_pins[0], &usb_device_b_pins[0]}, // shield {&usb_host_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_b_pins[4]}, // GND {&usb_host_a_pins[5], &usb_device_b_pins[5]}, // SSRX-, SSTX- {&usb_host_a_pins[6], &usb_device_b_pins[6]}, // SSRX+, SSTX+ {&usb_host_a_pins[7], &usb_device_b_pins[7]}, // GND_DRAIN {&usb_host_a_pins[8], &usb_device_b_pins[8]}, // SSTX-, SSRX- {&usb_host_a_pins[9], &usb_device_b_pins[9]}, // SSTX+, SSRX+ }; static const struct usb_connector_t* usb_a_device_b_connectors[] = { &usb_device_a_connector, &usb_device_b_connector, }; static const struct usb_pin_t* usb_a_device_b_power_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_device_a_pins[4], &usb_device_b_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_device_b_usb2_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_b_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_device_b_usb2_shielded_pins[][2] = { {&usb_device_a_pins[0], &usb_device_b_pins[0]}, // shield {&usb_device_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_b_pins[4]}, // GND }; static const struct usb_pin_t* usb_a_device_b_usb3_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_b_pins[4]}, // GND {&usb_device_a_pins[5], &usb_device_b_pins[5]}, // SSRX-, SSTX- {&usb_device_a_pins[6], &usb_device_b_pins[6]}, // SSRX+, SSTX+ {&usb_device_a_pins[7], &usb_device_b_pins[7]}, // GND_DRAIN {&usb_device_a_pins[8], &usb_device_b_pins[8]}, // SSTX-, SSRX- {&usb_device_a_pins[9], &usb_device_b_pins[9]}, // SSTX+, SSRX+ }; static const struct usb_pin_t* usb_a_device_b_usb3_shielded_pins[][2] = { {&usb_device_a_pins[0], &usb_device_b_pins[0]}, // shield {&usb_device_a_pins[1], &usb_device_b_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_b_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_b_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_b_pins[4]}, // GND {&usb_device_a_pins[5], &usb_device_b_pins[5]}, // SSRX-, SSTX- {&usb_device_a_pins[6], &usb_device_b_pins[6]}, // SSRX+, SSTX+ {&usb_device_a_pins[7], &usb_device_b_pins[7]}, // GND_DRAIN {&usb_device_a_pins[8], &usb_device_b_pins[8]}, // SSTX-, SSRX- {&usb_device_a_pins[9], &usb_device_b_pins[9]}, // SSTX+, SSRX+ }; static const struct usb_connector_t* usb_a_host_minib_connectors[] = { &usb_host_a_connector, &usb_device_minib_connector, }; static const struct usb_pin_t* usb_a_host_minib_power_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_minib_pins[1]}, // VBUS {&usb_host_a_pins[4], &usb_device_minib_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_host_minib_usb2_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_minib_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_minib_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_minib_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_minib_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_host_minib_usb2_shielded_pins[][2] = { {&usb_host_a_pins[0], &usb_device_minib_pins[0]}, // shield {&usb_host_a_pins[1], &usb_device_minib_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_minib_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_minib_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_minib_pins[5]}, // GND }; static const struct usb_connector_t* usb_a_device_minib_connectors[] = { &usb_device_a_connector, &usb_device_minib_connector, }; static const struct usb_pin_t* usb_a_device_minib_power_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_minib_pins[1]}, // VBUS {&usb_device_a_pins[4], &usb_device_minib_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_device_minib_usb2_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_minib_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_minib_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_minib_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_minib_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_device_minib_usb2_shielded_pins[][2] = { {&usb_device_a_pins[0], &usb_device_minib_pins[0]}, // shield {&usb_device_a_pins[1], &usb_device_minib_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_minib_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_minib_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_minib_pins[5]}, // GND }; static const struct usb_connector_t* usb_a_host_microb_connectors[] = { &usb_host_a_connector, &usb_device_microb_connector, }; static const struct usb_pin_t* usb_a_host_microb_power_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_host_a_pins[4], &usb_device_microb_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_host_microb_usb2_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_microb_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_host_microb_usb2_shielded_pins[][2] = { {&usb_host_a_pins[0], &usb_device_microb_pins[0]}, // shield {&usb_host_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_microb_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_host_microb_usb3_unshielded_pins[][2] = { {&usb_host_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_microb_pins[5]}, // GND {&usb_host_a_pins[5], &usb_device_microb_pins[6]}, // SSRX-, SSTX- {&usb_host_a_pins[6], &usb_device_microb_pins[7]}, // SSRX+, SSTX+ {&usb_host_a_pins[7], &usb_device_microb_pins[8]}, // GND_DRAIN {&usb_host_a_pins[8], &usb_device_microb_pins[9]}, // SSTX-, SSRX- {&usb_host_a_pins[9], &usb_device_microb_pins[10]}, // SSTX+, SSRX+ }; static const struct usb_pin_t* usb_a_host_microb_usb3_shielded_pins[][2] = { {&usb_host_a_pins[0], &usb_device_microb_pins[0]}, // shield {&usb_host_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_host_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_host_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_host_a_pins[4], &usb_device_microb_pins[5]}, // GND {&usb_host_a_pins[5], &usb_device_microb_pins[6]}, // SSRX-, SSTX- {&usb_host_a_pins[6], &usb_device_microb_pins[7]}, // SSRX+, SSTX+ {&usb_host_a_pins[7], &usb_device_microb_pins[8]}, // GND_DRAIN {&usb_host_a_pins[8], &usb_device_microb_pins[9]}, // SSTX-, SSRX- {&usb_host_a_pins[9], &usb_device_microb_pins[10]}, // SSTX+, SSRX+ }; static const struct usb_connector_t* usb_a_device_microb_connectors[] = { &usb_device_a_connector, &usb_device_microb_connector, }; static const struct usb_pin_t* usb_a_device_microb_power_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_device_a_pins[4], &usb_device_microb_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_device_microb_usb2_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_microb_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_device_microb_usb2_shielded_pins[][2] = { {&usb_device_a_pins[0], &usb_device_microb_pins[0]}, // shield {&usb_device_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_microb_pins[5]}, // GND }; static const struct usb_pin_t* usb_a_device_microb_usb3_unshielded_pins[][2] = { {&usb_device_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_microb_pins[5]}, // GND {&usb_device_a_pins[5], &usb_device_microb_pins[6]}, // SSRX-, SSTX- {&usb_device_a_pins[6], &usb_device_microb_pins[7]}, // SSRX+, SSTX+ {&usb_device_a_pins[7], &usb_device_microb_pins[8]}, // GND_DRAIN {&usb_device_a_pins[8], &usb_device_microb_pins[9]}, // SSTX-, SSRX- {&usb_device_a_pins[9], &usb_device_microb_pins[10]}, // SSTX+, SSRX+ }; static const struct usb_pin_t* usb_a_device_microb_usb3_shielded_pins[][2] = { {&usb_device_a_pins[0], &usb_device_microb_pins[0]}, // shield {&usb_device_a_pins[1], &usb_device_microb_pins[1]}, // VBUS {&usb_device_a_pins[2], &usb_device_microb_pins[2]}, // D- {&usb_device_a_pins[3], &usb_device_microb_pins[3]}, // D+ {&usb_device_a_pins[4], &usb_device_microb_pins[5]}, // GND {&usb_device_a_pins[5], &usb_device_microb_pins[6]}, // SSRX-, SSTX- {&usb_device_a_pins[6], &usb_device_microb_pins[7]}, // SSRX+, SSTX+ {&usb_device_a_pins[7], &usb_device_microb_pins[8]}, // GND_DRAIN {&usb_device_a_pins[8], &usb_device_microb_pins[9]}, // SSTX-, SSRX- {&usb_device_a_pins[9], &usb_device_microb_pins[10]}, // SSTX+, SSRX+ }; static const struct usb_connector_t* usb_c_host_connectors[] = { &usb_host_c_connector, }; static const struct usb_pin_t* usb_c_host_shunt_pins[][2] = { {&usb_host_c_pins[1], &usb_host_c_pins[13]}, // A1 GND, B12 GND {&usb_host_c_pins[2], &usb_host_c_pins[14]}, // A2 SSTXp1, B11 SSRXp1 {&usb_host_c_pins[3], &usb_host_c_pins[15]}, // A3 SSTXn1, B10 SSRXn1 {&usb_host_c_pins[4], &usb_host_c_pins[16]}, // A4 VBUS, B9 VBUS {&usb_host_c_pins[5], &usb_host_c_pins[17]}, // A5 CC1, B8 SBU2 {&usb_host_c_pins[6], &usb_host_c_pins[18]}, // A6 Dp1, B7 Dn2 {&usb_host_c_pins[7], &usb_host_c_pins[19]}, // A7 Dn1, B6 Dp2 {&usb_host_c_pins[8], &usb_host_c_pins[20]}, // A8 SBU1, B5 CC2 {&usb_host_c_pins[9], &usb_host_c_pins[21]}, // A9 VBUS, B4 VBUS {&usb_host_c_pins[10], &usb_host_c_pins[22]}, // A10 SSRXn2, B3 SSTXn2 {&usb_host_c_pins[11], &usb_host_c_pins[23]}, // A11 SSRXp2, B2 SSTXp2 {&usb_host_c_pins[12], &usb_host_c_pins[24]}, // A12 GND, B1 GND }; static const struct usb_connector_t* usb_c_device_connectors[] = { &usb_device_c_connector, }; static const struct usb_pin_t* usb_c_device_shunt_pins[][2] = { {&usb_device_c_pins[1], &usb_device_c_pins[13]}, // A1 GND, B12 GND {&usb_device_c_pins[2], &usb_device_c_pins[14]}, // A2 SSTXp1, B11 SSRXp1 {&usb_device_c_pins[3], &usb_device_c_pins[15]}, // A3 SSTXn1, B10 SSRXn1 {&usb_device_c_pins[4], &usb_device_c_pins[16]}, // A4 VBUS, B9 VBUS {&usb_device_c_pins[5], &usb_device_c_pins[17]}, // A5 CC1, B8 SBU2 {&usb_device_c_pins[6], &usb_device_c_pins[18]}, // A6 Dp1, B7 Dn2 {&usb_device_c_pins[7], &usb_device_c_pins[19]}, // A7 Dn1, B6 Dp2 {&usb_device_c_pins[8], &usb_device_c_pins[20]}, // A8 SBU1, B5 CC2 {&usb_device_c_pins[9], &usb_device_c_pins[21]}, // A9 VBUS, B4 VBUS {&usb_device_c_pins[10], &usb_device_c_pins[22]}, // A10 SSRXn2, B3 SSTXn2 {&usb_device_c_pins[11], &usb_device_c_pins[23]}, // A11 SSRXp2, B2 SSTXp2 {&usb_device_c_pins[12], &usb_device_c_pins[24]}, // A12 GND, B1 GND }; const struct usb_cable_t usb_cables[] = { { .name = "A-A power only", .connectors_nb = LENGTH(usb_a_a_connectors), .connectors = usb_a_a_connectors, .pin_pairs_nb = LENGTH(usb_a_a_power_unshielded_pins), .pin_pairs = usb_a_a_power_unshielded_pins, }, { .name = "A-A 2.0 unshielded", .connectors_nb = LENGTH(usb_a_a_connectors), .connectors = usb_a_a_connectors, .pin_pairs_nb = LENGTH(usb_a_a_usb2_unshielded_pins), .pin_pairs = usb_a_a_usb2_unshielded_pins, }, { .name = "A-A 2.0 shielded", .connectors_nb = LENGTH(usb_a_a_connectors), .connectors = usb_a_a_connectors, .pin_pairs_nb = LENGTH(usb_a_a_usb2_shielded_pins), .pin_pairs = usb_a_a_usb2_shielded_pins, }, { .name = "A-A 3.0 unshielded", .connectors_nb = LENGTH(usb_a_a_connectors), .connectors = usb_a_a_connectors, .pin_pairs_nb = LENGTH(usb_a_a_usb3_unshielded_pins), .pin_pairs = usb_a_a_usb3_unshielded_pins, }, { .name = "A-A 3.0 shielded", .connectors_nb = LENGTH(usb_a_a_connectors), .connectors = usb_a_a_connectors, .pin_pairs_nb = LENGTH(usb_a_a_usb3_shielded_pins), .pin_pairs = usb_a_a_usb3_shielded_pins, }, { .name = "A-B power only", .connectors_nb = LENGTH(usb_a_host_b_connectors), .connectors = usb_a_host_b_connectors, .pin_pairs_nb = LENGTH(usb_a_host_b_power_unshielded_pins), .pin_pairs = usb_a_host_b_power_unshielded_pins, }, { .name = "A-B 2.0 unshielded", .connectors_nb = LENGTH(usb_a_host_b_connectors), .connectors = usb_a_host_b_connectors, .pin_pairs_nb = LENGTH(usb_a_host_b_usb2_unshielded_pins), .pin_pairs = usb_a_host_b_usb2_unshielded_pins, }, { .name = "A-B 2.0 shielded", .connectors_nb = LENGTH(usb_a_host_b_connectors), .connectors = usb_a_host_b_connectors, .pin_pairs_nb = LENGTH(usb_a_host_b_usb2_shielded_pins), .pin_pairs = usb_a_host_b_usb2_shielded_pins, }, { .name = "A-B 3.0 unshielded", .connectors_nb = LENGTH(usb_a_host_b_connectors), .connectors = usb_a_host_b_connectors, .pin_pairs_nb = LENGTH(usb_a_host_b_usb3_unshielded_pins), .pin_pairs = usb_a_host_b_usb3_unshielded_pins, }, { .name = "A-B 3.0 shielded", .connectors_nb = LENGTH(usb_a_host_b_connectors), .connectors = usb_a_host_b_connectors, .pin_pairs_nb = LENGTH(usb_a_host_b_usb3_shielded_pins), .pin_pairs = usb_a_host_b_usb3_shielded_pins, }, { .name = "A-B power only", .connectors_nb = LENGTH(usb_a_device_b_connectors), .connectors = usb_a_device_b_connectors, .pin_pairs_nb = LENGTH(usb_a_device_b_power_unshielded_pins), .pin_pairs = usb_a_device_b_power_unshielded_pins, }, { .name = "A-B 2.0 unshielded", .connectors_nb = LENGTH(usb_a_device_b_connectors), .connectors = usb_a_device_b_connectors, .pin_pairs_nb = LENGTH(usb_a_device_b_usb2_unshielded_pins), .pin_pairs = usb_a_device_b_usb2_unshielded_pins, }, { .name = "A-B 2.0 shielded", .connectors_nb = LENGTH(usb_a_device_b_connectors), .connectors = usb_a_device_b_connectors, .pin_pairs_nb = LENGTH(usb_a_device_b_usb2_shielded_pins), .pin_pairs = usb_a_device_b_usb2_shielded_pins, }, { .name = "A-B 3.0 unshielded", .connectors_nb = LENGTH(usb_a_device_b_connectors), .connectors = usb_a_device_b_connectors, .pin_pairs_nb = LENGTH(usb_a_device_b_usb3_unshielded_pins), .pin_pairs = usb_a_device_b_usb3_unshielded_pins, }, { .name = "A-B 3.0 shielded", .connectors_nb = LENGTH(usb_a_device_b_connectors), .connectors = usb_a_device_b_connectors, .pin_pairs_nb = LENGTH(usb_a_device_b_usb3_shielded_pins), .pin_pairs = usb_a_device_b_usb3_shielded_pins, }, { .name = "A-miniB power only", .connectors_nb = LENGTH(usb_a_host_minib_connectors), .connectors = usb_a_host_minib_connectors, .pin_pairs_nb = LENGTH(usb_a_host_minib_power_unshielded_pins), .pin_pairs = usb_a_host_minib_power_unshielded_pins, }, { .name = "A-miniB 2.0 unshielded", .connectors_nb = LENGTH(usb_a_host_minib_connectors), .connectors = usb_a_host_minib_connectors, .pin_pairs_nb = LENGTH(usb_a_host_minib_usb2_unshielded_pins), .pin_pairs = usb_a_host_minib_usb2_unshielded_pins, }, { .name = "A-miniB 2.0 shielded", .connectors_nb = LENGTH(usb_a_host_minib_connectors), .connectors = usb_a_host_minib_connectors, .pin_pairs_nb = LENGTH(usb_a_host_minib_usb2_shielded_pins), .pin_pairs = usb_a_host_minib_usb2_shielded_pins, }, { .name = "A-miniB power only", .connectors_nb = LENGTH(usb_a_device_minib_connectors), .connectors = usb_a_device_minib_connectors, .pin_pairs_nb = LENGTH(usb_a_device_minib_power_unshielded_pins), .pin_pairs = usb_a_device_minib_power_unshielded_pins, }, { .name = "A-miniB 2.0 unshielded", .connectors_nb = LENGTH(usb_a_device_minib_connectors), .connectors = usb_a_device_minib_connectors, .pin_pairs_nb = LENGTH(usb_a_device_minib_usb2_unshielded_pins), .pin_pairs = usb_a_device_minib_usb2_unshielded_pins, }, { .name = "A-miniB 2.0 shielded", .connectors_nb = LENGTH(usb_a_device_minib_connectors), .connectors = usb_a_device_minib_connectors, .pin_pairs_nb = LENGTH(usb_a_device_minib_usb2_shielded_pins), .pin_pairs = usb_a_device_minib_usb2_shielded_pins, }, { .name = "A-microB power only", .connectors_nb = LENGTH(usb_a_host_microb_connectors), .connectors = usb_a_host_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_host_microb_power_unshielded_pins), .pin_pairs = usb_a_host_microb_power_unshielded_pins, }, { .name = "A-microB 2.0 unshielded", .connectors_nb = LENGTH(usb_a_host_microb_connectors), .connectors = usb_a_host_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_host_microb_usb2_unshielded_pins), .pin_pairs = usb_a_host_microb_usb2_unshielded_pins, }, { .name = "A-microB 2.0 shielded", .connectors_nb = LENGTH(usb_a_host_microb_connectors), .connectors = usb_a_host_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_host_microb_usb2_shielded_pins), .pin_pairs = usb_a_host_microb_usb2_shielded_pins, }, { .name = "A-microB 3.0 unshielded", .connectors_nb = LENGTH(usb_a_host_microb_connectors), .connectors = usb_a_host_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_host_microb_usb3_unshielded_pins), .pin_pairs = usb_a_host_microb_usb3_unshielded_pins, }, { .name = "A-microB 3.0 shielded", .connectors_nb = LENGTH(usb_a_host_microb_connectors), .connectors = usb_a_host_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_host_microb_usb3_shielded_pins), .pin_pairs = usb_a_host_microb_usb3_shielded_pins, }, { .name = "A-microB power only", .connectors_nb = LENGTH(usb_a_device_microb_connectors), .connectors = usb_a_device_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_device_microb_power_unshielded_pins), .pin_pairs = usb_a_device_microb_power_unshielded_pins, }, { .name = "A-microB 2.0 unshielded", .connectors_nb = LENGTH(usb_a_device_microb_connectors), .connectors = usb_a_device_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_device_microb_usb2_unshielded_pins), .pin_pairs = usb_a_device_microb_usb2_unshielded_pins, }, { .name = "A-microB 2.0 shielded", .connectors_nb = LENGTH(usb_a_device_microb_connectors), .connectors = usb_a_device_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_device_microb_usb2_shielded_pins), .pin_pairs = usb_a_device_microb_usb2_shielded_pins, }, { .name = "A-microB 3.0 unshielded", .connectors_nb = LENGTH(usb_a_device_microb_connectors), .connectors = usb_a_device_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_device_microb_usb3_unshielded_pins), .pin_pairs = usb_a_device_microb_usb3_unshielded_pins, }, { .name = "A-microB 3.0 shielded", .connectors_nb = LENGTH(usb_a_device_microb_connectors), .connectors = usb_a_device_microb_connectors, .pin_pairs_nb = LENGTH(usb_a_device_microb_usb3_shielded_pins), .pin_pairs = usb_a_device_microb_usb3_shielded_pins, }, { .name = "C shunt", .connectors_nb = LENGTH(usb_c_host_connectors), .connectors = usb_c_host_connectors, .pin_pairs_nb = LENGTH(usb_c_host_shunt_pins), .pin_pairs = usb_c_host_shunt_pins, }, { .name = "C shunt", .connectors_nb = LENGTH(usb_c_device_connectors), .connectors = usb_c_device_connectors, .pin_pairs_nb = LENGTH(usb_c_device_shunt_pins), .pin_pairs = usb_c_device_shunt_pins, }, }; void usb_cables_pins_float(const struct usb_connector_t* connector) { // input argument check if (NULL == connector) { return; } for (uint8_t pin = 0; pin < connector->pins_nb; pin++) { // go through every pin gpio_set_mode(connector->pins[pin].port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, connector->pins[pin].pin); // put pin to floating } } void usb_cables_connectors_float(const struct usb_connector_t** connectors, uint8_t connectors_nb) { if (NULL == connectors || 0 == connectors_nb) { return; } for (uint8_t connector = 0; connector < connectors_nb; connector++) { // go through every connector usb_cables_pins_float(connectors[connector]); } } /** test if two pins are connected * @param[in] pin1_port GPIO port for first pin * @param[in] pin1_pin GPIO pin for first pin * @param[in] pin2_port GPIO port for first pin * @param[in] pin2_pin GPIO pin for first pin * @return if there is any kind of connection between the pins * @note setting both levels (high, low) in both directions (pin1 to pin2 and pin2 to pin1) is tested, except for ground pins * @warning this is prone to false positives */ static bool usb_cables_check_pins(const struct usb_pin_t* pin1, const struct usb_pin_t* pin2) { cm3_assert(pin1 && pin2); if (pin1->port == pin2->port && pin1->pin == pin2->pin) { // it's the same pin return true; } uint8_t connections = 0; // numbers of connection configurations gpio_set_mode(pin2->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, pin2->pin); // we will read from this pin gpio_set(pin2->port, pin2->pin); // pull up gpio_clear(pin1->port, pin1->pin); // drive low gpio_set_mode(pin1->port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, pin1->pin); // we will drive this pin sleep_us(100); // wait for GPIO/line to settle if (!gpio_get(pin1->port, pin1->pin) && !gpio_get(pin2->port, pin2->pin)) { // if they are at the same level it means pin2 was able to drive low the pulled up pin1, thus they are connected connections++; } if (USB_PIN_TYPE_GROUND != pin1->type) { // don't drive a ground pin high gpio_set_mode(pin2->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, pin2->pin); // we will read from this pin gpio_clear(pin2->port, pin2->pin); // pull down gpio_set(pin1->port, pin1->pin); // drive high gpio_set_mode(pin1->port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, pin1->pin); // we will drive this pin sleep_us(100); // wait for GPIO/line to settle if (gpio_get(pin1->port, pin1->pin) && gpio_get(pin2->port, pin2->pin)) { // if they are at the same level it means pin2 was able to drive high the pulled low pin1, thus they are connected connections++; } } gpio_set_mode(pin1->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, pin1->pin); // we will read from this pin gpio_set(pin1->port, pin1->pin); // pull up gpio_clear(pin2->port, pin2->pin); // drive low gpio_set_mode(pin2->port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, pin2->pin); // we will drive this pin sleep_us(100); // wait for GPIO/line to settle if (!gpio_get(pin1->port, pin1->pin) && !gpio_get(pin2->port, pin2->pin)) { // if they are at the same level it means pin1 was able to drive low the pulled up pin2, thus they are connected connections++; } if (USB_PIN_TYPE_GROUND != pin2->type) { gpio_set_mode(pin1->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, pin1->pin); // we will read from this pin gpio_clear(pin1->port, pin1->pin); // pull down gpio_set(pin2->port, pin2->pin); // drive high gpio_set_mode(pin2->port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, pin2->pin); // we will drive this pin sleep_us(100); // wait for GPIO/line to settle if (gpio_get(pin1->port, pin1->pin) && gpio_get(pin2->port, pin2->pin)) { // if they are at the same level it means pin1 was able to drive high the pulled low pin2, thus they are connected connections++; } } gpio_set_mode(pin1->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, pin1->pin); // put pin back to safe floating state gpio_set_mode(pin2->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, pin2->pin); // put pin back to safe floating state if (0 == connections) { return 0; // no connections } else if (4 == connections) { return 1; // full connection } else { return -connections; // partial connection } } void usb_cables_check_intra(const struct usb_connector_t* connector, bool* connected) { // verify input arguments if (NULL == connector) { return; } // initialize output results if (connected) { for (uint8_t pin = 0; connector->pins_nb; pin++) { connected[pin] = false; } } usb_cables_pins_float(connector); // ensure we start in a safe state for (uint8_t pin_from = 0; pin_from < connector->pins_nb; pin_from++) { // test from every pin for (uint8_t pin_to = 0; pin_to < connector->pins_nb; pin_to++) { // test to every pin (except itself) // don't check the same pins if (pin_to == pin_from) { continue; } // don't check if power and ground pins are connected because loads lead to false positives if ((USB_PIN_TYPE_GROUND == connector->pins[pin_from].type || USB_PIN_TYPE_SHIELD == connector->pins[pin_from].type) && USB_PIN_TYPE_POWER == connector->pins[pin_to].type) { continue; } if (USB_PIN_TYPE_POWER == connector->pins[pin_from].type && (USB_PIN_TYPE_GROUND == connector->pins[pin_to].type || USB_PIN_TYPE_SHIELD == connector->pins[pin_to].type)) { continue; } if (usb_cables_check_pins(&connector->pins[pin_from], &connector->pins[pin_to])) { if (connected) { connected[pin_from] = true; connected[pin_to] = true; } else { printf("%s (%s) %s connected to %s\n", connector->name, connector->host ? "host" : "device", connector->pins[pin_from].name, connector->pins[pin_to].name); } } } } usb_cables_pins_float(connector); // go back to safe state } void usb_cables_check_inter(const struct usb_connector_t** connectors, uint8_t connectors_nb, bool* connected) { // verify input arguments if (NULL == connectors || 0 == connectors_nb) { return; } // initialize output result if (connected) { for (uint8_t connector = 0; connector < connectors_nb; connector++) { connected[connector] = false; } } usb_cables_connectors_float(connectors, connectors_nb); // ensure we start in a safe state for (uint8_t connector_from = 0; connector_from < connectors_nb; connector_from++) { // test from every connector for (uint8_t pin_from = 0; pin_from < connectors[connector_from]->pins_nb; pin_from++) { // test from every pin for (uint8_t connector_to = connector_from + 1; connector_to < connectors_nb; connector_to++) { // test to every connector (except itself) if (connector_to == connector_from) { // don't test the connector itself since we already did this test continue; } if (connected && connected[connector_to]) { // we already found a connection to this connector continue; } for (uint8_t pin_to = 0; pin_to < connectors[connector_to]->pins_nb; pin_to++) { // test to every pin // don't check if power and ground pins are connected because loads lead to false positives if ((USB_PIN_TYPE_GROUND == connectors[connector_from]->pins[pin_from].type || USB_PIN_TYPE_SHIELD == connectors[connector_from]->pins[pin_from].type) && USB_PIN_TYPE_POWER == connectors[connector_to]->pins[pin_to].type) { continue; } if (USB_PIN_TYPE_POWER == connectors[connector_from]->pins[pin_from].type && (USB_PIN_TYPE_GROUND == connectors[connector_to]->pins[pin_to].type || USB_PIN_TYPE_SHIELD == connectors[connector_to]->pins[pin_to].type)) { continue; } // check if cable is connected if (usb_cables_check_pins(&connectors[connector_from]->pins[pin_from], &connectors[connector_to]->pins[pin_to])) { if (connected) { // remember they are connected connected[connector_from] = true; connected[connector_to] = true; } else { printf("%s (%s) %s connected to %s (%s) %s\n", connectors[connector_from]->name, connectors[connector_from]->host ? "host" : "device", connectors[connector_from]->pins[pin_from].name, connectors[connector_to]->name, connectors[connector_to]->host ? "host" : "device", connectors[connector_to]->pins[pin_to].name); } } } } } } usb_cables_connectors_float(connectors, connectors_nb); // go back to safe state } void usb_cables_check_ground(const struct usb_connector_t** connectors, uint8_t connectors_nb, bool* connected) { // verify input arguments if (NULL == connectors || 0 == connectors_nb) { return; } // initialize output result if (connected) { for (uint8_t connector = 0; connector < connectors_nb; connector++) { connected[connector] = false; } } // pull up all ground pins for (uint8_t connector = 0; connector < connectors_nb; connector++) { for (uint8_t pin = 0; pin < connectors[connector]->pins_nb; pin++) { if (USB_PIN_TYPE_GROUND == connectors[connector]->pins[pin].type) { uint32_t pin_port = connectors[connector]->pins[pin].port; uint16_t pin_pin = connectors[connector]->pins[pin].pin; gpio_set_mode(pin_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, pin_pin); gpio_set(pin_port, pin_pin); } } } bool ground_found = false; // if we found the ground connection for (uint8_t connector_from = 0; connector_from < connectors_nb && !ground_found; connector_from++) { // test from every connector for (uint8_t pin_from = 0; pin_from < connectors[connector_from]->pins_nb && !ground_found; pin_from++) { // test from every pin if (USB_PIN_TYPE_GROUND != connectors[connector_from]->pins[pin_from].type) { // only consider ground connections continue; } // set pin low uint32_t pin_from_port = connectors[connector_from]->pins[pin_from].port; uint16_t pin_from_pin = connectors[connector_from]->pins[pin_from].pin; gpio_set_mode(pin_from_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, pin_from_pin); gpio_clear(pin_from_port, pin_from_pin); for (uint8_t connector_to = connector_from + 1; connector_to < connectors_nb; connector_to++) { // test every next connector if (connected && connected[connector_to]) { // we already found a connection to this connector continue; } for (uint8_t pin_to = 0; pin_to < connectors[connector_to]->pins_nb; pin_to++) { // test to every pin if (USB_PIN_TYPE_GROUND != connectors[connector_to]->pins[pin_to].type) { // only consider ground connections continue; } uint32_t pin_to_port = connectors[connector_to]->pins[pin_to].port; uint16_t pin_to_pin = connectors[connector_to]->pins[pin_to].pin; if (0 == gpio_get(pin_to_port, pin_to_pin)) { // we found a ground interconnection if (connected) { // remember they are connected connected[connector_from] = true; connected[connector_to] = true; } else { printf("%s (%s) %s connected to %s (%s) %s\n", connectors[connector_from]->name, connectors[connector_from]->host ? "host" : "device", connectors[connector_from]->pins[pin_from].name, connectors[connector_to]->name, connectors[connector_to]->host ? "host" : "device", connectors[connector_to]->pins[pin_to].name); } ground_found = true; // remember we found a ground connection } } } // pull pin back up gpio_set_mode(pin_from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, pin_from_pin); gpio_set(pin_from_port, pin_from_pin); } } // put all ground pins back to float for (uint8_t connector = 0; connector < connectors_nb; connector++) { for (uint8_t pin = 0; pin < connectors[connector]->pins_nb; pin++) { if (USB_PIN_TYPE_GROUND == connectors[connector]->pins[pin].type) { uint32_t pin_port = connectors[connector]->pins[pin].port; uint16_t pin_pin = connectors[connector]->pins[pin].pin; gpio_set_mode(pin_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, pin_pin); } } } } bool usb_cables_check_load(const struct usb_connector_t* connector) { // verify input arguments if (NULL == connector) { return false; } usb_cables_pins_float(connector); // ensure we start with all pins floating to not influence the check bool loaded = false; // remember if we found a load // pull power pin low (works better than pushing high and being strong enough to have a pull down pulled high) for (uint8_t pin_power = 0; pin_power < connector->pins_nb && !loaded; pin_power++) { if (USB_PIN_TYPE_POWER != connector->pins[pin_power].type) { continue; } uint32_t pin_power_port = connector->pins[pin_power].port; uint16_t pin_power_pin = connector->pins[pin_power].pin; gpio_set_mode(pin_power_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, pin_power_pin); gpio_clear(pin_power_port, pin_power_pin); for (uint8_t pin_ground = 0; pin_ground < connector->pins_nb && !loaded; pin_ground++) { if (USB_PIN_TYPE_GROUND != connector->pins[pin_ground].type) { continue; } uint32_t pin_ground_port = connector->pins[pin_ground].port; uint16_t pin_ground_pin = connector->pins[pin_ground].pin; // briefly pull low to discharge gpio_set_mode(pin_ground_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, pin_ground_pin); gpio_set(pin_ground_port, pin_ground_pin); // check if it is pulled high by VBUS sleep_us(100); if (0 == gpio_get(pin_ground_port, pin_ground_pin)) { loaded = true; } } gpio_set_mode(pin_power_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, pin_power_pin); // put back to floating } return loaded; } bool usb_cables_check_cable(const struct usb_cable_t* usb_cable, uint8_t* defined, uint8_t* undefined, uint8_t* disconnected) { if (NULL == usb_cable) { return false; } uint8_t _defined = 0, _undefined = 0, _disconnected = 0; // internal pair counting variables usb_cables_connectors_float(usb_cable->connectors, usb_cable->connectors_nb); // ensure we start in a safe state for (uint8_t connector_from = 0; connector_from < usb_cable->connectors_nb; connector_from++) { // test from every connector for (uint8_t pin_from = 0; pin_from < usb_cable->connectors[connector_from]->pins_nb; pin_from++) { // test from every pin uint32_t from_port = usb_cable->connectors[connector_from]->pins[pin_from].port; uint32_t from_pin = usb_cable->connectors[connector_from]->pins[pin_from].pin; for (uint8_t connector_to = 0; connector_to < usb_cable->connectors_nb; connector_to++) { // test to every connector for (uint8_t pin_to = 0; pin_to < usb_cable->connectors[connector_to]->pins_nb; pin_to++) { // test to every pin (except itself) uint32_t to_port = usb_cable->connectors[connector_to]->pins[pin_to].port; uint32_t to_pin = usb_cable->connectors[connector_to]->pins[pin_to].pin; // don't check if the same pins are connected if (from_port == to_port && from_pin == to_pin) { continue; } // don't check if power and ground pins are connected because loads lead to false positives if ((USB_PIN_TYPE_GROUND == usb_cable->connectors[connector_from]->pins[pin_from].type || USB_PIN_TYPE_SHIELD == usb_cable->connectors[connector_from]->pins[pin_from].type) && USB_PIN_TYPE_POWER == usb_cable->connectors[connector_to]->pins[pin_to].type) { continue; } if (USB_PIN_TYPE_POWER == usb_cable->connectors[connector_from]->pins[pin_from].type && (USB_PIN_TYPE_GROUND == usb_cable->connectors[connector_to]->pins[pin_to].type || USB_PIN_TYPE_SHIELD == usb_cable->connectors[connector_to]->pins[pin_to].type)) { continue; } // figure out if this connection pair is defined bool pair_defined = false; for (uint8_t pair = 0; pair < usb_cable->pin_pairs_nb; pair++) { if (usb_cable->pin_pairs[pair][0]->port == from_port && usb_cable->pin_pairs[pair][0]->pin == from_pin && usb_cable->pin_pairs[pair][1]->port == to_port && usb_cable->pin_pairs[pair][1]->pin == to_pin) { pair_defined = true; } if (usb_cable->pin_pairs[pair][1]->port == from_port && usb_cable->pin_pairs[pair][1]->pin == from_pin && usb_cable->pin_pairs[pair][0]->port == to_port && usb_cable->pin_pairs[pair][0]->pin == to_pin) { pair_defined = true; } } if (usb_cables_check_pins(&usb_cable->connectors[connector_from]->pins[pin_from], &usb_cable->connectors[connector_to]->pins[pin_to])) { // the connection is fine if (pair_defined) { _defined++; } else { _undefined++; } } else { // there is no connection if (pair_defined) { _disconnected++; } } } } } } usb_cables_connectors_float(usb_cable->connectors, usb_cable->connectors_nb); // ensure we return to a safe state // copy variables if (defined) { *defined = _defined; } if (undefined) { *undefined = _undefined; } if (disconnected) { *disconnected = _disconnected; } return (0 == _undefined && 0 == _disconnected && usb_cable->pin_pairs_nb <= _defined); }