application: get and print optional connections
This commit is contained in:
parent
3ce2418f18
commit
35c708dbd1
129
application.c
129
application.c
|
@ -138,9 +138,11 @@ struct cable_t {
|
|||
bool cables[LENGTH(usb_cables)]; // cable definitions the connectors set match to
|
||||
uint16_t unconnected_nb[LENGTH(usb_cables)]; // number of unconnected pairs which should be connected according to cable specification
|
||||
uint16_t unspecified_nb[LENGTH(usb_cables)]; // number of connected pairs which are not specified by cable
|
||||
uint16_t optional_nb[LENGTH(usb_cables)]; // number of connected pairs which are optional for this cable
|
||||
uint8_t cable_best; // best matching cable index (e.g. with lowest score)
|
||||
uint8_t (*unconnected)[2]; // unconnected pairs which should be connected according to best cable specification
|
||||
uint8_t (*unspecified)[2]; // connected pairs which are not specified by best cable
|
||||
uint8_t (*optional)[2]; // connected pairs which are optional for best cable
|
||||
};
|
||||
|
||||
/** clear the cable information
|
||||
|
@ -174,6 +176,9 @@ static void cable_clear(struct cable_t* cable)
|
|||
for (uint8_t i = 0; i < LENGTH(cable->unspecified_nb); i++) {
|
||||
cable->unspecified_nb[i] = 0;
|
||||
}
|
||||
for (uint8_t i = 0; i < LENGTH(cable->optional_nb); i++) {
|
||||
cable->optional_nb[i] = 0;
|
||||
}
|
||||
cable->cable_best = 0xff;
|
||||
if (cable->unconnected) {
|
||||
free(cable->unconnected);
|
||||
|
@ -183,6 +188,10 @@ static void cable_clear(struct cable_t* cable)
|
|||
free(cable->unspecified);
|
||||
cable->unspecified = NULL;
|
||||
}
|
||||
if (cable->optional) {
|
||||
free(cable->optional);
|
||||
cable->optional = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** detect cable presence by testing inter-connector ground connections
|
||||
|
@ -348,7 +357,7 @@ static void cable_cables(struct cable_t* cable)
|
|||
|
||||
/** calculate number of issues for matching cables
|
||||
* @param[in,out] cable cable for which to find the number of issues
|
||||
* @note resets connections and connections_nb, sets unconnected_nb, unspecified_nb, and cable_best based on cables
|
||||
* @note resets connections and connections_nb, sets unconnected_nb, unspecified_nb, optional_nb, and cable_best based on cables
|
||||
*/
|
||||
static void cable_issues_nb(struct cable_t* cable)
|
||||
{
|
||||
|
@ -364,6 +373,9 @@ static void cable_issues_nb(struct cable_t* cable)
|
|||
for (uint8_t i = 0; i < LENGTH(cable->unspecified_nb); i++) {
|
||||
cable->unspecified_nb[i] = 0;
|
||||
}
|
||||
for (uint8_t i = 0; i < LENGTH(cable->optional_nb); i++) {
|
||||
cable->optional_nb[i] = 0;
|
||||
}
|
||||
cable->cable_best = 0xff;
|
||||
|
||||
// ensure connections are available
|
||||
|
@ -392,7 +404,7 @@ static void cable_issues_nb(struct cable_t* cable)
|
|||
|
||||
// calculate score for cables
|
||||
uint16_t best_score = UINT16_MAX; // best cable score
|
||||
for (uint8_t cable_i = 0; cable_i < LENGTH(usb_cables) && cable_i < LENGTH(cable->cables) && cable_i < LENGTH(cable->unconnected_nb) && cable_i < LENGTH(cable->unspecified_nb); cable_i++) {
|
||||
for (uint8_t cable_i = 0; cable_i < LENGTH(usb_cables) && cable_i < LENGTH(cable->cables) && cable_i < LENGTH(cable->unconnected_nb) && cable_i < LENGTH(cable->unspecified_nb) && cable_i < LENGTH(cable->optional_nb); cable_i++) {
|
||||
if (!cable->cables[cable_i]) { // skip if the cable connectors do not match
|
||||
continue;
|
||||
}
|
||||
|
@ -400,16 +412,28 @@ static void cable_issues_nb(struct cable_t* cable)
|
|||
cable->unconnected_nb[cable_i] = usb_cable->mandatory_pairs_nb;
|
||||
cable->unspecified_nb[cable_i] = 0;
|
||||
for (uint16_t i = 0; i < cable->connections_nb; i++) {
|
||||
bool match = false;
|
||||
bool mandatory = false;
|
||||
for (uint8_t j = 0; j < usb_cable->mandatory_pairs_nb; j++) {
|
||||
if (cable->connections[i][0] == usb_cable->mandatory_pairs[j][0] && cable->connections[i][1] == usb_cable->mandatory_pairs[j][1]) {
|
||||
match = true;
|
||||
mandatory = true;
|
||||
} else if (cable->connections[i][0] == usb_cable->mandatory_pairs[j][1] && cable->connections[i][1] == usb_cable->mandatory_pairs[j][0]) {
|
||||
match = true;
|
||||
mandatory = true;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
bool optional = false;
|
||||
if (!mandatory) {
|
||||
for (uint8_t j = 0; j < usb_cable->optional_pairs_nb; j++) {
|
||||
if (cable->connections[i][0] == usb_cable->optional_pairs[j][0] && cable->connections[i][1] == usb_cable->optional_pairs[j][1]) {
|
||||
optional = true;
|
||||
} else if (cable->connections[i][0] == usb_cable->optional_pairs[j][1] && cable->connections[i][1] == usb_cable->optional_pairs[j][0]) {
|
||||
optional = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mandatory) {
|
||||
cable->unconnected_nb[cable_i]--;
|
||||
} else if (optional) {
|
||||
cable->optional_nb[cable_i]++;
|
||||
} else {
|
||||
cable->unspecified_nb[cable_i]++;
|
||||
}
|
||||
|
@ -424,7 +448,7 @@ static void cable_issues_nb(struct cable_t* cable)
|
|||
|
||||
/** list issues for best matching cable
|
||||
* @param[in,out] cable cable for which to calculate the score
|
||||
* @note set unconnected and unspecified based on cable_best
|
||||
* @note set unconnected, unspecified, and optional based on cable_best
|
||||
*/
|
||||
static void cable_issues(struct cable_t* cable)
|
||||
{
|
||||
|
@ -447,6 +471,11 @@ static void cable_issues(struct cable_t* cable)
|
|||
cable->unspecified = NULL;
|
||||
}
|
||||
cable->unspecified_nb[cable->cable_best] = 0;
|
||||
if (cable->optional) {
|
||||
free(cable->optional);
|
||||
cable->optional = NULL;
|
||||
}
|
||||
cable->optional_nb[cable->cable_best] = 0;
|
||||
|
||||
// find if cable pairs are actual connection
|
||||
const struct usb_cable_t* usb_cable = &usb_cables[cable->cable_best];
|
||||
|
@ -478,15 +507,40 @@ static void cable_issues(struct cable_t* cable)
|
|||
|
||||
// find if connection is defined in cable
|
||||
for (uint16_t i = 0; i < cable->connections_nb; i++) {
|
||||
bool match = false;
|
||||
bool mandatory = false;
|
||||
for (uint8_t j = 0; j < usb_cable->mandatory_pairs_nb; j++) {
|
||||
if (cable->connections[i][0] == usb_cable->mandatory_pairs[j][0] && cable->connections[i][1] == usb_cable->mandatory_pairs[j][1]) {
|
||||
match = true;
|
||||
mandatory = true;
|
||||
} else if (cable->connections[i][0] == usb_cable->mandatory_pairs[j][1] && cable->connections[i][1] == usb_cable->mandatory_pairs[j][0]) {
|
||||
match = true;
|
||||
mandatory = true;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
bool optional = false;
|
||||
if (!mandatory) {
|
||||
for (uint8_t j = 0; j < usb_cable->optional_pairs_nb; j++) {
|
||||
if (cable->connections[i][0] == usb_cable->optional_pairs[j][0] && cable->connections[i][1] == usb_cable->optional_pairs[j][1]) {
|
||||
optional = true;
|
||||
} else if (cable->connections[i][0] == usb_cable->optional_pairs[j][1] && cable->connections[i][1] == usb_cable->optional_pairs[j][0]) {
|
||||
optional = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optional) {
|
||||
cable->optional_nb[cable->cable_best]++;
|
||||
uint8_t (*new_connections)[2] = realloc(cable->optional, cable->optional_nb[cable->cable_best] * sizeof(uint8_t[2])); // no integer overflow is possible because of the max number of connections
|
||||
if (NULL == new_connections) { // allocation failed
|
||||
if (cable->optional) {
|
||||
free(cable->optional);
|
||||
}
|
||||
cable->optional = NULL;
|
||||
cable->optional_nb[cable->cable_best] = 0;
|
||||
return; // fail-safe return (without indicating error)
|
||||
}
|
||||
cable->optional = new_connections;
|
||||
cable->optional[cable->optional_nb[cable->cable_best] - 1][0] = cable->connections[i][0];
|
||||
cable->optional[cable->optional_nb[cable->cable_best] - 1][1] = cable->connections[i][1];
|
||||
} else if (!mandatory) {
|
||||
cable->unspecified_nb[cable->cable_best]++;
|
||||
uint8_t (*new_connections)[2] = realloc(cable->unspecified, cable->unspecified_nb[cable->cable_best] * sizeof(uint8_t[2])); // no integer overflow is possible because of the max number of connections
|
||||
if (NULL == new_connections) { // allocation failed
|
||||
|
@ -565,10 +619,11 @@ static void command_cables(void* argument)
|
|||
// step 2: check for known cable configuration
|
||||
printf("= cable check =\n");
|
||||
for (uint8_t cable = 0; cable < LENGTH(usb_cables); cable++) { // test every cable
|
||||
if (0xff == cable_i || cable == cable_i) {
|
||||
uint8_t pair_defined, pair_undefined;
|
||||
bool result = usb_cables_test_cable(&usb_cables[cable], &pair_defined, &pair_undefined, false);
|
||||
printf("%02u %s: %s (defined=%u/%u, undefined=%u)\n", cable, result ? "OK" : "KO", usb_cables[cable].name, pair_defined, usb_cables[cable].mandatory_pairs_nb, pair_undefined);
|
||||
iwdg_reset(); // kick the dog
|
||||
if (0xff == cable_i || cable == cable_i) { // only test specified cable (or all if unspecified)
|
||||
uint8_t pair_defined, pair_optional, pair_undefined;
|
||||
bool result = usb_cables_test_cable(&usb_cables[cable], &pair_defined, &pair_optional, &pair_undefined, false);
|
||||
printf("%02u %s: %s (defined=%u/%u, optional=%u/%u, undefined=%u)\n", cable, result ? "OK" : "KO", usb_cables[cable].name, pair_defined, usb_cables[cable].mandatory_pairs_nb, pair_optional, usb_cables[cable].optional_pairs_nb, pair_undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,7 +711,7 @@ static void command_find(void* argument)
|
|||
continue;
|
||||
}
|
||||
uint16_t issues = cable->unconnected_nb[cable_i] + cable->unspecified_nb[cable_i];
|
||||
printf("- %02u %s: %u (unconnected=%u/%u, undefined=%u)\n", cable_i, usb_cables[cable_i].name, issues, cable->unconnected_nb[cable_i], usb_cables[cable_i].mandatory_pairs_nb, cable->unspecified_nb[cable_i]);
|
||||
printf("- %02u %s: %u (unconnected=%u/%u, optional=%u/%u, undefined=%u)\n", cable_i, usb_cables[cable_i].name, issues, cable->unconnected_nb[cable_i], usb_cables[cable_i].mandatory_pairs_nb, cable->optional_nb[cable_i], usb_cables[cable_i].optional_pairs_nb, cable->unspecified_nb[cable_i]);
|
||||
}
|
||||
|
||||
// print connection details
|
||||
|
@ -671,10 +726,10 @@ static void command_find(void* argument)
|
|||
const uint16_t issues = cable->unconnected_nb[cable->cable_best] + cable->unspecified_nb[cable->cable_best];
|
||||
if (0 == issues) {
|
||||
printf("perfect matching cable: %s\n", usb_cable->name);
|
||||
goto end;
|
||||
} else {
|
||||
printf("closest matching cable: %s\n", usb_cable->name);
|
||||
printf("connection issue(s): %u (%u unconnected, %u unspecified)\n", issues, cable->unconnected_nb[cable->cable_best], cable->unspecified_nb[cable->cable_best]);
|
||||
}
|
||||
printf("closest matching cable: %s\n", usb_cable->name);
|
||||
printf("connection issue(s): %u (%u unconnected, %u unspecified)\n", issues, cable->unconnected_nb[cable->cable_best], cable->unspecified_nb[cable->cable_best]);
|
||||
if (cable->unconnected_nb[cable->cable_best] > 0) {
|
||||
printf("unconnected pins:\n");
|
||||
for (uint16_t i = 0; i < cable->unconnected_nb[cable->cable_best]; i++) {
|
||||
|
@ -695,7 +750,7 @@ static void command_find(void* argument)
|
|||
}
|
||||
}
|
||||
if (cable->unspecified_nb[cable->cable_best] > 0) {
|
||||
printf("unspecified pins connections:\n");
|
||||
printf("unspecified connections:\n");
|
||||
for (uint16_t i = 0; i < cable->unspecified_nb[cable->cable_best]; i++) {
|
||||
const struct usb_connector_t* connector_from = usb_cables_get_connector(cable->unspecified[i][0]);
|
||||
const struct usb_connector_t* connector_to = usb_cables_get_connector(cable->unspecified[i][1]);
|
||||
|
@ -713,6 +768,25 @@ static void command_find(void* argument)
|
|||
printf("%s\n", usb_pins[cable->unspecified[i][1]].name);
|
||||
}
|
||||
}
|
||||
if (cable->optional_nb[cable->cable_best] > 0) {
|
||||
printf("optional connections:\n");
|
||||
for (uint16_t i = 0; i < cable->optional_nb[cable->cable_best]; i++) {
|
||||
const struct usb_connector_t* connector_from = usb_cables_get_connector(cable->optional[i][0]);
|
||||
const struct usb_connector_t* connector_to = usb_cables_get_connector(cable->optional[i][1]);
|
||||
if (NULL == connector_from || NULL == connector_to) {
|
||||
continue;
|
||||
}
|
||||
printf("- %s ", connector_from->name);
|
||||
if (connector_from->variant) {
|
||||
printf("(%s) ", connector_from->variant);
|
||||
}
|
||||
printf("%s to %s ", usb_pins[cable->optional[i][0]].name, connector_to->name);
|
||||
if (connector_to->variant) {
|
||||
printf("(%s) ", connector_to->variant);
|
||||
}
|
||||
printf("%s\n", usb_pins[cable->optional[i][1]].name);
|
||||
}
|
||||
}
|
||||
printf("there is %s load in the cable\n", cable->load ? "a" : "no");
|
||||
|
||||
end:
|
||||
|
@ -895,10 +969,10 @@ static void command_test(void* argument)
|
|||
}
|
||||
bool cable_ok = false; // if the cable is connected
|
||||
while (!cable_ok) { // wait until all pin pairs of cable are connected
|
||||
uint8_t defined, undefined; // pair counting variables
|
||||
cable_ok = usb_cables_test_cable(&test_cables[cable], &defined, &undefined, true); // test cable
|
||||
uint8_t defined, optional, undefined; // pair counting variables
|
||||
cable_ok = usb_cables_test_cable(&test_cables[cable], &defined, &optional, &undefined, true); // test cable
|
||||
if (!cable_ok && defined > 0) { // not all pairs are connected
|
||||
printf("connection issues: defined=%u/%u, undefined=%u\n", defined, test_cables[cable].mandatory_pairs_nb, undefined); // show issue summary
|
||||
printf("connection issues: defined=%u/%u, optional=%u/%u, undefined=%u\n", defined, test_cables[cable].mandatory_pairs_nb, optional, test_cables[cable].optional_pairs_nb, undefined); // show issue summary
|
||||
}
|
||||
if (!cable_ok) {
|
||||
if (user_input_available) { // user interruption
|
||||
|
@ -1516,6 +1590,15 @@ void main(void)
|
|||
if (NULL != connector_from && NULL != connector_to) {
|
||||
snprintf(line, LENGTH(line), "%s_%s %s_%s", connector_from->shortname, usb_pins[cable_current->unspecified[i][0]].name, connector_to->shortname, usb_pins[cable_current->unspecified[i][1]].name);
|
||||
}
|
||||
} else if (cable_message_i == 5U + cable_next->unconnected_nb[cable_next->cable_best] + cable_next->unspecified_nb[cable_next->cable_best]) {
|
||||
snprintf(line, LENGTH(line), "optional: %u", cable_next->optional_nb[cable_next->cable_best]);
|
||||
} else if (cable_message_i < 6U + cable_next->unconnected_nb[cable_next->cable_best] + cable_next->unspecified_nb[cable_next->cable_best] + cable_next->optional_nb[cable_next->cable_best]) {
|
||||
uint16_t i = cable_message_i - 6U - cable_next->unconnected_nb[cable_next->cable_best] - cable_next->unspecified_nb[cable_next->cable_best];
|
||||
const struct usb_connector_t* connector_from = usb_cables_get_connector(cable_current->optional[i][0]);
|
||||
const struct usb_connector_t* connector_to = usb_cables_get_connector(cable_current->optional[i][1]);
|
||||
if (NULL != connector_from && NULL != connector_to) {
|
||||
snprintf(line, LENGTH(line), "%s_%s %s_%s", connector_from->shortname, usb_pins[cable_current->optional[i][0]].name, connector_to->shortname, usb_pins[cable_current->optional[i][1]].name);
|
||||
}
|
||||
} else { // end reached
|
||||
snprintf(line, LENGTH(line), "closest match");
|
||||
cable_message_i = 0; // restart
|
||||
|
|
24
usb_cables.c
24
usb_cables.c
|
@ -4946,12 +4946,12 @@ bool usb_cables_test_load(const struct usb_connector_t* connector)
|
|||
return loaded;
|
||||
}
|
||||
|
||||
bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, uint8_t* undefined, bool print)
|
||||
bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, uint8_t* optional, uint8_t* undefined, bool print)
|
||||
{
|
||||
if (NULL == cable) {
|
||||
return false;
|
||||
}
|
||||
uint8_t _defined = 0, _undefined = 0; // internal pair counting variables
|
||||
uint8_t _defined = 0, _optional = 0, _undefined = 0; // internal pair counting variables
|
||||
|
||||
usb_cables_connectors_float(cable->connectors, cable->connectors_nb); // ensure we start in a safe state
|
||||
for (uint8_t connector_from = 0; connector_from < cable->connectors_nb; connector_from++) { // test from every connector
|
||||
|
@ -4973,7 +4973,7 @@ bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, ui
|
|||
continue;
|
||||
}
|
||||
|
||||
// figure out if this connection pair is defined
|
||||
// figure out if this connection pair is defined as mandatory
|
||||
bool pair_defined = false;
|
||||
for (uint8_t pair = 0; pair < cable->mandatory_pairs_nb; pair++) {
|
||||
if (cable->mandatory_pairs[pair][0] == cable->connectors[connector_from]->pins[pin_from] && cable->mandatory_pairs[pair][1] == cable->connectors[connector_to]->pins[pin_to]) {
|
||||
|
@ -4984,10 +4984,25 @@ bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, ui
|
|||
}
|
||||
}
|
||||
|
||||
// figure out if this connection pair is defined as optional
|
||||
bool pair_optional = false;
|
||||
if (!pair_defined) {
|
||||
for (uint8_t pair = 0; pair < cable->optional_pairs_nb; pair++) {
|
||||
if (cable->optional_pairs[pair][0] == cable->connectors[connector_from]->pins[pin_from] && cable->optional_pairs[pair][1] == cable->connectors[connector_to]->pins[pin_to]) {
|
||||
pair_optional = true;
|
||||
}
|
||||
if (cable->optional_pairs[pair][1] == cable->connectors[connector_from]->pins[pin_from] && cable->optional_pairs[pair][0] == cable->connectors[connector_to]->pins[pin_to]) {
|
||||
pair_optional = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connection = usb_cables_test_pins(usb_pin_from, usb_pin_to);
|
||||
if (connection >= 0x22) {
|
||||
if (pair_defined) {
|
||||
_defined++;
|
||||
} else if (pair_optional) {
|
||||
_optional++;
|
||||
} else {
|
||||
_undefined++;
|
||||
if (print) {
|
||||
|
@ -5013,6 +5028,9 @@ bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, ui
|
|||
if (defined) {
|
||||
*defined = _defined;
|
||||
}
|
||||
if (optional) {
|
||||
*optional = _optional;
|
||||
}
|
||||
if (undefined) {
|
||||
*undefined = _undefined;
|
||||
}
|
||||
|
|
|
@ -114,13 +114,14 @@ bool usb_cables_test_ground(const struct usb_connector_t** connectors, uint8_t c
|
|||
bool usb_cables_test_load(const struct usb_connector_t* connector);
|
||||
/** test USB cable connections
|
||||
* @param[in] usb_cable USB cable to test
|
||||
* @param[out] defined number of pin pairs that are connected according to definition
|
||||
* @param[out] defined number of pin pairs that are connected according to mandatory definition
|
||||
* @param[out] optional number of pin pairs that are connected according to optional 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 tested in both directions
|
||||
*/
|
||||
bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, uint8_t* undefined, bool print);
|
||||
bool usb_cables_test_cable(const struct usb_cable_t* cable, uint8_t* defined, uint8_t* optional, uint8_t* undefined, bool print);
|
||||
/** test connections between connectors
|
||||
* @param[in] connectors connectors to check
|
||||
* @param[in] connectors_nb numbers of connectors
|
||||
|
|
Loading…
Reference in New Issue