2019-11-19 18:42:19 +01:00
/* 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/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 ,
} ,
{
. name = " VBUS " ,
. port = GPIOC ,
. pin = GPIO12 ,
} ,
{
. name = " D- " ,
. port = GPIOA ,
. pin = GPIO15 ,
} ,
{
. name = " D+ " ,
. port = GPIOG ,
. pin = GPIO6 ,
} ,
{
. name = " GND " ,
. port = GPIOG ,
. pin = GPIO2 ,
} ,
{
. name = " SSRX− " ,
. port = GPIOC ,
. pin = GPIO11 ,
} ,
{
. name = " SSRX+ " ,
. port = GPIOC ,
. pin = GPIO10 ,
} ,
{
. name = " GND_DRAIN " ,
. port = GPIOG ,
. pin = GPIO8 ,
} ,
{
. name = " SSTX- " ,
. port = GPIOG ,
. pin = GPIO4 ,
} ,
{
. name = " SSTX+ " ,
. port = GPIOD ,
. pin = GPIO14 ,
} ,
} ;
/** USB-C connector ("host" side) */
static const struct usb_pin_t usb_host_c_pins [ ] = {
{
. name = " shield " ,
. port = GPIOG ,
. pin = GPIO13 ,
} ,
{
. name = " GND-A1 " ,
. port = GPIOD ,
. pin = GPIO15 ,
} ,
{
. name = " SSTX+1 " ,
. port = GPIOG ,
. pin = GPIO3 ,
} ,
{
. name = " SSTX-1 " ,
. port = GPIOG ,
. pin = GPIO5 ,
} ,
{
. name = " VBUS-A4 " ,
. port = GPIOG ,
. pin = GPIO7 ,
} ,
{
. name = " CC1 " ,
. port = GPIOC ,
. pin = GPIO6 ,
} ,
{
. name = " D+1 " ,
. port = GPIOC ,
. pin = GPIO8 ,
} ,
{
. name = " D-1 " ,
. port = GPIOA ,
. pin = GPIO8 ,
} ,
{
. name = " SBU1 " ,
. port = GPIOA ,
. pin = GPIO10 ,
} ,
{
. name = " VBUS-A9 " ,
. port = GPIOG ,
. pin = GPIO11 ,
} ,
{
. name = " SSRX-2 " ,
. port = GPIOA ,
. pin = GPIO9 ,
} ,
{
. name = " SSRX+2 " ,
. port = GPIOC ,
. pin = GPIO9 ,
} ,
{
. name = " GND-A12 " ,
. port = GPIOC ,
. pin = GPIO7 ,
} ,
{
. name = " GND-B12 " ,
. port = GPIOG ,
. pin = GPIO12 ,
} ,
{
. name = " SSRX+1 " ,
. port = GPIOG ,
. pin = GPIO14 ,
} ,
{
. name = " SSRX-1 " ,
. port = GPIOG ,
. pin = GPIO10 ,
} ,
{
. name = " VBUS-B9 " ,
. port = GPIOG ,
. pin = GPIO9 ,
} ,
{
. name = " SBU2 " ,
. port = GPIOG ,
. pin = GPIO15 ,
} ,
{
. name = " D-2 " ,
. port = GPIOD ,
. pin = GPIO6 ,
} ,
{
. name = " D+2 " ,
. port = GPIOD ,
. pin = GPIO7 ,
} ,
{
. name = " CC2 " ,
. port = GPIOD ,
. pin = GPIO1 ,
} ,
{
. name = " VBUS-B4 " ,
. port = GPIOD ,
. pin = GPIO5 ,
} ,
{
. name = " SSTX-2 " ,
. port = GPIOD ,
. pin = GPIO4 ,
} ,
{
. name = " SSTX+2 " ,
. port = GPIOD ,
. pin = GPIO2 ,
} ,
{
. name = " GND-B1 " ,
. port = GPIOD ,
. pin = GPIO3 ,
} ,
} ;
/** 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 ,
} ,
{
. name = " VBUS " ,
. port = GPIOE ,
. pin = GPIO3 ,
} ,
{
. name = " D- " ,
. port = GPIOE ,
. pin = GPIO1 ,
} ,
{
. name = " D+ " ,
. port = GPIOB ,
. pin = GPIO9 ,
} ,
{
. name = " GND " ,
. port = GPIOB ,
. pin = GPIO5 ,
} ,
{
. name = " SSRX− " ,
. port = GPIOE ,
. pin = GPIO2 ,
} ,
{
. name = " SSRX+ " ,
. port = GPIOC ,
. pin = GPIO13 ,
} ,
{
. name = " GND_DRAIN " ,
. port = GPIOE ,
. pin = GPIO0 ,
} ,
{
. name = " SSTX- " ,
. port = GPIOB ,
. pin = GPIO8 ,
} ,
{
. name = " SSTX+ " ,
. port = GPIOB ,
. pin = GPIO4 ,
} ,
} ;
/** USB type B connector (device side) */
static const struct usb_pin_t usb_device_b_pins [ ] = {
{
. name = " shield " ,
. port = GPIOF ,
. pin = GPIO1 ,
} ,
{
. name = " VBUS " ,
. port = GPIOC ,
. pin = GPIO3 ,
} ,
{
. name = " D- " ,
. port = GPIOA ,
. pin = GPIO0 ,
} ,
{
. name = " D+ " ,
. port = GPIOA ,
. pin = GPIO4 ,
} ,
{
. name = " GND " ,
. port = GPIOC ,
. pin = GPIO0 ,
} ,
{
. name = " SSTX− " ,
. port = GPIOA ,
. pin = GPIO2 ,
} ,
{
. name = " SSTX+ " ,
. port = GPIOA ,
. pin = GPIO1 ,
} ,
{
. name = " GND_DRAIN " ,
. port = GPIOF ,
. pin = GPIO6 ,
} ,
{
. name = " SSRX- " ,
. port = GPIOC ,
. pin = GPIO2 ,
} ,
{
. name = " SSRX+ " ,
. port = GPIOC ,
. pin = GPIO1 ,
} ,
} ;
/** 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 ,
} ,
{
. name = " VBUS " ,
. port = GPIOE ,
. pin = GPIO4 ,
} ,
{
. name = " D- " ,
. port = GPIOE ,
. pin = GPIO5 ,
} ,
{
. name = " D+ " ,
. port = GPIOE ,
. pin = GPIO5 ,
} ,
{
. name = " ID " ,
. port = GPIOF ,
. pin = GPIO0 ,
} ,
{
. name = " GND " ,
. port = GPIOC ,
. pin = GPIO15 ,
} ,
} ;
/** USB micro-B connector (device side) */
static const struct usb_pin_t usb_device_microb_pins [ ] = {
{
. name = " shield " ,
. port = GPIOD ,
. pin = GPIO12 ,
} ,
{
. name = " VBUS " ,
. port = GPIOD ,
. pin = GPIO11 ,
} ,
{
. name = " D- " ,
. port = GPIOD ,
. pin = GPIO10 ,
} ,
{
. name = " D+ " ,
. port = GPIOD ,
. pin = GPIO9 ,
} ,
{
. name = " ID " ,
. port = GPIOD ,
. pin = GPIO8 ,
} ,
{
. name = " GND " ,
. port = GPIOB ,
. pin = GPIO15 ,
} ,
{
. name = " SSTX− " ,
. port = GPIOB ,
. pin = GPIO14 ,
} ,
{
. name = " SSTX+ " ,
. port = GPIOB ,
. pin = GPIO13 ,
} ,
{
. name = " GND_DRAIN " ,
. port = GPIOB ,
. pin = GPIO11 ,
} ,
{
. name = " SSRX- " ,
. port = GPIOB ,
. pin = GPIO10 ,
} ,
{
. name = " SSRX+ " ,
. port = GPIOB ,
. pin = GPIO12 ,
} ,
} ;
/** USB-C connector ("device" side) */
static const struct usb_pin_t usb_device_c_pins [ ] = {
{
. name = " shield " ,
. port = GPIOE ,
. pin = GPIO11 ,
} ,
{
. name = " GND-A1 " ,
. port = GPIOF ,
. pin = GPIO13 ,
} ,
{
. name = " SSTX+1 " ,
. port = GPIOF ,
. pin = GPIO12 ,
} ,
{
. name = " SSTX-1 " ,
. port = GPIOF ,
. pin = GPIO11 ,
} ,
{
. name = " VBUS-A4 " ,
. port = GPIOB ,
. pin = GPIO2 ,
} ,
{
. name = " CC1 " ,
. port = GPIOB ,
. pin = GPIO1 ,
} ,
{
. name = " D+1 " ,
. port = GPIOB ,
. pin = GPIO0 ,
} ,
{
. name = " D-1 " ,
. port = GPIOC ,
. pin = GPIO5 ,
} ,
{
. name = " SBU1 " ,
. port = GPIOC ,
. pin = GPIO4 ,
} ,
{
. name = " VBUS-A9 " ,
. port = GPIOA ,
. pin = GPIO7 ,
} ,
{
. name = " SSRX-2 " ,
. port = GPIOA ,
. pin = GPIO6 ,
} ,
{
. name = " SSRX+2 " ,
. port = GPIOA ,
. pin = GPIO5 ,
} ,
{
. name = " GND-A12 " ,
. port = GPIOA ,
. pin = GPIO3 ,
} ,
{
. name = " GND-B12 " ,
. port = GPIOE ,
. pin = GPIO10 ,
} ,
{
. name = " SSRX+1 " ,
. port = GPIOE ,
. pin = GPIO12 ,
} ,
{
. name = " SSRX-1 " ,
. port = GPIOE ,
. pin = GPIO9 ,
} ,
{
. name = " VBUS-B9 " ,
. port = GPIOE ,
. pin = GPIO8 ,
} ,
{
. name = " SBU2 " ,
. port = GPIOE ,
. pin = GPIO13 ,
} ,
{
. name = " D-2 " ,
. port = GPIOG ,
. pin = GPIO1 ,
} ,
{
. name = " D+2 " ,
. port = GPIOE ,
. pin = GPIO7 ,
} ,
{
. name = " CC2 " ,
. port = GPIOE ,
. pin = GPIO14 ,
} ,
{
. name = " VBUS-B4 " ,
. port = GPIOG ,
. pin = GPIO0 ,
} ,
{
. name = " SSTX-2 " ,
. port = GPIOF ,
. pin = GPIO15 ,
} ,
{
. name = " SSTX+2 " ,
. port = GPIOE ,
. pin = GPIO15 ,
} ,
{
. name = " GND-B1 " ,
. port = GPIOF ,
. pin = GPIO14 ,
} ,
} ;
/** 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 ,
} ,
{
. name = " L0p " ,
. port = GPIOF ,
. pin = GPIO9 ,
} ,
{
. name = " L0n " ,
. port = GPIOF ,
. pin = GPIO8 ,
} ,
{
. name = " ID0 " ,
. port = GPIOF ,
. pin = GPIO7 ,
} ,
{
. name = " PWR " ,
. port = GPIOF ,
. pin = GPIO5 ,
} ,
{
. name = " L1n " ,
. port = GPIOF ,
. pin = GPIO2 ,
} ,
{
. name = " L1p " ,
. port = GPIOF ,
. pin = GPIO3 ,
} ,
{
. name = " ID1 " ,
. port = GPIOF ,
. pin = GPIO4 ,
} ,
} ;
/** 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 ,
} ;
2019-11-20 03:22:32 +01:00
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 ,
2019-11-19 18:42:19 +01:00
} ;
/** USB cable definitions */
2019-11-20 03:22:32 +01:00
static const struct usb_connector_t * usb_a_a_connectors [ ] = {
& usb_host_a_connector ,
& usb_device_a_connector ,
2019-11-19 18:42:19 +01:00
} ;
2019-11-20 03:22:32 +01:00
static const struct usb_pin_t * usb_a_a_power_unshielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 1 ] , & usb_device_a_pins [ 1 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_a_pins [ 4 ] } ,
2019-11-19 18:42:19 +01:00
} ;
2019-11-20 03:22:32 +01:00
static const struct usb_pin_t * usb_a_a_usb2_unshielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 1 ] , & usb_device_a_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_a_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_a_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_a_pins [ 4 ] } ,
2019-11-19 18:42:19 +01:00
} ;
2019-11-20 03:22:32 +01:00
static const struct usb_pin_t * usb_a_a_usb2_shielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 0 ] , & usb_device_a_pins [ 0 ] } ,
{ & usb_host_a_pins [ 1 ] , & usb_device_a_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_a_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_a_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_a_pins [ 4 ] } ,
} ;
static const struct usb_pin_t * usb_a_a_usb3_unshielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 1 ] , & usb_device_a_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_a_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_a_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_a_pins [ 4 ] } ,
{ & usb_host_a_pins [ 5 ] , & usb_device_a_pins [ 5 ] } ,
{ & usb_host_a_pins [ 6 ] , & usb_device_a_pins [ 6 ] } ,
{ & usb_host_a_pins [ 7 ] , & usb_device_a_pins [ 7 ] } ,
{ & usb_host_a_pins [ 8 ] , & usb_device_a_pins [ 8 ] } ,
{ & usb_host_a_pins [ 9 ] , & usb_device_a_pins [ 9 ] } ,
} ;
static const struct usb_pin_t * usb_a_a_usb3_shielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 0 ] , & usb_device_a_pins [ 0 ] } ,
{ & usb_host_a_pins [ 1 ] , & usb_device_a_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_a_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_a_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_a_pins [ 4 ] } ,
{ & usb_host_a_pins [ 5 ] , & usb_device_a_pins [ 5 ] } ,
{ & usb_host_a_pins [ 6 ] , & usb_device_a_pins [ 6 ] } ,
{ & usb_host_a_pins [ 7 ] , & usb_device_a_pins [ 7 ] } ,
{ & usb_host_a_pins [ 8 ] , & usb_device_a_pins [ 8 ] } ,
{ & usb_host_a_pins [ 9 ] , & usb_device_a_pins [ 9 ] } ,
} ;
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 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_b_pins [ 4 ] } ,
} ;
static const struct usb_pin_t * usb_a_host_b_usb2_unshielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 1 ] , & usb_device_b_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_b_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_b_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_b_pins [ 4 ] } ,
} ;
static const struct usb_pin_t * usb_a_host_b_usb2_shielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 0 ] , & usb_device_b_pins [ 0 ] } ,
{ & usb_host_a_pins [ 1 ] , & usb_device_b_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_b_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_b_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_b_pins [ 4 ] } ,
} ;
static const struct usb_pin_t * usb_a_host_b_usb3_unshielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 1 ] , & usb_device_b_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_b_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_b_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_b_pins [ 4 ] } ,
{ & usb_host_a_pins [ 5 ] , & usb_device_b_pins [ 5 ] } ,
{ & usb_host_a_pins [ 6 ] , & usb_device_b_pins [ 6 ] } ,
{ & usb_host_a_pins [ 7 ] , & usb_device_b_pins [ 7 ] } ,
{ & usb_host_a_pins [ 8 ] , & usb_device_b_pins [ 8 ] } ,
{ & usb_host_a_pins [ 9 ] , & usb_device_b_pins [ 9 ] } ,
} ;
static const struct usb_pin_t * usb_a_host_b_usb3_shielded_pins [ ] [ 2 ] = {
{ & usb_host_a_pins [ 0 ] , & usb_device_b_pins [ 0 ] } ,
{ & usb_host_a_pins [ 1 ] , & usb_device_b_pins [ 1 ] } ,
{ & usb_host_a_pins [ 2 ] , & usb_device_b_pins [ 2 ] } ,
{ & usb_host_a_pins [ 3 ] , & usb_device_b_pins [ 3 ] } ,
{ & usb_host_a_pins [ 4 ] , & usb_device_b_pins [ 4 ] } ,
{ & usb_host_a_pins [ 5 ] , & usb_device_b_pins [ 5 ] } ,
{ & usb_host_a_pins [ 6 ] , & usb_device_b_pins [ 6 ] } ,
{ & usb_host_a_pins [ 7 ] , & usb_device_b_pins [ 7 ] } ,
{ & usb_host_a_pins [ 8 ] , & usb_device_b_pins [ 8 ] } ,
{ & usb_host_a_pins [ 9 ] , & usb_device_b_pins [ 9 ] } ,
2019-11-19 18:42:19 +01:00
} ;
const struct usb_cable_t usb_cables [ ] = {
{
. name = " A-A power only " ,
2019-11-20 03:22:32 +01:00
. connectors_nb = LENGTH ( usb_a_a_connectors ) ,
. connectors = usb_a_a_connectors ,
2019-11-19 18:42:19 +01:00
. pin_pairs_nb = LENGTH ( usb_a_a_power_unshielded_pins ) ,
. pin_pairs = usb_a_a_power_unshielded_pins ,
} ,
{
2019-11-20 03:22:32 +01:00
. name = " A-A 2.0 unshielded " ,
. connectors_nb = LENGTH ( usb_a_a_connectors ) ,
. connectors = usb_a_a_connectors ,
2019-11-19 18:42:19 +01:00
. pin_pairs_nb = LENGTH ( usb_a_a_usb2_unshielded_pins ) ,
. pin_pairs = usb_a_a_usb2_unshielded_pins ,
} ,
2019-11-20 03:22:32 +01:00
{
. 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 ,
} ,
2019-11-19 18:42:19 +01:00
} ;
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
}
}
2019-11-20 03:22:32 +01:00
void usb_cables_connectors_float ( const struct usb_connector_t * * connectors , uint8_t connectors_nb )
2019-11-19 18:42:19 +01:00
{
if ( NULL = = connectors | | 0 = = connectors_nb ) {
return ;
}
for ( uint8_t connector = 0 ; connector < connectors_nb ; connector + + ) { // go through every connector
2019-11-20 03:22:32 +01:00
usb_cables_pins_float ( connectors [ connector ] ) ;
2019-11-19 18:42:19 +01:00
}
}
2019-11-19 20:15:55 +01:00
/** 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 0 if the pins are not connected , > 0 if they are , < 0 if connection is not complete or bidirectional
* @ note setting both levels ( high , low ) in both directions ( pin1 to pin2 and pin2 to pin1 ) is tested
*/
static int8_t usb_cables_check_pins ( uint32_t pin1_port , uint16_t pin1_pin , uint32_t pin2_port , uint16_t pin2_pin )
{
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
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 + + ;
}
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
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
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 + + ;
}
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
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
}
}
2019-11-20 00:24:46 +01:00
void usb_cables_check_intra ( const struct usb_connector_t * connector , bool * connected )
2019-11-19 18:42:19 +01:00
{
2019-11-20 00:24:46 +01:00
// verify input arguments
2019-11-19 18:42:19 +01:00
if ( NULL = = connector ) {
return ;
}
2019-11-20 00:24:46 +01:00
// initialize output results
if ( connected ) {
for ( uint8_t pin = 0 ; connector - > pins_nb ; pin + + ) {
connected [ pin ] = false ;
}
}
2019-11-19 18:42:19 +01:00
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)
if ( pin_to = = pin_from ) {
continue ;
}
2019-11-19 20:15:55 +01:00
int8_t connections = usb_cables_check_pins ( connector - > pins [ pin_from ] . port , connector - > pins [ pin_from ] . pin , connector - > pins [ pin_to ] . port , connector - > pins [ pin_to ] . pin ) ;
if ( connections > 0 ) {
2019-11-20 00:24:46 +01:00
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 ) ;
}
2019-11-19 20:15:55 +01:00
} else if ( connections < 0 ) {
2019-11-20 00:24:46 +01:00
if ( ! connected ) {
printf ( " %s (%s) %s partially connected to %s (%d) \n " , connector - > name , connector - > host ? " host " : " device " , connector - > pins [ pin_from ] . name , connector - > pins [ pin_to ] . name , connections ) ;
}
2019-11-19 18:42:19 +01:00
}
}
}
usb_cables_pins_float ( connector ) ; // go back to safe state
}
2019-11-20 03:22:32 +01:00
void usb_cables_check_inter ( const struct usb_connector_t * * connectors , uint8_t connectors_nb , bool * connected )
2019-11-19 18:42:19 +01:00
{
2019-11-20 00:24:46 +01:00
// verify input arguments
2019-11-19 18:42:19 +01:00
if ( NULL = = connectors | | 0 = = connectors_nb ) {
return ;
}
2019-11-20 00:24:46 +01:00
// initialize output result
if ( connected ) {
for ( uint8_t connector = 0 ; connector < connectors_nb ; connector + + ) {
connected [ connector ] = false ;
}
}
2019-11-19 18:42:19 +01:00
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
2019-11-20 03:22:32 +01:00
for ( uint8_t pin_from = 0 ; pin_from < connectors [ connector_from ] - > pins_nb ; pin_from + + ) { // test from every pin
2019-11-19 18:42:19 +01:00
for ( uint8_t connector_to = 0 ; 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 ;
}
2019-11-20 03:22:32 +01:00
for ( uint8_t pin_to = 0 ; pin_to < connectors [ connector_to ] - > pins_nb ; pin_to + + ) { // test to every pin
int8_t connections = usb_cables_check_pins ( connectors [ connector_from ] - > pins [ pin_from ] . port , connectors [ connector_from ] - > pins [ pin_from ] . pin , connectors [ connector_to ] - > pins [ pin_to ] . port , connectors [ connector_to ] - > pins [ pin_to ] . pin ) ;
2019-11-19 20:15:55 +01:00
if ( connections > 0 ) {
2019-11-20 00:24:46 +01:00
if ( connected ) { // remember they are connected
connected [ connector_from ] = true ;
connected [ connector_to ] = true ;
} else {
2019-11-20 03:22:32 +01:00
printf ( " %s (%s) %s connected to %s (%s) %s \n " , connectors [ connector_from ] - > name , connectors [ connector_from ] - > host ? " host " : " device " , connectors [ connector_to ] - > pins [ pin_from ] . name , connectors [ connector_to ] - > name , connectors [ connector_to ] - > host ? " host " : " device " , connectors [ connector_to ] - > pins [ pin_to ] . name ) ;
2019-11-20 00:24:46 +01:00
}
2019-11-19 20:15:55 +01:00
} else if ( connections < 0 ) {
2019-11-20 00:24:46 +01:00
if ( ! connected ) {
2019-11-20 03:22:32 +01:00
printf ( " %s (%s) %s partially connected to %s (%s) %s (%u) \n " , connectors [ connector_from ] - > name , connectors [ connector_from ] - > host ? " host " : " device " , connectors [ connector_to ] - > pins [ pin_from ] . name , connectors [ connector_to ] - > name , connectors [ connector_to ] - > host ? " host " : " device " , connectors [ connector_to ] - > pins [ pin_to ] . name , connections ) ;
2019-11-20 00:24:46 +01:00
}
2019-11-19 18:42:19 +01:00
}
}
}
}
}
usb_cables_connectors_float ( connectors , connectors_nb ) ; // go back to safe state
}
bool usb_cables_check_cable ( const struct usb_cable_t * usb_cable , uint8_t * defined , uint8_t * undefined , uint8_t * disconnected , uint8_t * error )
{
* defined = 0 ;
* undefined = 0 ;
* disconnected = 0 ;
* error = 0 ;
if ( NULL = = usb_cable ) {
return false ;
}
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
2019-11-20 03:22:32 +01:00
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 ;
2019-11-19 18:42:19 +01:00
for ( uint8_t connector_to = 0 ; connector_to < usb_cable - > connectors_nb ; connector_to + + ) { // test to every connector
2019-11-20 03:22:32 +01:00
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 ;
2019-11-19 18:42:19 +01:00
if ( from_port = = to_port & & from_pin = = to_pin ) {
continue ;
}
2019-11-19 20:15:55 +01:00
int8_t connections = usb_cables_check_pins ( from_port , from_pin , to_port , to_pin ) ;
2019-11-19 18:42:19 +01:00
// figure out if this connection pair is defined
bool pair_defined = false ;
for ( uint8_t pair = 0 ; pair < usb_cable - > pin_pairs_nb ; pair + + ) {
2019-11-20 03:22:32 +01:00
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 ) {
2019-11-19 18:42:19 +01:00
pair_defined = true ;
}
2019-11-20 03:22:32 +01:00
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 ) {
2019-11-19 18:42:19 +01:00
pair_defined = true ;
}
}
2019-11-19 20:15:55 +01:00
if ( connections > 0 ) { // the connection is fine
2019-11-19 18:42:19 +01:00
if ( pair_defined ) {
( * defined ) + + ;
} else {
( * undefined ) + + ;
}
} else if ( 0 = = connections ) { // there is no connection
if ( pair_defined ) {
( * disconnected ) + + ;
}
} else { // there is an error in the connection
( * error ) + + ;
}
}
}
}
}
usb_cables_connectors_float ( usb_cable - > connectors , usb_cable - > connectors_nb ) ; // ensure we return to a safe state
2019-11-19 21:28:31 +01:00
return ( 0 = = * undefined & & 0 = = * disconnected & & 0 = = * error & & usb_cable - > pin_pairs_nb < = * defined ) ;
2019-11-19 18:42:19 +01:00
}