diff --git a/application.c b/application.c index 56e4e45..9fb35bf 100644 --- a/application.c +++ b/application.c @@ -1401,6 +1401,21 @@ void main(void) uint32_t last_connect_time = rtc_get_counter_val(); // last time a USB cable has been connected/disconnected bool interactive = false; // if there is user activity on the serial port bool action = false; // if an action has been performed don't go to sleep + + struct cable_t* cable_current = calloc(1, sizeof(struct cable_t)); // to store the currently detected cable + if (NULL == cable_current) { + printf("EOMEM\n"); + while (true); + } + cable_clear(cable_current); // initialize rest of cable structure + struct cable_t* cable_next = calloc(1, sizeof(struct cable_t)); // to store the next detected cable + if (NULL == cable_next) { + printf("EOMEM\n"); + while (true); + } + cable_clear(cable_next); // initialize rest of cable structure + bool cable_changed = false; // if the next cable is not the same as the current + while (true) { // infinite loop iwdg_reset(); // kick the dog if (user_input_available) { // user input is available @@ -1420,6 +1435,74 @@ void main(void) if (rtc_internal_tick_flag) { // the internal RTC ticked rtc_internal_tick_flag = false; // reset flag action = true; // action has been performed + if (!interactive) { // periodically check cable when not in interactive mode + + // start cable detection + cable_clear(cable_next); // clear definition + cable_detect(cable_next); // detect connected connectors + if (NULL == cable_next->connections && cable_next->connections_nb > 0) { + printf("EOMEM\n"); + while (true); + } + // if there is a cable, we need to identify it further + if (0 != cable_next->connections_nb) { + cable_connectors(cable_next); // first identify the connectors + cable_cables(cable_next); // find cables with matching connector set + cable_issues_nb(cable_next); // calculate score for cables (updates the connections) + if (NULL == cable_next->connections || 0 == cable_next->connections_nb) { + printf("EOMEM\n"); + while (true); + } + } + // compare next to current cable + if (cable_current->connections_nb != cable_next->connections_nb) { + cable_changed = true; // note it changed, but don't do anything until change is confirmed a second time + } else { // same number of connections + bool match = true; + for (uint16_t i = 0; i < cable_current->connections_nb && i < cable_next->connections_nb && match; i++) { + if (cable_current->connections[i][0] != cable_next->connections[i][0] || cable_current->connections[i][1] != cable_next->connections[i][1]) { + match = false; + } + } + if (!match) { // not the same connections + cable_changed = true; + } else if (cable_changed) { // it's the same cable, and it has been confirmed a second time + cable_changed = false; // remember it's the same cable + if (0 == cable_current->connections_nb) { // no cable plugged in + lcd_hd44780_clear_display(); // be sure the display is cleared + lcd_hd44780_write_line(false, lcd_default_line1, strlen(lcd_default_line1)); + lcd_hd44780_write_line(true, lcd_default_line2, strlen(lcd_default_line2)); + } else { // there is a new confirmed cable + cable_load(cable_next); // check if there is a load + cable_issues(cable_next); // get the exact issues + lcd_hd44780_clear_display(); // clear display + if (cable_next->cable_best < LENGTH(usb_cables) && cable_next->cable_best < LENGTH(cable_next->unconnected_nb) && cable_next->cable_best < LENGTH(cable_next->unspecified_nb)) { + const struct usb_cable_t* usb_cable = &usb_cables[cable_next->cable_best]; + lcd_hd44780_write_line(false, usb_cable->name, strlen(usb_cable->name)); + uint16_t issues = cable_next->unconnected_nb[cable_next->cable_best] + cable_next->unspecified_nb[cable_next->cable_best]; + if (0 == issues) { + lcd_hd44780_write_line(true, "perfect match", 13); + } else { + char score_str[17]; + uint8_t str_len = snprintf(score_str, LENGTH(score_str), "issues: %u", issues); + if (str_len) { + lcd_hd44780_write_line(true, score_str, str_len); + } + } + } else { + lcd_hd44780_write_line(false, "no matching", 11); + lcd_hd44780_write_line(true, "cable found", 11); + } + } + } else { // the cable did not change + // nothing to do, wait for cable change + } + } + // next cable because the current one (reuse allocated current for the next) + struct cable_t* cable_tmp = cable_current; + cable_current = cable_next; + cable_next = cable_tmp; + } // !interactive while (!interactive && rtc_get_counter_val() >= last_connect_time + SHUTDOWN_TIMEOUT) { // time to shut down #if !DEBUG BKP_DR1 = 0x22; // indicate we want to stay in standby mode (it's not possible to disable the independent watchdog and it will reset the system even in standby mode