From 226c6bcb660593afe5e8a8dc60d220ea949e1c43 Mon Sep 17 00:00:00 2001 From: Thomas Ingleby Date: Tue, 29 Apr 2014 16:46:10 +0100 Subject: [PATCH 1/3] gpio: Matured the GPIO API. * Greater use of return values. * Uses defined enum instead of char arrays Signed-off-by: Thomas Ingleby --- api/gpio.h | 93 +++++++++++++++++++++++++++++++++++++++++++------ src/gpio/gpio.c | 52 ++++++++++++++++++++------- 2 files changed, 121 insertions(+), 24 deletions(-) diff --git a/api/gpio.h b/api/gpio.h index 5475126..0298779 100644 --- a/api/gpio.h +++ b/api/gpio.h @@ -27,21 +27,92 @@ #include #include "maa.h" - +/** + * A strucutre representing a gpio pin. + */ typedef struct { - int pin; - int pinMap; - char path[64]; - FILE *value_fp; + /*@{*/ + int pin; /**< the pin number, as known to the os. */ + FILE *value_fp; /**< the file pointer to the value of the gpio /* + /*@}*/ } maa_gpio_context; -typedef char gpio_mode_t[16]; -typedef char gpio_dir_t[16]; +/** + * GPIO Output modes + */ +typedef enum { + MAA_GPIO_STRONG = 0, /**< Default. Strong high and low */ + MAA_GPIO_PULLUP = 1, /**< Resistive High */ + MAA_GPIO_PULLDOWN = 2, /**< Resistive Low */ + MAA_GPIO_HIZ = 3 /**< High Z State */ +} gpio_mode_t; +/** + * GPIO Direction options. + */ +typedef enum { + MAA_GPIO_OUT = 0, /**< Output. A Mode can also be set */ + MAA_GPIO_IN = 1 /**< Input. */ +} gpio_dir_t; + +/** Initialise gpio_context, based on board number + * + * @param pin pin number read from the board, i.e IO3 is 3. + * + * @returns + * maa_gpio_context based on the IO pin + */ maa_gpio_context* maa_gpio_init(int pin); -void maa_gpio_mode(maa_gpio_context *dev, gpio_mode_t mode); -void maa_gpio_dir(maa_gpio_context *dev, gpio_dir_t dir); -void maa_gpio_close(maa_gpio_context *dev); +/** Initialise gpio context without any mapping to a pin. + * - For more expert users + * + * @param gpiopin gpio pin as listed in SYSFS + * + * @return gpio context + */ +maa_gpio_context* maa_gpio_init_raw(int gpiopin); + +/** Set GPIO Output Mode, + * + * @param dev The GPIO context + * @param mode The GPIO Output Mode. + * + * @return maa result type. + */ +maa_result_t maa_gpio_mode(maa_gpio_context *dev, gpio_mode_t mode); + +/** Set GPIO direction + * + * @param dev The GPIO context. + * @param dir The direction of the GPIO. + * + * @return maa result type. + */ +maa_result_t maa_gpio_dir(maa_gpio_context *dev, gpio_dir_t dir); + +/** Close the GPIO context + * - Will free the memory for the context. + * + * @param dev the GPIO context + * + * @return maa result type. + */ +maa_result_t maa_gpio_close(maa_gpio_context *dev); + +/** Read the GPIO value. + * + * @param dev The GPIO context. + * + * @return the integer value of the GPIO + */ int maa_gpio_read(maa_gpio_context *dev); -void maa_gpio_write(maa_gpio_context *dev, int value); + +/** Write to the GPIO Value. + * + * @param dev The GPIO context. + * @param value Integer value to write. + * + * @return maa result type + */ +maa_result_t maa_gpio_write(maa_gpio_context *dev, int value); diff --git a/src/gpio/gpio.c b/src/gpio/gpio.c index 93d1415..65b9bb9 100644 --- a/src/gpio/gpio.c +++ b/src/gpio/gpio.c @@ -43,12 +43,20 @@ maa_gpio_get_valfp(maa_gpio_context *dev) maa_gpio_context* maa_gpio_init(int pin) +{ + //TODO + return NULL; +} + +maa_gpio_context* +maa_gpio_init_raw(int pin) { FILE *export_f; maa_gpio_context* dev = (maa_gpio_context*) malloc(sizeof(maa_gpio_context)); if ((export_f = fopen("/sys/class/gpio/export", "w")) == NULL) { fprintf(stderr, "Failed to open export for writing!\n"); + return NULL; } else { fprintf(export_f, "%d", pin); fclose(export_f); @@ -57,13 +65,13 @@ maa_gpio_init(int pin) return dev; } -void +maa_result_t maa_gpio_mode(maa_gpio_context *dev, gpio_mode_t mode) { - //gpio->pin + return MAA_ERROR_FEATURE_NOT_IMPLEMENTED; } -void +maa_result_t maa_gpio_dir(maa_gpio_context *dev, gpio_dir_t dir) { if (dev->value_fp != NULL) { @@ -75,11 +83,23 @@ maa_gpio_dir(maa_gpio_context *dev, gpio_dir_t dir) FILE *direction; if ((direction = fopen(filepath, "w")) == NULL) { fprintf(stderr, "Failed to open direction for writing!\n"); - } else { - fprintf(direction, dir); - fclose(direction); - dev->value_fp = NULL; + return MAA_ERROR_INVALID_RESOURCE; } + switch(dir) { + case MAA_GPIO_OUT: + fprintf(direction, "out"); + break; + case MAA_GPIO_IN: + fprintf(direction, "in"); + break; + default: + fclose(direction); + return MAA_ERROR_FEATURE_NOT_IMPLEMENTED; + break; + } + fclose(direction); + dev->value_fp = NULL; + return MAA_SUCCESS; } int @@ -95,7 +115,7 @@ maa_gpio_read(maa_gpio_context *dev) return atoi(buffer); } -void +maa_result_t maa_gpio_write(maa_gpio_context *dev, int value) { if (dev->value_fp == NULL) { @@ -104,18 +124,24 @@ maa_gpio_write(maa_gpio_context *dev, int value) fseek(dev->value_fp, SEEK_SET, 0); fprintf(dev->value_fp, "%d", value); fseek(dev->value_fp, SEEK_SET, 0); - + if (ferror(dev->value_fp) != 0) + return MAA_ERROR_INVALID_RESOURCE; + return MAA_SUCCESS; } -void +maa_result_t maa_gpio_close(maa_gpio_context *dev) { FILE *unexport_f; if ((unexport_f = fopen("/sys/class/gpio/unexport", "w")) == NULL) { fprintf(stderr, "Failed to open unexport for writing!\n"); - } else { - fprintf(unexport_f, "%d", dev->pin); - fclose(unexport_f); + return MAA_ERROR_INVALID_RESOURCE; } + fprintf(unexport_f, "%d", dev->pin); + fclose(unexport_f); + if (ferror(dev->value_fp) != 0) + return MAA_ERROR_INVALID_RESOURCE; + free(dev); + return MAA_SUCCESS; } From 0c0633e724a80822626232eaaac99665b48e9657 Mon Sep 17 00:00:00 2001 From: Thomas Ingleby Date: Tue, 29 Apr 2014 16:55:54 +0100 Subject: [PATCH 2/3] gpio: Add support for setting GPIO ouput drive. *Supports all exposed to sysfs Signed-off-by: Thomas Ingleby --- src/gpio/gpio.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/gpio/gpio.c b/src/gpio/gpio.c index 65b9bb9..1a94362 100644 --- a/src/gpio/gpio.c +++ b/src/gpio/gpio.c @@ -45,7 +45,7 @@ maa_gpio_context* maa_gpio_init(int pin) { //TODO - return NULL; + return maa_gpio_init_raw(pin); } maa_gpio_context* @@ -68,7 +68,38 @@ maa_gpio_init_raw(int pin) maa_result_t maa_gpio_mode(maa_gpio_context *dev, gpio_mode_t mode) { - return MAA_ERROR_FEATURE_NOT_IMPLEMENTED; + if (dev->value_fp != NULL) { + dev->value_fp = NULL; + } + char filepath[64]; + snprintf(filepath, 64, "/sys/class/gpio/gpio%d/drive", dev->pin); + + FILE *drive; + if ((drive = fopen(filepath, "w")) == NULL) { + fprintf(stderr, "Failed to open drive for writing!\n"); + return MAA_ERROR_INVALID_RESOURCE; + } + switch(mode) { + case MAA_GPIO_STRONG: + fprintf(drive, "strong"); + break; + case MAA_GPIO_PULLUP: + fprintf(drive, "pullup"); + break; + case MAA_GPIO_PULLDOWN: + fprintf(drive, "pulldown"); + break; + case MAA_GPIO_HIZ: + fprintf(drive, "hiz"); + break; + default: + fclose(drive); + return MAA_ERROR_FEATURE_NOT_IMPLEMENTED; + break; + } + fclose(drive); + dev->value_fp = NULL; + return MAA_SUCCESS; } maa_result_t From ac995a880316e3d49c744b81c5cdaca5579e3213 Mon Sep 17 00:00:00 2001 From: Thomas Ingleby Date: Tue, 29 Apr 2014 17:01:42 +0100 Subject: [PATCH 3/3] example: blink-io8.c Updated against new API Signed-off-by: Thomas Ingleby --- examples/blink-io8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/blink-io8.c b/examples/blink-io8.c index c3afa19..a26aba9 100644 --- a/examples/blink-io8.c +++ b/examples/blink-io8.c @@ -33,7 +33,7 @@ main(int argc, char **argv) maa_get_version()); maa_gpio_context* gpio; gpio = maa_gpio_init(26); - maa_gpio_dir(gpio, "out"); + maa_gpio_dir(gpio, MAA_GPIO_OUT); while (1) { maa_gpio_write(gpio, 0);