stm32f1/usb_cables.c

1716 lines
52 KiB
C

/* 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 <http://www.gnu.org/licenses/>.
*
*/
/** USB cable definitions and utilities
* @file
* @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2019
*/
/* standard libraries */
#include <stdint.h> // standard integer types
#include <string.h> // string utilities
/* STM32 (including CM3) libraries */
#include <libopencmsis/core_cm3.h> // Cortex M3 utilities
#include <libopencm3/cm3/assert.h> // assert definitions
#include <libopencm3/stm32/gpio.h> // 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]);
}
}
uint8_t 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 0xff; // all connections will work
}
uint8_t connection = 0; // the connection result to return
for (uint8_t direction = 0; direction < 2; direction++) { // test both directions
uint32_t from_port = (0 == direction ? pin2->port : pin1->port);
uint16_t from_pin = (0 == direction ? pin2->pin : pin1->pin);
uint32_t to_port = (0 == direction ? pin1->port : pin2->port);
uint16_t to_pin = (0 == direction ? pin1->pin : pin2->pin);
for (uint8_t mode = 0; mode < 3; mode++) { // test all connection types
// don't drive a ground pin high
if (((0 == direction && USB_PIN_TYPE_GROUND == pin2->type) || (1 == direction && USB_PIN_TYPE_GROUND == pin1->type)) && (0 == mode || 1 == mode)) {
continue;
}
// set pin mode
switch (mode) {
case 0:
gpio_set_mode(from_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, from_pin);
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin);
break;
case 1:
gpio_set_mode(from_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, from_pin);
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, to_pin);
break;
case 2:
gpio_set_mode(from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, from_pin);
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin);
break;
default:
break;
}
// test pattern
bool connected = true;
for (uint8_t pattern = 0; pattern < 8 && connected; pattern++) {
if (0 == pattern % 2) {
gpio_clear(from_port, from_pin);
gpio_set(to_port, to_pin);
sleep_us(25); // wait for GPIO/line to settle
if (gpio_get(to_port, to_pin)) {
connected = false;
}
} else {
gpio_set(from_port, from_pin);
gpio_clear(to_port, to_pin);
sleep_us(25); // wait for GPIO/line to settle
if (0 == gpio_get(to_port, to_pin)) {
connected = false;
}
}
}
if (connected) {
connection |= ((1 << mode) << (direction * 4));
}
}
// put back to floating
gpio_set_mode(from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, from_pin);
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin);
}
return 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;
}
uint8_t connection = usb_cables_check_pins(&connector->pins[pin_from], &connector->pins[pin_to]);
if (connection >= 0x44) {
if (connected) {
connected[pin_from] = true;
connected[pin_to] = true;
} else {
printf("%s (%s) %s connected to %s (%02x)\n", connector->name, connector->host ? "host" : "device", connector->pins[pin_from].name, connector->pins[pin_to].name, connection);
}
}
}
}
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
uint8_t connection = usb_cables_check_pins(&connectors[connector_from]->pins[pin_from], &connectors[connector_to]->pins[pin_to]);
if (connection >= 0x44) {
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;
}
}
uint8_t connection = usb_cables_check_pins(&usb_cable->connectors[connector_from]->pins[pin_from], &usb_cable->connectors[connector_to]->pins[pin_to]);
if (connection >= 0x44) {
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);
}