From 9b3391f3dbd5ef31e738e8738f367b8a2cee36ca Mon Sep 17 00:00:00 2001 From: Hewitt McGaughey Date: Wed, 30 Jun 2021 18:38:41 +0000 Subject: [PATCH 1/3] initial generic gpio work with gpio/pca9539r pins, some quick tests --- libraries/ms-drivers/inc/generic_gpio.h | 40 +++++ libraries/ms-drivers/rules.mk | 1 + libraries/ms-drivers/src/generic_gpio.c | 40 +++++ libraries/ms-drivers/test/test_generic_gpio.c | 156 ++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 libraries/ms-drivers/inc/generic_gpio.h create mode 100644 libraries/ms-drivers/src/generic_gpio.c create mode 100644 libraries/ms-drivers/test/test_generic_gpio.c diff --git a/libraries/ms-drivers/inc/generic_gpio.h b/libraries/ms-drivers/inc/generic_gpio.h new file mode 100644 index 000000000..75cb6c216 --- /dev/null +++ b/libraries/ms-drivers/inc/generic_gpio.h @@ -0,0 +1,40 @@ +// Generic GPIO interface +#include "gpio.h" +#include "pca9539r_gpio_expander.h" +#include "mcp23008_gpio_expander.h" + +typedef enum { + GEN_GPIO_TYPE_GPIO = 0, + GEN_GPIO_TYPE_PCA9539R, + GEN_GPIO_TYPE_MCP23008, + NUM_GEN_GPIO_TYPES, +} GenGpioType; + +typedef enum { + GEN_GPIO_STATE_LOW = 0, + GEN_GPIO_STATE_HIGH, + NUM_GEN_GPIO_STATES, +} GenGpioState; + +// Generic GPIO address. Holds a pointer to the correct type and stores the correct type +// to be used later. +typedef struct { + GenGpioType type; + GpioAddress *gpio_addr; + Pca9539rGpioAddress *pca_addr; + Mcp23008GpioAddress *mcp_addr; +} GenGpioAddress; + + +// Initialize the given onboard pin and configure the generic address with it. +StatusCode generic_gpio_init_gpio_pin(const GpioAddress *address, const GpioSettings *settings, GenGpioAddress *gen_addr); + +// Initialize the given PCA9539R pin and configure the generic address with it. +StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, const Pca9539rGpioSettings *settings, GenGpioAddress *gen_addr); + +// WARNING: the below functions currently cast between different state types, which assumes that LOW = 0 and HIGH = 1. +// Routes to the set function for address. +StatusCode generic_gpio_set_state(const GenGpioAddress *address, GenGpioState state); + +// Routes to the get function for address. +StatusCode generic_gpio_get_state(const GenGpioAddress *address, GenGpioState *state); \ No newline at end of file diff --git a/libraries/ms-drivers/rules.mk b/libraries/ms-drivers/rules.mk index 5f4d867ff..f049caf75 100644 --- a/libraries/ms-drivers/rules.mk +++ b/libraries/ms-drivers/rules.mk @@ -20,3 +20,4 @@ endif $(T)_test_bts7200_load_switch_MOCKS := adc_read_converted_pin $(T)_test_bts7040_load_switch_MOCKS := adc_read_converted_pin $(T)_test_voltage_regulator_MOCKS := gpio_get_state +$(T)_test_generic_gpio_MOCKS := gpio_set_state gpio_get_state pca9539r_gpio_set_state pca9539r_gpio_get_state diff --git a/libraries/ms-drivers/src/generic_gpio.c b/libraries/ms-drivers/src/generic_gpio.c new file mode 100644 index 000000000..b08f5c9a5 --- /dev/null +++ b/libraries/ms-drivers/src/generic_gpio.c @@ -0,0 +1,40 @@ +#include "generic_gpio.h" + +#include "status.h" +#include "log.h" + +StatusCode generic_gpio_init_gpio_pin(const GpioAddress *address, const GpioSettings *settings, GenGpioAddress *gen_addr) { + status_ok_or_return(gpio_init_pin(address, settings)); + gen_addr->type = GEN_GPIO_TYPE_GPIO; + gen_addr->gpio_addr = address; + return STATUS_CODE_OK; +} + +StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, const Pca9539rGpioSettings *settings, GenGpioAddress *gen_addr) { + status_ok_or_return(pca9539r_gpio_init_pin(address, settings)); + gen_addr->type = GEN_GPIO_TYPE_PCA9539R; + gen_addr->pca_addr = address; + return STATUS_CODE_OK; +} + +StatusCode generic_gpio_set_state(const GenGpioAddress *address, GenGpioState state) { + switch(address->type) { + case GEN_GPIO_TYPE_GPIO: + return gpio_set_state(address->gpio_addr, state); + case GEN_GPIO_TYPE_PCA9539R: + return pca9539r_gpio_set_state(address->pca_addr, state); + default: + return STATUS_CODE_INTERNAL_ERROR; + } +} + +StatusCode generic_gpio_get_state(const GenGpioAddress *address, GenGpioState *state) { + switch(address->type) { + case GEN_GPIO_TYPE_GPIO: + return gpio_get_state(address->gpio_addr, (GpioState*)state); + case GEN_GPIO_TYPE_PCA9539R: + return pca9539r_gpio_get_state(address->pca_addr, (Pca9539rGpioState*)state); + default: + return STATUS_CODE_INTERNAL_ERROR; + } +} \ No newline at end of file diff --git a/libraries/ms-drivers/test/test_generic_gpio.c b/libraries/ms-drivers/test/test_generic_gpio.c new file mode 100644 index 000000000..56a3b705f --- /dev/null +++ b/libraries/ms-drivers/test/test_generic_gpio.c @@ -0,0 +1,156 @@ +#include "generic_gpio.h" +#include "log.h" +#include "ms_test_helpers.h" +#include "controller_board_pins.h" + +#define TEST_I2C_PORT I2C_PORT_2 +#define TEST_I2C_ADDRESS 0x74 + +void setup_test(void) { + gpio_init(); + + I2CSettings i2c_settings = { + .speed = I2C_SPEED_FAST, // + .sda = CONTROLLER_BOARD_ADDR_I2C2_SDA, // + .scl = CONTROLLER_BOARD_ADDR_I2C2_SCL, // + }; + i2c_init(TEST_I2C_PORT, &i2c_settings); + + pca9539r_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); +} + +void teardown_test(void) {} + +// For testing gpio_set_state +static GpioAddress s_test_gpio_set_addr; +static GpioState s_test_gpio_set_state; + +StatusCode TEST_MOCK(gpio_set_state)(const GpioAddress *address, GpioState state) { + LOG_DEBUG("gpio_set_state called\n"); + s_test_gpio_set_addr = *address; + s_test_gpio_set_state = state; + return STATUS_CODE_OK; +} + +// For testing gpio_get_state +static GpioState s_test_gpio_get_state; + +StatusCode TEST_MOCK(gpio_get_state)(const GpioAddress *address, GpioState *input_state) { + LOG_DEBUG("gpio_get_state called\n"); + *input_state = s_test_gpio_get_state; + return STATUS_CODE_OK; +} + +// For testing pca9539r_gpio_set_state +static Pca9539rGpioAddress s_test_pca_set_addr; +static Pca9539rGpioState s_test_pca_set_state; + +StatusCode TEST_MOCK(pca9539r_gpio_set_state)(const Pca9539rGpioAddress *address, + Pca9539rGpioState input_state) { + LOG_DEBUG("pca9539r_set_state called\n"); + s_test_pca_set_addr = *address; + s_test_pca_set_state = input_state; + return STATUS_CODE_OK; +} + +// For testing pca9539r_gpio_get_state +static Pca9539rGpioState s_test_pca_get_state; + +StatusCode TEST_MOCK(pca9539r_gpio_get_state)(const Pca9539rGpioAddress *address, + Pca9539rGpioState *input_state) { + LOG_DEBUG("pca9539r_gpio_get_state called\n"); + *input_state = s_test_pca_get_state; + return STATUS_CODE_OK; +} + +// Make sure gpio pins initialize OK. +void test_gpio_init(void) { + GpioAddress test_addr = { + .port = GPIO_PORT_A, + .pin = 0, + }; + GpioSettings test_settings = { 0 }; + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_gpio_pin(&test_addr, &test_settings, &gen_addr)); +} + +// Initialize and set pin to high/low. Make sure calls get routed correctly. +void test_gpio_general_operation(void) { + GpioAddress test_addr = { + .port = GPIO_PORT_A, + .pin = 0, + }; + GpioSettings test_settings = { 0 }; + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_gpio_pin(&test_addr, &test_settings, &gen_addr)); + + // Set state + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); + TEST_ASSERT_EQUAL(GPIO_STATE_HIGH, s_test_gpio_set_state); + TEST_ASSERT_EQUAL(test_addr.port, s_test_gpio_set_addr.port); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_gpio_set_addr.pin); + + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); + TEST_ASSERT_EQUAL(GPIO_STATE_LOW, s_test_gpio_set_state); + TEST_ASSERT_EQUAL(test_addr.port, s_test_gpio_set_addr.port); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_gpio_set_addr.pin); + + // Get state + s_test_gpio_get_state = GPIO_STATE_HIGH; + GenGpioState test_state = GEN_GPIO_STATE_LOW; + TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); + TEST_ASSERT_EQUAL(test_state, GEN_GPIO_STATE_HIGH); +} + +// Make sure PCA9539R pins initialize OK. +void test_pca_init(void) { + Pca9539rGpioSettings test_settings = { + .direction = PCA9539R_GPIO_DIR_OUT, + .state = PCA9539R_GPIO_STATE_LOW, + }; + + Pca9539rGpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = PCA9539R_PIN_IO0_0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_pca9539r(&test_addr, &test_settings, &gen_addr)); +} + +// Initialize and set pin to high/low for pca9539r. Make sure calls get routed correctly. +void test_pca_general_operation(void) { + Pca9539rGpioSettings test_settings = { + .direction = PCA9539R_GPIO_DIR_OUT, + .state = PCA9539R_GPIO_STATE_LOW, + }; + + Pca9539rGpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = PCA9539R_PIN_IO0_0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_pca9539r(&test_addr, &test_settings, &gen_addr)); + + // Set state + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); + TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_HIGH, s_test_pca_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_pca_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); + + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); + TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_LOW, s_test_gpio_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_pca_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); + + // Get state + s_test_pca_get_state = GPIO_STATE_HIGH; + GenGpioState test_state = GEN_GPIO_STATE_LOW; + TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); + TEST_ASSERT_EQUAL(GEN_GPIO_STATE_HIGH, test_state); +} \ No newline at end of file From 6ee0c26d609511cbbd69e55dbfd7532ab8ec3a3d Mon Sep 17 00:00:00 2001 From: Hewitt McGaughey Date: Wed, 30 Jun 2021 23:24:11 +0000 Subject: [PATCH 2/3] add mcp23008 --- libraries/ms-drivers/inc/generic_gpio.h | 9 +- libraries/ms-drivers/rules.mk | 2 +- libraries/ms-drivers/src/generic_gpio.c | 15 ++- libraries/ms-drivers/test/test_generic_gpio.c | 111 +++++++++++++++--- 4 files changed, 114 insertions(+), 23 deletions(-) diff --git a/libraries/ms-drivers/inc/generic_gpio.h b/libraries/ms-drivers/inc/generic_gpio.h index 75cb6c216..79482c110 100644 --- a/libraries/ms-drivers/inc/generic_gpio.h +++ b/libraries/ms-drivers/inc/generic_gpio.h @@ -1,8 +1,10 @@ -// Generic GPIO interface +// Generic GPIO interface used when interfacing with multiple GPIO expanders and/or the onboard GPIO pins. +// Requires the GPIO type to be used to be initialized, as well as any other type-specific requirements like I2C. #include "gpio.h" #include "pca9539r_gpio_expander.h" #include "mcp23008_gpio_expander.h" +// Specific GPIO types to be accessed through generic GPIO. typedef enum { GEN_GPIO_TYPE_GPIO = 0, GEN_GPIO_TYPE_PCA9539R, @@ -10,6 +12,7 @@ typedef enum { NUM_GEN_GPIO_TYPES, } GenGpioType; +// Possible generic GPIO states. typedef enum { GEN_GPIO_STATE_LOW = 0, GEN_GPIO_STATE_HIGH, @@ -25,13 +28,15 @@ typedef struct { Mcp23008GpioAddress *mcp_addr; } GenGpioAddress; - // Initialize the given onboard pin and configure the generic address with it. StatusCode generic_gpio_init_gpio_pin(const GpioAddress *address, const GpioSettings *settings, GenGpioAddress *gen_addr); // Initialize the given PCA9539R pin and configure the generic address with it. StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, const Pca9539rGpioSettings *settings, GenGpioAddress *gen_addr); +// Initialize the given MCP23008 pin and configure the generic address with it. +StatusCode generic_gpio_init_mcp23008(const Mcp23008GpioAddress *address, const Mcp23008GpioSettings *settings, GenGpioAddress *gen_addr); + // WARNING: the below functions currently cast between different state types, which assumes that LOW = 0 and HIGH = 1. // Routes to the set function for address. StatusCode generic_gpio_set_state(const GenGpioAddress *address, GenGpioState state); diff --git a/libraries/ms-drivers/rules.mk b/libraries/ms-drivers/rules.mk index f049caf75..a29e4855a 100644 --- a/libraries/ms-drivers/rules.mk +++ b/libraries/ms-drivers/rules.mk @@ -20,4 +20,4 @@ endif $(T)_test_bts7200_load_switch_MOCKS := adc_read_converted_pin $(T)_test_bts7040_load_switch_MOCKS := adc_read_converted_pin $(T)_test_voltage_regulator_MOCKS := gpio_get_state -$(T)_test_generic_gpio_MOCKS := gpio_set_state gpio_get_state pca9539r_gpio_set_state pca9539r_gpio_get_state +$(T)_test_generic_gpio_MOCKS := gpio_set_state gpio_get_state pca9539r_gpio_set_state pca9539r_gpio_get_state mcp23008_gpio_set_state mcp23008_gpio_get_state diff --git a/libraries/ms-drivers/src/generic_gpio.c b/libraries/ms-drivers/src/generic_gpio.c index b08f5c9a5..45e21b4be 100644 --- a/libraries/ms-drivers/src/generic_gpio.c +++ b/libraries/ms-drivers/src/generic_gpio.c @@ -17,14 +17,23 @@ StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, const return STATUS_CODE_OK; } +StatusCode generic_gpio_init_mcp23008(const Mcp23008GpioAddress *address, const Mcp23008GpioSettings *settings, GenGpioAddress *gen_addr) { + status_ok_or_return(mcp23008_gpio_init_pin(address, settings)); + gen_addr->type = GEN_GPIO_TYPE_MCP23008; + gen_addr->mcp_addr = address; + return STATUS_CODE_OK; +} + StatusCode generic_gpio_set_state(const GenGpioAddress *address, GenGpioState state) { switch(address->type) { case GEN_GPIO_TYPE_GPIO: return gpio_set_state(address->gpio_addr, state); case GEN_GPIO_TYPE_PCA9539R: return pca9539r_gpio_set_state(address->pca_addr, state); + case GEN_GPIO_TYPE_MCP23008: + return mcp23008_gpio_set_state(address->mcp_addr, state); default: - return STATUS_CODE_INTERNAL_ERROR; + return STATUS_CODE_UNREACHABLE; } } @@ -34,7 +43,9 @@ StatusCode generic_gpio_get_state(const GenGpioAddress *address, GenGpioState *s return gpio_get_state(address->gpio_addr, (GpioState*)state); case GEN_GPIO_TYPE_PCA9539R: return pca9539r_gpio_get_state(address->pca_addr, (Pca9539rGpioState*)state); + case GEN_GPIO_TYPE_MCP23008: + return mcp23008_gpio_get_state(address->mcp_addr, (Mcp23008GpioState*)state); default: - return STATUS_CODE_INTERNAL_ERROR; + return STATUS_CODE_UNREACHABLE; } } \ No newline at end of file diff --git a/libraries/ms-drivers/test/test_generic_gpio.c b/libraries/ms-drivers/test/test_generic_gpio.c index 56a3b705f..bd6269591 100644 --- a/libraries/ms-drivers/test/test_generic_gpio.c +++ b/libraries/ms-drivers/test/test_generic_gpio.c @@ -6,21 +6,6 @@ #define TEST_I2C_PORT I2C_PORT_2 #define TEST_I2C_ADDRESS 0x74 -void setup_test(void) { - gpio_init(); - - I2CSettings i2c_settings = { - .speed = I2C_SPEED_FAST, // - .sda = CONTROLLER_BOARD_ADDR_I2C2_SDA, // - .scl = CONTROLLER_BOARD_ADDR_I2C2_SCL, // - }; - i2c_init(TEST_I2C_PORT, &i2c_settings); - - pca9539r_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); -} - -void teardown_test(void) {} - // For testing gpio_set_state static GpioAddress s_test_gpio_set_addr; static GpioState s_test_gpio_set_state; @@ -61,7 +46,46 @@ StatusCode TEST_MOCK(pca9539r_gpio_get_state)(const Pca9539rGpioAddress *address LOG_DEBUG("pca9539r_gpio_get_state called\n"); *input_state = s_test_pca_get_state; return STATUS_CODE_OK; -} +} + +// For testing mcp23008_gpio_set_state +static Mcp23008GpioAddress s_test_mcp_set_addr; +static Mcp23008GpioState s_test_mcp_set_state; + +StatusCode TEST_MOCK(mcp23008_gpio_set_state)(const Mcp23008GpioAddress *address, + const Mcp23008GpioState state) { + LOG_DEBUG("mcp23008_gpio_set_state called\n"); + s_test_mcp_set_addr = *address; + s_test_mcp_set_state = state; + return STATUS_CODE_OK; +} + +// For testing mcp23008_gpio_get_state +static Mcp23008GpioState s_test_mcp_get_state; + +StatusCode TEST_MOCK(mcp23008_gpio_get_state)(const Mcp23008GpioAddress *address, + Mcp23008GpioState *input_state) { + LOG_DEBUG("mcp23008_gpio_get_state called\n"); + *input_state = s_test_mcp_get_state; + return STATUS_CODE_OK; +} + +void setup_test(void) { + gpio_init(); + + I2CSettings i2c_settings = { + .speed = I2C_SPEED_FAST, // + .sda = CONTROLLER_BOARD_ADDR_I2C2_SDA, // + .scl = CONTROLLER_BOARD_ADDR_I2C2_SCL, // + }; + i2c_init(TEST_I2C_PORT, &i2c_settings); + + pca9539r_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); + + mcp23008_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); +} + +void teardown_test(void) {} // Make sure gpio pins initialize OK. void test_gpio_init(void) { @@ -144,12 +168,63 @@ void test_pca_general_operation(void) { TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); - TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_LOW, s_test_gpio_set_state); + TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_LOW, s_test_pca_set_state); TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_pca_set_addr.i2c_address); TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); // Get state - s_test_pca_get_state = GPIO_STATE_HIGH; + s_test_pca_get_state = PCA9539R_GPIO_STATE_HIGH; + GenGpioState test_state = GEN_GPIO_STATE_LOW; + TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); + TEST_ASSERT_EQUAL(GEN_GPIO_STATE_HIGH, test_state); +} + +// Make sure MCP23008 pins initialize OK. +void test_mcp_init(void) { + Mcp23008GpioSettings test_settings = { + .direction = MCP23008_GPIO_DIR_OUT, + .state = MCP23008_GPIO_STATE_LOW, + }; + + Mcp23008GpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = 0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_mcp23008(&test_addr, &test_settings, &gen_addr)); +} + +// Initialize and set pin to high/low for MCP23008. Make sure calls get routed correctly. +void test_mcp_general_operation(void) { + Mcp23008GpioSettings test_settings = { + .direction = MCP23008_GPIO_DIR_OUT, + .state = MCP23008_GPIO_STATE_LOW, + }; + + Mcp23008GpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = 0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_mcp23008(&test_addr, &test_settings, &gen_addr)); + + // Set state + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); + TEST_ASSERT_EQUAL(MCP23008_GPIO_STATE_HIGH, s_test_mcp_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_mcp_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_mcp_set_addr.pin); + + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); + TEST_ASSERT_EQUAL(MCP23008_GPIO_STATE_LOW, s_test_mcp_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_mcp_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_mcp_set_addr.pin); + + // Get state + s_test_mcp_get_state = MCP23008_GPIO_STATE_HIGH; GenGpioState test_state = GEN_GPIO_STATE_LOW; TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); TEST_ASSERT_EQUAL(GEN_GPIO_STATE_HIGH, test_state); From 78d2d6a69a07d9a84a777d0eda8216b8abe77957 Mon Sep 17 00:00:00 2001 From: Hewitt McGaughey Date: Wed, 30 Jun 2021 23:27:19 +0000 Subject: [PATCH 3/3] format, lint --- libraries/ms-drivers/inc/generic_gpio.h | 49 +-- libraries/ms-drivers/src/generic_gpio.c | 79 +++-- libraries/ms-drivers/test/test_generic_gpio.c | 316 +++++++++--------- 3 files changed, 228 insertions(+), 216 deletions(-) diff --git a/libraries/ms-drivers/inc/generic_gpio.h b/libraries/ms-drivers/inc/generic_gpio.h index 79482c110..4cb373e5c 100644 --- a/libraries/ms-drivers/inc/generic_gpio.h +++ b/libraries/ms-drivers/inc/generic_gpio.h @@ -1,45 +1,52 @@ -// Generic GPIO interface used when interfacing with multiple GPIO expanders and/or the onboard GPIO pins. -// Requires the GPIO type to be used to be initialized, as well as any other type-specific requirements like I2C. +#pragma once +// Generic GPIO interface used when interfacing with multiple GPIO expanders and/or the onboard GPIO +// pins. Requires the GPIO type to be used to be initialized, as well as any other type-specific +// requirements like I2C. #include "gpio.h" -#include "pca9539r_gpio_expander.h" #include "mcp23008_gpio_expander.h" +#include "pca9539r_gpio_expander.h" // Specific GPIO types to be accessed through generic GPIO. typedef enum { - GEN_GPIO_TYPE_GPIO = 0, - GEN_GPIO_TYPE_PCA9539R, - GEN_GPIO_TYPE_MCP23008, - NUM_GEN_GPIO_TYPES, + GEN_GPIO_TYPE_GPIO = 0, + GEN_GPIO_TYPE_PCA9539R, + GEN_GPIO_TYPE_MCP23008, + NUM_GEN_GPIO_TYPES, } GenGpioType; // Possible generic GPIO states. typedef enum { - GEN_GPIO_STATE_LOW = 0, - GEN_GPIO_STATE_HIGH, - NUM_GEN_GPIO_STATES, + GEN_GPIO_STATE_LOW = 0, + GEN_GPIO_STATE_HIGH, + NUM_GEN_GPIO_STATES, } GenGpioState; -// Generic GPIO address. Holds a pointer to the correct type and stores the correct type +// Generic GPIO address. Holds a pointer to the correct type and stores the correct type // to be used later. typedef struct { - GenGpioType type; - GpioAddress *gpio_addr; - Pca9539rGpioAddress *pca_addr; - Mcp23008GpioAddress *mcp_addr; + GenGpioType type; + GpioAddress *gpio_addr; + Pca9539rGpioAddress *pca_addr; + Mcp23008GpioAddress *mcp_addr; } GenGpioAddress; // Initialize the given onboard pin and configure the generic address with it. -StatusCode generic_gpio_init_gpio_pin(const GpioAddress *address, const GpioSettings *settings, GenGpioAddress *gen_addr); +StatusCode generic_gpio_init_gpio_pin(const GpioAddress *address, const GpioSettings *settings, + GenGpioAddress *gen_addr); // Initialize the given PCA9539R pin and configure the generic address with it. -StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, const Pca9539rGpioSettings *settings, GenGpioAddress *gen_addr); +StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, + const Pca9539rGpioSettings *settings, + GenGpioAddress *gen_addr); // Initialize the given MCP23008 pin and configure the generic address with it. -StatusCode generic_gpio_init_mcp23008(const Mcp23008GpioAddress *address, const Mcp23008GpioSettings *settings, GenGpioAddress *gen_addr); +StatusCode generic_gpio_init_mcp23008(const Mcp23008GpioAddress *address, + const Mcp23008GpioSettings *settings, + GenGpioAddress *gen_addr); -// WARNING: the below functions currently cast between different state types, which assumes that LOW = 0 and HIGH = 1. -// Routes to the set function for address. +// WARNING: the below functions currently cast between different state types, which assumes that LOW +// = 0 and HIGH = 1. Routes to the set function for address. StatusCode generic_gpio_set_state(const GenGpioAddress *address, GenGpioState state); // Routes to the get function for address. -StatusCode generic_gpio_get_state(const GenGpioAddress *address, GenGpioState *state); \ No newline at end of file +StatusCode generic_gpio_get_state(const GenGpioAddress *address, GenGpioState *state); diff --git a/libraries/ms-drivers/src/generic_gpio.c b/libraries/ms-drivers/src/generic_gpio.c index 45e21b4be..a87b135c3 100644 --- a/libraries/ms-drivers/src/generic_gpio.c +++ b/libraries/ms-drivers/src/generic_gpio.c @@ -1,51 +1,56 @@ #include "generic_gpio.h" -#include "status.h" #include "log.h" +#include "status.h" -StatusCode generic_gpio_init_gpio_pin(const GpioAddress *address, const GpioSettings *settings, GenGpioAddress *gen_addr) { - status_ok_or_return(gpio_init_pin(address, settings)); - gen_addr->type = GEN_GPIO_TYPE_GPIO; - gen_addr->gpio_addr = address; - return STATUS_CODE_OK; +StatusCode generic_gpio_init_gpio_pin(const GpioAddress *address, const GpioSettings *settings, + GenGpioAddress *gen_addr) { + status_ok_or_return(gpio_init_pin(address, settings)); + gen_addr->type = GEN_GPIO_TYPE_GPIO; + gen_addr->gpio_addr = address; + return STATUS_CODE_OK; } -StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, const Pca9539rGpioSettings *settings, GenGpioAddress *gen_addr) { - status_ok_or_return(pca9539r_gpio_init_pin(address, settings)); - gen_addr->type = GEN_GPIO_TYPE_PCA9539R; - gen_addr->pca_addr = address; - return STATUS_CODE_OK; +StatusCode generic_gpio_init_pca9539r(const Pca9539rGpioAddress *address, + const Pca9539rGpioSettings *settings, + GenGpioAddress *gen_addr) { + status_ok_or_return(pca9539r_gpio_init_pin(address, settings)); + gen_addr->type = GEN_GPIO_TYPE_PCA9539R; + gen_addr->pca_addr = address; + return STATUS_CODE_OK; } -StatusCode generic_gpio_init_mcp23008(const Mcp23008GpioAddress *address, const Mcp23008GpioSettings *settings, GenGpioAddress *gen_addr) { - status_ok_or_return(mcp23008_gpio_init_pin(address, settings)); - gen_addr->type = GEN_GPIO_TYPE_MCP23008; - gen_addr->mcp_addr = address; - return STATUS_CODE_OK; +StatusCode generic_gpio_init_mcp23008(const Mcp23008GpioAddress *address, + const Mcp23008GpioSettings *settings, + GenGpioAddress *gen_addr) { + status_ok_or_return(mcp23008_gpio_init_pin(address, settings)); + gen_addr->type = GEN_GPIO_TYPE_MCP23008; + gen_addr->mcp_addr = address; + return STATUS_CODE_OK; } StatusCode generic_gpio_set_state(const GenGpioAddress *address, GenGpioState state) { - switch(address->type) { - case GEN_GPIO_TYPE_GPIO: - return gpio_set_state(address->gpio_addr, state); - case GEN_GPIO_TYPE_PCA9539R: - return pca9539r_gpio_set_state(address->pca_addr, state); - case GEN_GPIO_TYPE_MCP23008: - return mcp23008_gpio_set_state(address->mcp_addr, state); - default: - return STATUS_CODE_UNREACHABLE; - } + switch (address->type) { + case GEN_GPIO_TYPE_GPIO: + return gpio_set_state(address->gpio_addr, state); + case GEN_GPIO_TYPE_PCA9539R: + return pca9539r_gpio_set_state(address->pca_addr, state); + case GEN_GPIO_TYPE_MCP23008: + return mcp23008_gpio_set_state(address->mcp_addr, state); + default: + return STATUS_CODE_UNREACHABLE; + } } StatusCode generic_gpio_get_state(const GenGpioAddress *address, GenGpioState *state) { - switch(address->type) { - case GEN_GPIO_TYPE_GPIO: - return gpio_get_state(address->gpio_addr, (GpioState*)state); - case GEN_GPIO_TYPE_PCA9539R: - return pca9539r_gpio_get_state(address->pca_addr, (Pca9539rGpioState*)state); - case GEN_GPIO_TYPE_MCP23008: - return mcp23008_gpio_get_state(address->mcp_addr, (Mcp23008GpioState*)state); - default: - return STATUS_CODE_UNREACHABLE; - } -} \ No newline at end of file + switch (address->type) { + case GEN_GPIO_TYPE_GPIO: + return gpio_get_state(address->gpio_addr, (GpioState *)state); + case GEN_GPIO_TYPE_PCA9539R: + return pca9539r_gpio_get_state(address->pca_addr, (Pca9539rGpioState *)state); + case GEN_GPIO_TYPE_MCP23008: + return mcp23008_gpio_get_state(address->mcp_addr, (Mcp23008GpioState *)state); + default: + return STATUS_CODE_UNREACHABLE; + } +} diff --git a/libraries/ms-drivers/test/test_generic_gpio.c b/libraries/ms-drivers/test/test_generic_gpio.c index bd6269591..9c81b2c24 100644 --- a/libraries/ms-drivers/test/test_generic_gpio.c +++ b/libraries/ms-drivers/test/test_generic_gpio.c @@ -1,7 +1,7 @@ +#include "controller_board_pins.h" #include "generic_gpio.h" #include "log.h" #include "ms_test_helpers.h" -#include "controller_board_pins.h" #define TEST_I2C_PORT I2C_PORT_2 #define TEST_I2C_ADDRESS 0x74 @@ -11,19 +11,19 @@ static GpioAddress s_test_gpio_set_addr; static GpioState s_test_gpio_set_state; StatusCode TEST_MOCK(gpio_set_state)(const GpioAddress *address, GpioState state) { - LOG_DEBUG("gpio_set_state called\n"); - s_test_gpio_set_addr = *address; - s_test_gpio_set_state = state; - return STATUS_CODE_OK; + LOG_DEBUG("gpio_set_state called\n"); + s_test_gpio_set_addr = *address; + s_test_gpio_set_state = state; + return STATUS_CODE_OK; } // For testing gpio_get_state static GpioState s_test_gpio_get_state; StatusCode TEST_MOCK(gpio_get_state)(const GpioAddress *address, GpioState *input_state) { - LOG_DEBUG("gpio_get_state called\n"); - *input_state = s_test_gpio_get_state; - return STATUS_CODE_OK; + LOG_DEBUG("gpio_get_state called\n"); + *input_state = s_test_gpio_get_state; + return STATUS_CODE_OK; } // For testing pca9539r_gpio_set_state @@ -31,201 +31,201 @@ static Pca9539rGpioAddress s_test_pca_set_addr; static Pca9539rGpioState s_test_pca_set_state; StatusCode TEST_MOCK(pca9539r_gpio_set_state)(const Pca9539rGpioAddress *address, - Pca9539rGpioState input_state) { - LOG_DEBUG("pca9539r_set_state called\n"); - s_test_pca_set_addr = *address; - s_test_pca_set_state = input_state; - return STATUS_CODE_OK; + Pca9539rGpioState input_state) { + LOG_DEBUG("pca9539r_set_state called\n"); + s_test_pca_set_addr = *address; + s_test_pca_set_state = input_state; + return STATUS_CODE_OK; } // For testing pca9539r_gpio_get_state static Pca9539rGpioState s_test_pca_get_state; StatusCode TEST_MOCK(pca9539r_gpio_get_state)(const Pca9539rGpioAddress *address, - Pca9539rGpioState *input_state) { - LOG_DEBUG("pca9539r_gpio_get_state called\n"); - *input_state = s_test_pca_get_state; - return STATUS_CODE_OK; -} + Pca9539rGpioState *input_state) { + LOG_DEBUG("pca9539r_gpio_get_state called\n"); + *input_state = s_test_pca_get_state; + return STATUS_CODE_OK; +} // For testing mcp23008_gpio_set_state static Mcp23008GpioAddress s_test_mcp_set_addr; static Mcp23008GpioState s_test_mcp_set_state; StatusCode TEST_MOCK(mcp23008_gpio_set_state)(const Mcp23008GpioAddress *address, - const Mcp23008GpioState state) { - LOG_DEBUG("mcp23008_gpio_set_state called\n"); - s_test_mcp_set_addr = *address; - s_test_mcp_set_state = state; - return STATUS_CODE_OK; + const Mcp23008GpioState state) { + LOG_DEBUG("mcp23008_gpio_set_state called\n"); + s_test_mcp_set_addr = *address; + s_test_mcp_set_state = state; + return STATUS_CODE_OK; } // For testing mcp23008_gpio_get_state static Mcp23008GpioState s_test_mcp_get_state; StatusCode TEST_MOCK(mcp23008_gpio_get_state)(const Mcp23008GpioAddress *address, - Mcp23008GpioState *input_state) { - LOG_DEBUG("mcp23008_gpio_get_state called\n"); - *input_state = s_test_mcp_get_state; - return STATUS_CODE_OK; + Mcp23008GpioState *input_state) { + LOG_DEBUG("mcp23008_gpio_get_state called\n"); + *input_state = s_test_mcp_get_state; + return STATUS_CODE_OK; } -void setup_test(void) { - gpio_init(); +void setup_test(void) { + gpio_init(); - I2CSettings i2c_settings = { - .speed = I2C_SPEED_FAST, // - .sda = CONTROLLER_BOARD_ADDR_I2C2_SDA, // - .scl = CONTROLLER_BOARD_ADDR_I2C2_SCL, // - }; - i2c_init(TEST_I2C_PORT, &i2c_settings); - - pca9539r_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); + I2CSettings i2c_settings = { + .speed = I2C_SPEED_FAST, // + .sda = CONTROLLER_BOARD_ADDR_I2C2_SDA, // + .scl = CONTROLLER_BOARD_ADDR_I2C2_SCL, // + }; + i2c_init(TEST_I2C_PORT, &i2c_settings); - mcp23008_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); + pca9539r_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); + + mcp23008_gpio_init(TEST_I2C_PORT, TEST_I2C_ADDRESS); } void teardown_test(void) {} // Make sure gpio pins initialize OK. void test_gpio_init(void) { - GpioAddress test_addr = { - .port = GPIO_PORT_A, - .pin = 0, - }; - GpioSettings test_settings = { 0 }; - GenGpioAddress gen_addr = { 0 }; - - TEST_ASSERT_OK(generic_gpio_init_gpio_pin(&test_addr, &test_settings, &gen_addr)); + GpioAddress test_addr = { + .port = GPIO_PORT_A, + .pin = 0, + }; + GpioSettings test_settings = { 0 }; + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_gpio_pin(&test_addr, &test_settings, &gen_addr)); } // Initialize and set pin to high/low. Make sure calls get routed correctly. void test_gpio_general_operation(void) { - GpioAddress test_addr = { - .port = GPIO_PORT_A, - .pin = 0, - }; - GpioSettings test_settings = { 0 }; - GenGpioAddress gen_addr = { 0 }; - - TEST_ASSERT_OK(generic_gpio_init_gpio_pin(&test_addr, &test_settings, &gen_addr)); - - // Set state - TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); - TEST_ASSERT_EQUAL(GPIO_STATE_HIGH, s_test_gpio_set_state); - TEST_ASSERT_EQUAL(test_addr.port, s_test_gpio_set_addr.port); - TEST_ASSERT_EQUAL(test_addr.pin, s_test_gpio_set_addr.pin); - - TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); - TEST_ASSERT_EQUAL(GPIO_STATE_LOW, s_test_gpio_set_state); - TEST_ASSERT_EQUAL(test_addr.port, s_test_gpio_set_addr.port); - TEST_ASSERT_EQUAL(test_addr.pin, s_test_gpio_set_addr.pin); - - // Get state - s_test_gpio_get_state = GPIO_STATE_HIGH; - GenGpioState test_state = GEN_GPIO_STATE_LOW; - TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); - TEST_ASSERT_EQUAL(test_state, GEN_GPIO_STATE_HIGH); + GpioAddress test_addr = { + .port = GPIO_PORT_A, + .pin = 0, + }; + GpioSettings test_settings = { 0 }; + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_gpio_pin(&test_addr, &test_settings, &gen_addr)); + + // Set state + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); + TEST_ASSERT_EQUAL(GPIO_STATE_HIGH, s_test_gpio_set_state); + TEST_ASSERT_EQUAL(test_addr.port, s_test_gpio_set_addr.port); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_gpio_set_addr.pin); + + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); + TEST_ASSERT_EQUAL(GPIO_STATE_LOW, s_test_gpio_set_state); + TEST_ASSERT_EQUAL(test_addr.port, s_test_gpio_set_addr.port); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_gpio_set_addr.pin); + + // Get state + s_test_gpio_get_state = GPIO_STATE_HIGH; + GenGpioState test_state = GEN_GPIO_STATE_LOW; + TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); + TEST_ASSERT_EQUAL(test_state, GEN_GPIO_STATE_HIGH); } // Make sure PCA9539R pins initialize OK. void test_pca_init(void) { - Pca9539rGpioSettings test_settings = { - .direction = PCA9539R_GPIO_DIR_OUT, - .state = PCA9539R_GPIO_STATE_LOW, - }; - - Pca9539rGpioAddress test_addr = { - .i2c_address = TEST_I2C_ADDRESS, - .pin = PCA9539R_PIN_IO0_0, - }; - - GenGpioAddress gen_addr = { 0 }; - - TEST_ASSERT_OK(generic_gpio_init_pca9539r(&test_addr, &test_settings, &gen_addr)); + Pca9539rGpioSettings test_settings = { + .direction = PCA9539R_GPIO_DIR_OUT, + .state = PCA9539R_GPIO_STATE_LOW, + }; + + Pca9539rGpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = PCA9539R_PIN_IO0_0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_pca9539r(&test_addr, &test_settings, &gen_addr)); } // Initialize and set pin to high/low for pca9539r. Make sure calls get routed correctly. void test_pca_general_operation(void) { - Pca9539rGpioSettings test_settings = { - .direction = PCA9539R_GPIO_DIR_OUT, - .state = PCA9539R_GPIO_STATE_LOW, - }; - - Pca9539rGpioAddress test_addr = { - .i2c_address = TEST_I2C_ADDRESS, - .pin = PCA9539R_PIN_IO0_0, - }; - - GenGpioAddress gen_addr = { 0 }; - - TEST_ASSERT_OK(generic_gpio_init_pca9539r(&test_addr, &test_settings, &gen_addr)); - - // Set state - TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); - TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_HIGH, s_test_pca_set_state); - TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_pca_set_addr.i2c_address); - TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); - - TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); - TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_LOW, s_test_pca_set_state); - TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_pca_set_addr.i2c_address); - TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); - - // Get state - s_test_pca_get_state = PCA9539R_GPIO_STATE_HIGH; - GenGpioState test_state = GEN_GPIO_STATE_LOW; - TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); - TEST_ASSERT_EQUAL(GEN_GPIO_STATE_HIGH, test_state); + Pca9539rGpioSettings test_settings = { + .direction = PCA9539R_GPIO_DIR_OUT, + .state = PCA9539R_GPIO_STATE_LOW, + }; + + Pca9539rGpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = PCA9539R_PIN_IO0_0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_pca9539r(&test_addr, &test_settings, &gen_addr)); + + // Set state + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); + TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_HIGH, s_test_pca_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_pca_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); + + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); + TEST_ASSERT_EQUAL(PCA9539R_GPIO_STATE_LOW, s_test_pca_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_pca_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_pca_set_addr.pin); + + // Get state + s_test_pca_get_state = PCA9539R_GPIO_STATE_HIGH; + GenGpioState test_state = GEN_GPIO_STATE_LOW; + TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); + TEST_ASSERT_EQUAL(GEN_GPIO_STATE_HIGH, test_state); } // Make sure MCP23008 pins initialize OK. void test_mcp_init(void) { - Mcp23008GpioSettings test_settings = { - .direction = MCP23008_GPIO_DIR_OUT, - .state = MCP23008_GPIO_STATE_LOW, - }; - - Mcp23008GpioAddress test_addr = { - .i2c_address = TEST_I2C_ADDRESS, - .pin = 0, - }; - - GenGpioAddress gen_addr = { 0 }; - - TEST_ASSERT_OK(generic_gpio_init_mcp23008(&test_addr, &test_settings, &gen_addr)); + Mcp23008GpioSettings test_settings = { + .direction = MCP23008_GPIO_DIR_OUT, + .state = MCP23008_GPIO_STATE_LOW, + }; + + Mcp23008GpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = 0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_mcp23008(&test_addr, &test_settings, &gen_addr)); } // Initialize and set pin to high/low for MCP23008. Make sure calls get routed correctly. void test_mcp_general_operation(void) { - Mcp23008GpioSettings test_settings = { - .direction = MCP23008_GPIO_DIR_OUT, - .state = MCP23008_GPIO_STATE_LOW, - }; - - Mcp23008GpioAddress test_addr = { - .i2c_address = TEST_I2C_ADDRESS, - .pin = 0, - }; - - GenGpioAddress gen_addr = { 0 }; - - TEST_ASSERT_OK(generic_gpio_init_mcp23008(&test_addr, &test_settings, &gen_addr)); - - // Set state - TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); - TEST_ASSERT_EQUAL(MCP23008_GPIO_STATE_HIGH, s_test_mcp_set_state); - TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_mcp_set_addr.i2c_address); - TEST_ASSERT_EQUAL(test_addr.pin, s_test_mcp_set_addr.pin); - - TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); - TEST_ASSERT_EQUAL(MCP23008_GPIO_STATE_LOW, s_test_mcp_set_state); - TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_mcp_set_addr.i2c_address); - TEST_ASSERT_EQUAL(test_addr.pin, s_test_mcp_set_addr.pin); - - // Get state - s_test_mcp_get_state = MCP23008_GPIO_STATE_HIGH; - GenGpioState test_state = GEN_GPIO_STATE_LOW; - TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); - TEST_ASSERT_EQUAL(GEN_GPIO_STATE_HIGH, test_state); -} \ No newline at end of file + Mcp23008GpioSettings test_settings = { + .direction = MCP23008_GPIO_DIR_OUT, + .state = MCP23008_GPIO_STATE_LOW, + }; + + Mcp23008GpioAddress test_addr = { + .i2c_address = TEST_I2C_ADDRESS, + .pin = 0, + }; + + GenGpioAddress gen_addr = { 0 }; + + TEST_ASSERT_OK(generic_gpio_init_mcp23008(&test_addr, &test_settings, &gen_addr)); + + // Set state + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_HIGH)); + TEST_ASSERT_EQUAL(MCP23008_GPIO_STATE_HIGH, s_test_mcp_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_mcp_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_mcp_set_addr.pin); + + TEST_ASSERT_OK(generic_gpio_set_state(&gen_addr, GEN_GPIO_STATE_LOW)); + TEST_ASSERT_EQUAL(MCP23008_GPIO_STATE_LOW, s_test_mcp_set_state); + TEST_ASSERT_EQUAL(test_addr.i2c_address, s_test_mcp_set_addr.i2c_address); + TEST_ASSERT_EQUAL(test_addr.pin, s_test_mcp_set_addr.pin); + + // Get state + s_test_mcp_get_state = MCP23008_GPIO_STATE_HIGH; + GenGpioState test_state = GEN_GPIO_STATE_LOW; + TEST_ASSERT_OK(generic_gpio_get_state(&gen_addr, &test_state)); + TEST_ASSERT_EQUAL(GEN_GPIO_STATE_HIGH, test_state); +}