From bcf1584fbe02c13777d424e4cf39dd91e88b323a Mon Sep 17 00:00:00 2001 From: Houman brinjcargorabi Date: Mon, 23 May 2016 13:55:57 +0100 Subject: [PATCH] mraa.c: Added common function to init io from a description Signed-off-by: Houman Brinjcargorabi Signed-off-by: Brendan Le Foll --- api/mraa/common.h | 13 ++++ api/mraa/common.hpp | 18 +++++ src/mraa.c | 157 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) diff --git a/api/mraa/common.h b/api/mraa/common.h index 0c9839c..c0467ba 100644 --- a/api/mraa/common.h +++ b/api/mraa/common.h @@ -293,6 +293,19 @@ mraa_result_t mraa_add_subplatform(mraa_platform_t subplatformtype, const char* */ mraa_result_t mraa_remove_subplatform(mraa_platform_t subplatformtype); +/** + * Create IO using a description in the format: + * [io]-[pin] + * [io]-[raw]-[pin] + * [io]-[raw]-[id]-[pin] + * [io]-[raw]-[path] + * + * @param IO description + * + * @return void* to IO context or NULL + */ +void* mraa_init_io(const char* desc); + #ifdef __cplusplus } #endif diff --git a/api/mraa/common.hpp b/api/mraa/common.hpp index 786518a..29894d3 100644 --- a/api/mraa/common.hpp +++ b/api/mraa/common.hpp @@ -309,4 +309,22 @@ removeSubplatform(Platform subplatformtype) return (Result) mraa_remove_subplatform((mraa_platform_t) subplatformtype); } +/** + * Create IO using a description in the format: + * [io]-[pin] + * [io]-[raw]-[pin] + * [io]-[raw]-[id]-[pin] + * [io]-[raw]-[path] + * + * @param IO description + * + * @return class T initialised using pointer to IO or NULL + */ +template +inline T* +initIo(std::string desc) +{ + return new T(mraa_init_io(desc.c_str())); +} + } diff --git a/src/mraa.c b/src/mraa.c index d82cc4b..e14f64b 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -41,6 +41,9 @@ #include #include #include +#include +#include +#include #if defined(IMRAA) #include @@ -52,6 +55,12 @@ #include "firmata/firmata_mraa.h" #include "gpio.h" #include "version.h" +#include "i2c.h" +#include "pwm.h" +#include "aio.h" +#include "spi.h" +#include "uart.h" + #define IIO_DEVICE_WILDCARD "iio:device*" mraa_board_t* plat = NULL; @@ -1073,3 +1082,151 @@ mraa_add_from_lockfile(const char* imraa_lock_file) return ret; } #endif + +void +mraa_to_upper(char* s) +{ + char* t = s; + for (; *t; ++t) { + *t = toupper(*t); + } +} + +mraa_result_t +mraa_atoi(char* intStr, int* value) +{ + char* end; + // here 10 determines the number base in which strol is to work + long val = strtol(intStr, &end, 10); + if (*end != '\0' || errno == ERANGE || end == intStr || val > INT_MAX || val < INT_MIN) { + *value = 0; + return MRAA_ERROR_UNSPECIFIED; + } + *value = (int) val; + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_init_io_helper(char** str, int* value, const char* delim) +{ + // This function is a result of a repeated pattern within mraa_init_io + // when determining if a value can be derived from a string + char* token; + token = strsep(str, delim); + // check to see if empty string returned + if (token == NULL) { + *value = 0; + return MRAA_ERROR_NO_DATA_AVAILABLE; + } + return mraa_atoi(token, value); +} + +void* +mraa_init_io(const char* desc) +{ + const char* delim = "-"; + int length = 0, raw = 0; + int pin = 0, id = 0; + // 256 denotes the maximum size of our buffer + // 8 denotes the maximum size of our type rounded to the nearest power of 2 + // max size is 4 + 1 for the \0 = 5 rounded to 8 + char buffer[256] = { 0 }, type[8] = { 0 }; + char *token = 0, *str = 0; + length = strlen(desc); + // Check to see the length is less than or equal to 255 which means + // byte 256 is supposed to be \0 + if (length > 255 || desc == NULL || length == 0) { + return NULL; + } + strncpy(buffer, desc, length); + + str = buffer; + token = strsep(&str, delim); + length = strlen(token); + // Check to see they haven't given us a type whose length is greater than the + // largest type we know about + if (length > 4) { + syslog(LOG_ERR, "mraa_init_io: An invalid IO type was provided"); + return NULL; + } + strncpy(type, token, length); + mraa_to_upper(type); + token = strsep(&str, delim); + // Check that they've given us more information than just the type + if (token == NULL) { + syslog(LOG_ERR, "mraa_init_io: Missing information after type"); + return NULL; + } + // If we cannot convert the pin to a number maybe it says raw? + if (mraa_atoi(token, &pin) != MRAA_SUCCESS) { + mraa_to_upper(token); + if (strncmp(token, "RAW", 3)) { + syslog(LOG_ERR, "mraa_init_io: Description does not adhere to a known format"); + return NULL; + } + raw = 1; + } + if (!raw && str != NULL) { + syslog(LOG_ERR, "mraa_init_io: More information than required was provided"); + return NULL; + } + + if (strncmp(type, "GPIO", 4) == 0) { + if (raw) { + if (mraa_init_io_helper(&str, &pin, delim) == MRAA_SUCCESS) { + return (void*) mraa_gpio_init_raw(pin); + } + syslog(LOG_ERR, "mraa_init_io: Invalid Raw description for GPIO"); + return NULL; + } + return (void*) mraa_gpio_init(pin); + } else if (strncmp(type, "I2C", 3) == 0) { + if (raw) { + if (mraa_init_io_helper(&str, &pin, delim) == MRAA_SUCCESS) { + return (void*) mraa_i2c_init_raw(pin); + } + syslog(LOG_ERR, "mraa_init_io: Invalid Raw description for I2C"); + return NULL; + } + return (void*) mraa_i2c_init(pin); + } else if (strncmp(type, "AIO", 3) == 0) { + if (raw) { + syslog(LOG_ERR, "mraa_init_io: Aio doesn't have a RAW mode"); + return NULL; + } + return (void*) mraa_aio_init(pin); + } else if (strncmp(type, "PWM", 3) == 0) { + if (raw) { + if (mraa_init_io_helper(&str, &id, delim) != MRAA_SUCCESS) { + syslog(LOG_ERR, "mraa_init_io: Pwm, unable to convert the chip id string into a useable Int"); + return NULL; + } + if (mraa_init_io_helper(&str, &pin, delim) != MRAA_SUCCESS) { + syslog(LOG_ERR, "mraa_init_io: Pwm, unable to convert the pin string into a useable Int"); + return NULL; + } + return (void*) mraa_pwm_init_raw(id, pin); + } + return (void*) mraa_pwm_init(pin); + } else if (strncmp(type, "SPI", 3) == 0) { + if (raw) { + if (mraa_init_io_helper(&str, &id, delim) != MRAA_SUCCESS) { + syslog(LOG_ERR, "mraa_init_io: Spi, unable to convert the bus string into a useable Int"); + return NULL; + } + if (mraa_init_io_helper(&str, &pin, delim) != MRAA_SUCCESS) { + syslog(LOG_ERR, "mraa_init_io: Spi, unable to convert the cs string into a useable Int"); + return NULL; + } + return (void*) mraa_spi_init_raw(id, pin); + } + return (void*) mraa_spi_init(pin); + } else if (strncmp(type, "UART", 4) == 0) { + if (raw) { + return (void*) mraa_uart_init_raw(str); + } + return (void*) mraa_uart_init(pin); + } + syslog(LOG_ERR, "mraa_init_io: Invalid IO type given."); + return NULL; +}