usb_cable: improve find connection test speed

This commit is contained in:
King Kévin 2019-12-09 20:25:54 +01:00
parent b9da72b3a7
commit 8b8dfa5141
2 changed files with 29 additions and 23 deletions

View File

@ -1407,30 +1407,31 @@ uint8_t usb_cables_check_pins(const struct usb_pin_t* pin1, const struct usb_pin
} }
uint8_t connection = 0; // the connection result to return uint8_t connection = 0; // the connection result to return
for (uint8_t direction = 0; direction < 2; direction++) { // test both directions for (int8_t mode = 3; mode >= 0; mode--) { // test all connection types (from most to least accurate)
uint32_t from_port = (0 == direction ? pin2->port : pin1->port); for (uint8_t direction = 0; direction < 2; direction++) { // test both directions
uint16_t from_pin = (0 == direction ? pin2->pin : pin1->pin); uint32_t from_port = (0 == direction ? pin2->port : pin1->port);
uint32_t to_port = (0 == direction ? pin1->port : pin2->port); uint16_t from_pin = (0 == direction ? pin2->pin : pin1->pin);
uint16_t to_pin = (0 == direction ? pin1->pin : pin2->pin); uint32_t to_port = (0 == direction ? pin1->port : pin2->port);
for (uint8_t mode = 0; mode < 3; mode++) { // test all connection types uint16_t to_pin = (0 == direction ? pin1->pin : pin2->pin);
// don't drive a ground pin high // 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)) { if (((0 == direction && USB_PIN_TYPE_GROUND == pin2->type) || (1 == direction && USB_PIN_TYPE_GROUND == pin1->type)) && (USB_PIN_CONNECTION_DRIVE_FLOAT == (1 << mode) || USB_PIN_CONNECTION_DRIVE_PULL == (1 << mode))) {
continue; continue;
} }
// set pin mode // set pin mode
switch (mode) { switch ((1 << mode)) {
case 0: 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(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); gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin);
break; break;
case 1: case USB_PIN_CONNECTION_PULL_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;
case 2:
gpio_set_mode(from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, from_pin); 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); gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin);
break; break;
case USB_PIN_CONNECTION_DRIVE_PULL:
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: default:
break; break;
} }
@ -1454,14 +1455,18 @@ uint8_t usb_cables_check_pins(const struct usb_pin_t* pin1, const struct usb_pin
} }
} }
if (connected) { if (connected) {
connection |= ((1 << mode) << (direction * 4)); connection |= (1 << (mode + direction * 4));
} }
} }
// put back to floating if ((connection & (1 << (mode + 0))) && (connection & (1 << (mode + 4)))) { // more accurate connection showed, no need to continue with least accurate test
gpio_set_mode(from_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, from_pin); break;
gpio_set_mode(to_port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, to_pin); }
} }
// 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; return connection;
} }
@ -1494,7 +1499,7 @@ void usb_cables_check_intra(const struct usb_connector_t* connector, bool* conne
} }
uint8_t connection = usb_cables_check_pins(&connector->pins[pin_from], &connector->pins[pin_to]); uint8_t connection = usb_cables_check_pins(&connector->pins[pin_from], &connector->pins[pin_to]);
if (connection >= 0x44) { if (connection >= 0x22) {
if (connected) { if (connected) {
connected[pin_from] = true; connected[pin_from] = true;
connected[pin_to] = true; connected[pin_to] = true;
@ -1542,7 +1547,7 @@ void usb_cables_check_inter(const struct usb_connector_t** connectors, uint8_t c
} }
// check if cable is connected // check if cable is connected
uint8_t connection = usb_cables_check_pins(&connectors[connector_from]->pins[pin_from], &connectors[connector_to]->pins[pin_to]); uint8_t connection = usb_cables_check_pins(&connectors[connector_from]->pins[pin_from], &connectors[connector_to]->pins[pin_to]);
if (connection >= 0x44) { if (connection >= 0x22) {
if (connected) { // remember they are connected if (connected) { // remember they are connected
connected[connector_from] = true; connected[connector_from] = true;
connected[connector_to] = true; connected[connector_to] = true;
@ -1716,7 +1721,7 @@ bool usb_cables_check_cable(const struct usb_cable_t* usb_cable, uint8_t* define
} }
uint8_t connection = usb_cables_check_pins(&usb_cable->connectors[connector_from]->pins[pin_from], &usb_cable->connectors[connector_to]->pins[pin_to]); 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 (connection >= 0x22) {
if (pair_defined) { if (pair_defined) {
_defined++; _defined++;
} else { } else {

View File

@ -31,11 +31,12 @@ enum usb_pin_type_t {
/** the type of connection between two pins /** the type of connection between two pins
* @note to be used as bit mask * @note to be used as bit mask
* @note ordered from least most most reliable/accurate
*/ */
enum usb_pin_connection_t { enum usb_pin_connection_t {
USB_PIN_CONNECTION_DRIVE_FLOAT = (1 << 0), /*< the output side is driven using pull/push, the input is floating */ USB_PIN_CONNECTION_DRIVE_FLOAT = (1 << 0), /*< the output side is driven using pull/push, the input is floating */
USB_PIN_CONNECTION_DRIVE_PULL = (1 << 1), /*< the output side is driven using pull/push, the input is pulled up/down */ USB_PIN_CONNECTION_PULL_FLOAT = (1 << 1), /*< the output side is driven using pull up/down, the input is floating */
USB_PIN_CONNECTION_PULL_FLOAT = (1 << 2), /*< 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 */
}; };
/** USB pin definition */ /** USB pin definition */