Skip to content

Commit

Permalink
revise MRAA's GPIO implementation (#966)
Browse files Browse the repository at this point in the history
resolves #965
  • Loading branch information
2bndy5 authored Mar 23, 2024
1 parent 73d6737 commit a6eae52
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 86 deletions.
5 changes: 0 additions & 5 deletions RF24.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 0 additions & 3 deletions RF24.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
6 changes: 2 additions & 4 deletions utility/MRAA/RF24_arch_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
106 changes: 44 additions & 62 deletions utility/MRAA/gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,92 +3,74 @@
*
*/

#include <map>
#include "gpio.h"

// cache for mraa::Gpio instances
std::map<rf24_gpio_pin_t, mraa::Gpio*> 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<rf24_gpio_pin_t, mraa::Gpio*>::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<rf24_gpio_pin_t, mraa::Gpio*>::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<rf24_gpio_pin_t, mraa::Gpio*>::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<rf24_gpio_pin_t, mraa::Gpio*>::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<rf24_gpio_pin_t, mraa::Gpio*>::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");
}
*/
}
30 changes: 18 additions & 12 deletions utility/MRAA/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,22 @@
#ifndef RF24_UTILITY_MRAA_GPIO_H_
#define RF24_UTILITY_MRAA_GPIO_H_

#include <stdexcept> // 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
{

Expand All @@ -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_

0 comments on commit a6eae52

Please sign in to comment.