mirror of https://github.com/OpenIPC/firmware.git
Update gpio-motors (#1744)
parent
c72d852460
commit
1280422da0
|
@ -1,6 +1,6 @@
|
||||||
config BR2_PACKAGE_GPIO_MOTORS
|
config BR2_PACKAGE_GPIO_MOTORS
|
||||||
bool "gpio-motors"
|
bool "gpio-motors"
|
||||||
help
|
help
|
||||||
Control stepper motors via sysfs GPIO. This code was developed
|
Control stepper motors via sysfs GPIO. Confirmed working with 24BYJ48
|
||||||
on a GrainMedia GM8136 board with 24BYJ48 stepper motors and a ULN2803
|
stepper motors and ULN2803s on GM8136, HI3516CV200, T21, and GK7102
|
||||||
but should be portable to any other platform with sysfs GPIO access.
|
SOCs and should be portable to any with sysfs GPIO access.
|
||||||
|
|
|
@ -5,19 +5,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *name;
|
|
||||||
int pan[4];
|
|
||||||
int tilt[4];
|
|
||||||
} config;
|
|
||||||
|
|
||||||
static config list[] = {
|
|
||||||
{ "gk7205v200", { 52, 53, 56, 57 }, { 69, 70, 59, 58 } },
|
|
||||||
{ "gm8136-faleemi",{ 51, 52, 53, 54 }, { 55, 28, 29, 30 } },
|
|
||||||
{ "hi3516cv200-fdt",{ 60, 61, 37, 38 }, { 54, 55, 56, 57 } },
|
|
||||||
{ "ssc337de-foscam",{ 1, 2, 12, 13 }, { 62, 63, 64, 65 } },
|
|
||||||
};
|
|
||||||
|
|
||||||
int PAN_PINS[4];
|
int PAN_PINS[4];
|
||||||
int TILT_PINS[4];
|
int TILT_PINS[4];
|
||||||
|
|
||||||
|
@ -27,8 +14,8 @@ int STEP_SEQUENCE[8][4] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
int REVERSE_STEP_SEQUENCE[8][4] = {
|
int REVERSE_STEP_SEQUENCE[8][4] = {
|
||||||
{1, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 1, 1}, {0, 0, 1, 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}
|
{0, 1, 1, 0}, {0, 1, 0, 0}, {1, 1, 0, 0}, {1, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
void release_gpio(int pin) {
|
void release_gpio(int pin) {
|
||||||
|
@ -39,26 +26,24 @@ void release_gpio(int pin) {
|
||||||
fprintf(file, "%d", 0);
|
fprintf(file, "%d", 0);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
} else {
|
} else {
|
||||||
printf("Unable to set value of GPIO %d to 0: [%d] %s\n", pin, errno, strerror(errno));
|
printf("Unable to set value of GPIO %d to 0: [%d] %s\n", pin, errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
file = fopen("/sys/class/gpio/unexport", "w");
|
file = fopen("/sys/class/gpio/unexport", "w");
|
||||||
if (file) {
|
if (file) {
|
||||||
fprintf(file, "%d", pin);
|
fprintf(file, "%d", pin);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
} else {
|
} else {
|
||||||
printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
for (int i = 0; i < 4; i++) {
|
release_gpio(PAN_PINS[i]);
|
||||||
release_gpio(PAN_PINS[i]);
|
release_gpio(TILT_PINS[i]);
|
||||||
release_gpio(TILT_PINS[i]);
|
}
|
||||||
}
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void export_gpio(int pin) {
|
void export_gpio(int pin) {
|
||||||
|
@ -70,8 +55,8 @@ void export_gpio(int pin) {
|
||||||
fprintf(file, "%d", pin);
|
fprintf(file, "%d", pin);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
} else {
|
} else {
|
||||||
printf("Unable export GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
printf("Unable export GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);
|
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);
|
||||||
|
@ -80,9 +65,8 @@ void export_gpio(int pin) {
|
||||||
fprintf(file, "out");
|
fprintf(file, "out");
|
||||||
fclose(file);
|
fclose(file);
|
||||||
} else {
|
} else {
|
||||||
printf("Unable to set direction of GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
printf("Unable to set direction of GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +76,8 @@ void unexport_gpio(int pin) {
|
||||||
fprintf(file, "%d", pin);
|
fprintf(file, "%d", pin);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
} else {
|
} else {
|
||||||
printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
printf("Unable to unexport GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,38 +89,56 @@ void set_gpio(int pin, int value) {
|
||||||
fprintf(file, "%d", value);
|
fprintf(file, "%d", value);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
} else {
|
} else {
|
||||||
printf("Unable to set value of GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
printf("Unable to set value of GPIO %d: [%d] %s\n", pin, errno, strerror(errno));
|
||||||
cleanup();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
char line[32];
|
||||||
|
if (fgets(line, sizeof(line), fp) != NULL) {
|
||||||
|
char *token = strtok(line, " ");
|
||||||
|
int index = 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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc != 5) {
|
if (argc != 4) {
|
||||||
fprintf(stderr, "Usage: %s <config> <pan steps> <tilt steps> <delay>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <pan steps> <tilt steps> <delay (ms)>\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pan_steps = atoi(argv[2]);
|
int pan_steps = atoi(argv[1]);
|
||||||
int tilt_steps = atoi(argv[3]);
|
int tilt_steps = atoi(argv[2]);
|
||||||
int delay = atoi(argv[4]);
|
int delay = atoi(argv[3]) * 1000;
|
||||||
|
|
||||||
config *selected_config = NULL;
|
get_gpio_config();
|
||||||
int config_count = sizeof(list) / sizeof(list[0]);
|
|
||||||
for (int i = 0; i < config_count; i++) {
|
|
||||||
if (strcmp(list[i].name, argv[1]) == 0) {
|
|
||||||
selected_config = &list[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selected_config == NULL) {
|
|
||||||
fprintf(stderr, "Error: config '%s' not found.\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
PAN_PINS[i] = selected_config->pan[i];
|
|
||||||
TILT_PINS[i] = selected_config->tilt[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
export_gpio(PAN_PINS[i]);
|
export_gpio(PAN_PINS[i]);
|
||||||
|
@ -150,7 +152,7 @@ int main(int argc, char *argv[]) {
|
||||||
int pan_micro = 0;
|
int pan_micro = 0;
|
||||||
int tilt_micro = 0;
|
int tilt_micro = 0;
|
||||||
|
|
||||||
while (pan_remaining > 0 || tilt_remaining > 0) {
|
while (pan_remaining > 0 || tilt_remaining > 0) {
|
||||||
int pan_has = pan_remaining > 0;
|
int pan_has = pan_remaining > 0;
|
||||||
int tilt_has = tilt_remaining > 0;
|
int tilt_has = tilt_remaining > 0;
|
||||||
|
|
||||||
|
@ -183,8 +185,10 @@ int main(int argc, char *argv[]) {
|
||||||
usleep(eff_delay);
|
usleep(eff_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
release_gpio(PAN_PINS[i]);
|
release_gpio(PAN_PINS[i]);
|
||||||
release_gpio(TILT_PINS[i]);
|
release_gpio(TILT_PINS[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue