Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revise MRAA driver's GPIO implementation #966

Merged
merged 1 commit into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_