usb_cables: improve pin test and make it more simpler
This commit is contained in:
parent
7dd50762b8
commit
e84a481669
|
@ -1128,54 +1128,55 @@ static void command_cplug(void* argument)
|
|||
// check if plug is present in socket by checking if the GND pins are interconnected
|
||||
bool gnd_any = false;
|
||||
bool gnd_all = true;
|
||||
uint8_t gnd;
|
||||
bool gnd;
|
||||
gnd = usb_cables_test_pins(&usb_pins[connector->pins[1]], &usb_pins[connector->pins[12]]); // A1- A12 GND
|
||||
gnd_any |= (gnd >= 0x11);
|
||||
gnd_all &= (gnd >= 0x11);
|
||||
gnd_any |= gnd;
|
||||
gnd_all &= gnd;
|
||||
gnd = usb_cables_test_pins(&usb_pins[connector->pins[1]], &usb_pins[connector->pins[12 + 1]]); // A1- B1 GND
|
||||
gnd_any |= (gnd >= 0x11);
|
||||
gnd_all &= (gnd >= 0x11);
|
||||
gnd_any |= gnd;
|
||||
gnd_all &= gnd;
|
||||
gnd = usb_cables_test_pins(&usb_pins[connector->pins[1]], &usb_pins[connector->pins[12 + 12]]); // A1- B12 GND
|
||||
gnd_any |= (gnd >= 0x11);
|
||||
gnd_all &= (gnd >= 0x11);
|
||||
gnd_any |= gnd;
|
||||
gnd_all &= gnd;
|
||||
gnd = usb_cables_test_pins(&usb_pins[connector->pins[12]], &usb_pins[connector->pins[12 + 1]]); // A12 - B1 GND
|
||||
gnd_any |= (gnd >= 0x11);
|
||||
gnd_all &= (gnd >= 0x11);
|
||||
gnd_any |= gnd;
|
||||
gnd_all &= gnd;
|
||||
gnd = usb_cables_test_pins(&usb_pins[connector->pins[12]], &usb_pins[connector->pins[12 + 12]]); // A12 - B12 GND
|
||||
gnd_any |= (gnd >= 0x11);
|
||||
gnd_all &= (gnd >= 0x11);
|
||||
gnd_any |= gnd;
|
||||
gnd_all &= gnd;
|
||||
gnd = usb_cables_test_pins(&usb_pins[connector->pins[12 + 1]], &usb_pins[connector->pins[12 + 12]]); // B1- B12 GND
|
||||
gnd_any |= (gnd >= 0x11);
|
||||
gnd_all &= (gnd >= 0x11);
|
||||
gnd_any |= gnd;
|
||||
gnd_all &= gnd;
|
||||
printf("- %s GND pins interconnected\n", gnd_all ? "all" : (gnd_any ? "some" : "no"));
|
||||
// check if plug is present in socket by checking if the VBUS pins are interconnected
|
||||
bool vbus_any = false;
|
||||
bool vbus_all = true;
|
||||
uint8_t vbus;
|
||||
bool vbus;
|
||||
vbus = usb_cables_test_pins(&usb_pins[connector->pins[4]], &usb_pins[connector->pins[9]]); // A4- A9 VBUS
|
||||
vbus_any |= (vbus >= 0x44);
|
||||
vbus_all &= (vbus >= 0x44);
|
||||
vbus_any |= vbus;
|
||||
vbus_all &= vbus;
|
||||
vbus = usb_cables_test_pins(&usb_pins[connector->pins[4]], &usb_pins[connector->pins[12 + 4]]); // A4- B4 VBUS
|
||||
vbus_any |= (vbus >= 0x44);
|
||||
vbus_all &= (vbus >= 0x44);
|
||||
vbus_any |= vbus;
|
||||
vbus_all &= vbus;
|
||||
vbus = usb_cables_test_pins(&usb_pins[connector->pins[4]], &usb_pins[connector->pins[12 + 9]]); // A4- B9 VBUS
|
||||
vbus_any |= (vbus >= 0x44);
|
||||
vbus_all &= (vbus >= 0x44);
|
||||
vbus_any |= vbus;
|
||||
vbus_all &= vbus;
|
||||
vbus = usb_cables_test_pins(&usb_pins[connector->pins[9]], &usb_pins[connector->pins[12 + 4]]); // A9 - B4 VBUS
|
||||
vbus_any |= (vbus >= 0x44);
|
||||
vbus_all &= (vbus >= 0x44);
|
||||
vbus_any |= vbus;
|
||||
vbus_all &= vbus;
|
||||
vbus = usb_cables_test_pins(&usb_pins[connector->pins[9]], &usb_pins[connector->pins[12 + 9]]); // A9 - B9 VBUS
|
||||
vbus_any |= (vbus >= 0x44);
|
||||
vbus_all &= (vbus >= 0x44);
|
||||
vbus_any |= vbus;
|
||||
vbus_all &= vbus;
|
||||
vbus = usb_cables_test_pins(&usb_pins[connector->pins[12 + 4]], &usb_pins[connector->pins[12 + 9]]); // B4- B9 VBUS
|
||||
vbus_any |= (vbus >= 0x44);
|
||||
vbus_all &= (vbus >= 0x44);
|
||||
vbus_any |= vbus;
|
||||
vbus_all &= vbus;
|
||||
printf("- %s VBUS pins interconnected\n", vbus_all ? "all" : (vbus_any ? "some" : "no"));
|
||||
// check if it is a powered cable (VCONN is connected to ground by Ra), or connected to sink
|
||||
uint8_t cc1 = usb_cables_test_pins(&usb_pins[connector->pins[5]], &usb_pins[connector->pins[12 + 1]]); // A5 CC1 - A1 GND
|
||||
printf("- CC1 %sconnected to GND (%02x)\n", (cc1 >= 0x21) ? "" : "not ", cc1);
|
||||
uint8_t cc2 = usb_cables_test_pins(&usb_pins[connector->pins[12 + 5]], &usb_pins[connector->pins[12 + 1]]); // B5 CC1 - A1 GND
|
||||
printf("- CC2 %sconnected to GND (%02x)\n", (cc2 >= 0x21) ? "" : "not ", cc2);
|
||||
bool cc1 = usb_cables_test_pins(&usb_pins[connector->pins[5]], &usb_pins[connector->pins[12 + 1]]); // A5 CC1 - A1 GND
|
||||
printf("- CC1 %sconnected to GND\n", cc1 ? "" : "not ");
|
||||
bool cc2 = usb_cables_test_pins(&usb_pins[connector->pins[12 + 5]], &usb_pins[connector->pins[12 + 1]]); // B5 CC1 - A1 GND
|
||||
printf("- CC2 %sconnected to GND\n", cc2 ? "" : "not ");
|
||||
/*
|
||||
if (cc1 >= 0x41) {
|
||||
puts("- this is a powered cable (CC1 is VCONN)\n");
|
||||
} else if (cc1 >= 0x21) {
|
||||
|
@ -1191,12 +1192,13 @@ static void command_cplug(void* argument)
|
|||
} else {
|
||||
puts("- there is no plug/cable\n");
|
||||
}
|
||||
*/
|
||||
// check if it should be connected to a source
|
||||
cc1 = usb_cables_test_pins(&usb_pins[connector->pins[5]], &usb_pins[connector->pins[4]]); // A5 CC1 - A4 VBUS
|
||||
printf("- CC1 %sconnected to VBUS (%02x)\n", (cc1 >= 0x22) ? "" : "not ", cc1);
|
||||
printf("- CC1 %sconnected to VBUS\n", cc1 ? "" : "not ");
|
||||
cc2 = usb_cables_test_pins(&usb_pins[connector->pins[12 + 5]], &usb_pins[connector->pins[4]]); // B5 CC1 - A1 VBUS
|
||||
printf("- CC2 %sconnected to VBUS (%02x)\n", (cc2 >= 0x22) ? "" : "not ", cc2);
|
||||
if (cc1 >= 0x22 || cc2 >= 0x22) {
|
||||
printf("- CC2 %sconnected to VBUS\n", cc2 ? "" : "not ");
|
||||
if (cc1 || cc2) {
|
||||
puts("- this cable is to be connected to a source on the other end (A plug)\n");
|
||||
}
|
||||
}
|
||||
|
@ -1208,15 +1210,15 @@ static void command_cplug(void* argument)
|
|||
return;
|
||||
}
|
||||
puts("cable interconnection\n");
|
||||
uint8_t conn;
|
||||
bool conn;
|
||||
conn = usb_cables_test_pins(&usb_pins[c1->pins[5]], &usb_pins[c2->pins[5]]); // A5 CC1 - A5 CC1
|
||||
printf("- CC1 %sconnected to CC1 (%02x)\n", (conn >= 0x22) ? "" : "not ", conn);
|
||||
printf("- CC1 %sconnected to CC1\n", conn ? "" : "not ");
|
||||
conn = usb_cables_test_pins(&usb_pins[c1->pins[5]], &usb_pins[c2->pins[12 + 5]]); // A5 CC1 - B5 CC2
|
||||
printf("- CC1 %sconnected to CC2 (%02x)\n", (conn >= 0x22) ? "" : "not ", conn);
|
||||
printf("- CC1 %sconnected to CC2\n", conn ? "" : "not ");
|
||||
conn = usb_cables_test_pins(&usb_pins[c1->pins[12 + 5]], &usb_pins[c2->pins[5]]); // B5 CC2 - A5 CC1
|
||||
printf("- CC2 %sconnected to CC1 (%02x)\n", (conn >= 0x22) ? "" : "not ", conn);
|
||||
printf("- CC2 %sconnected to CC1\n", conn ? "" : "not ");
|
||||
conn = usb_cables_test_pins(&usb_pins[c1->pins[12 + 5]], &usb_pins[c2->pins[12 + 5]]); // B5 CC2 - B5 CC2
|
||||
printf("- CC2 %sconnected to CC2 (%02x)\n", (conn >= 0x22) ? "" : "not ", conn);
|
||||
printf("- CC2 %sconnected to CC2\n", conn ? "" : "not ");
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
@ -1602,7 +1604,7 @@ void main(void)
|
|||
|
||||
uint16_t cable_message_i = 0; // the message index of the last cable message to be displayed
|
||||
uint32_t cable_message_t = last_connect_time; // the time stamp of the last message update
|
||||
|
||||
interactive = true;
|
||||
while (true) { // infinite loop
|
||||
iwdg_reset(); // kick the dog
|
||||
if (user_input_available) { // user input is available
|
||||
|
|
181
usb_cables.c
181
usb_cables.c
|
@ -4994,78 +4994,159 @@ const struct usb_connector_t* usb_cables_get_connector(uint8_t pin)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t usb_cables_test_pins(const struct usb_pin_t* pin1, const struct usb_pin_t* pin2)
|
||||
bool usb_cables_test_pins(const struct usb_pin_t* pin1, const struct usb_pin_t* pin2)
|
||||
{
|
||||
cm3_assert(pin1 && pin2);
|
||||
cm3_assert(pin1);
|
||||
cm3_assert(pin2);
|
||||
|
||||
if (pin1->port == pin2->port && pin1->pin == pin2->pin) { // it's the same pin
|
||||
return 0xff; // all connections will work
|
||||
return true; // all connections will work
|
||||
}
|
||||
|
||||
uint8_t connection = 0; // the connection result to return
|
||||
for (int8_t mode = 3; mode >= 0; mode--) { // test all connection types (from most to least accurate)
|
||||
/** how the connection is tested */
|
||||
enum connection_test_e {
|
||||
/** the output side is driven using pull/push, the input is pulled up/down
|
||||
* @note this will detect direct connections, when nothing is could be powered
|
||||
* @note there is no false positive, just false negatives when resistors are in line
|
||||
*/
|
||||
CONNECTION_TEST_DRIVE_PULL,
|
||||
/** the output side is driven using pull/push, the input is floating
|
||||
* @note this can also detect connections with inline resistors, since no pull-up/down will form a voltage divider
|
||||
* @note prone to noise since one side is floating
|
||||
*/
|
||||
CONNECTION_TEST_DRIVE_FLOAT,
|
||||
/** the output side is driven using pull up/down, the input is floating
|
||||
* @note this is similar to CONNECTION_TEST_DRIVE_FLOAT method, but meant for ground pins, which should not be driven.
|
||||
* @note since only a weak pull-up/down resistor is used, inline resistor will lead to voltage divider and possible false negatives
|
||||
*/
|
||||
CONNECTION_TEST_PULL_FLOAT,
|
||||
/** number of connections test */
|
||||
CONNECTION_TEST_COUNT,
|
||||
};
|
||||
|
||||
// the connection details
|
||||
struct usb_connection_t _connection = {
|
||||
.tx_pull_float = false,
|
||||
.tx_drive_float = false,
|
||||
.tx_drive_pull = false,
|
||||
.rx_pull_float = false,
|
||||
.rx_drive_float = false,
|
||||
.rx_drive_pull = false,
|
||||
};
|
||||
|
||||
for (enum connection_test_e connection_test = 0; connection_test < CONNECTION_TEST_COUNT; connection_test++) { // test all connection types (from most to least accurate)
|
||||
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);
|
||||
const struct usb_pin_t* pin_from = (0 == direction ? pin1 : pin2);
|
||||
const struct usb_pin_t* pin_to = (0 == direction ? pin2 : pin1);
|
||||
const uint32_t from_port = pin_from->port;
|
||||
const uint16_t from_pin = pin_from->pin;
|
||||
const uint32_t to_port = pin_to->port;
|
||||
const uint16_t to_pin = pin_to->pin;
|
||||
// don't drive a ground or shield pin high (shield might be connected to ground)
|
||||
if (((0 == direction && (USB_PIN_TYPE_GROUND == pin2->type || USB_PIN_TYPE_SHIELD == pin2->type)) || \
|
||||
(1 == direction && (USB_PIN_TYPE_GROUND == pin1->type || USB_PIN_TYPE_SHIELD == pin1->type))) && \
|
||||
(USB_PIN_CONNECTION_DRIVE_FLOAT == (1 << mode) || USB_PIN_CONNECTION_DRIVE_PULL == (1 << mode))) {
|
||||
if ((USB_PIN_TYPE_GROUND == pin_from->type || USB_PIN_TYPE_SHIELD == pin_from->type) && \
|
||||
(CONNECTION_TEST_DRIVE_PULL == connection_test || CONNECTION_TEST_DRIVE_FLOAT == connection_test)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// set pin mode
|
||||
switch ((1 << mode)) {
|
||||
case USB_PIN_CONNECTION_DRIVE_FLOAT:
|
||||
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 USB_PIN_CONNECTION_PULL_FLOAT:
|
||||
// set pin mode for sending pin
|
||||
switch (connection_test) {
|
||||
case CONNECTION_TEST_PULL_FLOAT:
|
||||
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;
|
||||
case USB_PIN_CONNECTION_DRIVE_PULL:
|
||||
case CONNECTION_TEST_DRIVE_PULL:
|
||||
case CONNECTION_TEST_DRIVE_FLOAT:
|
||||
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;
|
||||
default:
|
||||
continue; // unknown mode
|
||||
break;
|
||||
}
|
||||
// test pattern
|
||||
// note: the pattern length, and pauses between toggles are purely found out through testing
|
||||
// cross talk, noise, and capacitance are a pain to correctly get rid off
|
||||
// the result is not perfect, but often checking both directions eliminates false positives
|
||||
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;
|
||||
}
|
||||
for (uint8_t pattern = 0; pattern < 6 && connected; pattern++) { // the pattern is just a sequence on high/low
|
||||
// set alternatively high and low on one pin, and check level on the other pin
|
||||
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, to_pin); // first pull to remove capacitance
|
||||
if (0 == pattern % 2) { // test if high level is detected
|
||||
gpio_clear(to_port, to_pin); // pull down
|
||||
gpio_set(from_port, from_pin); // set high
|
||||
} else { // test if low level is detected
|
||||
gpio_set(to_port, to_pin); // pull up
|
||||
gpio_clear(from_port, from_pin); // set low
|
||||
}
|
||||
if (USB_PIN_TYPE_POWER == pin_from->type) {
|
||||
sleep_us(1000); // wait to cancel capacitance (10 nF, as used on VBUS in C plug)
|
||||
} 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;
|
||||
}
|
||||
sleep_us(10); // wait to settle
|
||||
}
|
||||
switch (connection_test) { // get to float (capacitance should be canceled)
|
||||
case CONNECTION_TEST_DRIVE_FLOAT:
|
||||
case CONNECTION_TEST_PULL_FLOAT:
|
||||
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sleep_us(10); // wait for signal to settle
|
||||
if ((0 == pattern % 2) && (0 == gpio_get(to_port, to_pin))) { // high level not detected
|
||||
connected = false;
|
||||
} else if ((pattern % 2) && gpio_get(to_port, to_pin)) { // low level not detected
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
if (connected) {
|
||||
connection |= (1 << (mode + direction * 4));
|
||||
// test connection result
|
||||
if (0 == direction) {
|
||||
switch (connection_test) {
|
||||
case CONNECTION_TEST_PULL_FLOAT:
|
||||
_connection.tx_pull_float = connected;
|
||||
break;
|
||||
case CONNECTION_TEST_DRIVE_FLOAT:
|
||||
_connection.tx_drive_float = connected;
|
||||
break;
|
||||
case CONNECTION_TEST_DRIVE_PULL:
|
||||
_connection.tx_drive_pull = connected;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (connection_test) {
|
||||
case CONNECTION_TEST_PULL_FLOAT:
|
||||
_connection.rx_pull_float = connected;
|
||||
break;
|
||||
case CONNECTION_TEST_DRIVE_FLOAT:
|
||||
_connection.rx_drive_float = connected;
|
||||
break;
|
||||
case CONNECTION_TEST_DRIVE_PULL:
|
||||
_connection.rx_drive_pull = connected;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((connection & (1 << (mode + 0))) && (connection & (1 << (mode + 4)))) { // more accurate connection showed, no need to continue with least accurate test
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // direction
|
||||
} // connection_test
|
||||
|
||||
// put back to floating
|
||||
gpio_set_mode(pin1->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, pin1->pin);
|
||||
gpio_set_mode(pin2->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, pin2->pin);
|
||||
|
||||
return connection;
|
||||
// summarize connection
|
||||
bool connected = true;
|
||||
if (USB_PIN_TYPE_GROUND == pin1->type || USB_PIN_TYPE_SHIELD == pin1->type) {
|
||||
connected &= _connection.tx_pull_float;
|
||||
} else { // not a ground pin
|
||||
connected &= _connection.tx_drive_float | _connection.tx_drive_pull;
|
||||
}
|
||||
if (USB_PIN_TYPE_GROUND == pin2->type || USB_PIN_TYPE_SHIELD == pin2->type) {
|
||||
connected &= _connection.rx_pull_float;
|
||||
} else { // not a ground pin
|
||||
connected &= _connection.rx_drive_float | _connection.rx_drive_pull;
|
||||
}
|
||||
|
||||
return connected;
|
||||
}
|
||||
|
||||
bool usb_cables_test_ground(const struct usb_connector_t** connectors, uint8_t connectors_nb, bool* connected)
|
||||
|
@ -5236,8 +5317,8 @@ bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, ui
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t connection = usb_cables_test_pins(usb_pin_from, usb_pin_to);
|
||||
if (connection >= 0x22) {
|
||||
const bool connection = usb_cables_test_pins(usb_pin_from, usb_pin_to);
|
||||
if (connection) {
|
||||
if (pair_defined) {
|
||||
_defined++;
|
||||
} else if (pair_optional) {
|
||||
|
@ -5292,7 +5373,7 @@ uint8_t** usb_cables_test_connections(const struct usb_connector_t** connectors,
|
|||
continue;
|
||||
}
|
||||
for (uint8_t pin_from_i = 0; pin_from_i < connector_from->pins_nb; pin_from_i++) { // test from every pin
|
||||
uint8_t pin_from = connector_from->pins[pin_from_i]; // get pin
|
||||
const uint8_t pin_from = connector_from->pins[pin_from_i]; // get pin
|
||||
if (pin_from >= LENGTH(usb_pins)) { // check pin
|
||||
continue;
|
||||
}
|
||||
|
@ -5309,7 +5390,7 @@ uint8_t** usb_cables_test_connections(const struct usb_connector_t** connectors,
|
|||
continue;
|
||||
}
|
||||
for (uint8_t pin_to_i = 0; pin_to_i < connector_to->pins_nb; pin_to_i++) { // test to every pin
|
||||
uint8_t pin_to = connector_to->pins[pin_to_i]; // get pin
|
||||
const uint8_t pin_to = connector_to->pins[pin_to_i]; // get pin
|
||||
const struct usb_pin_t* usb_pin_to = &usb_pins[pin_to]; // get to pin
|
||||
if (pin_to >= LENGTH(usb_pins)) { // check pin
|
||||
continue;
|
||||
|
@ -5335,8 +5416,8 @@ uint8_t** usb_cables_test_connections(const struct usb_connector_t** connectors,
|
|||
}
|
||||
|
||||
// test connection
|
||||
uint8_t connection = usb_cables_test_pins(usb_pin_from, usb_pin_to);
|
||||
if (connection >= 0x22) {
|
||||
const bool connected = usb_cables_test_pins(usb_pin_from, usb_pin_to);
|
||||
if (connected) {
|
||||
if (UINT16_MAX == (*connections_nb)) { // we already found the maximum of connections
|
||||
return (uint8_t**)connections;
|
||||
}
|
||||
|
|
51
usb_cables.h
51
usb_cables.h
|
@ -22,21 +22,49 @@
|
|||
enum usb_pin_type_e {
|
||||
USB_PIN_TYPE_UNDEFINED, /*< the default type, undefined */
|
||||
USB_PIN_TYPE_GROUND, /*< ground (including ground drain) */
|
||||
USB_PIN_TYPE_POWER, /*< power (VBUS) */
|
||||
USB_PIN_TYPE_POWER, /*< power (VBUS, VCONN) */
|
||||
USB_PIN_TYPE_SHIELD, /*< shield */
|
||||
USB_PIN_TYPE_DIFFERENTIAL, /*< differential data pairs (D+/-, SSTX+/-, SSRX+/-) */
|
||||
USB_PIN_TYPE_IDENTIFICATION, /*< pin to identify type (often connected to power or ground through resistor) */
|
||||
USB_PIN_TYPE_OTHER, /*< any other type */
|
||||
};
|
||||
|
||||
/** the type of connection between two pins
|
||||
* @note to be used as bit mask
|
||||
* @note ordered from least most most reliable/accurate
|
||||
*/
|
||||
enum usb_pin_connection_e {
|
||||
USB_PIN_CONNECTION_DRIVE_FLOAT = (1 << 0), /*< the output side is driven using pull/push, the input is floating */
|
||||
USB_PIN_CONNECTION_PULL_FLOAT = (1 << 1), /*< the output side is driven using pull up/down, the input is floating */
|
||||
USB_PIN_CONNECTION_DRIVE_PULL = (1 << 2), /*< the output side is driven using pull/push, the input is pulled up/down */
|
||||
/** the type of connection between two pins */
|
||||
struct usb_connection_t {
|
||||
/** pin1 is driven using pull up/down, pin2 is floating, set if a pattern set on pin1 is received on pin2
|
||||
* @note this method is similar to tx_drive_float, but meant for ground pins, which should not be driven.
|
||||
* @note prone to false negative when there is an inline resistor (which forms a voltage divider)
|
||||
* @note this might not be set (e.g. tested) if tx_drive_float or tx_drive_pull are set
|
||||
*/
|
||||
bool tx_pull_float;
|
||||
/** pin1 is driven using push/pull, pin2 is floating, set if a pattern set on pin1 is received on pin2
|
||||
* @note this can also detect connections with inline resistors, since no pull-up/down will form a voltage divider
|
||||
* @note prone to false positive since pin2 is floating
|
||||
* @note this might not be set (e.g. tested) tx_drive_pull is set
|
||||
*/
|
||||
bool tx_drive_float;
|
||||
/** pin1 is driven using push/pull, pin2 is pulled up/down, set if a pattern set on pin1 is received on pin1
|
||||
* @note this will detect direct connections, when nothing is could be powered
|
||||
* @note prone to false negative when there is an inline resistor (which forms a voltage divider)
|
||||
*/
|
||||
bool tx_drive_pull;
|
||||
/** pin2 is driven using pull up/down, pin1 is floating, set if a pattern set on pin2 is received on pin1
|
||||
* @note this method is similar to tx_drive_float, but meant for ground pins, which should not be driven.
|
||||
* @note prone to false negative when there is an inline resistor (which forms a voltage divider)
|
||||
* @note this might not be set (e.g. tested) if tx_drive_float or tx_drive_pull are set
|
||||
*/
|
||||
bool rx_pull_float;
|
||||
/** pin2 is driven using push/pull, pin1 is floating, set if a pattern set on pin2 is received on pin1
|
||||
* @note this can also detect connections with inline resistors, since no pull-up/down will form a voltage divider
|
||||
* @note prone to false positive since pin1 is floating
|
||||
* @note this might not be set (e.g. tested) tx_drive_pull is set
|
||||
*/
|
||||
bool rx_drive_float;
|
||||
/** pin2 is driven using push/pull, pin1 is pulled up/down, set if a pattern set on pin2 is received on pin1
|
||||
* @note this will detect direct connections, when nothing is could be powered
|
||||
* @note prone to false negative when there is an inline resistor (which forms a voltage divider)
|
||||
*/
|
||||
bool rx_drive_pull;
|
||||
};
|
||||
|
||||
/** USB pin definition */
|
||||
|
@ -196,10 +224,9 @@ const struct usb_connector_t* usb_cables_get_connector(uint8_t pin);
|
|||
/** test if two pins are connected
|
||||
* @param[in] pin1 first pin
|
||||
* @param[in] pin2 second pin
|
||||
* @return first nibble corresponds to the connection types (usb_pin_connection_e) from pin1 to pin2, second nibble from pin2 to pin1
|
||||
* @note setting both levels (high, low) in both directions (pin1 to pin2 and pin2 to pin1) are tested, except for ground pins
|
||||
* @return if the two pins are connected
|
||||
*/
|
||||
uint8_t usb_cables_test_pins(const struct usb_pin_t* pin1, const struct usb_pin_t* pin2);
|
||||
bool usb_cables_test_pins(const struct usb_pin_t* pin1, const struct usb_pin_t* pin2);
|
||||
/** test connectors for connections between ground pins of the connectors
|
||||
* @param[in] connectors connectors to test
|
||||
* @param[in] connectors_nb numbers of connectors
|
||||
|
|
Loading…
Reference in New Issue