/* 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, ...) */ const char* variant; /*< variant if there are more than one of the same connector */ uint8_t pins_nb; /*< number of pins */ const uint8_t* pins; /*< all connector pins indexes */ }; /** 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 uint8_t (*pin_pairs)[2]; /*< list of connected pin index pairs (order does not matter) */ }; /** USB pin definitions */ extern const struct usb_pin_t usb_pins[105]; /** USB connectors definitions */ extern const struct usb_connector_t* usb_connectors[8]; /** USB cables definitions */ extern const struct usb_cable_t usb_cables[77]; /** set every USB pin from every USB connector to input floating */ void usb_cables_pins_float(void); /** set every pin of connector to input floating * @param[in] connector connector on which to set the pins floating */ void usb_cables_connector_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); /** get connector from pin * @param[in] pin pin index in usb_pins * @return corresponding connector (NULL if none found) */ 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_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 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[in] print print connection errors * @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* cable, uint8_t* defined, uint8_t* undefined, bool print); /** test connections between connectors * @param[in] connectors connectors to check * @param[in] connectors_nb numbers of connectors * @param[in] include_intra if connections between pins within a connector should be tested * @param[in] ground_only only test connections between ground pins * @param[out] connections_nb number of connections found * @return list of pin pairs connections (NULL if 0 connections have been found or no connections have been found but no memory is available) * @the list of pin pairs connections is allocated memory which should be freed by the caller */ uint8_t** usb_cables_test_connections(const struct usb_connector_t** connectors, uint8_t connectors_nb, bool include_intra, bool ground_only, uint16_t* connections_nb);