diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..20d5904 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "stdbool.h": "c" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 17bdc08..728b284 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,16 +2,16 @@ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", - "type":"shell", - "command": "make", - "echoCommand": true, - "problemMatcher": { - "base": "gcc", - }, "tasks": [ { "label": "all", - "args": ["all"], + "type":"shell", + "command": "make all -j4", + "problemMatcher": { + "base": "gcc", + "owner": "gcc", + "fileLocation":"absolute" + }, "group": { "kind": "build", "isDefault": true @@ -19,7 +19,23 @@ }, { "label": "clean", - "args": ["clean"], + "type":"shell", + "command": "make clean -j4", + "problemMatcher": { + "base": "gcc", + "owner": "gcc", + "fileLocation":"absolute" + }, + "group": { + "kind": "build", + "isDefault": true + } } - ] -} \ No newline at end of file + ], + "presentation": { + "focus": true, + "reveal": "always", + "panel": "shared", + "clear": true, + } +} diff --git a/inc/def.h b/inc/def.h deleted file mode 100644 index c4b2dc5..0000000 --- a/inc/def.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __INC_DEF_H__ -#define __INC_DEF_H__ - -#define HELLO "Hello world!" - -#endif // __INC_DEF_H__ \ No newline at end of file diff --git a/inc/gpio.h b/inc/gpio.h new file mode 100644 index 0000000..0048c41 --- /dev/null +++ b/inc/gpio.h @@ -0,0 +1,14 @@ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +struct gpio { + unsigned int pin; +}; + +int gpio_open(const struct gpio *gpio); +int gpio_close(const struct gpio *gpio); +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 diff --git a/src/gpio.c b/src/gpio.c new file mode 100644 index 0000000..487c9de --- /dev/null +++ b/src/gpio.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include + +#include + +struct ftdi_obj { + struct ftdi_context *ftdi; + bool is_open; + unsigned int vendor_id; + unsigned int product_id; + unsigned char bit_mask; +}; + +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; + unsigned char init_value = 0; + bool init_write = false; + + + if(NULL == gpio) { + syslog(LOG_ERR, "No valid gpio object given.\n"); + return EXIT_FAILURE; + } + + if(!ftdi_obj.is_open) { + res = ftdi_open(); + if(res != EXIT_SUCCESS) { + return EXIT_FAILURE; + } + 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) +{ + 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; +} + +int gpio_read(const struct gpio *gpio, unsigned int *value) +{ + 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; +} + +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) +{ +} diff --git a/src/main.c b/src/main.c index 08b36d2..1ef9719 100644 --- a/src/main.c +++ b/src/main.c @@ -1,58 +1,43 @@ +#include #include #include #include -#include -#include +#include + +static const struct gpio gpio = { + .pin = 0x08, +}; -#define LED 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); - 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]); - } - - sleep(1); - } + gpio_close(&gpio); - ftdi_usb_close(ftdi); -done: - ftdi_free(ftdi); - closelog(); - - return retval; + return EXIT_SUCCESS; }