From 07d0168a96640d111eb4b160ea32024565f01329 Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Thu, 13 Oct 2016 15:58:44 -0600 Subject: [PATCH] rotaryencoder: add C driver and example; FTI; C++ wraps C Signed-off-by: Jon Trulson --- examples/c/CMakeLists.txt | 1 + examples/c/rotaryencoder.c | 69 ++++++++++++++ include/fti/upm_rotaryencoder.h | 46 +++++++++ include/upm_fti.h | 4 +- src/rotaryencoder/CMakeLists.txt | 14 ++- src/rotaryencoder/rotaryencoder.c | 129 ++++++++++++++++++++++++++ src/rotaryencoder/rotaryencoder.cxx | 57 ++---------- src/rotaryencoder/rotaryencoder.h | 84 +++++++++++++++++ src/rotaryencoder/rotaryencoder.hpp | 124 ++++++++++++------------- src/rotaryencoder/rotaryencoder_fti.c | 106 +++++++++++++++++++++ 10 files changed, 513 insertions(+), 121 deletions(-) create mode 100644 examples/c/rotaryencoder.c create mode 100644 include/fti/upm_rotaryencoder.h create mode 100644 src/rotaryencoder/rotaryencoder.c create mode 100644 src/rotaryencoder/rotaryencoder.h create mode 100644 src/rotaryencoder/rotaryencoder_fti.c diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index 1b8dac47..729c880b 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -125,6 +125,7 @@ add_example (biss0001) add_example (bmi160) add_example (jhd1313m1) add_example (lm35) +add_example (rotaryencoder) # Custom examples add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps) diff --git a/examples/c/rotaryencoder.c b/examples/c/rotaryencoder.c new file mode 100644 index 00000000..edb265a3 --- /dev/null +++ b/examples/c/rotaryencoder.c @@ -0,0 +1,69 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "rotaryencoder.h" +#include "upm_utilities.h" + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + + +int main() +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + // Instantiate a Grove Rotary Encoder, using signal pins D2 and D3 + rotaryencoder_context sensor = rotaryencoder_init(2, 3); + + if (!sensor) + { + printf("rotaryencoder_init() failed.\n"); + return 1; + } + + while (shouldRun) + { + printf("Position: %d\n", rotaryencoder_get_position(sensor)); + + upm_delay_ms(100); + } + + + printf("Exiting...\n"); + + rotaryencoder_close(sensor); + +//! [Interesting] + return 0; +} diff --git a/include/fti/upm_rotaryencoder.h b/include/fti/upm_rotaryencoder.h new file mode 100644 index 00000000..383dd721 --- /dev/null +++ b/include/fti/upm_rotaryencoder.h @@ -0,0 +1,46 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef UPM_ROTARYENCODER_H_ +#define UPM_ROTARYENCODER_H_ + +#include "upm_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Rotary Encoder function table */ +typedef struct _upm_rotaryencoder_ft +{ + /* Set the initial position (count) */ + upm_result_t (*upm_rotaryencoder_set_position) (const void* dev, int pos); + /* Get the current position (count) */ + upm_result_t (*upm_rotaryencoder_get_position) (const void* dev, int *pos); +} upm_rotaryencoder_ft; + +#ifdef __cplusplus +} +#endif + +#endif /* UPM_ROTARYENCODER_H_ */ diff --git a/include/upm_fti.h b/include/upm_fti.h index bd227c6a..e7a5b8b0 100644 --- a/include/upm_fti.h +++ b/include/upm_fti.h @@ -74,7 +74,8 @@ typedef enum { UPM_WIRELESS, UPM_STREAM, UPM_ORP, - UPM_BINARY + UPM_BINARY, + UPM_ROTARYENCODER } upm_sensor_t; /* Supported IO protocols via MRAA */ @@ -122,6 +123,7 @@ typedef struct _upm_sensor_ft* (*func_get_upm_sensor_ft)(upm_sensor_t sensor_typ #include #include #include +#include #ifdef __cplusplus } diff --git a/src/rotaryencoder/CMakeLists.txt b/src/rotaryencoder/CMakeLists.txt index 099e87d1..473e5a97 100644 --- a/src/rotaryencoder/CMakeLists.txt +++ b/src/rotaryencoder/CMakeLists.txt @@ -1,5 +1,9 @@ -set (libname "rotaryencoder") -set (libdescription "upm grove rotary encoder module") -set (module_src ${libname}.cxx) -set (module_hpp ${libname}.hpp) -upm_module_init() +upm_mixed_module_init (NAME rotaryencoder + DESCRIPTION "Rotary Encoder" + C_HDR rotaryencoder.h + C_SRC rotaryencoder.c + CPP_HDR rotaryencoder.hpp + CPP_SRC rotaryencoder.cxx + FTI_SRC rotaryencoder_fti.c + CPP_WRAPS_C + REQUIRES mraa) diff --git a/src/rotaryencoder/rotaryencoder.c b/src/rotaryencoder/rotaryencoder.c new file mode 100644 index 00000000..c616d897 --- /dev/null +++ b/src/rotaryencoder/rotaryencoder.c @@ -0,0 +1,129 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "rotaryencoder.h" + + +// our ISR +static void rotaryencoder_isr(void *ctx) +{ + assert (ctx != NULL); + + rotaryencoder_context dev = (rotaryencoder_context)ctx; + + if (mraa_gpio_read(dev->gpioA)) + { + if (mraa_gpio_read(dev->gpioB)) + dev->position++; // CW + else + dev->position--; // CCW + } +} + +rotaryencoder_context rotaryencoder_init(int pin_a, int pin_b) +{ + rotaryencoder_context dev = + (rotaryencoder_context)malloc(sizeof(struct _rotaryencoder_context)); + + if (!dev) + return NULL; + + // make sure MRAA is initialized + int mraa_rv; + if ((mraa_rv = mraa_init()) != MRAA_SUCCESS) + { + printf("%s: mraa_init() failed (%d).\n", __FUNCTION__, mraa_rv); + rotaryencoder_close(dev); + return NULL; + } + + // MRAA contexts... + if ( !(dev->gpioA = mraa_gpio_init(pin_a)) ) + { + printf("%s: mraa_gpio_init(pin_a) failed\n", + __FUNCTION__); + rotaryencoder_close(dev); + return NULL; + } + + mraa_gpio_dir(dev->gpioA, MRAA_GPIO_IN); + + if ( !(dev->gpioB = mraa_gpio_init(pin_b)) ) + { + printf("%s: mraa_gpio_init(pin_b) failed\n", + __FUNCTION__); + rotaryencoder_close(dev); + return NULL; + } + + mraa_gpio_dir(dev->gpioB, MRAA_GPIO_IN); + + dev->position = 0; + + // setup the ISR + + // We would prefer to use MRAA_GPIO_EDGE_BOTH for better resolution, + // but that does not appear to be supported universally + if (mraa_gpio_isr(dev->gpioA, MRAA_GPIO_EDGE_RISING, + &rotaryencoder_isr, dev)) + { + printf("%s: mraa_gpio_isr() failed\n", + __FUNCTION__); + rotaryencoder_close(dev); + return NULL; + } + + return dev; +} + +void rotaryencoder_close(rotaryencoder_context dev) +{ + assert (dev != NULL); + + if (dev->gpioA) + { + mraa_gpio_isr_exit(dev->gpioA); + mraa_gpio_close(dev->gpioA); + } + + if (dev->gpioB) + mraa_gpio_close(dev->gpioB); + + free(dev); +} + +void rotaryencoder_set_position(const rotaryencoder_context dev, int count) +{ + assert (dev != NULL); + + dev->position = count; +} + +int rotaryencoder_get_position(const rotaryencoder_context dev) +{ + assert (dev != NULL); + + return dev->position; +} diff --git a/src/rotaryencoder/rotaryencoder.cxx b/src/rotaryencoder/rotaryencoder.cxx index cc368d79..71370c7d 100644 --- a/src/rotaryencoder/rotaryencoder.cxx +++ b/src/rotaryencoder/rotaryencoder.cxx @@ -1,6 +1,6 @@ /* * Author: Jon Trulson - * Copyright (c) 2015 Intel Corporation. + * Copyright (c) 2015-2016 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -29,67 +29,28 @@ #include "rotaryencoder.hpp" using namespace upm; -using namespace std; -RotaryEncoder::RotaryEncoder(int pinA, int pinB) +RotaryEncoder::RotaryEncoder(int pinA, int pinB) : + m_rotaryencoder(rotaryencoder_init(pinA, pinB)) { - if ( !(m_gpioA = mraa_gpio_init(pinA)) ) - { - throw std::invalid_argument(std::string(__FUNCTION__) + - ": mraa_gpio_init(pinA) failed, invalid pin?"); - return; - } - - mraa_gpio_dir(m_gpioA, MRAA_GPIO_IN); - - if ( !(m_gpioB = mraa_gpio_init(pinB)) ) - { - throw std::invalid_argument(std::string(__FUNCTION__) + - ": mraa_gpio_init(pinB) failed, invalid pin?"); - return; - } - - mraa_gpio_dir(m_gpioB, MRAA_GPIO_IN); - - m_position = 0; - - // setup the ISR - - // We would prefer to use MRAA_GPIO_EDGE_BOTH for better resolution, - // but that does not appear to be supported - mraa_gpio_isr(m_gpioA, MRAA_GPIO_EDGE_RISING, - &signalAISR, this); + if (!m_rotaryencoder) + throw std::runtime_error(std::string(__FUNCTION__) + + ": rotaryencoder_init failed"); } RotaryEncoder::~RotaryEncoder() { - mraa_gpio_isr_exit(m_gpioA); - - mraa_gpio_close(m_gpioA); - mraa_gpio_close(m_gpioB); + rotaryencoder_close(m_rotaryencoder); } void RotaryEncoder::initPosition(int count) { - m_position = count; + rotaryencoder_set_position(m_rotaryencoder, count); } int RotaryEncoder::position() { - return m_position; -} - -void RotaryEncoder::signalAISR(void *ctx) -{ - upm::RotaryEncoder *This = (upm::RotaryEncoder *)ctx; - - if (mraa_gpio_read(This->m_gpioA)) - { - if (mraa_gpio_read(This->m_gpioB)) - This->m_position++; // CW - else - This->m_position--; // CCW - } + return rotaryencoder_get_position(m_rotaryencoder); } diff --git a/src/rotaryencoder/rotaryencoder.h b/src/rotaryencoder/rotaryencoder.h new file mode 100644 index 00000000..02f514d9 --- /dev/null +++ b/src/rotaryencoder/rotaryencoder.h @@ -0,0 +1,84 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @file rotaryencoder.h + * @library rotaryencoder + * @brief C API for the rotaryencoder driver + * + * @include rotaryencoder.c + */ + + /** + * Device context + */ + typedef struct _rotaryencoder_context { + mraa_gpio_context gpioA; + mraa_gpio_context gpioB; + + volatile int position; + } *rotaryencoder_context; + + /** + * RotaryEncoder initialization + * + * @param pinA Digital pin to use for signal A + * @param pinB Digital pin to use for signal B + */ + rotaryencoder_context rotaryencoder_init(int pin_a, int pin_b); + + /** + * RotaryEncoder close function + */ + void rotaryencoder_close(rotaryencoder_context dev); + + /** + * Resets the position to a given number. + * + * @param count Integer to initialize the position to + */ + void rotaryencoder_set_position(const rotaryencoder_context dev, + int count); + + /** + * Gets the position value. + * + */ + int rotaryencoder_get_position(const rotaryencoder_context dev); + + +#ifdef __cplusplus +} +#endif diff --git a/src/rotaryencoder/rotaryencoder.hpp b/src/rotaryencoder/rotaryencoder.hpp index 2cf6bff0..63f70e0e 100644 --- a/src/rotaryencoder/rotaryencoder.hpp +++ b/src/rotaryencoder/rotaryencoder.hpp @@ -1,6 +1,6 @@ /* * Author: Jon Trulson - * Copyright (c) 2015 Intel Corporation. + * Copyright (c) 2015-2016 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -23,83 +23,73 @@ */ #pragma once -#include -#include -#include -#include +#include "rotaryencoder.h" namespace upm { -/** - * @brief Grove Rotary Encoder library - * @defgroup rotaryencoder libupm-rotaryencoder - * @ingroup seeed gpio other hak - */ -/** - * @library rotaryencoder - * @sensor rotaryencoder - * @comname Grove Rotary Encoder - * @type other - * @man seeed - * @web http://www.seeedstudio.com/wiki/Grove_-_Encoder - * @con gpio - * @kit hak - * - * @brief API for the Grove Rotary Encoder - * - * UPM module for the Grove rotary encoder. This rotary encoder - * encodes a rotation signal into electronic pulses that can be used - * to measure rotation and direction. It is useful in cases where a - * rotary knob is required, but using a potentiometer is not - * desirable. A rotary encoder can turn a full 360 degrees - * without a stop and does not place a resistive load on the - * circuit, as is the case with a potentiometer. - * - * This module maintains a position that is incremented or - * decremented according to the rotation on the encoder. - * - * @image html rotaryencoder.jpg - * @snippet rotaryencoder.cxx Interesting - */ - class RotaryEncoder { - public: /** - * RotaryEncoder constructor - * - * @param pinA Digital pin to use for signal A - * @param pinB Digital pin to use for signal B + * @brief Grove Rotary Encoder library + * @defgroup rotaryencoder libupm-rotaryencoder + * @ingroup seeed gpio other hak */ - RotaryEncoder(int pinA, int pinB); - /** - * RotaryEncoder destructor - */ - ~RotaryEncoder(); /** - * Resets the position to a given number; default is 0. + * @library rotaryencoder + * @sensor rotaryencoder + * @comname Grove Rotary Encoder + * @type other + * @man seeed + * @web http://www.seeedstudio.com/wiki/Grove_-_Encoder + * @con gpio + * @kit hak * - * @param count Integer to initialize the position to + * @brief API for the Grove Rotary Encoder + * + * UPM module for the Grove rotary encoder. This rotary encoder + * encodes a rotation signal into electronic pulses that can be used + * to measure rotation and direction. It is useful in cases where a + * rotary knob is required, but using a potentiometer is not + * desirable. A rotary encoder can turn a full 360 degrees + * without a stop and does not place a resistive load on the + * circuit, as is the case with a potentiometer. + * + * This module maintains a position that is incremented or + * decremented according to the rotation on the encoder. + * + * @image html rotaryencoder.jpg + * @snippet rotaryencoder.cxx Interesting */ - void initPosition(int count=0); - /** - * Gets the position value - * - */ - int position(); + class RotaryEncoder { + public: + /** + * RotaryEncoder constructor + * + * @param pinA Digital pin to use for signal A + * @param pinB Digital pin to use for signal B + */ + RotaryEncoder(int pinA, int pinB); + /** + * RotaryEncoder destructor + */ + ~RotaryEncoder(); - private: - /** - * Interrupt service routine (ISR) for signal A - * - * @param ctx User context for the ISR (*this pointer) - */ - static void signalAISR(void *ctx); - - volatile int m_position; - mraa_gpio_context m_gpioA; - mraa_gpio_context m_gpioB; - }; + /** + * Resets the position to a given number; default is 0. + * + * @param count Integer to initialize the position to + */ + void initPosition(int count=0); + + /** + * Gets the position value + * + */ + int position(); + + private: + rotaryencoder_context m_rotaryencoder; + }; } diff --git a/src/rotaryencoder/rotaryencoder_fti.c b/src/rotaryencoder/rotaryencoder_fti.c new file mode 100644 index 00000000..df999597 --- /dev/null +++ b/src/rotaryencoder/rotaryencoder_fti.c @@ -0,0 +1,106 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "rotaryencoder.h" + +#include +#include + +#include "upm_fti.h" +#include "upm_sensor.h" + +/** + * This file implements the Function Table Interface (FTI) for this sensor + */ + +const char upm_rotaryencoder_name[] = "ROTARYENCODER"; +const char upm_rotaryencoder_description[] = "Rotary Encoder"; +const upm_protocol_t upm_rotaryencoder_protocol[] = {UPM_GPIO, UPM_GPIO}; +const upm_sensor_t upm_rotaryencoder_category[] = {UPM_ROTARYENCODER}; + +// forward declarations +const upm_sensor_descriptor_t upm_rotaryencoder_get_descriptor(); +const void* upm_rotaryencoder_get_ft(upm_sensor_t sensor_type); +void* upm_rotaryencoder_init_name(); +void upm_rotaryencoder_close(void* dev); +upm_result_t upm_rotaryencoder_get_pos(const void* dev, int *pos); +upm_result_t upm_rotaryencoder_set_pos(const void* dev, int pos); + +const upm_sensor_descriptor_t upm_rotaryencoder_get_descriptor() +{ + upm_sensor_descriptor_t usd; + usd.name = upm_rotaryencoder_name; + usd.description = upm_rotaryencoder_description; + usd.protocol_size = 2; + usd.protocol = upm_rotaryencoder_protocol; + usd.category_size = 1; + usd.category = upm_rotaryencoder_category; + return usd; +} + +static const upm_sensor_ft ft = +{ + .upm_sensor_init_name = upm_rotaryencoder_init_name, + .upm_sensor_close = upm_rotaryencoder_close, + .upm_sensor_get_descriptor = upm_rotaryencoder_get_descriptor +}; + +static const upm_rotaryencoder_ft rft = +{ + .upm_rotaryencoder_get_position = upm_rotaryencoder_get_pos, + .upm_rotaryencoder_set_position = upm_rotaryencoder_set_pos, +}; + +const void* upm_rotaryencoder_get_ft(upm_sensor_t sensor_type) +{ + if (sensor_type == UPM_SENSOR) + return &ft; + + if (sensor_type == UPM_ROTARYENCODER) + return &rft; + + return NULL; +} + +void* upm_rotaryencoder_init_name() +{ + return NULL; +} + +void upm_rotaryencoder_close(void* dev) +{ + rotaryencoder_close((rotaryencoder_context)dev); +} + +upm_result_t upm_rotaryencoder_set_pos(const void *dev, int pos) +{ + rotaryencoder_set_position((rotaryencoder_context)dev, pos); + return UPM_SUCCESS; +} + +upm_result_t upm_rotaryencoder_get_pos(const void *dev, int *pos) +{ + *pos = rotaryencoder_get_position((rotaryencoder_context)dev); + return UPM_SUCCESS; +}