diff --git a/RF24.cpp b/RF24.cpp index 9e5b4a83..2e500b69 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -1030,11 +1030,6 @@ bool RF24::_init_pins() #if defined(RF24_LINUX) - #if defined(MRAA) - GPIO(); - gpio.begin(ce_pin, csn_pin); - #endif - pinMode(ce_pin, OUTPUT); ce(LOW); delay(100); diff --git a/RF24.h b/RF24.h index 4361b1f7..c029c8e8 100644 --- a/RF24.h +++ b/RF24.h @@ -127,9 +127,6 @@ class RF24 #if defined(RF24_SPI_PTR) _SPI* _spi; #endif // defined (RF24_SPI_PTR) -#if defined(MRAA) - GPIO gpio; -#endif rf24_gpio_pin_t ce_pin; /* "Chip Enable" pin, activates the RX or TX role */ rf24_gpio_pin_t csn_pin; /* SPI Chip select */ diff --git a/utility/MRAA/RF24_arch_config.h b/utility/MRAA/RF24_arch_config.h index a3c63629..99e80bfa 100644 --- a/utility/MRAA/RF24_arch_config.h +++ b/utility/MRAA/RF24_arch_config.h @@ -22,8 +22,6 @@ #define RF24_LINUX //typedef uint16_t prog_uint16_t; -typedef uint16_t rf24_gpio_pin_t; -#define RF24_PIN_INVALID 0xFFFF #define PSTR(x) (x) #define printf_P printf @@ -38,9 +36,9 @@ typedef uint16_t rf24_gpio_pin_t; #define IF_SERIAL_DEBUG(x) #endif -#define digitalWrite(pin, value) gpio.write(pin, value) +#define digitalWrite(pin, value) GPIO::write(pin, value) #define digitalRead(pin) GPIO::read(pin) -#define pinMode(pin, direction) gpio.open(pin, direction) +#define pinMode(pin, direction) GPIO::open(pin, direction) #ifndef __TIME_H__ // Prophet: Redefine time functions only if precompiled arduino time is not included diff --git a/utility/MRAA/gpio.cpp b/utility/MRAA/gpio.cpp index 31d24958..543228fb 100644 --- a/utility/MRAA/gpio.cpp +++ b/utility/MRAA/gpio.cpp @@ -3,92 +3,74 @@ * */ +#include #include "gpio.h" +// cache for mraa::Gpio instances +std::map gpio_cache; + GPIO::GPIO() { - // Prophet: basic members initialization - gpio_ce_pin = -1; - //gpio_cs_pin = -1; - gpio_0 = NULL; - //gpio_1 = NULL; } GPIO::~GPIO() { - // Prophet: this should free memory, and unexport pins when RF24 and/or GPIO gets deleted or goes out of scope - this->close(gpio_ce_pin); - //this->close(gpio_cs_pin); -} - -void GPIO::begin(uint8_t ce_pin, uint8_t cs_pin) -{ - gpio_ce_pin = ce_pin; - //gpio_cs_pin = cs_pin; - - // Prophet: owner can be set here, because we use our pins exclusively, and are making mraa:Gpio context persistent - // so pins will be unexported only if close is called, or on destruction - gpio_0 = new mraa::Gpio(ce_pin /*,0*/); - //gpio_1 = new mraa::Gpio(cs_pin/*,0*/); + // deinitialize cache of mraa::Gpio instances/pointers + std::map::iterator i; + for (i = gpio_cache.begin(); i != gpio_cache.end(); i++) { + i->second->close(); + } + gpio_cache.clear(); } -void GPIO::open(int port, int DDR) +void GPIO::open(rf24_gpio_pin_t port, mraa::Dir DDR) { - if (port == gpio_ce_pin) { - gpio_0 = new mraa::Gpio(port, 0); - // WARNING: use of memory mapped file system is deprecated in MRAA lib - gpio_0->useMmap(true); // `false` (or just not calling `useMmap()`) uses default file system? - gpio_0->dir((mraa::Dir)DDR); + // check that mraa::Gpio context doesn't already exist + std::map::iterator i = gpio_cache.find(port); + if (i == gpio_cache.end()) { + mraa::Gpio* gpio_inst = new mraa::Gpio(port); + gpio_cache[port] = gpio_inst; + gpio_inst->dir(DDR); + } + else { + i->second->dir(DDR); } - /* - else if(port == gpio_cs_pin) { - gpio_1 = new mraa::Gpio(port,0); - gpio_1->useMmap(true); - gpio_1->dir( (mraa::Dir)DDR); - }*/ } -void GPIO::close(int port) +void GPIO::close(rf24_gpio_pin_t port) { - // Prophet: using same theme of working with port numbers as with GPIO::open, - // checking for mraa::Gpio context existence to be sure, that GPIO::begin was called - if (port == gpio_ce_pin) { - if (gpio_0 != NULL) { - delete gpio_0; - } + // check that mraa::Gpio context exists, meaning GPIO::open() was called. + std::map::iterator i = gpio_cache.find(port); + if (i != gpio_cache.end()) { + i->second->close(); // close the cached Gpio instance + gpio_cache.erase(i); // Delete cache entry } - - /* - if(port == gpio_cs_pin) { - if (gpio_1 != NULL) { - delete gpio_1; - } - } - */ } -int GPIO::read(int port) +int GPIO::read(rf24_gpio_pin_t port) { - if (port == gpio_ce_pin) { - return gpio_0->read(); - } - /* - else if(port == gpio_cs_pin) { - return gpio_1->read(); + // get cache gpio instance + std::map::iterator i = gpio_cache.find(port); + if (i != gpio_cache.end()) { + return i->second->read(); } - */ + throw GPIOException("[GPIO::read] pin was not initialized with GPIO::open()"); return -1; } -void GPIO::write(int port, int value) +void GPIO::write(rf24_gpio_pin_t port, int value) { - - if (port == gpio_ce_pin) { - gpio_0->write(value); + mraa::Result result = mraa::Result::ERROR_UNSPECIFIED; // a default + // get cache gpio instance + std::map::iterator i = gpio_cache.find(port); + if (i != gpio_cache.end()) { + result = i->second->write(value); + } + else { + throw GPIOException("[GPIO::write] pin was not initialized with GPIO::open()"); } - /* - else if(port == gpio_cs_pin) { - gpio_1->write( value); + + if (result != mraa::Result::SUCCESS) { + throw GPIOException("GPIO::write() failed"); } - */ } diff --git a/utility/MRAA/gpio.h b/utility/MRAA/gpio.h index 7d343f73..229f5bc5 100644 --- a/utility/MRAA/gpio.h +++ b/utility/MRAA/gpio.h @@ -6,8 +6,22 @@ #ifndef RF24_UTILITY_MRAA_GPIO_H_ #define RF24_UTILITY_MRAA_GPIO_H_ +#include // std::runtime_error, std::string #include "mraa.hpp" +typedef uint16_t rf24_gpio_pin_t; +#define RF24_PIN_INVALID 0xFFFF + +/** Specific exception for GPIO errors */ +class GPIOException : public std::runtime_error +{ +public: + explicit GPIOException(const std::string& msg) + : std::runtime_error(msg) + { + } +}; + class GPIO { @@ -16,21 +30,13 @@ class GPIO virtual ~GPIO(); - void begin(uint8_t ce_pin, uint8_t cs_pin); - - void open(int port, int DDR); - - void close(int port); + static void open(rf24_gpio_pin_t port, mraa::Dir DDR); - int read(int port); + static void close(rf24_gpio_pin_t port); - void write(int port, int value); + static int read(rf24_gpio_pin_t port); -private: - int gpio_ce_pin; /** ce_pin value of the RF24 device **/ - // int gpio_cs_pin; /** cs_pin value of the RF24 device **/ - mraa::Gpio* gpio_0; /** gpio object for ce_pin **/ - // mraa::Gpio* gpio_1; /** gpio object for cs_pin **/ + static void write(rf24_gpio_pin_t port, int value); }; #endif // RF24_UTILITY_MRAA_GPIO_H_