Skip to content

Commit

Permalink
wrap MRAA lib's Gpio::isr() for IRQ support
Browse files Browse the repository at this point in the history
I also removed MRAA exclusion from examples build. Previously, interruptConfigure.cpp was not built for MRAA driver.
  • Loading branch information
2bndy5 committed Mar 26, 2024
1 parent 7441eef commit 62f73e4
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ include $(CONFIG_FILE)
# Objects to compile
OBJECTS=RF24.o
ifeq ($(DRIVER), MRAA)
OBJECTS+=spi.o gpio.o compatibility.o
OBJECTS+=spi.o gpio.o compatibility.o interrupt.o
else ifeq ($(DRIVER), RPi)
OBJECTS+=spi.o bcm2835.o compatibility.o interrupt.o
else ifeq ($(DRIVER), SPIDEV)
Expand Down
8 changes: 1 addition & 7 deletions examples_linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(EXAMPLES_LIST
streamingData
multiceiverDemo
scanner
interruptConfigure
)

project(RF24Examples CXX)
Expand All @@ -23,13 +24,6 @@ include(../cmake/AutoConfig_RF24_DRIVER.cmake)
find_library(RF24 rf24 REQUIRED)
message(STATUS "using RF24 library: ${RF24}")

# conditionally append "interruptConfigure" to the EXAMPLES_LIST
if("${RF24_DRIVER}" STREQUAL "MRAA")
message(STATUS "Skipping interruptConfigure.cpp example as it is incompatible with selected driver library")
else() # not using MRAA or wiringPi drivers (or pigpio lib was found)
list(APPEND EXAMPLES_LIST interruptConfigure)
endif()


set(linked_libs
${RF24}
Expand Down
5 changes: 1 addition & 4 deletions examples_linux/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ endif
include ../Makefile.inc

# define all programs
PROGRAMS = gettingstarted acknowledgementPayloads manualAcknowledgements streamingData multiceiverDemo scanner
ifneq ($(DRIVER), MRAA)
PROGRAMS+=interruptConfigure
endif
PROGRAMS = gettingstarted acknowledgementPayloads manualAcknowledgements streamingData multiceiverDemo scanner interruptConfigure

include Makefile.examples
4 changes: 3 additions & 1 deletion utility/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ elseif("${RF24_DRIVER}" STREQUAL "MRAA") # use MRAA
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/compatibility.cpp
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/interrupt.cpp
PARENT_SCOPE
)
install(FILES
Expand All @@ -75,7 +76,8 @@ elseif("${RF24_DRIVER}" STREQUAL "MRAA") # use MRAA
${RF24_DRIVER}/spi.h
${RF24_DRIVER}/compatibility.h
${RF24_DRIVER}/RF24_arch_config.h
DESTINATION include/RF24/utility/${RF24_DRIVER}
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/interrupt.h
DESTINATION include/RF24/utility/${RF24_DRIVER}
)
elseif("${RF24_DRIVER}" STREQUAL "pigpio") # use pigpio
set(RF24_LINKED_DRIVER ${LibPIGPIO} PARENT_SCOPE)
Expand Down
1 change: 1 addition & 0 deletions utility/MRAA/includes.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
#endif

#include "MRAA/RF24_arch_config.h"
#include "MRAA/interrupt.h"

#endif // RF24_UTILITY_INCLUDES_H_
60 changes: 60 additions & 0 deletions utility/MRAA/interrupt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <map>
#include <mraa.h> // mraa_strresult()
#include <mraa.hpp> // mraa::Gpio
#include "interrupt.h"
#include "gpio.h" // rf24_gpio_pin_t

#ifdef __cplusplus
extern "C" {
#endif

std::map<rf24_gpio_pin_t, mraa::Gpio*> irqCache;

int attachInterrupt(rf24_gpio_pin_t pin, uint8_t mode, void (*function)(void))
{
// ensure pin is not already being used in a separate thread
detachInterrupt(pin);
GPIO::close(pin);

mraa::Gpio* gpio = new mraa::Gpio(pin);
mraa::Result status = gpio->dir(mraa::DIR_IN);
if (status != mraa::SUCCESS) {
std::string msg = "[attachInterrupt] Could not set the pin as an input; ";
msg += mraa_strresult((mraa_result_t)status);
throw IRQException(msg);
return 0;
}
status = gpio->isr((mraa::Edge)mode, (void (*)(void*))function, NULL);
if (status != mraa::SUCCESS) {
std::string msg = "[attachInterrupt] Could not setup the ISR; ";
msg += mraa_strresult((mraa_result_t)status);
throw IRQException(msg);
return 0;
}

std::pair<std::map<rf24_gpio_pin_t, mraa::Gpio*>::iterator, bool> indexPair = irqCache.insert(std::pair<rf24_gpio_pin_t, mraa::Gpio*>(pin, gpio));
if (!indexPair.second) {
// this should not be reached, but indexPair.first needs to be the inserted map element
gpio->close();
throw IRQException("[attachInterrupt] Could not cache the mraa::Gpio object");
return 0;
}
return 1;
}

int detachInterrupt(rf24_gpio_pin_t pin)
{
std::map<rf24_gpio_pin_t, mraa::Gpio*>::iterator cachedPin = irqCache.find(pin);
if (cachedPin == irqCache.end()) {
return 0; // pin not in cache; just exit
}
cachedPin->second->close();
irqCache.erase(cachedPin);
return 1;
}

#ifdef __cplusplus
}
#endif

#endif // !defined(ARDUINO)
44 changes: 44 additions & 0 deletions utility/MRAA/interrupt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef RF24_UTILITY_MRAA_INTERRUPT_H_
#define RF24_UTILITY_MRAA_INTERRUPT_H_

#include <stdexcept> // std::exception, std::string
#include "mraa.hpp" // mraa::
#include "gpio.h" // rf24_gpio_pin_t

#ifdef __cplusplus
extern "C" {
#endif

enum Edge
{
INT_EDGE_FALLING = mraa::Edge::EDGE_FALLING,
INT_EDGE_RISING = mraa::Edge::EDGE_RISING,
INT_EDGE_BOTH = mraa::Edge::EDGE_BOTH,
};

/** Specific exception for IRQ errors */
class IRQException : public std::runtime_error
{
public:
explicit IRQException(const std::string& msg)
: std::runtime_error(msg)
{
}
};

/**
* Take the details and create an interrupt handler that will
* callback to the user-supplied function.
*/
int attachInterrupt(rf24_gpio_pin_t pin, uint8_t mode, void (*function)(void));

/**
* Will cancel the interrupt thread, close the filehandle and release the pin.
*/
int detachInterrupt(rf24_gpio_pin_t pin);

#ifdef __cplusplus
}
#endif

#endif // RF24_UTILITY_MRAA_INTERRUPT_H_

0 comments on commit 62f73e4

Please sign in to comment.