From 226c6bcb660593afe5e8a8dc60d220ea949e1c43 Mon Sep 17 00:00:00 2001 From: Thomas Ingleby Date: Tue, 29 Apr 2014 16:46:10 +0100 Subject: [PATCH] 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 @@ -44,11 +44,19 @@ 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; } -- 2.7.4