diff --git a/general/package/gpio-motors/src/gpio-motors.c b/general/package/gpio-motors/src/gpio-motors.c index 813197fb..142c3d09 100644 --- a/general/package/gpio-motors/src/gpio-motors.c +++ b/general/package/gpio-motors/src/gpio-motors.c @@ -7,188 +7,215 @@ int PAN_PINS[4]; int TILT_PINS[4]; +int SELECT_PIN = -1; int STEP_SEQUENCE[8][4] = { - {1, 0, 0, 0}, {1, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0}, - {0, 0, 1, 0}, {0, 0, 1, 1}, {0, 0, 0, 1}, {1, 0, 0, 1} + {1, 0, 0, 0}, {1, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0}, + {0, 0, 1, 0}, {0, 0, 1, 1}, {0, 0, 0, 1}, {1, 0, 0, 1} }; int REVERSE_STEP_SEQUENCE[8][4] = { - {1, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 1, 1}, {0, 0, 1, 0}, - {0, 1, 1, 0}, {0, 1, 0, 0}, {1, 1, 0, 0}, {1, 0, 0, 0} + {1, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 1, 1}, {0, 0, 1, 0}, + {0, 1, 1, 0}, {0, 1, 0, 0}, {1, 1, 0, 0}, {1, 0, 0, 0} }; void release_gpio(int pin) { - char path[50]; - snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); - FILE *file = fopen(path, "w"); - if (file) { - fprintf(file, "%d", 0); - fclose(file); - } else { - printf("Unable to set value of GPIO %d to 0: [%d] %s\n", pin, errno, strerror(errno)); - } + char path[50]; + snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); + FILE *file = fopen(path, "w"); + if (file) { + fprintf(file, "%d", 0); + fclose(file); + } - file = fopen("/sys/class/gpio/unexport", "w"); - if (file) { - fprintf(file, "%d", pin); - fclose(file); - } else { - printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); - } + file = fopen("/sys/class/gpio/unexport", "w"); + if (file) { + fprintf(file, "%d", pin); + fclose(file); + } else { + printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); + } } void cleanup() { - for (int i = 0; i < 4; i++) { - release_gpio(PAN_PINS[i]); - release_gpio(TILT_PINS[i]); - } - exit(EXIT_FAILURE); + for (int i = 0; i < 4; i++) { + release_gpio(PAN_PINS[i]); + release_gpio(TILT_PINS[i]); + } + + if (SELECT_PIN != -1) { + release_gpio(SELECT_PIN); + } + + exit(EXIT_FAILURE); } void export_gpio(int pin) { - char path[50]; - FILE *file; + char path[50]; + FILE *file; - file = fopen("/sys/class/gpio/export", "w"); - if (file) { - fprintf(file, "%d", pin); - fclose(file); - } else { - printf("Unable export GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); - cleanup(); - } + file = fopen("/sys/class/gpio/export", "w"); + if (file) { + fprintf(file, "%d", pin); + fclose(file); + } else { + printf("Unable export GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); + cleanup(); + } - snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin); - file = fopen(path, "w"); - if (file) { - fprintf(file, "out"); - fclose(file); - } else { - printf("Unable to set direction of GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); - cleanup(); - } + snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin); + file = fopen(path, "w"); + if (file) { + fprintf(file, "out"); + fclose(file); + } else { + printf("Unable to set direction of GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); + cleanup(); + } } void unexport_gpio(int pin) { - FILE *file = fopen("/sys/class/gpio/unexport", "w"); - if (file) { - fprintf(file, "%d", pin); - fclose(file); - } else { - printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); - cleanup(); - } + FILE *file = fopen("/sys/class/gpio/unexport", "w"); + if (file) { + fprintf(file, "%d", pin); + fclose(file); + } else { + printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); + cleanup(); + } } void set_gpio(int pin, int value) { - char path[50]; - snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); - FILE *file = fopen(path, "w"); - if (file) { - fprintf(file, "%d", value); - fclose(file); - } else { - printf("Unable to set value of GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); - cleanup(); - } + char path[50]; + snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); + FILE *file = fopen(path, "w"); + if (file) { + fprintf(file, "%d", value); + fclose(file); + } else { + printf("Unable to set value of GPIO %d: [%d] %s\n", pin, errno, strerror(errno)); + cleanup(); + } } void get_gpio_config() { - FILE *fp = popen("fw_printenv -n gpio_motors", "r"); - if (fp == NULL) { - printf("Unable to run fw_printenv\n"); - exit(EXIT_FAILURE); - } + FILE *fp = popen("fw_printenv -n gpio_motors", "r"); + if (fp == NULL) { + printf("Unable to run fw_printenv\n"); + exit(EXIT_FAILURE); + } - char line[32]; - if (fgets(line, sizeof(line), fp) != NULL) { - char *token = strtok(line, " "); - int index = 0; + char line[64]; + if (fgets(line, sizeof(line), fp) != NULL) { + char *token = strtok(line, " "); + int value[8]; + int count = 0; - while (token != NULL && index < 8) { - if (index < 4) { - PAN_PINS[index] = atoi(token); - } else { - TILT_PINS[index - 4] = atoi(token); - } - token = strtok(NULL, " "); - index++; - } + while (token != NULL && count < 8) { + value[count++] = atoi(token); + token = strtok(NULL, " "); + } - if (index != 8) { - printf("Error: Expected 8 GPIO values, but got %d.\n", index); - exit(EXIT_FAILURE); - } - } else { - printf("Error: Unable to read gpio_motors from fw_printenv.\n"); - exit(EXIT_FAILURE); - } + if (count == 8) { + for (int i = 0; i < 4; i++) { + PAN_PINS[i] = value[i]; + TILT_PINS[i] = value[i + 4]; + } + } else if (count == 5) { + for (int i = 0; i < 4; i++) { + PAN_PINS[i] = value[i]; + TILT_PINS[i] = value[i]; + } + SELECT_PIN = value[4]; + } else { + printf("Error: Expected 8 or 5 GPIO values, but got %d\n", count); + exit(EXIT_FAILURE); + } + } else { + printf("Error: Unable to read gpio_motors from fw_printenv\n"); + exit(EXIT_FAILURE); + } - fclose(fp); + pclose(fp); } int main(int argc, char *argv[]) { - if (argc != 4) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } + if (argc != 4) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } - int pan_steps = atoi(argv[1]); - int tilt_steps = atoi(argv[2]); - int delay = atoi(argv[3]) * 1000; + int pan_steps = atoi(argv[1]); + int tilt_steps = atoi(argv[2]); + int delay = atoi(argv[3]) * 1000; - get_gpio_config(); + get_gpio_config(); - for (int i = 0; i < 4; i++) { - export_gpio(PAN_PINS[i]); - export_gpio(TILT_PINS[i]); - } + for (int i = 0; i < 4; i++) { + export_gpio(PAN_PINS[i]); + export_gpio(TILT_PINS[i]); + } - int pan_remaining = abs(pan_steps); - int tilt_remaining = abs(tilt_steps); - int pan_reverse = (pan_steps < 0); - int tilt_reverse = (tilt_steps < 0); - int pan_micro = 0; - int tilt_micro = 0; + if (SELECT_PIN != -1) { + export_gpio(SELECT_PIN); + } - while (pan_remaining > 0 || tilt_remaining > 0) { - int pan_has = pan_remaining > 0; - int tilt_has = tilt_remaining > 0; + int pan_remaining = abs(pan_steps); + int tilt_remaining = abs(tilt_steps); + int pan_reverse = (pan_steps < 0); + int tilt_reverse = (tilt_steps < 0); + int pan_micro = 0; + int tilt_micro = 0; - int pan_eff = pan_has ? (tilt_has ? delay : delay / 2) : 0; - int tilt_eff = tilt_has ? (pan_has ? delay : delay / 2) : 0; - int eff_delay = (pan_eff > tilt_eff) ? pan_eff : tilt_eff; + while (pan_remaining > 0 || tilt_remaining > 0) { + int pan_has = pan_remaining > 0; + int tilt_has = tilt_remaining > 0; - if (pan_has) { - const int (*seq)[4] = pan_reverse ? REVERSE_STEP_SEQUENCE : STEP_SEQUENCE; - for (int k = 0; k < 4; k++) { - set_gpio(PAN_PINS[k], seq[pan_micro][k]); - } - if (++pan_micro >= 8) { - pan_micro = 0; - pan_remaining--; - } - } + int pan_eff = pan_has ? (tilt_has ? delay : delay / 2) : 0; + int tilt_eff = tilt_has ? (pan_has ? delay : delay / 2) : 0; + int eff_delay = (pan_eff > tilt_eff) ? pan_eff : tilt_eff; - if (tilt_has) { - const int (*seq)[4] = tilt_reverse ? REVERSE_STEP_SEQUENCE : STEP_SEQUENCE; - for (int k = 0; k < 4; k++) { - set_gpio(TILT_PINS[k], seq[tilt_micro][k]); - } - if (++tilt_micro >= 8) { - tilt_micro = 0; - tilt_remaining--; - } - } + if (pan_has) { + if (SELECT_PIN != -1) { + set_gpio(SELECT_PIN, 0); + } - usleep(eff_delay); - } + const int (*seq)[4] = pan_reverse ? REVERSE_STEP_SEQUENCE : STEP_SEQUENCE; + for (int k = 0; k < 4; k++) { + set_gpio(PAN_PINS[k], seq[pan_micro][k]); + } + if (++pan_micro >= 8) { + pan_micro = 0; + pan_remaining--; + } + } - for (int i = 0; i < 4; i++) { - release_gpio(PAN_PINS[i]); - release_gpio(TILT_PINS[i]); - } + if (tilt_has) { + if (SELECT_PIN != -1) { + set_gpio(SELECT_PIN, 1); + } - return 0; + const int (*seq)[4] = tilt_reverse ? REVERSE_STEP_SEQUENCE : STEP_SEQUENCE; + for (int k = 0; k < 4; k++) { + set_gpio(TILT_PINS[k], seq[tilt_micro][k]); + } + if (++tilt_micro >= 8) { + tilt_micro = 0; + tilt_remaining--; + } + } + + usleep(eff_delay); + } + + for (int i = 0; i < 4; i++) { + release_gpio(PAN_PINS[i]); + release_gpio(TILT_PINS[i]); + } + + if (SELECT_PIN != -1) { + release_gpio(SELECT_PIN); + } + + return 0; }