初始化提交
This commit is contained in:
45
arduino-cli/libraries/RF24/utility/RPi/RF24_arch_config.h
Normal file
45
arduino-cli/libraries/RF24/utility/RPi/RF24_arch_config.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef __ARCH_CONFIG_H__
|
||||
#define __ARCH_CONFIG_H__
|
||||
|
||||
#define RF24_LINUX
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "bcm2835.h"
|
||||
#include "spi.h"
|
||||
#include "compatibility.h"
|
||||
|
||||
#define _SPI spi
|
||||
|
||||
#if defined SPI_HAS_TRANSACTION && !defined SPI_UART && !defined SOFTSPI
|
||||
#define RF24_SPI_TRANSACTIONS
|
||||
#endif
|
||||
// GCC a Arduino Missing
|
||||
#define _BV(x) (1<<(x))
|
||||
#define pgm_read_word(p) (*(p))
|
||||
#define pgm_read_byte(p) (*(p))
|
||||
#define pgm_read_ptr(p) (*(p))
|
||||
|
||||
//typedef uint16_t prog_uint16_t;
|
||||
#define PSTR(x) (x)
|
||||
#define printf_P printf
|
||||
#define strlen_P strlen
|
||||
#define PROGMEM
|
||||
#define PRIPSTR "%s"
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
#define IF_SERIAL_DEBUG(x) ({x;})
|
||||
#else
|
||||
#define IF_SERIAL_DEBUG(x)
|
||||
#endif
|
||||
|
||||
#define digitalWrite(pin, value) bcm2835_gpio_write(pin, value)
|
||||
#define pinMode(pin, value) bcm2835_gpio_fsel(pin,value);
|
||||
#define OUTPUT BCM2835_GPIO_FSEL_OUTP
|
||||
|
||||
#endif
|
||||
2031
arduino-cli/libraries/RF24/utility/RPi/bcm2835.c
Normal file
2031
arduino-cli/libraries/RF24/utility/RPi/bcm2835.c
Normal file
File diff suppressed because it is too large
Load Diff
2029
arduino-cli/libraries/RF24/utility/RPi/bcm2835.h
Normal file
2029
arduino-cli/libraries/RF24/utility/RPi/bcm2835.h
Normal file
File diff suppressed because it is too large
Load Diff
13
arduino-cli/libraries/RF24/utility/RPi/compatibility.c
Normal file
13
arduino-cli/libraries/RF24/utility/RPi/compatibility.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "compatibility.h"
|
||||
|
||||
uint32_t millis(void)
|
||||
{
|
||||
struct timeval now;
|
||||
uint32_t ms;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
ms = ((now.tv_sec * 1000000) + now.tv_usec) / 1000;
|
||||
return (ms);
|
||||
|
||||
}
|
||||
17
arduino-cli/libraries/RF24/utility/RPi/compatibility.h
Normal file
17
arduino-cli/libraries/RF24/utility/RPi/compatibility.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef COMPATIBLITY_H
|
||||
#define COMPATIBLITY_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern uint32_t millis(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //Compatibility.h
|
||||
10
arduino-cli/libraries/RF24/utility/RPi/includes.h
Normal file
10
arduino-cli/libraries/RF24/utility/RPi/includes.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __RF24_INCLUDES_H__
|
||||
#define __RF24_INCLUDES_H__
|
||||
|
||||
#define RF24_RPi
|
||||
|
||||
#include "RPi/bcm2835.h"
|
||||
#include "RPi/RF24_arch_config.h"
|
||||
#include "RPi/interrupt.h"
|
||||
|
||||
#endif
|
||||
221
arduino-cli/libraries/RF24/utility/RPi/interrupt.c
Normal file
221
arduino-cli/libraries/RF24/utility/RPi/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]) != 0) //Cancel the thread
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (close(sysFds[pin]) != 0) //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/RPi/interrupt.h
Normal file
72
arduino-cli/libraries/RF24/utility/RPi/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
|
||||
66
arduino-cli/libraries/RF24/utility/RPi/spi.cpp
Normal file
66
arduino-cli/libraries/RF24/utility/RPi/spi.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "spi.h"
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdexcept>
|
||||
|
||||
static pthread_mutex_t spiMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
bool bcmIsInitialized = false;
|
||||
|
||||
SPI::SPI()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SPI::begin(int busNo, uint32_t spi_speed)
|
||||
{
|
||||
if (!bcmIsInitialized) {
|
||||
if (!bcm2835_init()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
bcmIsInitialized = true;
|
||||
bcm2835_spi_begin();
|
||||
}
|
||||
|
||||
void SPI::beginTransaction(SPISettings settings)
|
||||
{
|
||||
if (geteuid() != 0) {
|
||||
throw std::runtime_error("Process should run as root");
|
||||
}
|
||||
pthread_mutex_lock(&spiMutex);
|
||||
setBitOrder(settings.border);
|
||||
setDataMode(settings.dmode);
|
||||
setClockDivider(settings.clck);
|
||||
}
|
||||
|
||||
void SPI::endTransaction()
|
||||
{
|
||||
pthread_mutex_unlock(&spiMutex);
|
||||
}
|
||||
|
||||
void SPI::setBitOrder(uint8_t bit_order)
|
||||
{
|
||||
bcm2835_spi_setBitOrder(bit_order);
|
||||
}
|
||||
|
||||
void SPI::setDataMode(uint8_t data_mode)
|
||||
{
|
||||
bcm2835_spi_setDataMode(data_mode);
|
||||
}
|
||||
|
||||
void SPI::setClockDivider(uint32_t spi_speed)
|
||||
{
|
||||
//bcm2835_spi_setClockDivider(spi_speed);
|
||||
bcm2835_spi_set_speed_hz(spi_speed);
|
||||
}
|
||||
|
||||
void SPI::chipSelect(int csn_pin)
|
||||
{
|
||||
bcm2835_spi_chipSelect(csn_pin);
|
||||
delayMicroseconds(5);
|
||||
}
|
||||
|
||||
SPI::~SPI()
|
||||
{
|
||||
|
||||
}
|
||||
100
arduino-cli/libraries/RF24/utility/RPi/spi.h
Normal file
100
arduino-cli/libraries/RF24/utility/RPi/spi.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* TMRh20 2015
|
||||
* SPI layer for RF24 <-> BCM2835
|
||||
*/
|
||||
/**
|
||||
* @file spi.h
|
||||
* \cond HIDDEN_SYMBOLS
|
||||
* Class declaration for SPI helper files
|
||||
*/
|
||||
#ifndef _SPI_H_INCLUDED
|
||||
#define _SPI_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bcm2835.h"
|
||||
#include "interrupt.h"
|
||||
#include "../../RF24_config.h"
|
||||
|
||||
#define SPI_HAS_TRANSACTION
|
||||
#define MSBFIRST BCM2835_SPI_BIT_ORDER_MSBFIRST
|
||||
#define SPI_MODE0 BCM2835_SPI_MODE0
|
||||
//#define RF24_SPI_SPEED 10000000 //BCM2835_SPI_SPEED_4MHZ
|
||||
|
||||
class SPISettings {
|
||||
public:
|
||||
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
|
||||
{
|
||||
init(clock, bitOrder, dataMode);
|
||||
}
|
||||
|
||||
SPISettings()
|
||||
{
|
||||
init(RF24_SPI_SPEED, MSBFIRST, SPI_MODE0);
|
||||
}
|
||||
|
||||
uint32_t clck;
|
||||
uint8_t border;
|
||||
uint8_t dmode;
|
||||
private:
|
||||
|
||||
void init(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
|
||||
{
|
||||
clck = clock;
|
||||
border = bitOrder;
|
||||
dmode = dataMode;
|
||||
}
|
||||
|
||||
friend class SPIClass;
|
||||
};
|
||||
|
||||
class SPI {
|
||||
public:
|
||||
|
||||
SPI();
|
||||
|
||||
virtual ~SPI();
|
||||
|
||||
inline static uint8_t transfer(uint8_t _data);
|
||||
|
||||
inline static void transfernb(char* tbuf, char* rbuf, uint32_t len);
|
||||
|
||||
inline static void transfern(char* buf, uint32_t len);
|
||||
|
||||
static void begin(int busNo, uint32_t spi_speed = RF24_SPI_SPEED);
|
||||
|
||||
static void end();
|
||||
|
||||
static void setBitOrder(uint8_t bit_order);
|
||||
|
||||
static void setDataMode(uint8_t data_mode);
|
||||
|
||||
static void setClockDivider(uint32_t spi_speed);
|
||||
|
||||
static void chipSelect(int csn_pin);
|
||||
|
||||
static void beginTransaction(SPISettings settings);
|
||||
|
||||
static void endTransaction();
|
||||
|
||||
|
||||
};
|
||||
|
||||
uint8_t SPI::transfer(uint8_t _data)
|
||||
{
|
||||
uint8_t data = bcm2835_spi_transfer(_data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
|
||||
{
|
||||
bcm2835_spi_transfernb(tbuf, rbuf, len);
|
||||
}
|
||||
|
||||
void SPI::transfern(char* buf, uint32_t len)
|
||||
{
|
||||
transfernb(buf, buf, len);
|
||||
}
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
#endif
|
||||
Reference in New Issue
Block a user