Compare commits

..

2 Commits

Author SHA1 Message Date
Thomas Klaehn
7a08c8b113 Debug config for vs code ide 2019-07-15 12:06:43 +02:00
Thomas Klaehn
455cee9ce1 gpio driver 2019-07-15 12:06:34 +02:00
3 changed files with 53 additions and 77 deletions

View File

@ -9,6 +9,6 @@ int gpio_open(const struct gpio *gpio);
int gpio_close(const struct gpio *gpio); int gpio_close(const struct gpio *gpio);
int gpio_read(const struct gpio *gpio, unsigned int *value); int gpio_read(const struct gpio *gpio, unsigned int *value);
int gpio_write(const struct gpio *gpio, unsigned int value); int gpio_write(const struct gpio *gpio, unsigned int value);
void gpio_toggle(const struct gpio *gpio); int gpio_toggle(const struct gpio *gpio);
#endif #endif

View File

@ -10,7 +10,8 @@ struct ftdi_obj {
bool is_open; bool is_open;
unsigned int vendor_id; unsigned int vendor_id;
unsigned int product_id; unsigned int product_id;
unsigned char bit_mask; 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 = { static struct ftdi_obj ftdi_obj = {
@ -19,6 +20,7 @@ static struct ftdi_obj ftdi_obj = {
.vendor_id = 0x0403, .vendor_id = 0x0403,
.product_id = 0x6001, .product_id = 0x6001,
.bit_mask = 0, .bit_mask = 0,
.status_mask = 0,
}; };
static int ftdi_open(void) static int ftdi_open(void)
@ -38,18 +40,7 @@ static int ftdi_open(void)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
return EXIT_SUCCESS; res = ftdi_read_data(ftdi_obj.ftdi, &(ftdi_obj.status_mask), 1);
}
static int gpio_read_mask(const struct gpio *gpio, unsigned char *mask)
{
int res;
if(NULL == gpio || NULL == mask) {
return EXIT_FAILURE;
}
res = ftdi_read_data(ftdi_obj.ftdi, mask, 1);
if(res < 0) { if(res < 0) {
syslog(LOG_ERR, "unable to readfrom ftdi device: %d (%s)\n", res, syslog(LOG_ERR, "unable to readfrom ftdi device: %d (%s)\n", res,
ftdi_get_error_string(ftdi_obj.ftdi)); ftdi_get_error_string(ftdi_obj.ftdi));
@ -62,9 +53,7 @@ static int gpio_read_mask(const struct gpio *gpio, unsigned char *mask)
int gpio_open(const struct gpio *gpio) int gpio_open(const struct gpio *gpio)
{ {
int res; int res;
unsigned char init_value = 0; unsigned int init_value = 0;
bool init_write = false;
if(NULL == gpio) { if(NULL == gpio) {
syslog(LOG_ERR, "No valid gpio object given.\n"); syslog(LOG_ERR, "No valid gpio object given.\n");
@ -76,7 +65,6 @@ int gpio_open(const struct gpio *gpio)
if(res != EXIT_SUCCESS) { if(res != EXIT_SUCCESS) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
init_write = true;
} }
ftdi_obj.bit_mask |= (unsigned char)gpio->pin; ftdi_obj.bit_mask |= (unsigned char)gpio->pin;
@ -85,15 +73,21 @@ int gpio_open(const struct gpio *gpio)
if(res < 0) { if(res < 0) {
syslog(LOG_ERR, "unable to set bit bang mode: %d (%s)\n", res, syslog(LOG_ERR, "unable to set bit bang mode: %d (%s)\n", res,
ftdi_get_error_string(ftdi_obj.ftdi)); ftdi_get_error_string(ftdi_obj.ftdi));
ftdi_usb_close(ftdi_obj.ftdi);
ftdi_free(ftdi_obj.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_free(ftdi_obj.ftdi);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
ftdi_obj.is_open = true; ftdi_obj.is_open = true;
if(init_write) {
ftdi_write_data(ftdi_obj.ftdi, &init_value, 1);
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -103,8 +97,9 @@ int gpio_close(const struct gpio *gpio)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
unsigned char pin = (unsigned char)gpio->pin; gpio_write(gpio, 0);
ftdi_obj.bit_mask &= ~pin;
ftdi_obj.bit_mask &= ~(unsigned char)(gpio->pin);
if(ftdi_obj.bit_mask == 0) { if(ftdi_obj.bit_mask == 0) {
ftdi_usb_close(ftdi_obj.ftdi); ftdi_usb_close(ftdi_obj.ftdi);
ftdi_free(ftdi_obj.ftdi); ftdi_free(ftdi_obj.ftdi);
@ -115,21 +110,11 @@ int gpio_close(const struct gpio *gpio)
int gpio_read(const struct gpio *gpio, unsigned int *value) int gpio_read(const struct gpio *gpio, unsigned int *value)
{ {
int res;
unsigned char buf;
if(NULL == gpio || NULL == value) { if(NULL == gpio || NULL == value) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
res = gpio_read_mask(gpio, &buf); if(ftdi_obj.status_mask & (unsigned char)(gpio->pin)) {
if(res != EXIT_SUCCESS) {
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; *value = 1;
} else { } else {
*value = 0; *value = 0;
@ -141,38 +126,48 @@ int gpio_read(const struct gpio *gpio, unsigned int *value)
int gpio_write(const struct gpio *gpio, unsigned int value) int gpio_write(const struct gpio *gpio, unsigned int value)
{ {
int res; int res;
unsigned char buf; unsigned char mask;
if(NULL == gpio) { if(NULL == gpio) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
res = gpio_read_mask(gpio, &buf);
if(res != EXIT_SUCCESS) {
syslog(LOG_ERR, "write failed for 0x%02x, error %d (%s)\n", buf, res,
ftdi_get_error_string(ftdi_obj.ftdi));
return EXIT_FAILURE;
}
syslog(LOG_DEBUG, "current state: 0x%02x\n", buf);
if(value == 0) { if(value == 0) {
buf &= ~(unsigned char)(gpio->pin); mask &= ~(unsigned char)(gpio->pin);
} }
else { else {
buf |= (unsigned char)(gpio->pin); mask |= (unsigned char)(gpio->pin);
} }
syslog(LOG_DEBUG, "new state: 0x%02x\n", buf);
res = ftdi_write_data(ftdi_obj.ftdi, &buf, 1); res = ftdi_write_data(ftdi_obj.ftdi, &mask, 1);
if(res < 0) { if(res < 0) {
syslog(LOG_ERR, "write failed for 0x%x, error %d (%s)\n", value, res, 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(ftdi_obj.ftdi));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
ftdi_obj.status_mask = mask;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void gpio_toggle(const struct gpio *gpio) int gpio_toggle(const struct gpio *gpio)
{ {
int res;
unsigned char mask = ftdi_obj.status_mask;
if(NULL == gpio) {
return EXIT_FAILURE;
}
mask ^= (unsigned char)(gpio->pin);
res = ftdi_write_data(ftdi_obj.ftdi, &mask, 1);
if(res < 0) {
syslog(LOG_ERR, "toggle failed, error %d (%s)\n", res,
ftdi_get_error_string(ftdi_obj.ftdi));
return EXIT_FAILURE;
}
ftdi_obj.status_mask = mask;
return EXIT_SUCCESS;
} }

View File

@ -33,38 +33,19 @@ int main(int argc, char *argv[])
return res; return res;
} }
gpio_write(&gpio_1, 1);
gpio_write(&gpio_2, 0);
for(cnt = 0; cnt < 10; cnt++) { for(cnt = 0; cnt < 10; cnt++) {
value = cnt & 0x01; gpio_toggle(&gpio_1);
res = gpio_write(&gpio_1, value); gpio_toggle(&gpio_2);
if(cnt % 2) { gpio_read(&gpio_1, &value);
res |= gpio_write(&gpio_2, value); printf("Gpio1: %u\n", value);
} gpio_read(&gpio_2, &value);
if(res != EXIT_SUCCESS) { printf("Gpio2: %u\n", value);
syslog(LOG_ERR, "Unable to write to gpio\n");
gpio_close(&gpio_1);
gpio_close(&gpio_2);
return res;
}
res = gpio_read(&gpio_1, &value);
if(res != EXIT_SUCCESS) {
syslog(LOG_ERR, "Unable to read from gpio pin %u\n", gpio_1.pin);
gpio_close(&gpio_1);
return res;
}
printf("read 1 value: 0x%02x\n", value);
if(cnt % 2) {
res = gpio_read(&gpio_2, &value);
if(res != EXIT_SUCCESS) {
syslog(LOG_ERR, "Unable to read from gpio pin %u\n", gpio_2.pin);
gpio_close(&gpio_2);
return res;
}
printf("read 2 value: 0x%02x\n", value);
}
sleep(1); sleep(1);
} }
gpio_close(&gpio_1); gpio_close(&gpio_1);
gpio_close(&gpio_2);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }