diff --git a/include/iqrf_debug.h b/include/iqrf_debug.h new file mode 100644 index 0000000..61f6c8d --- /dev/null +++ b/include/iqrf_debug.h @@ -0,0 +1,21 @@ +#pragma once + +#ifdef NDEBUG +#ifndef IQRF_DEBUG_PRINT +#define IQRF_DEBUG_PRINT(fmt, ...) +#endif +#ifndef IQRF_DEBUG_PRINTF +#define IQRF_DEBUG_PRINTF(fmt, ...) +#endif +#else +#ifndef IQRF_DEBUG_PRINT +#define IQRF_DEBUG_PRINT(str) do { \ + fprintf(stderr, "%s:%d - %s(): " str "\n", __FILE__, __LINE__, __func__); \ +} while (0) +#endif +#ifndef IQRF_DEBUG_PRINTF +#define IQRF_DEBUG_PRINTF(fmt, ...) do { \ + fprintf(stderr, "%s:%d - %s(): " fmt "\n", __FILE__, __LINE__, __func__, __VA_ARGS__); \ +} while (0) +#endif +#endif diff --git a/include/iqrf_gpio.h b/include/iqrf_gpio.h new file mode 100644 index 0000000..2eed22f --- /dev/null +++ b/include/iqrf_gpio.h @@ -0,0 +1,124 @@ +#ifndef IQRF_GPIO_H +#define IQRF_GPIO_H + +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#endif + +#include "iqrf_debug.h" +#include "sleepWrapper.h" + +#define IQRF_GPIO_SYSFS_BASE_PATH "/sys/class/gpio/" +#define IQRF_GPIO_SYSFS_BUFFER_SIZE 64 +#define IQRF_GPIO_DIRECTION_BUFFER_SIZE 4 +#define IQRF_GPIO_PIN_BUFFER_SIZE 20 +#define IQRF_GPIO_VALUE_BUFFER_SIZE 2 + +static const int64_t IQRF_GPIO_PIN_UNKNOWN = -1; + +typedef enum { + IQRF_GPIO_ACTION_DIRECTION, + IQRF_GPIO_ACTION_VALUE, +} iqrf_gpio_action_t; + +typedef enum { + IQRF_GPIO_DIRECTION_UNKNOWN = -1, + IQRF_GPIO_DIRECTION_IN, + IQRF_GPIO_DIRECTION_OUT, +} iqrf_gpio_direction_t; + +typedef enum { + IQRF_GPIO_ERROR_OK, + IQRF_GPIO_ERROR_INVALID_PIN, + IQRF_GPIO_ERROR_OPEN_FAILED, + IQRF_GPIO_ERROR_WRITE_FAILED, + IQRF_GPIO_ERROR_NULL_POINTER, +} iqrf_gpio_error_t; + +/** + * Exports the GPIO pin + * @param pin GPIO pin to export + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_export(int64_t pin); + +/** + * Unexports the GPIO pin + * @param pin GPIO pin to unexport + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_unexport(int64_t pin); + +/** + * Retrieves the direction for GPIO pin + * @param pin GPIO pin + * @param direction GPIO pin direction + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_get_direction(int64_t pin, iqrf_gpio_direction_t *direction); + +/** + * Sets the direction for GPIO pin + * @param pin GPIO pin + * @param direction GPIO pin direction + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_set_direction(int64_t pin, iqrf_gpio_direction_t direction); + +/** + * Retrieves the direction for GPIO pin + * @param pin GPIO pin + * @param value GPIO pin output value + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_get_value(int64_t pin, bool *value); + +/** + * Sets the direction for GPIO pin + * @param pin GPIO pin + * @param value GPIO pin output value + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_set_value(int64_t pin, bool value); + +/** + * Creates sysfs path + * @param pin GPIO pin + * @param action GPIO action + * @param targetPath + */ +void iqrf_gpio_create_sysfs_path(int64_t pin, iqrf_gpio_action_t action, char *targetPath); + +/** + * Initializes a GPIO pin + * @param pin GPIO pin number + * @param direction GPIO pin direction + * @param initialValue Initial output value + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_init(int64_t pin, iqrf_gpio_direction_t direction, bool initialValue); + +/** + * Initializes a GPIO pin as an input + * @param pin GPIO pin number + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_init_input(int64_t pin); + +/** + * Initializes a GPIO pin as an output + * @param pin GPIO pin + * @param initialValue Initial output value + * @return Execution status + */ +iqrf_gpio_error_t iqrf_gpio_init_output(int64_t pin, bool initialValue); + +#endif diff --git a/spi_iqrf/CMakeLists.txt b/spi_iqrf/CMakeLists.txt index 7d4c12b..a0c3ba9 100644 --- a/spi_iqrf/CMakeLists.txt +++ b/spi_iqrf/CMakeLists.txt @@ -1,7 +1,5 @@ project(spi_iqrf) -set(_SRC_FILES - spi_iqrf.c -) +set(_SRC_FILES iqrf_gpio.c spi_iqrf.c) add_library(${PROJECT_NAME} STATIC ${_SRC_FILES}) diff --git a/spi_iqrf/iqrf_gpio.c b/spi_iqrf/iqrf_gpio.c new file mode 100644 index 0000000..e8475e6 --- /dev/null +++ b/spi_iqrf/iqrf_gpio.c @@ -0,0 +1,230 @@ +#include "iqrf_gpio.h" + +#ifdef WIN32 +#define snprintf _snprintf +#endif + +static const char* IQRF_GPIO_ACTION_DIRECTION_STR = "direction"; +static const char* IQRF_GPIO_ACTION_VALUE_STR = "value"; +static const char* IQRF_GPIO_DIRECTION_IN_STR = "in"; +static const char* IQRF_GPIO_DIRECTION_OUT_STR = "out"; + +void iqrf_gpio_create_sysfs_path(int64_t pin, iqrf_gpio_action_t action, char *targetPath) { + const char *actionString = action == IQRF_GPIO_ACTION_DIRECTION ? IQRF_GPIO_ACTION_DIRECTION_STR : IQRF_GPIO_ACTION_VALUE_STR; + snprintf(targetPath, IQRF_GPIO_SYSFS_BUFFER_SIZE, IQRF_GPIO_SYSFS_BASE_PATH"gpio%"PRId64"/%s", pin, actionString); +} + +iqrf_gpio_error_t iqrf_gpio_export(int64_t pin) { +#ifdef WIN32 + return IQRF_GPIO_ERROR_OK; +#else + if (pin < 0) { + IQRF_DEBUG_PRINTF("Invalid GPIO pin number: %"PRId64, pin); + return IQRF_GPIO_ERROR_INVALID_PIN; + } + char *path = IQRF_GPIO_SYSFS_BASE_PATH"export"; + int fd = open(path, O_WRONLY); + if (fd == -1) { + IQRF_DEBUG_PRINTF("Unable to open path \"%s\". Reason: %s", path, strerror(errno)); + return IQRF_GPIO_ERROR_OPEN_FAILED; + } + char buffer[IQRF_GPIO_PIN_BUFFER_SIZE] = ""; + snprintf(buffer, IQRF_GPIO_PIN_BUFFER_SIZE, "%"PRId64, pin); + ssize_t writtenSize = write(fd, buffer, IQRF_GPIO_PIN_BUFFER_SIZE); + if (writtenSize == -1) { + close(fd); + IQRF_DEBUG_PRINTF("Unable to write '%s' into \"%s\". Reason: %s", buffer, path, strerror(errno)); + return IQRF_GPIO_ERROR_WRITE_FAILED; + } + close(fd); + return IQRF_GPIO_ERROR_OK; +#endif +} + +iqrf_gpio_error_t iqrf_gpio_unexport(int64_t pin) { +#ifdef WIN32 + return IQRF_GPIO_ERROR_OK; +#else + if (pin < 0) { + IQRF_DEBUG_PRINTF("Invalid GPIO pin number: %"PRId64, pin); + return IQRF_GPIO_ERROR_INVALID_PIN; + } + char *path = IQRF_GPIO_SYSFS_BASE_PATH"unexport"; + int fd = open(path, O_WRONLY); + if (fd == -1) { + IQRF_DEBUG_PRINTF("Unable to open path \"%s\". Reason: %s", path, strerror(errno)); + return IQRF_GPIO_ERROR_OPEN_FAILED; + } + char buffer[IQRF_GPIO_PIN_BUFFER_SIZE] = ""; + snprintf(buffer, IQRF_GPIO_PIN_BUFFER_SIZE, "%"PRId64, pin); + ssize_t writtenSize = write(fd, buffer, IQRF_GPIO_PIN_BUFFER_SIZE); + if (writtenSize == -1) { + close(fd); + IQRF_DEBUG_PRINTF("Unable to write '%s' into \"%s\". Reason: %s", buffer, path, strerror(errno)); + return IQRF_GPIO_ERROR_WRITE_FAILED; + } + close(fd); + return IQRF_GPIO_ERROR_OK; +#endif +} + +iqrf_gpio_error_t iqrf_gpio_get_direction(int64_t pin, iqrf_gpio_direction_t *direction) { +#ifdef WIN32 + return IQRF_GPIO_ERROR_OK; +#else + if (direction == NULL) { + return IQRF_GPIO_ERROR_NULL_POINTER; + } + if (pin < 0) { + IQRF_DEBUG_PRINTF("Invalid GPIO pin number: %"PRId64, pin); + return IQRF_GPIO_ERROR_INVALID_PIN; + } + char path[IQRF_GPIO_SYSFS_BUFFER_SIZE] = ""; + iqrf_gpio_create_sysfs_path(pin, IQRF_GPIO_ACTION_DIRECTION, path); + int fd = open(path, O_RDONLY); + if (fd == -1) { + IQRF_DEBUG_PRINTF("Unable to open path \"%s\". Reason: %s", path, strerror(errno)); + return IQRF_GPIO_ERROR_OPEN_FAILED; + } + char buffer[IQRF_GPIO_DIRECTION_BUFFER_SIZE] = ""; + ssize_t readSize = read(fd, buffer, IQRF_GPIO_DIRECTION_BUFFER_SIZE); + if (readSize == -1) { + close(fd); + IQRF_DEBUG_PRINTF("Unable to read from %s", path); + return IQRF_GPIO_ERROR_WRITE_FAILED; + } + if (strncmp(buffer, IQRF_GPIO_DIRECTION_IN_STR, IQRF_GPIO_DIRECTION_BUFFER_SIZE - 1) == 0) { + *direction = IQRF_GPIO_DIRECTION_IN; + } else if (strncmp(buffer, IQRF_GPIO_DIRECTION_OUT_STR, IQRF_GPIO_DIRECTION_BUFFER_SIZE - 1) == 0) { + *direction = IQRF_GPIO_DIRECTION_OUT; + } else { + *direction = IQRF_GPIO_DIRECTION_UNKNOWN; + } + close(fd); + return IQRF_GPIO_ERROR_OK; +#endif +} + +iqrf_gpio_error_t iqrf_gpio_set_direction(int64_t pin, iqrf_gpio_direction_t direction) { +#ifdef WIN32 + return IQRF_GPIO_ERROR_OK; +#else + if (pin < 0) { + IQRF_DEBUG_PRINTF("Invalid GPIO pin number: %"PRId64, pin); + return IQRF_GPIO_ERROR_INVALID_PIN; + } + char path[IQRF_GPIO_SYSFS_BUFFER_SIZE] = ""; + iqrf_gpio_create_sysfs_path(pin, IQRF_GPIO_ACTION_DIRECTION, path); + int fd = open(path, O_WRONLY); + if (fd == -1) { + IQRF_DEBUG_PRINTF("Unable to open path \"%s\". Reason: %s", path, strerror(errno)); + return IQRF_GPIO_ERROR_OPEN_FAILED; + } + const char *buffer = direction == IQRF_GPIO_DIRECTION_IN ? IQRF_GPIO_DIRECTION_IN_STR : IQRF_GPIO_DIRECTION_OUT_STR; + ssize_t writtenSize = write(fd, buffer, strlen(buffer)); + if (writtenSize == -1) { + close(fd); + IQRF_DEBUG_PRINTF("Unable to write '%s' into \"%s\". Reason: %s", buffer, path, strerror(errno)); + return IQRF_GPIO_ERROR_WRITE_FAILED; + } + close(fd); + return IQRF_GPIO_ERROR_OK; +#endif +} + +iqrf_gpio_error_t iqrf_gpio_get_value(int64_t pin, bool *value) { +#ifdef WIN32 + return IQRF_GPIO_ERROR_OK; +#else + if (value == NULL) { + return IQRF_GPIO_ERROR_NULL_POINTER; + } + if (pin < 0) { + IQRF_DEBUG_PRINTF("Invalid GPIO pin number: %"PRId64, pin); + return IQRF_GPIO_ERROR_INVALID_PIN; + } + char path[IQRF_GPIO_SYSFS_BUFFER_SIZE] = ""; + iqrf_gpio_create_sysfs_path(pin, IQRF_GPIO_ACTION_VALUE, path); + int fd = open(path, O_RDONLY); + if (fd == -1) { + IQRF_DEBUG_PRINTF("Unable to open path \"%s\". Reason: %s", path, strerror(errno)); + return IQRF_GPIO_ERROR_OPEN_FAILED; + } + char buffer[IQRF_GPIO_VALUE_BUFFER_SIZE] = ""; + ssize_t readSize = read(fd, buffer, IQRF_GPIO_VALUE_BUFFER_SIZE); + if (readSize == -1) { + close(fd); + IQRF_DEBUG_PRINTF("Unable to read from %s", path); + return IQRF_GPIO_ERROR_WRITE_FAILED; + } + *value = strncmp(buffer, "1", IQRF_GPIO_VALUE_BUFFER_SIZE - 1) == 0; + close(fd); + return IQRF_GPIO_ERROR_OK; +#endif +} + +iqrf_gpio_error_t iqrf_gpio_set_value(int64_t pin, bool value) { +#ifdef WIN32 + return IQRF_GPIO_ERROR_OK; +#else + if (pin < 0) { + IQRF_DEBUG_PRINTF("Invalid GPIO pin number: %"PRId64, pin); + return IQRF_GPIO_ERROR_INVALID_PIN; + } + char path[IQRF_GPIO_SYSFS_BUFFER_SIZE] = ""; + iqrf_gpio_create_sysfs_path(pin, IQRF_GPIO_ACTION_VALUE, path); + int fd = open(path, O_WRONLY); + if (fd == -1) { + IQRF_DEBUG_PRINTF("Unable to open path \"%s\". Reason: %s", path, strerror(errno)); + return IQRF_GPIO_ERROR_OPEN_FAILED; + } + const char *buffer = value ? "1" : "0"; + ssize_t writtenSize = write(fd, buffer, 2); + if (writtenSize == -1) { + close(fd); + IQRF_DEBUG_PRINTF("Unable to write '%s' into \"%s\". Reason: %s", buffer, path, strerror(errno)); + return IQRF_GPIO_ERROR_WRITE_FAILED; + } + close(fd); + return IQRF_GPIO_ERROR_OK; +#endif +} + +iqrf_gpio_error_t iqrf_gpio_init(int64_t pin, iqrf_gpio_direction_t direction, bool initialValue) { +#ifdef WIN32 + return IQRF_GPIO_ERROR_OK; +#else + iqrf_gpio_error_t error = iqrf_gpio_export(pin); + if (error) { + return error; + } + + char *directionStr = direction == IQRF_GPIO_DIRECTION_IN ? "input" : "output"; + for (uint8_t i = 1; i <= 10; i++) { + error = iqrf_gpio_set_direction(pin, direction); + if (!error) { + IQRF_DEBUG_PRINTF("GPIO pin #%"PRId64" direction \"%s\" is successfully set. Attempt: %d", pin, directionStr, i); + break; + } + IQRF_DEBUG_PRINTF("Failed to set direction \"%s\" on GPIO pin #%"PRId64". Wait for 100 ms to next try: %d", directionStr, pin, i); + SLEEP(100); + } + + if (direction == IQRF_GPIO_DIRECTION_OUT) { + error = iqrf_gpio_set_value(pin, initialValue); + if (error) { + return error; + } + } + + return IQRF_GPIO_ERROR_OK; +#endif +} + +iqrf_gpio_error_t iqrf_gpio_init_input(int64_t pin) { + return iqrf_gpio_init(pin, IQRF_GPIO_DIRECTION_IN, false); +} + +iqrf_gpio_error_t iqrf_gpio_init_output(int64_t pin, bool initialValue) { + return iqrf_gpio_init(pin, IQRF_GPIO_DIRECTION_OUT, initialValue); +} diff --git a/spi_iqrf/spi_iqrf.c b/spi_iqrf/spi_iqrf.c index 2e350e1..38df8ac 100644 --- a/spi_iqrf/spi_iqrf.c +++ b/spi_iqrf/spi_iqrf.c @@ -15,7 +15,6 @@ * limitations under the License. */ -#include #include #include #include @@ -24,7 +23,6 @@ //TODO use std::chrono::high_resolution_clock for timing #ifndef WIN32 #include -#include #include #include #include @@ -89,25 +87,10 @@ static uint64_t get_ms_ts() #endif #include -#include "declspec.h" #include #include -#ifdef WIN32 -#define snprintf _snprintf -#endif - -/* constants */ -#define GPIO_BASE_PATH "/sys/class/gpio" -#define GPIO_EXPORT_PATH GPIO_BASE_PATH"/export" -#define GPIO_UNEXPORT_PATH GPIO_BASE_PATH"/unexport" - -#define GPIO_DIRECTION_STR "direction" -#define GPIO_VALUE_STR "value" - -/* gpio clibspi_gpio_getDirection state */ -#define GPIO_DIRECTION_IN_STR "in" -#define GPIO_DIRECTION_OUT_STR "out" +#include "iqrf_gpio.h" /************************************/ /* Private constants */ @@ -168,16 +151,6 @@ typedef enum _spi_iqrf_SPICtype { CTYPE_BUFFER_UNCHANGED } spi_iqrf_SPICtype; -/** Values that represent GPIO directions. */ -typedef enum _clibspi_gpio_direction { - ///< An enum constant representing not available GPIO direction - GPIO_DIRECTION_NOT_AVAILABLE = -1, - ///< An enum constant representing GPIO input - GPIO_DIRECTION_IN = 0, - ///< An enum constant representing GPIO output - GPIO_DIRECTION_OUT -} clibspi_gpio_direction; - /************************************/ /* Private variables */ /************************************/ @@ -209,15 +182,6 @@ static int spi_reset_tr(unsigned int spiMasterEnableOutState); static int spi_iqrf_open(void); static int spi_iqrf_close(void); -int clibspi_gpio_export(uint32_t gpio); -int clibspi_gpio_unexport(uint32_t gpio); -int clibspi_gpio_setDirection(uint32_t gpio, clibspi_gpio_direction dir); -clibspi_gpio_direction clibspi_gpio_getDirection(uint32_t gpio); -int clibspi_gpio_setValue(uint32_t gpio, int val); -int clibspi_gpio_getValue(uint32_t gpio); -int clibspi_gpio_setup(uint32_t gpio, clibspi_gpio_direction dir, int val); -int clibspi_gpio_cleanup(uint32_t gpio); - /** * Initializes nullTransfer structure for low speed communication. * It is used for application of T1 delay - see document: @@ -717,24 +681,24 @@ int spi_iqrf_initAdvanced(const spi_iqrf_config_struct *configStruct) // Initialize PGM SW pin, SPI master enable pin & power enable if (spiIqrfConfig->pgmSwitchGpioPin != -1) { - clibspi_gpio_setup((uint32_t)spiIqrfConfig->pgmSwitchGpioPin, GPIO_DIRECTION_OUT, 0); + iqrf_gpio_init_output(spiIqrfConfig->pgmSwitchGpioPin, 0); } if (spiIqrfConfig->powerEnableGpioPin != -1) { - clibspi_gpio_setup((uint32_t)spiIqrfConfig->powerEnableGpioPin, GPIO_DIRECTION_OUT, 1); + iqrf_gpio_init_output(spiIqrfConfig->powerEnableGpioPin, 1); } if (spiIqrfConfig->busEnableGpioPin != -1) { - clibspi_gpio_setup((uint32_t)spiIqrfConfig->busEnableGpioPin, GPIO_DIRECTION_OUT, 1); + iqrf_gpio_init_output(spiIqrfConfig->busEnableGpioPin, 1); } else { if (spiIqrfConfig->spiEnableGpioPin != -1) { - clibspi_gpio_setup((uint32_t)spiIqrfConfig->spiEnableGpioPin, GPIO_DIRECTION_OUT, 1); + iqrf_gpio_init_output(spiIqrfConfig->spiEnableGpioPin, 1); } if (spiIqrfConfig->uartEnableGpioPin != -1) { - clibspi_gpio_setup((uint32_t)spiIqrfConfig->uartEnableGpioPin, GPIO_DIRECTION_OUT, 0); + iqrf_gpio_init_output(spiIqrfConfig->uartEnableGpioPin, 0); } if (spiIqrfConfig->i2cEnableGpioPin != -1) { - clibspi_gpio_setup((uint32_t)spiIqrfConfig->i2cEnableGpioPin, GPIO_DIRECTION_OUT, 0); + iqrf_gpio_init_output(spiIqrfConfig->i2cEnableGpioPin, 0); } } @@ -750,22 +714,22 @@ int spi_iqrf_initAdvanced(const spi_iqrf_config_struct *configStruct) spi_iqrf_setCommunicationMode(SPI_IQRF_HIGH_SPEED_MODE); return BASE_TYPES_OPER_OK; } else { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->powerEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->powerEnableGpioPin); if (spiIqrfConfig->busEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->busEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->busEnableGpioPin); } else { if (spiIqrfConfig->spiEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->spiEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->spiEnableGpioPin); } if (spiIqrfConfig->uartEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->uartEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->uartEnableGpioPin); } if (spiIqrfConfig->i2cEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->i2cEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->i2cEnableGpioPin); } } if (spiIqrfConfig->pgmSwitchGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->pgmSwitchGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->pgmSwitchGpioPin); } return BASE_TYPES_OPER_ERROR; } @@ -1447,19 +1411,19 @@ static int spi_reset_tr(unsigned int spiMasterEnableOutState) { // Disconnect SPI master from TR module if (spiIqrfConfig->busEnableGpioPin != -1) { - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->busEnableGpioPin, 0) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->busEnableGpioPin, 0) < 0) return BASE_TYPES_OPER_ERROR; } else { if (spiIqrfConfig->spiEnableGpioPin != -1) { - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->spiEnableGpioPin, 0) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->spiEnableGpioPin, 0) < 0) return BASE_TYPES_OPER_ERROR; } if (spiIqrfConfig->uartEnableGpioPin != -1) { - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->uartEnableGpioPin, 0) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->uartEnableGpioPin, 0) < 0) return BASE_TYPES_OPER_ERROR; } if (spiIqrfConfig->i2cEnableGpioPin != -1) { - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->i2cEnableGpioPin, 0) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->i2cEnableGpioPin, 0) < 0) return BASE_TYPES_OPER_ERROR; } } @@ -1467,14 +1431,14 @@ static int spi_reset_tr(unsigned int spiMasterEnableOutState) SLEEP(1); // Disable PWR for TR - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->powerEnableGpioPin, 0) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->powerEnableGpioPin, 0) < 0) return BASE_TYPES_OPER_ERROR; // Sleep for 300ms SLEEP(300); // Enable PWR for TR - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->powerEnableGpioPin, 1) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->powerEnableGpioPin, 1) < 0) return BASE_TYPES_OPER_ERROR; SLEEP(1); @@ -1482,11 +1446,11 @@ static int spi_reset_tr(unsigned int spiMasterEnableOutState) if (spiMasterEnableOutState != 0) { // Connect SPI master to TR module if (spiIqrfConfig->busEnableGpioPin != -1) { - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->busEnableGpioPin, 1) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->busEnableGpioPin, 1) < 0) return BASE_TYPES_OPER_ERROR; } else { if (spiIqrfConfig->spiEnableGpioPin != -1) { - if (clibspi_gpio_setValue((uint32_t)spiIqrfConfig->spiEnableGpioPin, 1) < 0) + if (iqrf_gpio_set_value(spiIqrfConfig->spiEnableGpioPin, 1) < 0) return BASE_TYPES_OPER_ERROR; } } @@ -1575,21 +1539,21 @@ int spi_iqrf_pe(void) return BASE_TYPES_OPER_OK; if (spiIqrfConfig->busEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->busEnableGpioPin, 0); + iqrf_gpio_set_value(spiIqrfConfig->busEnableGpioPin, 0); } else { if (spiIqrfConfig->spiEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->spiEnableGpioPin, 0); + iqrf_gpio_set_value(spiIqrfConfig->spiEnableGpioPin, 0); } if (spiIqrfConfig->uartEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->uartEnableGpioPin, 0); + iqrf_gpio_set_value(spiIqrfConfig->uartEnableGpioPin, 0); } if (spiIqrfConfig->i2cEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->i2cEnableGpioPin, 0); + iqrf_gpio_set_value(spiIqrfConfig->i2cEnableGpioPin, 0); } } if (spiIqrfConfig->pgmSwitchGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->pgmSwitchGpioPin, 1); + iqrf_gpio_set_value(spiIqrfConfig->pgmSwitchGpioPin, 1); } else { return SPI_HW_ERROR_PGMPIN; } @@ -1600,18 +1564,18 @@ int spi_iqrf_pe(void) // Sleep for 500ms SLEEP(500); - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->pgmSwitchGpioPin, 0); + iqrf_gpio_set_value(spiIqrfConfig->pgmSwitchGpioPin, 0); if (spiIqrfConfig->busEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->busEnableGpioPin, 1); + iqrf_gpio_set_value(spiIqrfConfig->busEnableGpioPin, 1); } else { if (spiIqrfConfig->spiEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->spiEnableGpioPin, 1); + iqrf_gpio_set_value(spiIqrfConfig->spiEnableGpioPin, 1); } if (spiIqrfConfig->uartEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->uartEnableGpioPin, 0); + iqrf_gpio_set_value(spiIqrfConfig->uartEnableGpioPin, 0); } if (spiIqrfConfig->i2cEnableGpioPin != -1) { - clibspi_gpio_setValue((uint32_t)spiIqrfConfig->i2cEnableGpioPin, 0); + iqrf_gpio_set_value(spiIqrfConfig->i2cEnableGpioPin, 0); } } @@ -1692,331 +1656,24 @@ int spi_iqrf_destroy(void) libIsInitialized = 0; // destroy used rpi_io library - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->powerEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->powerEnableGpioPin); if (spiIqrfConfig->busEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->busEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->busEnableGpioPin); } else { if (spiIqrfConfig->spiEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->spiEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->spiEnableGpioPin); } if (spiIqrfConfig->uartEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->uartEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->uartEnableGpioPin); } if (spiIqrfConfig->i2cEnableGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->i2cEnableGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->i2cEnableGpioPin); } } if (spiIqrfConfig->pgmSwitchGpioPin != -1) { - clibspi_gpio_cleanup((uint32_t)spiIqrfConfig->pgmSwitchGpioPin); + iqrf_gpio_unexport(spiIqrfConfig->pgmSwitchGpioPin); } return spi_iqrf_close(); } - -/* ========================================================================= */ -/* GPIO manipulation functions */ -/* ========================================================================= */ - -/** -* Setup GPIO path -* -* @param [in] gpio GPIO -* @param [in] action action -* @param [in] target target -* @param [in] len length -* -*/ -static void clibspi_setup_gpio_path(const uint32_t gpio, const char *action, char *target, int len) -{ - snprintf(target, len, GPIO_BASE_PATH"/gpio%d/%s", gpio, action); -} - -/** -* Writes data stored in @c fd file to buffer. -* -* @param [in] fd file to write. -* @param [in] buf buffer where file is written -* -* @return -1 = error during write -* @return 0 = file was successfully written -*/ -static int clibspi_write_data(FILE *fd, const char *buf) -{ - int ret = 0; - - ret = fwrite(buf, 1, strlen(buf), fd); - if (ret != (int)strlen(buf)) { - printf("Error during writing to file\n"); - ret = -1; - } else { - ret = 0; - } - - return ret; -} - -/** -* Exports the GPIO pin to the GPIO array -* -* @param num GPIO number -* -* @return 0 = operation was performed successfully. -* @return -1 = some error occurred. -*/ -int clibspi_gpio_export(uint32_t num) -{ - FILE *fd = fopen(GPIO_EXPORT_PATH, "w"); - char buf[5]; - int ret; - - if (!fd) { - printf("Error during opening file: %s\n", strerror(errno)); - return -1; - } - - snprintf(buf, sizeof(buf), "%d", num); - ret = clibspi_write_data(fd, buf); - if (ret) - goto err; - -err: - fclose(fd); - return ret; -} - -/** -* Unexports the GPIO pin from the GPIO array -* -* @param num GPIO number -* -* @return 0 = operation was performed successfully. -* @return -1 = some error occurred. -*/ -int clibspi_gpio_unexport(uint32_t num) -{ - FILE *fd = fopen(GPIO_UNEXPORT_PATH, "w"); - char buf[5]; - int ret; - - if (!fd) { - printf("Error during opening file: %s\n", strerror(errno)); - return -1; - } - - snprintf(buf, sizeof(buf), "%d", num); - ret = clibspi_write_data(fd, buf); - if (ret) - goto err; - -err: - fclose(fd); - return ret; -} - - -/** -* Gets direction of the GPIO -* -* @param gpio GPIO -* @param dir GPIO direction = GPIO_DIRECTION_IN or GPIO_DIRECTION_OUT -* -* @return 0 = operation was performed successfully. -* @return -1 = some error occurred. -*/ -int clibspi_gpio_setDirection(uint32_t gpio, clibspi_gpio_direction dir) -{ - char path[50]; - char buf[4]; - FILE *fd = NULL; - int ret; - - clibspi_setup_gpio_path(gpio, GPIO_DIRECTION_STR, path, sizeof(path)); - - fd = fopen(path, "w"); - - if (!fd) { - printf("Error during opening file (set direction): %s %s\n", path, strerror(errno)); - return -1; - } - if (dir == GPIO_DIRECTION_IN) - strncpy(buf, GPIO_DIRECTION_IN_STR, sizeof(buf)); - else if (dir == GPIO_DIRECTION_OUT) - strncpy(buf, GPIO_DIRECTION_OUT_STR, sizeof(buf)); - - ret = clibspi_write_data(fd, buf); - if (ret) - goto err; - -err: - fclose(fd); - return ret; -} - -/** -* Gets direction of the GPIO -* -* @param gpio GPIO -* -* @return GPIO_DIRECTION_IN = GPIO set to input. -* @return GPIO_DIRECTION_OUT = GPIO set to output. -*/ -clibspi_gpio_direction clibspi_gpio_getDirection(uint32_t gpio) -{ - char path[50]; - char buf[4]; - FILE *fd = NULL; - int ret; - clibspi_gpio_direction dir; - - clibspi_setup_gpio_path(gpio, GPIO_DIRECTION_STR, path, sizeof(path)); - - fd = fopen(path, "r"); - - if (!fd) { - printf("Error during opening file (get direction): %s\n", strerror(errno)); - return GPIO_DIRECTION_NOT_AVAILABLE; - } - - dir = GPIO_DIRECTION_NOT_AVAILABLE; - - ret = fread(buf, 1, sizeof(buf), fd); - if (!ret) { - printf("Error during reading file\n"); - goto err; - } - - if (!strcmp(buf, GPIO_DIRECTION_IN_STR)) - dir = GPIO_DIRECTION_IN; - else if (!strcmp(buf, GPIO_DIRECTION_OUT_STR)) - dir = GPIO_DIRECTION_OUT; - -err: - fclose(fd); - return dir; -} - -/** -* Sets GPIO value -* -* @param gpio GPIO -* @param val value -* -* @return 0 = operation was performed successfully. -* @return -1 = some error occurred. -*/ -int clibspi_gpio_setValue(uint32_t gpio, int val) -{ - char path[50]; - char buf[2]; - FILE *fd = NULL; - int ret; - - clibspi_setup_gpio_path(gpio, GPIO_VALUE_STR, path, sizeof(path)); - - fd = fopen(path, "w"); - - if (!fd) { - printf("Error during opening file: %s\n", strerror(errno)); - return -1; - } - - snprintf(buf, sizeof(buf), "%d", val); - ret = clibspi_write_data(fd, buf); - if (ret) - goto err; - -err: - fclose(fd); - return ret; -} - -/** -* Gets GPIO value -* -* @param gpio GPIO -* -* @return GPIO value -*/ -int clibspi_gpio_getValue(uint32_t gpio) -{ - char path[50]; - char buf[2]; - FILE *fd = NULL; - int ret; - - clibspi_setup_gpio_path(gpio, GPIO_VALUE_STR, path, sizeof(path)); - - fd = fopen(path, "r"); - - if (!fd) { - printf("Error during opening file: %s\n", strerror(errno)); - return -1; - } - - ret = fread(buf, 1, sizeof(buf), fd); - if (!ret) { - printf("Error during reading file\n"); - ret = -1; - goto err; - } - - ret = strtol(buf, NULL, 10); - -err: - fclose(fd); - return ret; -} - -/** -* Setup GPIO -* -* @param gpio GPIO -* @param dir GPIO direction -* @param val GPIO value -* -* @return 0 = operation was performed successfully. -* @return -1 = some error occurred. -*/ -int clibspi_gpio_setup(uint32_t gpio, clibspi_gpio_direction dir, int val) -{ - int ret; - - ret = clibspi_gpio_export(gpio); - if (ret) - return ret; - - int i; - for (i = 1; i <= 10; i++) { - ret = clibspi_gpio_setDirection(gpio, dir); - if (!ret) { - printf("clibspi_gpio_setup() setDir success: %d\n", i); - break; - } else { - printf("clibspi_gpio_setup() setDir failed wait for 100 ms to next try: %d\n", i); - SLEEP(100); - } - } - - // set gpio value when output clibspi_gpio_getDirection - if (dir == GPIO_DIRECTION_OUT) { - ret = clibspi_gpio_setValue(gpio, val); - if (ret) - return ret; - } - - return ret; -} - -/** -* Cleans and releases GPIO -* -* @param gpio GPIO -* -* @return 0 = operation was performed successfully. -* @return -1 = some error occurred. -*/ -int clibspi_gpio_cleanup(uint32_t gpio) -{ - return (clibspi_gpio_unexport(gpio)); -}