Compare commits
1 Commits
082277bf25
...
2600ca8742
Author | SHA1 | Date | |
---|---|---|---|
|
2600ca8742 |
@ -7,8 +7,8 @@ struct gpio {
|
||||
|
||||
int gpio_open(const struct gpio *gpio);
|
||||
int gpio_close(const struct gpio *gpio);
|
||||
char gpio_read(const struct gpio *gpio);
|
||||
void gpio_write(const struct gpio *gpio, char byte);
|
||||
int gpio_read(const struct gpio *gpio, unsigned int *value);
|
||||
int gpio_write(const struct gpio *gpio, unsigned int value);
|
||||
void gpio_toggle(const struct gpio *gpio);
|
||||
|
||||
#endif
|
||||
|
139
src/gpio.c
139
src/gpio.c
@ -5,58 +5,153 @@
|
||||
|
||||
#include <gpio.h>
|
||||
|
||||
struct gpio_obj {
|
||||
struct ftdi_obj {
|
||||
struct ftdi_context *ftdi;
|
||||
bool is_open;
|
||||
unsigned int vendor_id;
|
||||
unsigned int product_id;
|
||||
unsigned char bit_mask;
|
||||
};
|
||||
|
||||
static struct gpio_obj gpio_obj = {
|
||||
static struct ftdi_obj ftdi_obj = {
|
||||
.ftdi = NULL,
|
||||
.is_open = false,
|
||||
.vendor_id = 0x0403,
|
||||
.product_id = 0x6001,
|
||||
.bit_mask = 0,
|
||||
};
|
||||
|
||||
static int ftdi_open(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
if((ftdi_obj.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);
|
||||
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);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int gpio_open(const struct gpio *gpio)
|
||||
{
|
||||
int res;
|
||||
if((gpio_obj.ftdi = ftdi_new()) == 0) {
|
||||
syslog(LOG_ERR, "ftdi_new failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
res = ftdi_usb_open(gpio_obj.ftdi, 0x0403, 0x6001);
|
||||
if (res < 0 && res != -5) {
|
||||
syslog(LOG_ERR, "unable to open ftdi device: %d (%s)\n", res,
|
||||
ftdi_get_error_string(gpio_obj.ftdi));
|
||||
ftdi_free(gpio_obj.ftdi);
|
||||
unsigned char init_value = 0;
|
||||
bool init_write = false;
|
||||
|
||||
|
||||
if(NULL == gpio) {
|
||||
syslog(LOG_ERR, "No valid gpio object given.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
res = ftdi_set_bitmode(gpio_obj.ftdi, (char)gpio->pin, BITMODE_BITBANG);
|
||||
if(res < 0) {
|
||||
syslog(LOG_ERR, "unable to set bit bang mode: %d (%s)\n", res,
|
||||
ftdi_get_error_string(gpio_obj.ftdi));
|
||||
ftdi_free(gpio_obj.ftdi);
|
||||
if(!ftdi_obj.is_open) {
|
||||
res = ftdi_open();
|
||||
if(res != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
gpio_obj.is_open = true;
|
||||
init_write = true;
|
||||
}
|
||||
|
||||
ftdi_obj.bit_mask |= (unsigned char)gpio->pin;
|
||||
res = ftdi_set_bitmode(ftdi_obj.ftdi, ftdi_obj.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_free(ftdi_obj.ftdi);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
ftdi_obj.is_open = true;
|
||||
|
||||
if(init_write) {
|
||||
ftdi_write_data(ftdi_obj.ftdi, &init_value, 1);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int gpio_close(const struct gpio *gpio)
|
||||
{
|
||||
ftdi_usb_close(gpio_obj.ftdi);
|
||||
ftdi_free(gpio_obj.ftdi);
|
||||
if(NULL == gpio) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
unsigned char pin = (unsigned char)gpio->pin;
|
||||
ftdi_obj.bit_mask &= ~pin;
|
||||
if(ftdi_obj.bit_mask == 0) {
|
||||
ftdi_usb_close(ftdi_obj.ftdi);
|
||||
ftdi_free(ftdi_obj.ftdi);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
char gpio_read(const struct gpio *gpio)
|
||||
int gpio_read(const struct gpio *gpio, unsigned int *value)
|
||||
{
|
||||
return 0;
|
||||
int res;
|
||||
unsigned char buf;
|
||||
|
||||
if(NULL == gpio || NULL == value) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
res = ftdi_read_data(ftdi_obj.ftdi, &buf, 1);
|
||||
if(res < 0) {
|
||||
syslog(LOG_ERR, "unable to readfrom ftdi device: %d (%s)\n", res,
|
||||
ftdi_get_error_string(ftdi_obj.ftdi));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if(buf & (unsigned char)(gpio->pin)) {
|
||||
*value = 1;
|
||||
} else {
|
||||
*value = 0;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void gpio_write(const struct gpio *gpio, char byte)
|
||||
int gpio_write(const struct gpio *gpio, unsigned int value)
|
||||
{
|
||||
int res;
|
||||
unsigned int current_state;
|
||||
unsigned char buf;
|
||||
|
||||
if(NULL == gpio) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
res = gpio_read(gpio, ¤t_state);
|
||||
if(res != EXIT_SUCCESS) {
|
||||
syslog(LOG_ERR, "write failed for 0x%x, error %d (%s)\n", value, res,
|
||||
ftdi_get_error_string(ftdi_obj.ftdi));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
buf = (unsigned char)current_state;
|
||||
if(value == 0) {
|
||||
buf &= ~(unsigned char)(gpio->pin);
|
||||
}
|
||||
else {
|
||||
buf |= (unsigned char)(gpio->pin);
|
||||
}
|
||||
|
||||
res = ftdi_write_data(ftdi_obj.ftdi, &buf, 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));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void gpio_toggle(const struct gpio *gpio)
|
||||
|
66
src/main.c
66
src/main.c
@ -1,56 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <ftdi.h>
|
||||
|
||||
#define LED 0x08
|
||||
#include <gpio.h>
|
||||
|
||||
const struct gpio gpio = {
|
||||
.pin = 0x08,
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct ftdi_context *ftdi;
|
||||
int f, retval, cnt;
|
||||
unsigned char buf[1];
|
||||
int res;
|
||||
unsigned int value;
|
||||
|
||||
openlog("ftdi_gpio", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||
setlogmask(LOG_DEBUG);
|
||||
// setlogmask(LOG_DEBUG);
|
||||
|
||||
if ((ftdi = ftdi_new()) == 0) {
|
||||
syslog(LOG_ERR, "ftdi_new failed\n");
|
||||
return EXIT_FAILURE;
|
||||
res = gpio_open(&gpio);
|
||||
if(res != EXIT_SUCCESS) {
|
||||
syslog(LOG_ERR, "Unable to open gpio pin %u\n", gpio.pin);
|
||||
return res;
|
||||
}
|
||||
|
||||
f = ftdi_usb_open(ftdi, 0x0403, 0x6001);
|
||||
|
||||
if (f < 0 && f != -5) {
|
||||
syslog(LOG_ERR, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi));
|
||||
retval = 1;
|
||||
goto done;
|
||||
res = gpio_write(&gpio, 0x00);
|
||||
if(res != EXIT_SUCCESS) {
|
||||
syslog(LOG_ERR, "Unable to write to gpio pin %u\n", gpio.pin);
|
||||
gpio_close(&gpio);
|
||||
return res;
|
||||
}
|
||||
|
||||
f = ftdi_set_bitmode(ftdi, LED, BITMODE_BITBANG);
|
||||
if(f < 0) {
|
||||
syslog(LOG_ERR, "unable to set bit bang mode: %d (%s)\n", f, ftdi_get_error_string(ftdi));
|
||||
retval = 1;
|
||||
goto done;
|
||||
res = gpio_read(&gpio, &value);
|
||||
if(res != EXIT_SUCCESS) {
|
||||
syslog(LOG_ERR, "Unable to read from gpio pin %u\n", gpio.pin);
|
||||
gpio_close(&gpio);
|
||||
return res;
|
||||
}
|
||||
printf("read value: 0x%02x\n", value);
|
||||
|
||||
buf[0] = 0;
|
||||
for(cnt = 0; cnt < 10; cnt++) {
|
||||
buf[0] ^= LED,
|
||||
f = ftdi_write_data(ftdi, buf, 1);
|
||||
if(f < 0) {
|
||||
syslog(LOG_ERR, "write failed for 0x%x, error %d (%s)\n",buf[0], f, ftdi_get_error_string(ftdi));
|
||||
cnt = 10;
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "set LED to: %u\n", (unsigned int)buf[0]);
|
||||
}
|
||||
gpio_close(&gpio);
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
ftdi_usb_close(ftdi);
|
||||
done:
|
||||
ftdi_free(ftdi);
|
||||
closelog();
|
||||
|
||||
return retval;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user