初始化提交
This commit is contained in:
68
arduino-cli/libraries/RF24/utility/SPIDEV/RF24_arch_config.h
Normal file
68
arduino-cli/libraries/RF24/utility/SPIDEV/RF24_arch_config.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
|
||||
*/
|
||||
#ifndef __ARCH_CONFIG_H__
|
||||
#define __ARCH_CONFIG_H__
|
||||
|
||||
#define RF24_LINUX
|
||||
|
||||
#include <stddef.h>
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
#include "compatibility.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
//#define RF24_SPI_SPEED RF24_SPIDEV_SPEED
|
||||
|
||||
#define _BV(x) (1<<(x))
|
||||
#define _SPI spi
|
||||
|
||||
//#undef SERIAL_DEBUG
|
||||
#ifdef SERIAL_DEBUG
|
||||
#define IF_SERIAL_DEBUG(x) ({x;})
|
||||
#else
|
||||
#define IF_SERIAL_DEBUG(x)
|
||||
#endif
|
||||
|
||||
// Avoid spurious warnings
|
||||
#if 1
|
||||
#if !defined( NATIVE ) && defined( ARDUINO )
|
||||
#undef PROGMEM
|
||||
#define PROGMEM __attribute__(( section(".progmem.data") ))
|
||||
#undef PSTR
|
||||
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef uint16_t prog_uint16_t;
|
||||
#define PSTR(x) (x)
|
||||
#define printf_P printf
|
||||
#define strlen_P strlen
|
||||
#define PROGMEM
|
||||
#define pgm_read_word(p) (*(p))
|
||||
#define PRIPSTR "%s"
|
||||
#define pgm_read_byte(p) (*(p))
|
||||
#define pgm_read_ptr(p) (*(p))
|
||||
|
||||
// Function, constant map as a result of migrating from Arduino
|
||||
#define LOW GPIO::OUTPUT_LOW
|
||||
#define HIGH GPIO::OUTPUT_HIGH
|
||||
#define INPUT GPIO::DIRECTION_IN
|
||||
#define OUTPUT GPIO::DIRECTION_OUT
|
||||
#define digitalWrite(pin, value) GPIO::write(pin, value)
|
||||
#define pinMode(pin, direction) GPIO::open(pin, direction)
|
||||
#define delay(milisec) __msleep(milisec)
|
||||
#define delayMicroseconds(usec) __usleep(usec)
|
||||
#define millis() __millis()
|
||||
|
||||
#endif // __ARCH_CONFIG_H__
|
||||
// vim:ai:cin:sts=2 sw=2 ft=cpp
|
||||
50
arduino-cli/libraries/RF24/utility/SPIDEV/compatibility.c
Normal file
50
arduino-cli/libraries/RF24/utility/SPIDEV/compatibility.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "compatibility.h"
|
||||
|
||||
static uint32_t mtime, seconds, useconds;
|
||||
//static struct timeval start, end;
|
||||
struct timespec start, end;
|
||||
|
||||
/**********************************************************************/
|
||||
/**
|
||||
* This function is added in order to simulate arduino delay() function
|
||||
* @param milisec
|
||||
*/
|
||||
void __msleep(int milisec)
|
||||
{
|
||||
struct timespec req;// = {0};
|
||||
req.tv_sec = (time_t) milisec / 1000;
|
||||
req.tv_nsec = (milisec % 1000) * 1000000L;
|
||||
//nanosleep(&req, (struct timespec *)NULL);
|
||||
clock_nanosleep(CLOCK_REALTIME, 0, &req, NULL);
|
||||
}
|
||||
|
||||
void __usleep(int microsec)
|
||||
{
|
||||
struct timespec req;// = {0};
|
||||
req.tv_sec = (time_t) microsec / 1000000;
|
||||
req.tv_nsec = (microsec / 1000000) * 1000;
|
||||
//nanosleep(&req, (struct timespec *)NULL);
|
||||
clock_nanosleep(CLOCK_REALTIME, 0, &req, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is added in order to simulate arduino millis() function
|
||||
*/
|
||||
|
||||
|
||||
void __start_timer()
|
||||
{
|
||||
//gettimeofday(&start, NULL);
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
|
||||
}
|
||||
|
||||
uint32_t __millis()
|
||||
{
|
||||
//gettimeofday(&end, NULL);
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
|
||||
seconds = end.tv_sec - start.tv_sec;
|
||||
useconds = (end.tv_nsec - start.tv_nsec) / 1000;
|
||||
|
||||
mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
|
||||
return mtime;
|
||||
}
|
||||
34
arduino-cli/libraries/RF24/utility/SPIDEV/compatibility.h
Normal file
34
arduino-cli/libraries/RF24/utility/SPIDEV/compatibility.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* File: compatiblity.h
|
||||
* Author: purinda
|
||||
*
|
||||
* Created on 24 June 2012, 3:08 PM
|
||||
* patch for safer monotonic clock & millis() correction for 64bit LDV 2018
|
||||
*/
|
||||
|
||||
#ifndef COMPATIBLITY_H
|
||||
#define COMPATIBLITY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h> // for uintXX_t types
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
void __msleep(int milisec);
|
||||
|
||||
void __usleep(int milisec);
|
||||
|
||||
void __start_timer();
|
||||
|
||||
uint32_t __millis();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COMPATIBLITY_H */
|
||||
|
||||
167
arduino-cli/libraries/RF24/utility/SPIDEV/gpio.cpp
Normal file
167
arduino-cli/libraries/RF24/utility/SPIDEV/gpio.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* https://github.com/mrshu/GPIOlib
|
||||
* Copyright (c) 2011, Copyright (c) 2011 mr.Shu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified on 24 June 2012, 11:06 AM
|
||||
* File: gpio.cpp
|
||||
* Author: purinda (purinda@gmail.com)
|
||||
*
|
||||
* Patched for filedescriptor catching and error control by L Diaz 2018
|
||||
*/
|
||||
|
||||
#include "gpio.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
std::map<int, GPIOfdCache_t> GPIO::cache;
|
||||
|
||||
GPIO::GPIO()
|
||||
{
|
||||
}
|
||||
|
||||
GPIO::~GPIO()
|
||||
{
|
||||
}
|
||||
|
||||
void GPIO::open(int port, int DDR)
|
||||
{
|
||||
FILE* f;
|
||||
f = fopen("/sys/class/gpio/export", "w");
|
||||
if (f == NULL) {
|
||||
throw GPIOException("can't export GPIO pin .check access rights");
|
||||
}
|
||||
fprintf(f, "%d\n", port);
|
||||
fclose(f);
|
||||
|
||||
int counter = 0;
|
||||
char file[128];
|
||||
sprintf(file, "/sys/class/gpio/gpio%d/direction", port);
|
||||
|
||||
while ((f = fopen(file, "w")) == NULL) { //Wait 10 seconds for the file to be accessible if not open on first attempt
|
||||
sleep(1);
|
||||
counter++;
|
||||
if (counter > 10) {
|
||||
throw GPIOException("can't access /sys/class/gpio/gpio%d/direction GPIO pin. check access rights");
|
||||
/*perror("Could not open /sys/class/gpio/gpio%d/direction");
|
||||
exit(0); */
|
||||
}
|
||||
}
|
||||
int l = (DDR == 0) ? fprintf(f, "in\n") : fprintf(f, "out\n");
|
||||
if (!(l == 3 || l == 4)) {
|
||||
fclose(f);
|
||||
throw GPIOException("can't set direction on GPIO pin. check access rights");
|
||||
}
|
||||
/*
|
||||
if (DDR == 0)
|
||||
fprintf(f, "in\n");
|
||||
else printf(f, "out\n");
|
||||
*/
|
||||
fclose(f);
|
||||
|
||||
// Caches the GPIO descriptor;
|
||||
sprintf(file, "/sys/class/gpio/gpio%d/value", port);
|
||||
int flags = (DDR == 0) ? O_RDONLY : O_WRONLY;
|
||||
int fd = ::open(file, flags);
|
||||
if (fd < 0) {
|
||||
throw GPIOException("Can't open the GPIO");
|
||||
} else {
|
||||
cache[port] = fd; // cache the fd;
|
||||
lseek(fd, SEEK_SET, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GPIO::close(int port)
|
||||
{
|
||||
std::map<int, GPIOfdCache_t>::iterator i;
|
||||
i = cache.find(port);
|
||||
if (i != cache.end()) {
|
||||
close(i->second); // close the cached fd
|
||||
cache.erase(i); // Delete cache entry
|
||||
}
|
||||
// Do unexport
|
||||
FILE* f;
|
||||
f = fopen("/sys/class/gpio/unexport", "w");
|
||||
if (f != NULL) {
|
||||
fprintf(f, "%d\n", port);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
int GPIO::read(int port)
|
||||
{
|
||||
std::map<int, GPIOfdCache_t>::iterator i;
|
||||
int fd;
|
||||
i = cache.find(port);
|
||||
if (i == cache.end()) { // Fallback to open the gpio
|
||||
GPIO::open(port, GPIO::DIRECTION_IN);
|
||||
i = cache.find(port);
|
||||
if (i == cache.end()) {
|
||||
throw GPIOException("can't access to GPIO");
|
||||
} else {
|
||||
fd = i->second;
|
||||
}
|
||||
} else {
|
||||
fd = i->second;
|
||||
}
|
||||
|
||||
char c;
|
||||
if (lseek(fd, 0, SEEK_SET) == 0 && ::read(fd, &c, 1) == 1) {
|
||||
return (c == '0') ? 0 : 1;
|
||||
} else {
|
||||
throw GPIOException("can't access to GPIO");
|
||||
}
|
||||
|
||||
/*FILE *f;
|
||||
|
||||
char file[128];
|
||||
sprintf(file, "/sys/class/gpio/gpio%d/value", port);
|
||||
f = fopen(file, "r");
|
||||
|
||||
int i;
|
||||
fscanf(f, "%d", &i);
|
||||
fclose(f);
|
||||
return i;
|
||||
*/
|
||||
}
|
||||
|
||||
void GPIO::write(int port, int value)
|
||||
{
|
||||
std::map<int, GPIOfdCache_t>::iterator i;
|
||||
int fd;
|
||||
i = cache.find(port);
|
||||
if (i == cache.end()) { // Fallback to open the gpio
|
||||
GPIO::open(port, GPIO::DIRECTION_OUT);
|
||||
i = cache.find(port);
|
||||
if (i == cache.end()) {
|
||||
throw GPIOException("can't access to GPIO");
|
||||
} else {
|
||||
fd = i->second;
|
||||
}
|
||||
} else {
|
||||
fd = i->second;
|
||||
}
|
||||
|
||||
if (lseek(fd, 0, SEEK_SET) != 0) {
|
||||
throw GPIOException("can't access to GPIO");
|
||||
}
|
||||
int l = (value == 0) ? ::write(fd, "0\n", 2) : ::write(fd, "1\n", 2);
|
||||
if (l != 2) {
|
||||
throw GPIOException("can't access to GPIO");
|
||||
}
|
||||
|
||||
/*FILE *f;
|
||||
|
||||
char file[128];
|
||||
sprintf(file, "/sys/class/gpio/gpio%d/value", port);
|
||||
f = fopen(file, "w");
|
||||
|
||||
if (value == 0) fprintf(f, "0\n");
|
||||
else fprintf(f, "1\n");
|
||||
|
||||
fclose(f);*/
|
||||
}
|
||||
95
arduino-cli/libraries/RF24/utility/SPIDEV/gpio.h
Normal file
95
arduino-cli/libraries/RF24/utility/SPIDEV/gpio.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* https://github.com/mrshu/GPIOlib
|
||||
* Copyright (c) 2011, Copyright (c) 2011 mr.Shu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified on 24 June 2012, 11:06 AM
|
||||
* File: gpio.h
|
||||
* Author: purinda (purinda@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef H
|
||||
#define H
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
/** Specific excpetion for SPI errors */
|
||||
class GPIOException : public std::runtime_error {
|
||||
public:
|
||||
explicit GPIOException(const std::string& msg)
|
||||
:std::runtime_error(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @file gpio.h
|
||||
* \cond HIDDEN_SYMBOLS
|
||||
* Class declaration for GPIO helper files
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Example GPIO.h file
|
||||
*
|
||||
* @defgroup GPIO GPIO Example
|
||||
*
|
||||
* See RF24_arch_config.h for additional information
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef int GPIOfdCache_t;
|
||||
|
||||
class GPIO {
|
||||
public:
|
||||
|
||||
/* Constants */
|
||||
static const int DIRECTION_OUT = 1;
|
||||
static const int DIRECTION_IN = 0;
|
||||
|
||||
static const int OUTPUT_HIGH = 1;
|
||||
static const int OUTPUT_LOW = 0;
|
||||
|
||||
GPIO();
|
||||
|
||||
/**
|
||||
* Similar to Arduino pinMode(pin,mode);
|
||||
* @param port
|
||||
* @param DDR
|
||||
*/
|
||||
static void open(int port, int DDR);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param port
|
||||
*/
|
||||
static void close(int port);
|
||||
|
||||
/**
|
||||
* Similar to Arduino digitalRead(pin);
|
||||
* @param port
|
||||
* @param value
|
||||
*/
|
||||
static int read(int port);
|
||||
|
||||
/**
|
||||
* Similar to Arduino digitalWrite(pin,state);
|
||||
* @param port
|
||||
* @param value
|
||||
*/
|
||||
static void write(int port, int value);
|
||||
|
||||
virtual ~GPIO();
|
||||
|
||||
private:
|
||||
/* fd cache */
|
||||
static std::map<int, GPIOfdCache_t> cache;
|
||||
};
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
/*@}*/
|
||||
#endif /* H */
|
||||
9
arduino-cli/libraries/RF24/utility/SPIDEV/includes.h
Normal file
9
arduino-cli/libraries/RF24/utility/SPIDEV/includes.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __RF24_INCLUDES_H__
|
||||
#define __RF24_INCLUDES_H__
|
||||
|
||||
#define RF24_SPIDEV
|
||||
|
||||
#include "SPIDEV/RF24_arch_config.h"
|
||||
#include "SPIDEV/interrupt.h"
|
||||
|
||||
#endif
|
||||
221
arduino-cli/libraries/RF24/utility/SPIDEV/interrupt.c
Normal file
221
arduino-cli/libraries/RF24/utility/SPIDEV/interrupt.c
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
Interrupts functions extruded from wiringPi library by Oitzu.
|
||||
|
||||
wiringPi Copyright (c) 2012 Gordon Henderson
|
||||
https://projects.drogon.net/raspberry-pi/wiringpi
|
||||
wiringPi is free software: GNU Lesser General Public License
|
||||
see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include "interrupt.h"
|
||||
#include <pthread.h>
|
||||
|
||||
//#define delay(x) bcm2835_delay(x)
|
||||
|
||||
static pthread_mutex_t pinMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static volatile int pinPass = -1;
|
||||
|
||||
pthread_t threadId[64];
|
||||
|
||||
// sysFds:
|
||||
// Map a file descriptor from the /sys/class/gpio/gpioX/value
|
||||
static int sysFds[64] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1,};
|
||||
|
||||
// ISR Data
|
||||
static void (* isrFunctions[64])(void);
|
||||
|
||||
int waitForInterrupt(int pin, int mS)
|
||||
{
|
||||
int fd, x;
|
||||
uint8_t c;
|
||||
struct pollfd polls;
|
||||
|
||||
if ((fd = sysFds[pin]) == -1) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
// Setup poll structure
|
||||
|
||||
polls.fd = fd;
|
||||
polls.events = POLLPRI; // Urgent data!
|
||||
|
||||
// Wait for it ...
|
||||
x = poll(&polls, 1, mS);
|
||||
|
||||
// Do a dummy read to clear the interrupt
|
||||
// A one character read appars to be enough.
|
||||
// Followed by a seek to reset it.
|
||||
|
||||
(void) read(fd, &c, 1);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int piHiPri(const int pri)
|
||||
{
|
||||
struct sched_param sched;
|
||||
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
|
||||
if (pri > sched_get_priority_max(SCHED_RR)) {
|
||||
sched.sched_priority = sched_get_priority_max(SCHED_RR);
|
||||
} else {
|
||||
sched.sched_priority = pri;
|
||||
}
|
||||
|
||||
return sched_setscheduler(0, SCHED_RR, &sched);
|
||||
}
|
||||
|
||||
void* interruptHandler(void* arg)
|
||||
{
|
||||
int myPin;
|
||||
|
||||
(void) piHiPri(55); // Only effective if we run as root
|
||||
|
||||
myPin = pinPass;
|
||||
pinPass = -1;
|
||||
|
||||
for (;;) {
|
||||
if (waitForInterrupt(myPin, -1) > 0) {
|
||||
pthread_mutex_lock(&pinMutex);
|
||||
isrFunctions[myPin]();
|
||||
pthread_mutex_unlock(&pinMutex);
|
||||
pthread_testcancel(); //Cancel at this point if we have an cancellation request.
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int attachInterrupt(int pin, int mode, void (* function)(void))
|
||||
{
|
||||
const char* modeS;
|
||||
char fName[64];
|
||||
char pinS[8];
|
||||
pid_t pid;
|
||||
int count, i;
|
||||
char c;
|
||||
int bcmGpioPin;
|
||||
|
||||
bcmGpioPin = pin;
|
||||
|
||||
if (mode != INT_EDGE_SETUP) {
|
||||
/**/ if (mode == INT_EDGE_FALLING) {
|
||||
modeS = "falling";
|
||||
} else if (mode == INT_EDGE_RISING) {
|
||||
modeS = "rising";
|
||||
} else {
|
||||
modeS = "both";
|
||||
}
|
||||
|
||||
sprintf(pinS, "%d", bcmGpioPin);
|
||||
|
||||
if ((pid = fork()) < 0) { // Fail
|
||||
return printf("wiringPiISR: fork failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
if (pid == 0) // Child, exec
|
||||
{
|
||||
/**/ if (access("/usr/local/bin/gpio", X_OK) == 0) {
|
||||
execl("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
|
||||
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
|
||||
} else if (access("/usr/bin/gpio", X_OK) == 0) {
|
||||
execl("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
|
||||
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
|
||||
} else {
|
||||
return printf("wiringPiISR: Can't find gpio program\n");
|
||||
}
|
||||
} else { // Parent, wait
|
||||
wait(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (sysFds[bcmGpioPin] == -1) {
|
||||
sprintf(fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin);
|
||||
if ((sysFds[bcmGpioPin] = open(fName, O_RDWR)) < 0) {
|
||||
return printf("wiringPiISR: unable to open %s: %s\n", fName, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
ioctl(sysFds[bcmGpioPin], FIONREAD, &count);
|
||||
for (i = 0; i < count; ++i) {
|
||||
read(sysFds[bcmGpioPin], &c, 1);
|
||||
}
|
||||
|
||||
isrFunctions[pin] = function;
|
||||
|
||||
pthread_mutex_lock(&pinMutex);
|
||||
pinPass = pin;
|
||||
pthread_create(&threadId[bcmGpioPin], NULL, interruptHandler, NULL);
|
||||
while (pinPass != -1)
|
||||
delay (1);
|
||||
pthread_mutex_unlock(&pinMutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int detachInterrupt(int pin)
|
||||
{
|
||||
char pinS[8];
|
||||
const char* modeS = "none";
|
||||
pid_t pid;
|
||||
|
||||
if (!pthread_cancel(threadId[pin])) //Cancel the thread
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!close(sysFds[pin])) //Close filehandle
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set wiringPi to 'none' interrupt mode */
|
||||
|
||||
sprintf(pinS, "%d", pin);
|
||||
|
||||
if ((pid = fork()) < 0) { // Fail
|
||||
return printf("wiringPiISR: fork failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
if (pid == 0) // Child, exec
|
||||
{
|
||||
/**/ if (access("/usr/local/bin/gpio", X_OK) == 0) {
|
||||
execl("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
|
||||
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
|
||||
} else if (access("/usr/bin/gpio", X_OK) == 0) {
|
||||
execl("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
|
||||
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
|
||||
} else {
|
||||
return printf("wiringPiISR: Can't find gpio program\n");
|
||||
}
|
||||
} else { // Parent, wait
|
||||
wait(NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rfNoInterrupts()
|
||||
{
|
||||
pthread_mutex_lock(&pinMutex);
|
||||
}
|
||||
|
||||
void rfInterrupts()
|
||||
{
|
||||
pthread_mutex_unlock(&pinMutex);
|
||||
}
|
||||
72
arduino-cli/libraries/RF24/utility/SPIDEV/interrupt.h
Normal file
72
arduino-cli/libraries/RF24/utility/SPIDEV/interrupt.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Interrupts functions extruded from wiringPi library by Oitzu.
|
||||
|
||||
wiringPi Copyright (c) 2012 Gordon Henderson
|
||||
https://projects.drogon.net/raspberry-pi/wiringpi
|
||||
wiringPi is free software: GNU Lesser General Public License
|
||||
see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include "RF24_arch_config.h"
|
||||
|
||||
#define INT_EDGE_SETUP 0
|
||||
#define INT_EDGE_FALLING 1
|
||||
#define INT_EDGE_RISING 2
|
||||
#define INT_EDGE_BOTH 3
|
||||
|
||||
/*
|
||||
* interruptHandler:
|
||||
* This is a thread and gets started to wait for the interrupt we're
|
||||
* hoping to catch. It will call the user-function when the interrupt
|
||||
* fires.
|
||||
*********************************************************************************
|
||||
*/
|
||||
void* interruptHandler(void* arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* waitForInterrupt:
|
||||
* Pi Specific.
|
||||
* Wait for Interrupt on a GPIO pin.
|
||||
* This is actually done via the /sys/class/gpio interface regardless of
|
||||
* the wiringPi access mode in-use. Maybe sometime it might get a better
|
||||
* way for a bit more efficiency.
|
||||
*********************************************************************************
|
||||
*/
|
||||
extern int waitForInterrupt(int pin, int mS);
|
||||
|
||||
/*
|
||||
* piHiPri:
|
||||
* Attempt to set a high priority schedulling for the running program
|
||||
*********************************************************************************
|
||||
*/
|
||||
extern int piHiPri(const int pri);
|
||||
|
||||
/*
|
||||
* attachInterrupt (Original: wiringPiISR):
|
||||
* Pi Specific.
|
||||
* Take the details and create an interrupt handler that will do a call-
|
||||
* back to the user supplied function.
|
||||
*********************************************************************************
|
||||
*/
|
||||
extern int attachInterrupt(int pin, int mode, void (* function)(void));
|
||||
|
||||
/*
|
||||
* detachInterrupt:
|
||||
* Pi Specific detachInterrupt.
|
||||
* Will cancel the interrupt thread, close the filehandle and
|
||||
* setting wiringPi back to 'none' mode.
|
||||
*********************************************************************************
|
||||
*/
|
||||
extern int detachInterrupt(int pin);
|
||||
|
||||
extern void rfNoInterrupts();
|
||||
|
||||
extern void rfInterrupts();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
191
arduino-cli/libraries/RF24/utility/SPIDEV/spi.cpp
Normal file
191
arduino-cli/libraries/RF24/utility/SPIDEV/spi.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* File: spi.cpp
|
||||
* Author: Purinda Gunasekara <purinda@gmail.com>
|
||||
*
|
||||
* Created on 24 June 2012, 11:00 AM
|
||||
*
|
||||
* Patched for exception handling and selectable SPI SPEED by ldiaz 2018.
|
||||
*
|
||||
* Inspired from spidev test in linux kernel documentation
|
||||
* www.kernel.org/doc/Documentation/spi/spidev_test.c
|
||||
*/
|
||||
|
||||
#include "spi.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define RF24_SPIDEV_BITS 8
|
||||
|
||||
SPI::SPI()
|
||||
:fd(-1), _spi_speed(RF24_SPI_SPEED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SPI::begin(int busNo, uint32_t spi_speed)
|
||||
{
|
||||
|
||||
if (this->spiIsInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* set spidev accordingly to busNo like:
|
||||
* busNo = 23 -> /dev/spidev2.3
|
||||
*
|
||||
* a bit messy but simple
|
||||
* */
|
||||
char device[] = "/dev/spidev0.0";
|
||||
device[11] += (busNo / 10) % 10;
|
||||
device[13] += busNo % 10;
|
||||
|
||||
if (this->fd >= 0) // check whether spi is already open
|
||||
{
|
||||
close(this->fd);
|
||||
this->fd = -1;
|
||||
}
|
||||
|
||||
this->fd = open(device, O_RDWR);
|
||||
if (this->fd < 0) {
|
||||
throw SPIException("can't open device");
|
||||
}
|
||||
/*
|
||||
{
|
||||
perror("can't open device");
|
||||
abort();
|
||||
|
||||
}*/
|
||||
this->spiIsInitialized = true;
|
||||
init(spi_speed);
|
||||
}
|
||||
|
||||
void SPI::init(uint32_t speed)
|
||||
{
|
||||
uint8_t bits = RF24_SPIDEV_BITS;
|
||||
uint8_t mode = 0;
|
||||
|
||||
int ret;
|
||||
/*
|
||||
* spi mode
|
||||
*/
|
||||
ret = ioctl(this->fd, SPI_IOC_WR_MODE, &mode);
|
||||
if (ret == -1) {
|
||||
throw SPIException("cant set WR spi mode");
|
||||
}
|
||||
/*{
|
||||
perror("can't set spi mode");
|
||||
abort();
|
||||
}*/
|
||||
|
||||
ret = ioctl(this->fd, SPI_IOC_RD_MODE, &mode);
|
||||
if (ret == -1) {
|
||||
throw SPIException("can't set RD spi mode");
|
||||
}
|
||||
/*{
|
||||
perror("can't set spi mode");
|
||||
abort();
|
||||
}*/
|
||||
|
||||
/*
|
||||
* bits per word
|
||||
*/
|
||||
ret = ioctl(this->fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
|
||||
if (ret == -1) {
|
||||
throw SPIException("can't set WR bits per word");
|
||||
}
|
||||
/*{
|
||||
perror("can't set bits per word");
|
||||
abort();
|
||||
}*/
|
||||
|
||||
ret = ioctl(this->fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
|
||||
if (ret == -1) {
|
||||
throw SPIException("can't set RD bits per word");
|
||||
}
|
||||
/*{
|
||||
perror("can't set bits per word");
|
||||
abort();
|
||||
}*/
|
||||
/*
|
||||
* max speed hz
|
||||
*/
|
||||
ret = ioctl(this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||
if (ret == -1) {
|
||||
throw SPIException("can't WR set max speed hz");
|
||||
}
|
||||
/*{
|
||||
perror("can't set max speed hz");
|
||||
abort();
|
||||
}*/
|
||||
|
||||
ret = ioctl(this->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
|
||||
if (ret == -1) {
|
||||
throw SPIException("can't RD set max speed hz");
|
||||
}
|
||||
/*{
|
||||
perror("can't set max speed hz");
|
||||
abort();
|
||||
}*/
|
||||
_spi_speed = speed;
|
||||
}
|
||||
|
||||
uint8_t SPI::transfer(uint8_t tx)
|
||||
{
|
||||
struct spi_ioc_transfer tr;
|
||||
memset(&tr, 0, sizeof(tr));
|
||||
tr.tx_buf = (unsigned long) &tx;
|
||||
uint8_t rx;
|
||||
tr.rx_buf = (unsigned long) ℞
|
||||
tr.len = sizeof(tx);
|
||||
tr.speed_hz = _spi_speed; //RF24_SPI_SPEED;
|
||||
tr.delay_usecs = 0;
|
||||
tr.bits_per_word = RF24_SPIDEV_BITS;
|
||||
tr.cs_change = 0;
|
||||
|
||||
int ret;
|
||||
ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
|
||||
if (ret < 1) {
|
||||
throw SPIException("can't send spi message");
|
||||
}
|
||||
/*{
|
||||
perror("can't send spi message");
|
||||
abort();
|
||||
}*/
|
||||
|
||||
return rx;
|
||||
}
|
||||
|
||||
void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
|
||||
{
|
||||
struct spi_ioc_transfer tr;
|
||||
memset(&tr, 0, sizeof(tr));
|
||||
tr.tx_buf = (unsigned long) tbuf;
|
||||
tr.rx_buf = (unsigned long) rbuf;
|
||||
tr.len = len;
|
||||
tr.speed_hz = _spi_speed; //RF24_SPI_SPEED;
|
||||
tr.delay_usecs = 0;
|
||||
tr.bits_per_word = RF24_SPIDEV_BITS;
|
||||
tr.cs_change = 0;
|
||||
|
||||
int ret;
|
||||
ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
|
||||
if (ret < 1) {
|
||||
throw SPIException("can't send spi message");
|
||||
}
|
||||
/*{
|
||||
perror("can't send spi message");
|
||||
abort();
|
||||
}*/
|
||||
}
|
||||
|
||||
SPI::~SPI()
|
||||
{
|
||||
if (this->fd >= 0) {
|
||||
close(this->fd);
|
||||
}
|
||||
}
|
||||
93
arduino-cli/libraries/RF24/utility/SPIDEV/spi.h
Normal file
93
arduino-cli/libraries/RF24/utility/SPIDEV/spi.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* File: spi.h
|
||||
* Author: Purinda Gunasekara <purinda@gmail.com>
|
||||
*
|
||||
* Created on 24 June 2012, 11:00 AM
|
||||
*/
|
||||
|
||||
#ifndef SPI_H
|
||||
#define SPI_H
|
||||
|
||||
/**
|
||||
* @file spi.h
|
||||
* \cond HIDDEN_SYMBOLS
|
||||
* Class declaration for SPI helper files
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example GPIO.h file
|
||||
*
|
||||
* @defgroup SPI SPI Example
|
||||
*
|
||||
* See RF24_arch_config.h for additional information
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../../RF24_config.h"
|
||||
|
||||
/** Specific excpetion for SPI errors */
|
||||
class SPIException : public std::runtime_error {
|
||||
public:
|
||||
explicit SPIException(const std::string& msg)
|
||||
:std::runtime_error(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class SPI {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* SPI constructor
|
||||
*/
|
||||
SPI();
|
||||
|
||||
/**
|
||||
* Start SPI
|
||||
*/
|
||||
void begin(int busNo, uint32_t spi_speed = RF24_SPI_SPEED);
|
||||
|
||||
/**
|
||||
* Transfer a single byte
|
||||
* @param tx Byte to send
|
||||
* @return Data returned via spi
|
||||
*/
|
||||
uint8_t transfer(uint8_t tx);
|
||||
|
||||
/**
|
||||
* Transfer a buffer of data
|
||||
* @param tbuf Transmit buffer
|
||||
* @param rbuf Receive buffer
|
||||
* @param len Length of the data
|
||||
*/
|
||||
void transfernb(char* tbuf, char* rbuf, uint32_t len);
|
||||
|
||||
/**
|
||||
* Transfer a buffer of data without an rx buffer
|
||||
* @param buf Pointer to a buffer of data
|
||||
* @param len Length of the data
|
||||
*/
|
||||
void transfern(char* buf, uint32_t len)
|
||||
{
|
||||
transfernb(buf, buf, len);
|
||||
}
|
||||
|
||||
~SPI();
|
||||
|
||||
private:
|
||||
|
||||
int fd;
|
||||
uint32_t _spi_speed;
|
||||
bool spiIsInitialized = false;
|
||||
void init(uint32_t spi_speed = RF24_SPI_SPEED);
|
||||
};
|
||||
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
/*@}*/
|
||||
#endif /* SPI_H */
|
||||
Reference in New Issue
Block a user