From 1f4714a35103c53a62aebda1f13d15b0fb3249fb Mon Sep 17 00:00:00 2001 From: fordsfords Date: Sat, 25 Jun 2016 20:02:45 -0500 Subject: [PATCH] Got rid of last of GPIO port constants from code. --- source/c_pwm.c | 15 ++++++------- source/common.c | 52 ++++++++++++++++++++++----------------------- source/common.h | 25 ++++++++++++++++++---- source/event_gpio.c | 14 ++++++------ source/py_gpio.c | 19 ++++++++++++----- 5 files changed, 75 insertions(+), 50 deletions(-) diff --git a/source/c_pwm.c b/source/c_pwm.c index c38657c..0a565b3 100644 --- a/source/c_pwm.c +++ b/source/c_pwm.c @@ -89,7 +89,7 @@ int initialize_pwm(void) return -1; } len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); - write(fd, str_gpio, len); + ssize_t s = write(fd, str_gpio, len); ASSRT(s == len); close(fd); pwm_initialized = 1; @@ -120,7 +120,7 @@ int pwm_set_frequency(const char *key, float freq) { pwm->period_ns = period_ns; len = snprintf(buffer, sizeof(buffer), "%lu", period_ns); - write(pwm->period_fd, buffer, len); + ssize_t s = write(pwm->period_fd, buffer, len); ASSRT(s == len); } return 1; @@ -148,7 +148,7 @@ int pwm_set_polarity(const char *key, int polarity) { { len = snprintf(buffer, sizeof(buffer), "%s", "inverted"); } - write(pwm->polarity_fd, buffer, len); + ssize_t s = write(pwm->polarity_fd, buffer, len); ASSRT(s == len); return 0; } @@ -170,7 +170,7 @@ int pwm_set_duty_cycle(const char *key, float duty) { pwm->duty = (unsigned long)(pwm->period_ns * (duty / 100.0)); len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty); - write(pwm->duty_fd, buffer, len); + ssize_t s = write(pwm->duty_fd, buffer, len); ASSRT(s == len); return 0; } @@ -193,7 +193,7 @@ int pwm_set_enable(const char *key, int enable) pwm->enable = enable; len = snprintf(buffer, sizeof(buffer), "%d", pwm->enable); - write(pwm->enable_fd, buffer, len); + ssize_t s = write(pwm->enable_fd, buffer, len); ASSRT(s == len); return 0; } @@ -213,7 +213,7 @@ int pwm_start(const char *key, float duty, float freq, int polarity) } //setup the pwm base path, the chip only has one pwm - snprintf(pwm_base_path, sizeof(pwm_base_path), "/sys/class/pwm/pwmchip0/%d", "pwm0"); + snprintf(pwm_base_path, sizeof(pwm_base_path), "/sys/class/pwm/pwmchip0/pwm%d", 0); //create the path for the period and duty snprintf(enable_path, sizeof(enable_path), "%s/enable", pwm_base_path); @@ -283,7 +283,6 @@ int pwm_start(const char *key, float duty, float freq, int polarity) int pwm_disable(const char *key) { struct pwm_exp *pwm, *temp, *prev_pwm = NULL; - char fragment[18]; int fd, len; char str_gpio[2]; @@ -302,7 +301,7 @@ int pwm_disable(const char *key) return -1; } len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); - write(fd, str_gpio, len); + ssize_t s = write(fd, str_gpio, len); ASSRT(s == len); close(fd); // remove from list diff --git a/source/common.c b/source/common.c index 993c073..25c5f71 100644 --- a/source/common.c +++ b/source/common.c @@ -45,11 +45,9 @@ SOFTWARE. #include #include #include -#include int setup_error = 0; int module_setup = 0; -int xio_base_address = -1; /* not yet initialized */ // In the pins_t structure, the "base_method" field tells how // the "gpio" field should be interpreted. @@ -150,6 +148,7 @@ pins_t pins_info[] = { { NULL, NULL, 0 } }; + // CREDIT FOR THIS FUNCTION DUE TO HOWIE KATZ OF NTC AND STEVE FORD // THIS WILL FIND THE PROPER XIO BASE SYSFS NUMBER // PORTED TO C FORM HOWIE'S PYTHON CODE WITH THE HELP OF STEVE: @@ -159,51 +158,55 @@ pins_t pins_info[] = { // http://stackoverflow.com/questions/612097/how-can-i-get-the-list-of-files-in-a-directory-using-c-or-c #define GPIO_PATH "/sys/class/gpio" #define EXPANDER "pcf8574a\n" -#define OLDXIOBASE 408 -int get_xio_base() +int get_xio_base(void) { - int xiobase = -1; char label_file[80]; FILE *label_fp; char base_file[80]; FILE *base_fp; char input_line[80]; + // Makes use of static variable xio_base_address to maintain state between + // calls. First time this is called, xio_base_address is -1, so the actual + // base address is calculated and stored in xio_base_address. Subsequent + // calls just use the previously-calculated value. + static int xio_base_address = -1; DIR *dir; struct dirent *ent; struct stat sbuf; - if ((dir = opendir (GPIO_PATH)) != NULL) { - while ((ent = readdir (dir)) != NULL) { + if (xio_base_address == -1 && (dir = opendir (GPIO_PATH)) != NULL) { + while (xio_base_address == -1 && (ent = readdir (dir)) != NULL) { lstat(ent->d_name,&sbuf); if (S_ISDIR(sbuf.st_mode)) { if (strcmp(".",ent->d_name) == 0 || strcmp("..",ent->d_name) == 0) { - continue; + continue; /* skip "." and ".." entries */ } //printf ("%s\n", ent->d_name); sprintf(label_file, "%s/%s/label", GPIO_PATH, ent->d_name); //printf("label_file='%s'\n", label_file); label_fp = fopen(label_file, "r"); if (label_fp != NULL) { - fgets(input_line, sizeof(input_line), label_fp); assert(strlen(input_line) < sizeof(input_line)-1); + char *s = fgets(input_line, sizeof(input_line), label_fp); + ASSRT(s == input_line && strlen(input_line) < sizeof(input_line)-1); fclose(label_fp); if (strcmp(input_line, EXPANDER) == 0) { /* Found the expander, get the contents of base */ sprintf(base_file, "%s/%s/base", GPIO_PATH, ent->d_name); - base_fp = fopen(base_file, "r"); assert(base_fp != NULL); - fgets(input_line, sizeof(input_line), base_fp); assert(strlen(input_line) < sizeof(input_line)-1); + base_fp = fopen(base_file, "r"); ASSRT(base_fp != NULL); + s = fgets(input_line, sizeof(input_line), base_fp); + ASSRT(s == input_line && strlen(input_line) < sizeof(input_line)-1); fclose(base_fp); - xiobase = atoi(input_line); - break; /* Found it, exit the while */ + xio_base_address = atoi(input_line); /* remember the result */ } - } - } - } + } /* if label file is open */ + } /* if isdir */ + } /* while */ closedir (dir); } - return xiobase; -} + return xio_base_address; +} /* get_xio_base */ int gpio_number(pins_t *pin) @@ -216,16 +219,13 @@ int gpio_number(pins_t *pin) break; case BASE_METHOD_XIO: - if (xio_base_address == -1) { - xio_base_address = get_xio_base(); /* only call this the first time */ - } - gpio_num = pin->gpio + xio_base_address; + gpio_num = pin->gpio + get_xio_base(); break; } - assert(gpio_num != -1); + ASSRT(gpio_num != -1); return gpio_num; -} +} /* gpio_number */ int lookup_gpio_by_key(const char *key) @@ -397,11 +397,11 @@ int build_path(const char *partial_path, const char *prefix, char *full_path, si if (found_string != NULL && (ep->d_name - found_string) == 0) { snprintf(full_path, full_path_len, "%s/%s", partial_path, ep->d_name); - (void) closedir (dp); + closedir (dp); return 1; } } - (void) closedir (dp); + closedir (dp); } else { return 0; } diff --git a/source/common.h b/source/common.h index 716482c..e6020f1 100644 --- a/source/common.h +++ b/source/common.h @@ -42,14 +42,31 @@ SOFTWARE. #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +// See http://blog.geeky-boy.com/2016/06/of-compiler-warnings-and-asserts-in.html +#define ASSRT(cond_expr) do { \ + if (!(cond_expr)) { \ + fprintf(stderr, "ASSRT failed at %s:%d (%s)", __FILE__, __LINE__, #cond_expr); \ + fflush(stderr); \ + abort(); \ +} } while (0) + #define FILENAME_BUFFER_SIZE 128 -int get_xio_base(); +int setup_error; +int module_setup; + +int get_xio_base(void); +int lookup_gpio_by_key(const char *key); +int lookup_gpio_by_name(const char *name); +int lookup_ain_by_key(const char *key); +int lookup_ain_by_name(const char *name); +int copy_key_by_key(const char *input_key, char *key); +int copy_pwm_key_by_key(const char *input_key, char *key); +int get_key_by_name(const char *name, char *key); +int get_pwm_key_by_name(const char *name, char *key); int get_gpio_number(const char *key, unsigned int *gpio); -int get_pwm_key(const char *input, char *key); int get_key(const char *input, char *key); +int get_pwm_key(const char *input, char *key); int get_adc_ain(const char *key, unsigned int *ain); int build_path(const char *partial_path, const char *prefix, char *full_path, size_t full_path_len); int get_spi_bus_path_number(unsigned int spi); -int setup_error; -int module_setup; diff --git a/source/event_gpio.c b/source/event_gpio.c index 51da8e1..db16426 100644 --- a/source/event_gpio.c +++ b/source/event_gpio.c @@ -92,7 +92,7 @@ int gpio_export(unsigned int gpio) return -1; } len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); - write(fd, str_gpio, len); + ssize_t s = write(fd, str_gpio, len); ASSRT(s == len); close(fd); // add to list @@ -201,7 +201,7 @@ int gpio_unexport(unsigned int gpio) return -1; len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); - write(fd, str_gpio, len); + ssize_t s = write(fd, str_gpio, len); ASSRT(s == len); close(fd); // remove from list @@ -241,7 +241,7 @@ int gpio_set_direction(unsigned int gpio, unsigned int in_flag) strncpy(direction, "in", ARRAY_SIZE(direction) - 1); } - write(fd, direction, strlen(direction)); + ssize_t s = write(fd, direction, strlen(direction)); ASSRT(s == strlen(direction)); close(fd); return 0; } @@ -257,7 +257,7 @@ int gpio_get_direction(unsigned int gpio, unsigned int *value) return -1; lseek(fd, 0, SEEK_SET); - read(fd, &direction, sizeof(direction) - 1); + ssize_t s = read(fd, &direction, sizeof(direction) - 1); ASSRT(s > 0); if (strcmp(direction, "out") == 0) { *value = OUTPUT; @@ -285,7 +285,7 @@ int gpio_set_value(unsigned int gpio, unsigned int value) strncpy(vstr, "0", ARRAY_SIZE(vstr) - 1); } - write(fd, vstr, strlen(vstr)); + ssize_t s = write(fd, vstr, strlen(vstr)); ASSRT(s == strlen(vstr)); close(fd); return 0; } @@ -302,7 +302,7 @@ int gpio_get_value(unsigned int gpio, unsigned int *value) } lseek(fd, 0, SEEK_SET); - read(fd, &ch, sizeof(ch)); + ssize_t s = read(fd, &ch, sizeof(ch)); ASSRT(s > 0); if (ch != '0') { *value = 1; @@ -323,7 +323,7 @@ int gpio_set_edge(unsigned int gpio, unsigned int edge) if ((fd = open(filename, O_WRONLY)) < 0) return -1; - write(fd, stredge[edge], strlen(stredge[edge]) + 1); + ssize_t s = write(fd, stredge[edge], strlen(stredge[edge]) + 1); ASSRT(s == strlen(stredge[edge]) + 1); close(fd); return 0; } diff --git a/source/py_gpio.c b/source/py_gpio.c index 2f3f71d..9cefaf1 100644 --- a/source/py_gpio.c +++ b/source/py_gpio.c @@ -129,7 +129,8 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar gpio_export(gpio); gpio_set_direction(gpio, direction); - if (gpio < 408) { + // For some reason, the following code doesn't work for XIOs. Skip. + if (!(gpio >= lookup_gpio_by_name("XIO-P0") && gpio <= lookup_gpio_by_name("XIO-P7"))) { if (direction == OUTPUT) { gpio_set_value(gpio, initial); } else { @@ -285,7 +286,9 @@ static PyObject *py_add_event_callback(PyObject *self, PyObject *args, PyObject return NULL; // check to ensure gpio is one of the allowed pins - if (gpio != 35 && gpio != 193 && !(gpio <= 415 && gpio >= 408)) { + if (gpio != lookup_gpio_by_name("AP-EINT3") + && gpio != lookup_gpio_by_name("AP-EINT1") + && !(gpio >= lookup_gpio_by_name("XIO-P0") && gpio <= lookup_gpio_by_name("XIO-P7"))) { PyErr_SetString(PyExc_RuntimeError, "Callbacks currently available on AP-EINT1, AP-EINT3, and XIO-P0 to XIO-P7 only"); return NULL; } @@ -332,7 +335,9 @@ static PyObject *py_add_event_detect(PyObject *self, PyObject *args, PyObject *k return NULL; // check to ensure gpio is one of the allowed pins - if (gpio != 35 && gpio != 193 && !(gpio <= 415 && gpio >= 408)) { + if (gpio != lookup_gpio_by_name("AP-EINT3") + && gpio != lookup_gpio_by_name("AP-EINT1") + && !(gpio >= lookup_gpio_by_name("XIO-P0") && gpio <= lookup_gpio_by_name("XIO-P7"))) { PyErr_SetString(PyExc_RuntimeError, "Edge Detection currently available on AP-EINT1, AP-EINT3, and XIO-P0 to XIO-P7 only"); return NULL; } @@ -386,7 +391,9 @@ static PyObject *py_remove_event_detect(PyObject *self, PyObject *args) return NULL; // check to ensure gpio is one of the allowed pins - if (gpio != 35 && gpio != 193 && !(gpio <= 415 && gpio >= 408)) { + if (gpio != lookup_gpio_by_name("AP-EINT3") + && gpio != lookup_gpio_by_name("AP-EINT1") + && !(gpio >= lookup_gpio_by_name("XIO-P0") && gpio <= lookup_gpio_by_name("XIO-P7"))) { PyErr_SetString(PyExc_RuntimeError, "Edge Detection currently available on AP-EINT1, AP-EINT3, and XIO-P0 to XIO-P7 only"); return NULL; } @@ -448,7 +455,9 @@ static PyObject *py_wait_for_edge(PyObject *self, PyObject *args) return NULL; // check to ensure gpio is one of the allowed pins - if (gpio != 35 && gpio != 193 && !(gpio <= 415 && gpio >= 408)) { + if (gpio != lookup_gpio_by_name("AP-EINT3") + && gpio != lookup_gpio_by_name("AP-EINT1") + && !(gpio >= lookup_gpio_by_name("XIO-P0") && gpio <= lookup_gpio_by_name("XIO-P7"))) { PyErr_SetString(PyExc_RuntimeError, "Edge Detection currently available on AP-EINT1, AP-EINT3, and XIO-P0 to XIO-P7 only"); return NULL; }