Compare commits

..

2 Commits

Author SHA1 Message Date
Thomas Klaehn
a6c2d808eb Debug config for vs code ide 2019-07-15 12:46:28 +02:00
Thomas Klaehn
7aaac22e6b gpio driver 2019-07-15 12:46:22 +02:00
4 changed files with 61 additions and 51 deletions

15
inc/ftdi_dev.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef __FTDI_DEV_H__
#define __FTDI_DEV_H__
#include <ftdi.h>
struct ftdi_dev {
struct ftdi_context *ftdi;
bool is_open;
unsigned int vendor_id;
unsigned int product_id;
unsigned char bit_mask; /* Mask of used bits */
unsigned char status_mask; /* Mask of current status of used bits */
};
#endif

View File

@ -3,6 +3,7 @@
struct gpio {
unsigned int pin;
struct ftdi_dev *ftdi_dev;
};
int gpio_open(const struct gpio *gpio);

View File

@ -1,49 +1,31 @@
#include <stdlib.h>
#include <syslog.h>
#include <stdbool.h>
#include <ftdi.h>
#include <ftdi_dev.h>
#include <gpio.h>
struct ftdi_obj {
struct ftdi_context *ftdi;
bool is_open;
unsigned int vendor_id;
unsigned int product_id;
unsigned char bit_mask; /* Mask of used bits */
unsigned char status_mask; /* Mask of current status of used bits */
};
static struct ftdi_obj ftdi_obj = {
.ftdi = NULL,
.is_open = false,
.vendor_id = 0x0403,
.product_id = 0x6001,
.bit_mask = 0,
.status_mask = 0,
};
static int ftdi_open(void)
static int ftdi_open(const struct gpio *gpio)
{
int res;
if((ftdi_obj.ftdi = ftdi_new()) == 0) {
if((gpio->ftdi_dev->ftdi = ftdi_new()) == 0) {
syslog(LOG_ERR, "ftdi_new failed\n");
return EXIT_FAILURE;
}
res = ftdi_usb_open(ftdi_obj.ftdi, ftdi_obj.vendor_id, ftdi_obj.product_id);
res = ftdi_usb_open(gpio->ftdi_dev->ftdi, gpio->ftdi_dev->vendor_id, gpio->ftdi_dev->product_id);
if (res < 0 && res != -5) {
syslog(LOG_ERR, "unable to open ftdi device: %d (%s)\n", res,
ftdi_get_error_string(ftdi_obj.ftdi));
ftdi_free(ftdi_obj.ftdi);
ftdi_get_error_string(gpio->ftdi_dev->ftdi));
ftdi_free(gpio->ftdi_dev->ftdi);
return EXIT_FAILURE;
}
res = ftdi_read_data(ftdi_obj.ftdi, &(ftdi_obj.status_mask), 1);
res = ftdi_read_data(gpio->ftdi_dev->ftdi, &(gpio->ftdi_dev->status_mask), 1);
if(res < 0) {
syslog(LOG_ERR, "unable to readfrom ftdi device: %d (%s)\n", res,
ftdi_get_error_string(ftdi_obj.ftdi));
ftdi_get_error_string(gpio->ftdi_dev->ftdi));
return EXIT_FAILURE;
}
@ -60,33 +42,33 @@ int gpio_open(const struct gpio *gpio)
return EXIT_FAILURE;
}
if(!ftdi_obj.is_open) {
res = ftdi_open();
if(!gpio->ftdi_dev->is_open) {
res = ftdi_open(gpio);
if(res != EXIT_SUCCESS) {
return EXIT_FAILURE;
}
}
ftdi_obj.bit_mask |= (unsigned char)gpio->pin;
syslog(LOG_DEBUG, "bitmask: 0x%02x\n", ftdi_obj.bit_mask);
res = ftdi_set_bitmode(ftdi_obj.ftdi, ftdi_obj.bit_mask, BITMODE_BITBANG);
gpio->ftdi_dev->bit_mask |= (unsigned char)gpio->pin;
syslog(LOG_DEBUG, "bitmask: 0x%02x\n", gpio->ftdi_dev->bit_mask);
res = ftdi_set_bitmode(gpio->ftdi_dev->ftdi, gpio->ftdi_dev->bit_mask, BITMODE_BITBANG);
if(res < 0) {
syslog(LOG_ERR, "unable to set bit bang mode: %d (%s)\n", res,
ftdi_get_error_string(ftdi_obj.ftdi));
ftdi_usb_close(ftdi_obj.ftdi);
ftdi_free(ftdi_obj.ftdi);
ftdi_get_error_string(gpio->ftdi_dev->ftdi));
ftdi_usb_close(gpio->ftdi_dev->ftdi);
ftdi_free(gpio->ftdi_dev->ftdi);
return EXIT_FAILURE;
}
res = gpio_write(gpio, init_value);
if(res < 0) {
syslog(LOG_ERR, "unable to write to gpio %u (%s)\n", gpio->pin,
ftdi_get_error_string(ftdi_obj.ftdi));
ftdi_usb_close(ftdi_obj.ftdi);
ftdi_free(ftdi_obj.ftdi);
ftdi_get_error_string(gpio->ftdi_dev->ftdi));
ftdi_usb_close(gpio->ftdi_dev->ftdi);
ftdi_free(gpio->ftdi_dev->ftdi);
return EXIT_FAILURE;
}
ftdi_obj.is_open = true;
gpio->ftdi_dev->is_open = true;
return EXIT_SUCCESS;
}
@ -99,10 +81,10 @@ int gpio_close(const struct gpio *gpio)
gpio_write(gpio, 0);
ftdi_obj.bit_mask &= ~(unsigned char)(gpio->pin);
if(ftdi_obj.bit_mask == 0) {
ftdi_usb_close(ftdi_obj.ftdi);
ftdi_free(ftdi_obj.ftdi);
gpio->ftdi_dev->bit_mask &= ~(unsigned char)(gpio->pin);
if(gpio->ftdi_dev->bit_mask == 0) {
ftdi_usb_close(gpio->ftdi_dev->ftdi);
ftdi_free(gpio->ftdi_dev->ftdi);
}
return EXIT_SUCCESS;
@ -114,7 +96,7 @@ int gpio_read(const struct gpio *gpio, unsigned int *value)
return EXIT_FAILURE;
}
if(ftdi_obj.status_mask & (unsigned char)(gpio->pin)) {
if(gpio->ftdi_dev->status_mask & (unsigned char)(gpio->pin)) {
*value = 1;
} else {
*value = 0;
@ -139,13 +121,13 @@ int gpio_write(const struct gpio *gpio, unsigned int value)
mask |= (unsigned char)(gpio->pin);
}
res = ftdi_write_data(ftdi_obj.ftdi, &mask, 1);
res = ftdi_write_data(gpio->ftdi_dev->ftdi, &mask, 1);
if(res < 0) {
syslog(LOG_ERR, "write failed for 0x%x, error %d (%s)\n", value, res,
ftdi_get_error_string(ftdi_obj.ftdi));
ftdi_get_error_string(gpio->ftdi_dev->ftdi));
return EXIT_FAILURE;
}
ftdi_obj.status_mask = mask;
gpio->ftdi_dev->status_mask = mask;
return EXIT_SUCCESS;
}
@ -153,7 +135,7 @@ int gpio_write(const struct gpio *gpio, unsigned int value)
int gpio_toggle(const struct gpio *gpio)
{
int res;
unsigned char mask = ftdi_obj.status_mask;
unsigned char mask = gpio->ftdi_dev->status_mask;
if(NULL == gpio) {
return EXIT_FAILURE;
@ -161,13 +143,13 @@ int gpio_toggle(const struct gpio *gpio)
mask ^= (unsigned char)(gpio->pin);
res = ftdi_write_data(ftdi_obj.ftdi, &mask, 1);
res = ftdi_write_data(gpio->ftdi_dev->ftdi, &mask, 1);
if(res < 0) {
syslog(LOG_ERR, "toggle failed, error %d (%s)\n", res,
ftdi_get_error_string(ftdi_obj.ftdi));
ftdi_get_error_string(gpio->ftdi_dev->ftdi));
return EXIT_FAILURE;
}
ftdi_obj.status_mask = mask;
gpio->ftdi_dev->status_mask = mask;
return EXIT_SUCCESS;
}

View File

@ -2,7 +2,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <stdbool.h>
#include <ftdi_dev.h>
#include <gpio.h>
/*
@ -12,11 +13,22 @@
#define GPIO4 0x14 // RTS (green on FTDI) + DTR (on SparkFun breakout)
*/
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,
};
static const struct gpio gpio_2 = {
.pin = 0x01, /* TX (orange wire on FTDI cable) */
.ftdi_dev = &ftdi_obj,
};
int main(int argc, char *argv[])