Compare commits
5 Commits
62fc41d5c9
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
5ef54fa1fc | ||
|
3431597f5a | ||
|
07775772a7 | ||
|
f4cc51669b | ||
|
3cbcfee449 |
17
.vscode/c_cpp_properties.json
vendored
Normal file
17
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/usr/include/libftdi1"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/clang",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "clang-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -8,7 +8,7 @@
|
|||||||
"name": "(gdb) Launch",
|
"name": "(gdb) Launch",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/bin/test",
|
"program": "${workspaceFolder}/bin/test/unit/gpio_ftdi",
|
||||||
"args": [],
|
"args": [],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
|
19
Makefile
19
Makefile
@@ -1,8 +1,8 @@
|
|||||||
CROSS_COMPILE ?=
|
CROSS_COMPILE ?=
|
||||||
|
|
||||||
TARGET_FILE ?= ftdi_gpio
|
TARGET_FILE ?= gpio_ftdi
|
||||||
STATIC_LIB_FILE ?= libftdi_gpio.a
|
STATIC_LIB_FILE ?= libgpio_ftdi.a
|
||||||
DYNAMIC_LIB_FILE ?= libftdi_gpio.so
|
DYNAMIC_LIB_FILE ?= libgpio_ftdi.so
|
||||||
|
|
||||||
CC = $(CROSS_COMPILE)gcc
|
CC = $(CROSS_COMPILE)gcc
|
||||||
CPP = $(CROSS_COMPILE)cpp
|
CPP = $(CROSS_COMPILE)cpp
|
||||||
@@ -19,11 +19,10 @@ UNIT_TEST_SRC_DIR = test/unit
|
|||||||
UNIT_TEST_OBJ_DIR = $(OBJ_DIR)/$(UNIT_TEST_SRC_DIR)
|
UNIT_TEST_OBJ_DIR = $(OBJ_DIR)/$(UNIT_TEST_SRC_DIR)
|
||||||
|
|
||||||
PREFIX ?= /usr
|
PREFIX ?= /usr
|
||||||
LIB_INSTALL_DIR ?= $(PREFIX)/lib/ftdi_gpio
|
LIB_INSTALL_DIR ?= $(PREFIX)/lib
|
||||||
INC_INSTALL_DIR ?= $(PREFIX)/include/ftdi_gpio
|
INC_INSTALL_DIR ?= $(PREFIX)/include/lib$(TARGET_FILE)
|
||||||
|
|
||||||
INCLUDES := inc
|
INCLUDES := inc
|
||||||
INCLUDES += /usr/include/libftdi1
|
|
||||||
|
|
||||||
ifneq "$(findstring $(MAKECMDGOALS), build_unit_test exec_unit_test coverage)" ""
|
ifneq "$(findstring $(MAKECMDGOALS), build_unit_test exec_unit_test coverage)" ""
|
||||||
INCLUDES += test/inc
|
INCLUDES += test/inc
|
||||||
@@ -52,7 +51,7 @@ UNIT_TEST_TARGET = $(BIN_DIR)/$(UNIT_TEST_SRC_DIR)/$(TARGET_FILE)
|
|||||||
|
|
||||||
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||||
|
|
||||||
.PHONY: all install clean
|
.PHONY: all install uninstall clean
|
||||||
all: $(STATIC_LIB) $(DYNAMIC_LIB)
|
all: $(STATIC_LIB) $(DYNAMIC_LIB)
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
@@ -62,6 +61,12 @@ install: all
|
|||||||
install -m 0777 $(DYNAMIC_LIB) $(LIB_INSTALL_DIR)
|
install -m 0777 $(DYNAMIC_LIB) $(LIB_INSTALL_DIR)
|
||||||
install -m 0644 inc/* $(INC_INSTALL_DIR)
|
install -m 0644 inc/* $(INC_INSTALL_DIR)
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f $(LIB_INSTALL_DIR)/$(STATIC_LIB)
|
||||||
|
rm -f $(LIB_INSTALL_DIR)/$(DYNAMIC_LIB)
|
||||||
|
rm -f $(addprefix $(INC_INSTALL_DIR)/,$(shell ls inc))
|
||||||
|
rm -rf $(INC_INSTALL_DIR)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(STATIC_LIB) $(DYNAMIC_LIB)
|
rm -f $(STATIC_LIB) $(DYNAMIC_LIB)
|
||||||
rm -f $(OBJS) $(patsubst %.o,%.d,$(OBJS))
|
rm -f $(OBJS) $(patsubst %.o,%.d,$(OBJS))
|
||||||
|
114
README.md
Normal file
114
README.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# GPIO_FTDI
|
||||||
|
|
||||||
|
Gpio driver using ftdi usb chips e.g.:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ lsusb
|
||||||
|
Bus 001 Device 008: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
* libftdi1
|
||||||
|
* libftdi1-dev
|
||||||
|
|
||||||
|
### Debian
|
||||||
|
|
||||||
|
```shell
|
||||||
|
apt install libftdi1 libftdi1-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alpine Linux
|
||||||
|
|
||||||
|
```shell
|
||||||
|
apk add libftdi1 libftdi1-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```shell
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
Installs `lobgpio_ftdi.a` and `libgpio_ftdi.so` in the directory `$(PREFIX)/lib/`. It also installs the include header files `ftdi_dev.h` and `gpio.h` in the directory `$(PREFIX)/include/gpio_ftdi`. The default value for `PREFIX` is: `PREFIX=usr`. To use another location for installation changing the value of the `PREFIX` variable is needed. E.g.:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
PREFIX=/usr/local/ make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Uninstallation
|
||||||
|
|
||||||
|
```shell
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
Removes the files installed with the `install` make target.
|
||||||
|
> **NOTE:** When `PREFIX` variable was changed during installation process the same value needs to be set for uninstallation. E.g.:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
PREFIX=/usr/local/ make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <ftdi_dev.h>
|
||||||
|
#include <gpio.h>
|
||||||
|
|
||||||
|
static struct ftdi_dev ftdi_obj = {
|
||||||
|
.ftdi = NULL,
|
||||||
|
.is_open = false,
|
||||||
|
.vendor_id = 0x0403,
|
||||||
|
.product_id = 0x6001,
|
||||||
|
.bit_mask = 0,
|
||||||
|
.status_mask = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct gpio gpio_1 = {
|
||||||
|
.pin = 0x08, /* CTS (brown wire on FTDI cable) */
|
||||||
|
.ftdi_dev = &ftdi_obj,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int res, cnt;
|
||||||
|
unsigned int value;
|
||||||
|
|
||||||
|
openlog("ftdi_gpio", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||||
|
|
||||||
|
res = gpio_open(&gpio_1);
|
||||||
|
if(res != EXIT_SUCCESS) {
|
||||||
|
syslog(LOG_ERR, "Unable to open gpio\n");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_write(&gpio_1, 1);
|
||||||
|
for(cnt = 0; cnt < 10; cnt++) {
|
||||||
|
gpio_toggle(&gpio_1);
|
||||||
|
gpio_read(&gpio_1, &value);
|
||||||
|
printf("Gpio1: %u\n", value);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
gpio_close(&gpio_1);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional make targets
|
||||||
|
|
||||||
|
| Target | Meaning |
|
||||||
|
| --------------- | ----------------------------------------------------------- |
|
||||||
|
| all | Build the code, assemble the static and shared library. |
|
||||||
|
| install | Install the libraries and necessary include header files. |
|
||||||
|
| uninstall | Uninstall the libraries and necessary include header files. |
|
||||||
|
| clean | Clean up build artifacts. |
|
||||||
|
| build_unit_test | Build the unit tests. |
|
||||||
|
| exec_unit_test | Execute the unit tests. |
|
||||||
|
| coverage | Determine code coverage of the unit tests. |
|
||||||
|
| check | Static code analysis (cppcheck). |
|
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __FTDI_DEV_H__
|
#ifndef __FTDI_DEV_H__
|
||||||
#define __FTDI_DEV_H__
|
#define __FTDI_DEV_H__
|
||||||
|
|
||||||
#include <ftdi.h>
|
#include <libftdi1/ftdi.h>
|
||||||
|
|
||||||
struct ftdi_dev {
|
struct ftdi_dev {
|
||||||
struct ftdi_context *ftdi;
|
struct ftdi_context *ftdi;
|
||||||
|
24
src/gpio.c
24
src/gpio.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -38,11 +39,7 @@ int gpio_open(const struct gpio *gpio)
|
|||||||
int res;
|
int res;
|
||||||
unsigned char init_value = 0;
|
unsigned char init_value = 0;
|
||||||
|
|
||||||
if(NULL == gpio) {
|
assert(NULL != gpio);
|
||||||
syslog(LOG_ERR, "No valid gpio object given.\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!gpio->ftdi_dev->is_open) {
|
if(!gpio->ftdi_dev->is_open) {
|
||||||
res = ftdi_open(gpio);
|
res = ftdi_open(gpio);
|
||||||
if(res != EXIT_SUCCESS) {
|
if(res != EXIT_SUCCESS) {
|
||||||
@@ -76,9 +73,7 @@ int gpio_open(const struct gpio *gpio)
|
|||||||
// cppcheck-suppress unusedFunction
|
// cppcheck-suppress unusedFunction
|
||||||
int gpio_close(const struct gpio *gpio)
|
int gpio_close(const struct gpio *gpio)
|
||||||
{
|
{
|
||||||
if(NULL == gpio) {
|
assert(NULL != gpio);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_write(gpio, 0);
|
gpio_write(gpio, 0);
|
||||||
|
|
||||||
@@ -95,9 +90,8 @@ int gpio_close(const struct gpio *gpio)
|
|||||||
// cppcheck-suppress unusedFunction
|
// cppcheck-suppress unusedFunction
|
||||||
int gpio_read(const struct gpio *gpio, unsigned int *value)
|
int gpio_read(const struct gpio *gpio, unsigned int *value)
|
||||||
{
|
{
|
||||||
if(NULL == gpio || NULL == value) {
|
assert(NULL != gpio);
|
||||||
return EXIT_FAILURE;
|
assert(NULL != value);
|
||||||
}
|
|
||||||
|
|
||||||
if(gpio->ftdi_dev->status_mask & (unsigned char)(gpio->pin)) {
|
if(gpio->ftdi_dev->status_mask & (unsigned char)(gpio->pin)) {
|
||||||
*value = 1;
|
*value = 1;
|
||||||
@@ -113,9 +107,7 @@ int gpio_write(const struct gpio *gpio, unsigned int value)
|
|||||||
int res;
|
int res;
|
||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
||||||
if(NULL == gpio) {
|
assert(NULL != gpio);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask = gpio->ftdi_dev->status_mask;
|
mask = gpio->ftdi_dev->status_mask;
|
||||||
|
|
||||||
@@ -143,9 +135,7 @@ int gpio_toggle(const struct gpio *gpio)
|
|||||||
int res;
|
int res;
|
||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
||||||
if(NULL == gpio) {
|
assert(NULL != gpio);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask = (gpio->ftdi_dev->status_mask) ^ (unsigned char)(gpio->pin);
|
mask = (gpio->ftdi_dev->status_mask) ^ (unsigned char)(gpio->pin);
|
||||||
|
|
||||||
|
@@ -9,10 +9,6 @@
|
|||||||
#include <ftdi_dev.h>
|
#include <ftdi_dev.h>
|
||||||
#include <gpio.h>
|
#include <gpio.h>
|
||||||
|
|
||||||
UTEST(gpio_close, invalid_gpio_obj) {
|
|
||||||
ASSERT_EQ(gpio_close(NULL), EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
UTEST(gpio_close, empty_bitmask) {
|
UTEST(gpio_close, empty_bitmask) {
|
||||||
struct gpio gpio_1;
|
struct gpio gpio_1;
|
||||||
struct ftdi_dev ftdi_obj;
|
struct ftdi_dev ftdi_obj;
|
||||||
|
@@ -89,10 +89,6 @@ UTEST(gpio_open, ftdi_open_success) {
|
|||||||
ASSERT_EQ(gpio_open(&gpio_1), EXIT_SUCCESS);
|
ASSERT_EQ(gpio_open(&gpio_1), EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
UTEST(gpio_open, invalid_gpio_obj) {
|
|
||||||
ASSERT_EQ(gpio_open(NULL), EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
UTEST(gpio_open, ftdi_set_bitmode_failed) {
|
UTEST(gpio_open, ftdi_set_bitmode_failed) {
|
||||||
struct gpio gpio_1;
|
struct gpio gpio_1;
|
||||||
struct ftdi_dev ftdi_obj;
|
struct ftdi_dev ftdi_obj;
|
||||||
|
@@ -11,11 +11,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
UTEST(gpio_read, invalid_params) {
|
|
||||||
|
|
||||||
ASSERT_EQ(gpio_read(NULL, NULL), EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
UTEST(gpio_read, value_0) {
|
UTEST(gpio_read, value_0) {
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
struct gpio gpio_1;
|
struct gpio gpio_1;
|
||||||
|
@@ -11,11 +11,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
UTEST(gpio_toggle, invalid_params) {
|
|
||||||
|
|
||||||
ASSERT_EQ(gpio_toggle(NULL), EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
UTEST(gpio_toggle, ftdi_write_data_fails) {
|
UTEST(gpio_toggle, ftdi_write_data_fails) {
|
||||||
struct gpio gpio_1;
|
struct gpio gpio_1;
|
||||||
struct ftdi_dev ftdi_obj;
|
struct ftdi_dev ftdi_obj;
|
||||||
|
@@ -9,11 +9,6 @@
|
|||||||
#include <ftdi_dev.h>
|
#include <ftdi_dev.h>
|
||||||
#include <gpio.h>
|
#include <gpio.h>
|
||||||
|
|
||||||
UTEST(gpio_write, invalid_params) {
|
|
||||||
|
|
||||||
ASSERT_EQ(gpio_write(NULL, 0), EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
UTEST(gpio_write, value_0) {
|
UTEST(gpio_write, value_0) {
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
struct gpio gpio_1;
|
struct gpio gpio_1;
|
||||||
|
Reference in New Issue
Block a user