-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Roman Ondráček <ondracek.roman@centrum.cz>
- Loading branch information
Showing
5 changed files
with
413 additions
and
383 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#ifndef IQRF_GPIO_H | ||
#define IQRF_GPIO_H | ||
|
||
#include <errno.h> | ||
#include <inttypes.h> | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
|
||
#ifndef WIN32 | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
Oops, something went wrong.