/* 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 . * */ /** USB cable definitions and utilities * @file * @author King Kévin * @date 2019 */ /** the USB pin type */ enum usb_pin_type_t { 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_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_t { 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 */ }; /** USB pin definition */ struct usb_pin_t { const char* name; /*< pin name */ uint32_t port; /*< on which MCU port is this pin connected */ uint16_t pin; /*< on which MCU pin is this pin connected */ enum usb_pin_type_t type; /*< pin type */ }; /** USB connector definition */ struct usb_connector_t { const char* name; /*< connector name (A, B, mini-B, micro-B, C, ...) */ bool host; /*< if on host or device side */ uint8_t pins_nb; /*< number of pins */ const struct usb_pin_t* pins; /*< all connector pins */ }; /** USB cable definition */ struct usb_cable_t { const char* name; /*< cable name */ uint8_t connectors_nb; /*< number of connectors */ const struct usb_connector_t** connectors; /*< list of connectors this cables uses */ uint8_t pin_pairs_nb; /* number of connected pin pairs */ const struct usb_pin_t* (*pin_pairs)[2]; /*< list of connected pin pairs (order does not matter) */ }; /** USB connectors definitions */ extern const struct usb_connector_t* usb_connectors[8]; /** USB cables definitions */ extern const struct usb_cable_t usb_cables[35]; /** set every pin of connector to input floating * @param[in] connector connector on which to set the pins floating */ void usb_cables_pins_float(const struct usb_connector_t* connector); /** set every pin to the connectors to input floating * @param[in] connectors list on connectors on which to set the pins floating * @param[in] connectors_nb numbers of connectors */ void usb_cables_connectors_float(const struct usb_connector_t** connectors, uint8_t connectors_nb); /** 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_t) 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 */ uint8_t usb_cables_check_pins(const struct usb_pin_t* pin1, const struct usb_pin_t* pin2); /** check connector for connections between pins of this connector * @param[in] connector connector to check * @param[out] connected which of the pins are connected (NULL to just print the pins) */ void usb_cables_check_intra(const struct usb_connector_t* connector, bool* connected); /** check connectors for connections between pins of the connectors * @param[in] connectors connectors to check * @param[in] connectors_nb numbers of connectors * @param[out] connected which of the connectors are connected (NULL to just print the connections) * @note connection between pin of the same connector are not checked * @note when connected is NULL all pin connections will be tested, else some might be skipped to speed scan */ void usb_cables_check_inter(const struct usb_connector_t** connectors, uint8_t connectors_nb, bool* connected); /** check connectors for connections between ground pins of the connectors * @param[in] connectors connectors to check * @param[in] connectors_nb numbers of connectors * @param[out] connected which of the connectors are connected (NULL to just print the connections) * @note connection between pin on the same connector are not checked * @note this is faster than usb_cables_check_inter but only checks the ground pins * @note it assumes all grounds are connected (e.g. only one cable is connected) */ void usb_cables_check_ground(const struct usb_connector_t** connectors, uint8_t connectors_nb, bool* connected); /** check if there is a load on the connector * @param[in] connector connector to check * @return if there is a load on the connector */ bool usb_cables_check_load(const struct usb_connector_t* connector); /** check USB cable connections * @param[in] usb_cable USB cable to check * @param[out] defined number of pin pairs that are connected according to definition * @param[out] undefined number of pin pairs that are connected but not according to definition * @param[out] disconnected number of pin pairs that are not connected but should according to definition * @return if the connections of the cable correspond to the definition * @note each pair is checked in both directions */ bool usb_cables_check_cable(const struct usb_cable_t* usb_cable, uint8_t* defined, uint8_t* undefined, uint8_t* disconnected);