diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..5703028 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -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 +} \ No newline at end of file diff --git a/src/gpio.c b/src/gpio.c index e87b8d8..238a81d 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -9,7 +9,7 @@ static int ftdi_open(const struct gpio *gpio) { int res; - if((gpio->ftdi_dev->ftdi = ftdi_new()) == 0) { + if((gpio->ftdi_dev->ftdi = ftdi_new()) == NULL) { syslog(LOG_ERR, "ftdi_new failed\n"); return EXIT_FAILURE; } @@ -35,7 +35,7 @@ static int ftdi_open(const struct gpio *gpio) int gpio_open(const struct gpio *gpio) { int res; - unsigned int init_value = 0; + unsigned char init_value = 0; if(NULL == gpio) { syslog(LOG_ERR, "No valid gpio object given.\n"); @@ -50,7 +50,6 @@ int gpio_open(const struct gpio *gpio) } 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, @@ -60,7 +59,7 @@ int gpio_open(const struct gpio *gpio) return EXIT_FAILURE; } - res = gpio_write(gpio, init_value); + res = ftdi_write_data(gpio->ftdi_dev->ftdi, &init_value, 1); if(res < 0) { syslog(LOG_ERR, "unable to write to gpio %u (%s)\n", gpio->pin, ftdi_get_error_string(gpio->ftdi_dev->ftdi)); @@ -85,6 +84,7 @@ int gpio_close(const struct gpio *gpio) if(gpio->ftdi_dev->bit_mask == 0) { ftdi_usb_close(gpio->ftdi_dev->ftdi); ftdi_free(gpio->ftdi_dev->ftdi); + gpio->ftdi_dev->is_open = false; } return EXIT_SUCCESS; diff --git a/test/inc/mock_ftdi.h b/test/inc/mock_ftdi.h new file mode 100644 index 0000000..cb56bb0 --- /dev/null +++ b/test/inc/mock_ftdi.h @@ -0,0 +1,18 @@ +#ifndef __MOCK_FTDI_H__ +#define __MOCK_FTDI_H__ + +#include + +DEFINE_FFF_GLOBALS; + +DECLARE_FAKE_VOID_FUNC(ftdi_free, struct ftdi_context *); + +DECLARE_FAKE_VALUE_FUNC(int, ftdi_usb_open, struct ftdi_context *, int, int); +DECLARE_FAKE_VALUE_FUNC(int, ftdi_usb_close, struct ftdi_context *); +DECLARE_FAKE_VALUE_FUNC(struct ftdi_context *, ftdi_new); +DECLARE_FAKE_VALUE_FUNC(const char *, ftdi_get_error_string, struct ftdi_context *); +DECLARE_FAKE_VALUE_FUNC(int, ftdi_set_bitmode, struct ftdi_context *, unsigned char, unsigned char); +DECLARE_FAKE_VALUE_FUNC(int, ftdi_read_data, struct ftdi_context *, unsigned char *, int); +DECLARE_FAKE_VALUE_FUNC(int, ftdi_write_data, struct ftdi_context *, const unsigned char *, int); + +#endif diff --git a/test/unit/gpio_close.c b/test/unit/gpio_close.c new file mode 100644 index 0000000..457c864 --- /dev/null +++ b/test/unit/gpio_close.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +UTEST(gpio_close, invalid_gpio_obj) { + ASSERT_EQ(gpio_close(NULL), EXIT_FAILURE); +} + +UTEST(gpio_close, empty_bitmask) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.is_open = true; + ftdi_obj.bit_mask = 0x08; + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + ASSERT_EQ(gpio_close(&gpio_1), EXIT_SUCCESS); + +} \ No newline at end of file diff --git a/test/unit/gpio_open.c b/test/unit/gpio_open.c new file mode 100644 index 0000000..98e2dfc --- /dev/null +++ b/test/unit/gpio_open.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +UTEST(gpio_open, invalid_ftdi_new_result) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.ftdi = NULL, + ftdi_obj.is_open = false, + ftdi_obj.vendor_id = 0x0403, + ftdi_obj.product_id = 0x6001, + ftdi_obj.bit_mask = 0, + ftdi_obj.status_mask = 0, + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_new_fake.return_val = NULL; + + ASSERT_EQ(gpio_open(&gpio_1), EXIT_FAILURE); +} + +UTEST(gpio_open, ftdi_usb_open_failed) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + struct ftdi_context ftdi_ctx; + ftdi_obj.ftdi = NULL, + ftdi_obj.is_open = false, + ftdi_obj.vendor_id = 0x0403, + ftdi_obj.product_id = 0x6001, + ftdi_obj.bit_mask = 0, + ftdi_obj.status_mask = 0, + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_new_fake.return_val = &ftdi_ctx; + ftdi_usb_open_fake.return_val = -1; + ASSERT_EQ(gpio_open(&gpio_1), EXIT_FAILURE); +} + +UTEST(gpio_open, ftdi_read_data_failed) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + struct ftdi_context ftdi_ctx; + ftdi_obj.ftdi = NULL, + ftdi_obj.is_open = false, + ftdi_obj.vendor_id = 0x0403, + ftdi_obj.product_id = 0x6001, + ftdi_obj.bit_mask = 0, + ftdi_obj.status_mask = 0, + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_new_fake.return_val = &ftdi_ctx; + ftdi_usb_open_fake.return_val = 0; + ftdi_read_data_fake.return_val = -1; + ASSERT_EQ(gpio_open(&gpio_1), EXIT_FAILURE); +} + +UTEST(gpio_open, ftdi_open_success) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + struct ftdi_context ftdi_ctx; + ftdi_obj.ftdi = NULL, + ftdi_obj.is_open = false, + ftdi_obj.vendor_id = 0x0403, + ftdi_obj.product_id = 0x6001, + ftdi_obj.bit_mask = 0, + ftdi_obj.status_mask = 0, + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_new_fake.return_val = &ftdi_ctx; + ftdi_usb_open_fake.return_val = 0; + ftdi_read_data_fake.return_val = 0; + 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) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + struct ftdi_context ftdi_ctx; + ftdi_obj.ftdi = NULL, + ftdi_obj.is_open = false, + ftdi_obj.vendor_id = 0x0403, + ftdi_obj.product_id = 0x6001, + ftdi_obj.bit_mask = 0, + ftdi_obj.status_mask = 0, + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_new_fake.return_val = &ftdi_ctx; + ftdi_usb_open_fake.return_val = 0; + ftdi_read_data_fake.return_val = 0; + ftdi_set_bitmode_fake.return_val = -1; + ASSERT_EQ(gpio_open(&gpio_1), EXIT_FAILURE); +} + +UTEST(gpio_open, ftdi_write_data_failed) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + struct ftdi_context ftdi_ctx; + ftdi_obj.ftdi = NULL, + ftdi_obj.is_open = false, + ftdi_obj.vendor_id = 0x0403, + ftdi_obj.product_id = 0x6001, + ftdi_obj.bit_mask = 0, + ftdi_obj.status_mask = 0, + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_new_fake.return_val = &ftdi_ctx; + ftdi_usb_open_fake.return_val = 0; + ftdi_read_data_fake.return_val = 0; + ftdi_set_bitmode_fake.return_val = 0; + ftdi_write_data_fake.return_val = -1; + ASSERT_EQ(gpio_open(&gpio_1), EXIT_FAILURE); +} + +UTEST(gpio_open, success) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + struct ftdi_context ftdi_ctx; + ftdi_obj.ftdi = NULL, + ftdi_obj.is_open = false, + ftdi_obj.vendor_id = 0x0403, + ftdi_obj.product_id = 0x6001, + ftdi_obj.bit_mask = 0, + ftdi_obj.status_mask = 0, + + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_new_fake.return_val = &ftdi_ctx; + ftdi_usb_open_fake.return_val = 0; + ftdi_read_data_fake.return_val = 0; + ftdi_set_bitmode_fake.return_val = 0; + ftdi_write_data_fake.return_val = 0; + ASSERT_EQ(gpio_open(&gpio_1), EXIT_SUCCESS); +} diff --git a/test/unit/gpio_read.c b/test/unit/gpio_read.c new file mode 100644 index 0000000..a110f22 --- /dev/null +++ b/test/unit/gpio_read.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +UTEST(gpio_read, invalid_params) { + + ASSERT_EQ(gpio_read(NULL, NULL), EXIT_FAILURE); +} + +UTEST(gpio_read, value_0) { + unsigned int result; + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.status_mask = ~0x08; + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ASSERT_EQ(gpio_read(&gpio_1, &result), EXIT_SUCCESS); + result = ((ftdi_obj.status_mask) & (gpio_1.pin)) >> 3; + ASSERT_EQ(result, 0) +} + +UTEST(gpio_read, value_1) { + unsigned int result; + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.status_mask = 0x08; + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ASSERT_EQ(gpio_read(&gpio_1, &result), EXIT_SUCCESS); + result = ((ftdi_obj.status_mask) & (gpio_1.pin)) >> 3; + ASSERT_EQ(result, 1) +} diff --git a/test/unit/gpio_toggle.c b/test/unit/gpio_toggle.c new file mode 100644 index 0000000..afd91aa --- /dev/null +++ b/test/unit/gpio_toggle.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +UTEST(gpio_toggle, invalid_params) { + + ASSERT_EQ(gpio_toggle(NULL), EXIT_FAILURE); +} + +UTEST(gpio_toggle, ftdi_write_data_fails) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.status_mask = 0; + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_write_data_fake.return_val = -1; + + ASSERT_EQ(gpio_toggle(&gpio_1), EXIT_FAILURE); +} + +UTEST(gpio_toggle, success) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.status_mask = 0; + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_write_data_fake.return_val = 0; + + ASSERT_EQ(gpio_toggle(&gpio_1), EXIT_SUCCESS); +} diff --git a/test/unit/gpio_write.c b/test/unit/gpio_write.c new file mode 100644 index 0000000..ee0abac --- /dev/null +++ b/test/unit/gpio_write.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +UTEST(gpio_write, invalid_params) { + + ASSERT_EQ(gpio_write(NULL, 0), EXIT_FAILURE); +} + +UTEST(gpio_write, value_0) { + unsigned int result; + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.status_mask = 0xff; + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_write_data_fake.return_val = 0; + + ASSERT_EQ(gpio_write(&gpio_1, 0), EXIT_SUCCESS); + result = ((ftdi_obj.status_mask) & (gpio_1.pin)) >> 3; + ASSERT_EQ(result, 0) +} + +UTEST(gpio_write, value_1) { + unsigned int result; + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.status_mask = 0; + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_write_data_fake.return_val = 0; + + ASSERT_EQ(gpio_write(&gpio_1, 1), EXIT_SUCCESS); + result = ((ftdi_obj.status_mask) | (gpio_1.pin)) >> 3; + ASSERT_EQ(result, 1) +} + +UTEST(gpio_write, ftdi_write_data_failed) { + struct gpio gpio_1; + struct ftdi_dev ftdi_obj; + + ftdi_obj.status_mask = 0; + gpio_1.pin = 0x08; + gpio_1.ftdi_dev = &ftdi_obj; + + ftdi_write_data_fake.return_val = -1; + + ASSERT_EQ(gpio_write(&gpio_1, 0), EXIT_FAILURE); +} diff --git a/test/unit/main.c b/test/unit/main.c new file mode 100644 index 0000000..40e82ff --- /dev/null +++ b/test/unit/main.c @@ -0,0 +1,8 @@ +#include +#include +#include + +#include + +UTEST_MAIN(); + diff --git a/test/unit/mock_ftdi.c b/test/unit/mock_ftdi.c new file mode 100644 index 0000000..f1062e5 --- /dev/null +++ b/test/unit/mock_ftdi.c @@ -0,0 +1,13 @@ +#include + +DEFINE_FFF_GLOBALS; + +DEFINE_FAKE_VOID_FUNC(ftdi_free, struct ftdi_context *); + +DEFINE_FAKE_VALUE_FUNC(int, ftdi_usb_open, struct ftdi_context *, int, int); +DEFINE_FAKE_VALUE_FUNC(int, ftdi_usb_close, struct ftdi_context *); +DEFINE_FAKE_VALUE_FUNC(struct ftdi_context *, ftdi_new); +DEFINE_FAKE_VALUE_FUNC(const char *, ftdi_get_error_string, struct ftdi_context *); +DEFINE_FAKE_VALUE_FUNC(int, ftdi_set_bitmode, struct ftdi_context *, unsigned char, unsigned char); +DEFINE_FAKE_VALUE_FUNC(int, ftdi_read_data, struct ftdi_context *, unsigned char *, int); +DEFINE_FAKE_VALUE_FUNC(int, ftdi_write_data, struct ftdi_context *, const unsigned char *, int); diff --git a/test/unit/test_gpio.c b/test/unit/test_gpio.c deleted file mode 100644 index 2e6a1cb..0000000 --- a/test/unit/test_gpio.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -DEFINE_FFF_GLOBALS; - -FAKE_VOID_FUNC(ftdi_free, struct ftdi_context *); - -FAKE_VALUE_FUNC(int, ftdi_usb_open, struct ftdi_context *, int, int); -FAKE_VALUE_FUNC(int, ftdi_usb_close, struct ftdi_context *); -FAKE_VALUE_FUNC(struct ftdi_context *, ftdi_new); -FAKE_VALUE_FUNC(const char *, ftdi_get_error_string, struct ftdi_context *); -FAKE_VALUE_FUNC(int, ftdi_set_bitmode, struct ftdi_context *, unsigned char, unsigned char); -FAKE_VALUE_FUNC(int, ftdi_read_data, struct ftdi_context *, unsigned char *, int); -FAKE_VALUE_FUNC(int, ftdi_write_data, struct ftdi_context *, const unsigned char *, int); - -UTEST_MAIN(); - -UTEST(gpio, gpio_open) { - struct gpio gpio_1; - struct ftdi_dev ftdi_obj; - struct ftdi_context ftdi_ctx; - - ftdi_obj.ftdi = NULL, - ftdi_obj.is_open = false, - ftdi_obj.vendor_id = 0x0403, - ftdi_obj.product_id = 0x6001, - ftdi_obj.bit_mask = 0, - ftdi_obj.status_mask = 0, - - gpio_1.pin = 0x08; - gpio_1.ftdi_dev = &ftdi_obj; - - ASSERT_EQ(gpio_open(NULL), EXIT_FAILURE); - - ftdi_new_fake.return_val = &ftdi_ctx; - ASSERT_EQ(gpio_open(&gpio_1), EXIT_SUCCESS); -}