usb_cables: add and use common method to test connection between two pins
This commit is contained in:
parent
99515e579f
commit
84035eaca7
135
usb_cables.c
135
usb_cables.c
|
@ -727,6 +727,67 @@ void usb_cables_connectors_float(const struct usb_connector_t* connectors, uint8
|
|||
}
|
||||
}
|
||||
|
||||
/** 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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void usb_cables_check_intra(const struct usb_connector_t* connector)
|
||||
{
|
||||
// input argument check
|
||||
|
@ -736,25 +797,17 @@ void usb_cables_check_intra(const struct usb_connector_t* connector)
|
|||
|
||||
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
|
||||
gpio_set_mode(connector->pins[pin_from].port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, connector->pins[pin_from].pin); // we will drive the from 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;
|
||||
}
|
||||
gpio_set_mode(connector->pins[pin_to].port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, connector->pins[pin_to].pin); // we will read every to pin
|
||||
gpio_set(connector->pins[pin_to].port, connector->pins[pin_to].pin); // pull up
|
||||
gpio_clear(connector->pins[pin_from].port, connector->pins[pin_from].pin); // drive low
|
||||
if (gpio_get(connector->pins[pin_to].port, connector->pins[pin_to].pin) == gpio_get(connector->pins[pin_from].port, connector->pins[pin_from].pin)) { // if they are at the same level it means the from pin was able to drive low the pulled up to pin, thus they are connected
|
||||
printf("%s (%s) %s connected to %s (on low)\n", connector->name, connector->host ? "host" : "device", connector->pins[pin_from].name, connector->pins[pin_to].name);
|
||||
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) {
|
||||
printf("%s (%s) %s connected to %s\n", connector->name, connector->host ? "host" : "device", connector->pins[pin_from].name, connector->pins[pin_to].name);
|
||||
} else if (connections < 0) {
|
||||
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);
|
||||
}
|
||||
gpio_clear(connector->pins[pin_to].port, connector->pins[pin_to].pin); // pull up
|
||||
gpio_set(connector->pins[pin_from].port, connector->pins[pin_from].pin); // drive low
|
||||
if (gpio_get(connector->pins[pin_to].port, connector->pins[pin_to].pin) == gpio_get(connector->pins[pin_from].port, connector->pins[pin_from].pin)) { // if they are at the same level it means the from pin was able to drive high the pulled down to pin, thus they are connected
|
||||
printf("%s (%s) %s connected to %s (on high)\n", connector->name, connector->host ? "host" : "device", connector->pins[pin_from].name, connector->pins[pin_to].name);
|
||||
}
|
||||
gpio_set_mode(connector->pins[pin_to].port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, connector->pins[pin_to].pin); // put pin back to safe floating state
|
||||
}
|
||||
gpio_set_mode(connector->pins[pin_from].port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, connector->pins[pin_from].pin); // put pin back to safe floating state
|
||||
}
|
||||
usb_cables_pins_float(connector); // go back to safe state
|
||||
}
|
||||
|
@ -768,27 +821,19 @@ void usb_cables_check_inter(const struct usb_connector_t* connectors, uint8_t co
|
|||
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
|
||||
gpio_set_mode(connectors[connector_from].pins[pin_from].port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, connectors[connector_from].pins[pin_from].pin); // we will drive the from pin
|
||||
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;
|
||||
}
|
||||
for (uint8_t pin_to = 0; pin_to < connectors[connector_to].pins_nb; pin_to++) { // test to every pin (except itself)
|
||||
gpio_set_mode(connectors[connector_to].pins[pin_to].port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, connectors[connector_to].pins[pin_to].pin); // we will read every to pin
|
||||
gpio_set(connectors[connector_to].pins[pin_to].port, connectors[connector_to].pins[pin_to].pin); // pull up
|
||||
gpio_clear(connectors[connector_from].pins[pin_from].port, connectors[connector_from].pins[pin_from].pin); // drive low
|
||||
if (gpio_get(connectors[connector_to].pins[pin_to].port, connectors[connector_to].pins[pin_to].pin) == gpio_get(connectors[connector_from].pins[pin_from].port, connectors[connector_from].pins[pin_from].pin)) { // if they are at the same level it means the from pin was able to drive low the pulled up to pin, thus they are connected
|
||||
printf("%s (%s) %s connected to %s (%s) %s (on low)\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);
|
||||
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);
|
||||
if (connections > 0) {
|
||||
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);
|
||||
} else if (connections < 0) {
|
||||
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);
|
||||
}
|
||||
gpio_clear(connectors[connector_to].pins[pin_to].port, connectors[connector_to].pins[pin_to].pin); // pull down
|
||||
gpio_set(connectors[connector_from].pins[pin_from].port, connectors[connector_from].pins[pin_from].pin); // drive high
|
||||
if (gpio_get(connectors[connector_to].pins[pin_to].port, connectors[connector_to].pins[pin_to].pin) == gpio_get(connectors[connector_from].pins[pin_from].port, connectors[connector_from].pins[pin_from].pin)) { // if they are at the same level it means the from pin was able to drive high the pulled down to pin, thus they are connected
|
||||
printf("%s %s connected to %s %s (on high)\n", connectors[connector_from].name, connectors[connector_from].pins[pin_from].name, connectors[connector_to].name, connectors[connector_to].pins[pin_to].name);
|
||||
}
|
||||
gpio_set_mode(connectors[connector_to].pins[pin_to].port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, connectors[connector_to].pins[pin_to].pin); // put pin back to safe floating state
|
||||
}
|
||||
}
|
||||
gpio_set_mode(connectors[connector_from].pins[pin_from].port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, connectors[connector_from].pins[pin_from].pin); // put pin back to safe floating state
|
||||
}
|
||||
}
|
||||
usb_cables_connectors_float(connectors, connectors_nb); // go back to safe state
|
||||
|
@ -818,39 +863,7 @@ bool usb_cables_check_cable(const struct usb_cable_t* usb_cable, uint8_t* define
|
|||
continue;
|
||||
}
|
||||
|
||||
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, to_pin); // we will read from this pin
|
||||
gpio_set(to_port, to_pin); // pull up
|
||||
gpio_clear(from_port, from_pin); // drive low
|
||||
gpio_set_mode(from_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, from_pin); // we will drive this pin
|
||||
bool from_to_low = (gpio_get(to_port, to_pin) == gpio_get(to_port, to_pin)); // if they are at the same level it means the from pin was able to drive low the pulled up to pin, thus they are connected
|
||||
|
||||
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, to_pin); // we will read from this pin
|
||||
gpio_clear(to_port, to_pin); // pull up
|
||||
gpio_set(from_port, from_pin); // drive low
|
||||
gpio_set_mode(from_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, from_pin); // we will drive this pin
|
||||
bool from_to_high = (gpio_get(to_port, to_pin) == gpio_get(to_port, to_pin)); // if they are at the same level it means the from pin was able to drive high the pulled low to pin, thus they are connected
|
||||
|
||||
gpio_set_mode(from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, from_pin); // we will read from this pin
|
||||
gpio_set(from_port, from_pin); // pull up
|
||||
gpio_clear(to_port, to_pin); // drive low
|
||||
gpio_set_mode(to_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, to_pin); // we will drive this pin
|
||||
bool to_from_low = (gpio_get(to_port, to_pin) == gpio_get(to_port, to_pin)); // if they are at the same level it means the to pin was able to drive low the pulled up from pin, thus they are connected
|
||||
|
||||
gpio_set_mode(from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, from_pin); // we will read from this pin
|
||||
gpio_clear(from_port, from_pin); // pull up
|
||||
gpio_set(to_port, to_pin); // drive low
|
||||
gpio_set_mode(to_port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, to_pin); // we will drive this pin
|
||||
bool to_from_high = (gpio_get(to_port, to_pin) == gpio_get(to_port, to_pin)); // if they are at the same level it means the to pin was able to drive high the pulled low from pin, thus they are connected
|
||||
|
||||
gpio_set_mode(from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, from_pin); // put pin back to safe floating state
|
||||
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin); // put pin back to safe floating state
|
||||
|
||||
// calculate the connection rate (the booleans are only in case the want to debug)
|
||||
uint8_t connections = 0;
|
||||
if (from_to_low) connections++;
|
||||
if (from_to_high) connections++;
|
||||
if (to_from_low) connections++;
|
||||
if (to_from_high) connections++;
|
||||
int8_t connections = usb_cables_check_pins(from_port, from_pin, to_port, to_pin);
|
||||
|
||||
// figure out if this connection pair is defined
|
||||
bool pair_defined = false;
|
||||
|
@ -863,7 +876,7 @@ bool usb_cables_check_cable(const struct usb_cable_t* usb_cable, uint8_t* define
|
|||
}
|
||||
}
|
||||
|
||||
if (4 == connections) { // the connection is fine
|
||||
if (connections > 0) { // the connection is fine
|
||||
if (pair_defined) {
|
||||
(*defined)++;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue