From 4bb077e70b8240dfcc15e0cca56411337514bff9 Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Wed, 25 Mar 2015 12:58:02 -0600 Subject: [PATCH] a110x: Add interrupt support and a suitable example Signed-off-by: Jon Trulson Signed-off-by: John Van Drasek --- examples/c++/CMakeLists.txt | 2 + examples/c++/a110x-intr.cxx | 76 +++++++++++++++++++++++++++++++++++++ src/a110x/a110x.cxx | 22 ++++++++++- src/a110x/a110x.h | 20 ++++++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 examples/c++/a110x-intr.cxx diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 0f2bb4e0..6864a90f 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -104,6 +104,7 @@ add_executable (adafruitms1438-example adafruitms1438.cxx) add_executable (adafruitms1438-stepper-example adafruitms1438-stepper.cxx) add_executable (hx711-example hx711.cxx) add_executable (flex-example flex.cxx) +add_executable (a110x-intr-example a110x-intr.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -293,3 +294,4 @@ target_link_libraries (adafruitms1438-example adafruitms1438 ${CMAKE_THREAD_LIBS target_link_libraries (adafruitms1438-stepper-example adafruitms1438 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (hx711-example hx711 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (flex-example flex ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (a110x-intr-example a110x ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/a110x-intr.cxx b/examples/c++/a110x-intr.cxx new file mode 100644 index 00000000..187c2edb --- /dev/null +++ b/examples/c++/a110x-intr.cxx @@ -0,0 +1,76 @@ +/* + * 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 "a110x.h" + +using namespace std; + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + +// Our pulse counter +volatile unsigned int counter = 0; + +// Our interrupt handler +void hallISR(void *arg) +{ + counter++; +} + +int main () +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + // Instantiate an A110X sensor on digital pin D2 + upm::A110X* hall = new upm::A110X(2); + + // This example uses a user-supplied interrupt handler to count + // pulses that occur when a magnetic field of the correct polarity + // is detected. This could be used to measure the rotations per + // minute (RPM) of a rotor for example. + + hall->installISR(hallISR, NULL); + + while (shouldRun) + { + cout << "Pulses detected: " << counter << endl; + + sleep(1); + } +//! [Interesting] + + cout << "Exiting..." << endl; + + delete hall; + return 0; +} diff --git a/src/a110x/a110x.cxx b/src/a110x/a110x.cxx index fef7e94d..33c4f25a 100644 --- a/src/a110x/a110x.cxx +++ b/src/a110x/a110x.cxx @@ -31,8 +31,6 @@ using namespace std; A110X::A110X(int pin) { - mraa_init(); - if ( !(m_gpio = mraa_gpio_init(pin)) ) { cerr << __FUNCTION__ << ": mraa_gpio_init() failed" << endl; @@ -40,10 +38,14 @@ A110X::A110X(int pin) } mraa_gpio_dir(m_gpio, MRAA_GPIO_IN); + m_isrInstalled = false; } A110X::~A110X() { + if (m_isrInstalled) + uninstallISR(); + mraa_gpio_close(m_gpio); } @@ -52,3 +54,19 @@ bool A110X::magnetDetected() return (!mraa_gpio_read(m_gpio) ? true : false); } +void A110X::installISR(void (*isr)(void *), void *arg) +{ + if (m_isrInstalled) + uninstallISR(); + + // install our interrupt handler + mraa_gpio_isr(m_gpio, MRAA_GPIO_EDGE_FALLING, + isr, arg); + m_isrInstalled = true; +} + +void A110X::uninstallISR() +{ + mraa_gpio_isr_exit(m_gpio); + m_isrInstalled = false; +} diff --git a/src/a110x/a110x.h b/src/a110x/a110x.h index 754d5f4e..98ad0d2f 100644 --- a/src/a110x/a110x.h +++ b/src/a110x/a110x.h @@ -50,7 +50,10 @@ namespace upm { * whether it is detecting a magnetic field with south polarity * perpendicular to the sensor element. * + * An example showing a simple test for the presence of a field * @snippet a110x.cxx Interesting + * An example demonstrating the use of an interrupt handler to count pulses + * @snippet a110x-intr.cxx Interesting */ class A110X { public: @@ -71,7 +74,24 @@ namespace upm { */ bool magnetDetected(); + /** + * Install an Interrupt Service Routine (ISR) to be called when + * the appropriate magnetic field is detected. + * + * @param fptr function pointer to function to be called on interrupt + * @param arg pointer to an object that will be supplied as an + * arguement to the ISR. + */ + void installISR(void (*isr)(void *), void *arg); + + /** + * Uninstall the previously installed Interrupt Service Routine (ISR) + * + */ + void uninstallISR(); + private: + bool m_isrInstalled; mraa_gpio_context m_gpio; }; }