feat: 全量同步 254 个常用的 Arduino 扩展库文件

This commit is contained in:
yczpf2019
2026-01-24 16:05:38 +08:00
parent c665ba662b
commit 397b9a23a3
6878 changed files with 2732224 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
/*
TMRh20 2015
ATTiny Configuration File
*/
#ifndef __RF24_ARCH_CONFIG_H__
#define __RF24_ARCH_CONFIG_H__
/*** USER DEFINES: ***/
//#define FAILURE_HANDLING
//#define MINIMAL
/**********************/
#define rf24_max(a, b) (a>b?a:b)
#define rf24_min(a, b) (a<b?a:b)
#if ARDUINO < 100
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
#include <stddef.h>
// Include the header file for SPI functions ( Main SPI code is contained in RF24.cpp for simplicity )
#include "spi.h"
#define _SPI SPI
#ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({x;})
#else
#define IF_SERIAL_DEBUG(x)
#if defined(RF24_TINY)
#define printf_P(...)
#endif
#endif
#include <avr/pgmspace.h>
#define PRIPSTR "%S"
#endif // __RF24_ARCH_CONFIG_H__

View File

@@ -0,0 +1,55 @@
// ATTiny support code is from https://github.com/jscrane/RF24
/**
* @file spi.h
* \cond HIDDEN_SYMBOLS
* Class declaration for SPI helper files
*/
#include <stdio.h>
#include <Arduino.h>
#include <avr/pgmspace.h>
#define SPI_CLOCK_DIV4 0x00
#define SPI_CLOCK_DIV16 0x01
#define SPI_CLOCK_DIV64 0x02
#define SPI_CLOCK_DIV128 0x03
#define SPI_CLOCK_DIV2 0x04
#define SPI_CLOCK_DIV8 0x05
#define SPI_CLOCK_DIV32 0x06
//#define SPI_CLOCK_DIV64 0x07
#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define SPI_MODE2 0x08
#define SPI_MODE3 0x0C
#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
class SPIClass {
public:
static byte transfer(byte _data);
// SPI Configuration methods
inline static void attachInterrupt();
inline static void detachInterrupt(); // Default
static void begin(); // Default
static void end();
static void setBitOrder(uint8_t);
static void setDataMode(uint8_t);
static void setClockDivider(uint8_t);
};
extern SPIClass SPI;
/**
* \endcond
*/

View File

@@ -0,0 +1,54 @@
This is a fork from **http://tmrh20.github.io/RF24** which can be build as a static library for Atmel Studio 7.
Not all files are needed.
Just copy the following structure into a GCC Static Library project in AS7:
```
utility\
ATXMega256D3\
compatibility.c
compatibility.h
gpio.cpp
gpio.h
gpio_helper.c
gpio_helper.h
includes.h
RF24_arch_config.h
spi.cpp
spi.h
nRF24L01.h
printf.h
RF24.cpp
RF24.h
RF24_config.h
```
Only ATXMega256D3 is supported right now!
## Notes
The millisecond functionality is based on the TCE0 so don't use these pins as IO.
The operating frequency of the uC is 32MHz. If else change the TCE0 registers appropriatly in function **__start_timer()** in **compatibility.c** file for your frequency.
## Usage
Add the library to your project!
In the file where the **main()** is put the following in order to update the millisecond functionality:
```
ISR(TCE0_OVF_vect)
{
update_milisec();
}
```
Declare the rf24 radio with **RF24 radio(XMEGA_PORTC_PIN3, XMEGA_SPI_PORT_C);**
First parameter is the CE pin which can be any available pin on the uC.
Second parameter is the CS which can be on port C (**XMEGA_SPI_PORT_C**) or on port D (**XMEGA_SPI_PORT_D**).
Call the **__start_timer()** to start the millisecond timer.
** For further information please see http://tmrh20.github.io/RF24 for all documentation**

View File

@@ -0,0 +1,83 @@
/*
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.
*/
/**
* @file RF24_arch_config.h
* General defines and includes for RF24/Linux
*/
/**
* Example of RF24_arch_config.h for RF24 portability
*
* @defgroup Porting_General Porting: General
*
*
* @{
*/
#ifndef __RF24_ARCH_CONFIG_H__
#define __RF24_ARCH_CONFIG_H__
#include <stddef.h>
#include <avr/pgmspace.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 _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
// Use the avr pgmspace commands
//// 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))
// 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 // __RF24_ARCH_CONFIG_H__
/*@}*/

View File

@@ -0,0 +1,64 @@
/*
* compatibility.c
*
* Created: 19/1/2016 15:31:35
* Author: akatran
*/
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
volatile uint32_t _millis;
void __msleep(int milisec)
{
while (milisec-- > 0) {
_delay_ms(1);
}
}
void __usleep(int usec)
{
while (usec-- > 0) {
_delay_us(1);
}
}
void __start_timer()
{
// Timer details : Clock is 32MHz, Timer resolution is 8bit, Prescaler is 256, Period is 124, Real Time is 0.001s
/* Set the timer to run at the fastest rate. */
TCE0.CTRLA = TC_CLKSEL_DIV256_gc;
/* Configure the timer for normal counting. */
TCE0.CTRLB = TC_WGMODE_NORMAL_gc;
/* At 2 MHz, one tick is 0.5 us. Set period to 8 us. */
TCE0.PER = 124;
//TCC0.PER = 2;
/* Configure timer to generate an interrupt on overflow. */
TCE0.INTCTRLA = TC_OVFINTLVL_HI_gc;
/* Enable this interrupt level. */
PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
_millis = 0;
}
long __millis()
{
return _millis;
}
void update_milisec()
{
_millis++;
}

View File

@@ -0,0 +1,49 @@
/*
* File: compatiblity.h
* Author: purinda
*
* Created on 24 June 2012, 3:08 PM
*/
/**
* @file compatibility.h
* Class declaration for SPI helper files
*/
/**
* Example of compatibility.h class declaration for timing functions portability
*
* @defgroup Porting_Timing Porting: Timing
*
*
* @{
*/
#ifndef COMPATIBLITY_H
#define COMPATIBLITY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
//#include <time.h>
//#include <sys/time.h>
void __msleep(int milisec);
void __usleep(int usec);
void __start_timer();
long __millis();
void update_milisec();
#ifdef __cplusplus
}
#endif
#endif /* COMPATIBLITY_H */
/*@}*/

View File

@@ -0,0 +1,46 @@
/*
* gpio.cpp
*
* Created: 20/1/2016 11:57:21
* Author: akatran
*/
//#include "gpio_helper.h"
#include "gpio.h"
#include <stdlib.h>
void GPIO::open(int port, int DDR)
{
uint8_t pin;
PORT_t* p = GPIO_getPort(port, &pin);
if (DDR == 0) {
p->DIRCLR = pin;
} else if (DDR == 1) {
p->DIRSET = pin;
}
}
void GPIO::close(int port)
{
// Nothing to do with close;
}
int read(int port)
{
uint8_t pin;
PORT_t* p = GPIO_getPort(port, &pin);
return p->IN;
}
void GPIO::write(int port, int value)
{
uint8_t pin;
PORT_t* p = GPIO_getPort(port, &pin);
if (value == 0) {
p->OUTCLR = pin;
} else if (value == 1) {
p->OUTSET = pin;
}
}

View File

@@ -0,0 +1,65 @@
/**
* @file gpio.h
* Class declaration for SPI helper files
*/
/**
* Example of gpio.h class declaration for GPIO portability
*
* @defgroup Porting_GPIO Porting: GPIO
*
*
* @{
*/
#ifndef GPIO_H
#define GPIO_H
#include <avr/io.h>
#include "gpio_helper.h"
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();
};
#endif /* GPIO_H */
/*@}*/

View File

@@ -0,0 +1,39 @@
/*
* gpio_helper.c
*
* Created: 22/1/2016 15:28:48
* Author: akatran
*/
#include "gpio_helper.h"
/**
* Get the port corresponding in portnum. Default is PORTC.
*/
PORT_t* GPIO_getPort(int pinnum, uint8_t* pin_bm)
//PORT_t * GPIO_getPort(int portnum)
{
PORT_t* port = &PORTC;
if ((pinnum >= XMEGA_PORTA_PIN0) && (pinnum <= XMEGA_PORTA_PIN7)) {
port = &PORTA;
*pin_bm = (1 << pinnum);
} else if ((pinnum >= XMEGA_PORTB_PIN0) && (pinnum <= XMEGA_PORTB_PIN7)) {
port = &PORTB;
*pin_bm = (1 << (pinnum - 8));
} else if ((pinnum >= XMEGA_PORTC_PIN0) && (pinnum <= XMEGA_PORTC_PIN7)) {
port = &PORTC;
*pin_bm = (1 << (pinnum - 16));
} else if ((pinnum >= XMEGA_PORTD_PIN0) && (pinnum <= XMEGA_PORTD_PIN7)) {
port = &PORTD;
*pin_bm = (1 << (pinnum - 24));
} else if ((pinnum >= XMEGA_PORTE_PIN0) && (pinnum <= XMEGA_PORTE_PIN7)) {
port = &PORTE;
*pin_bm = (1 << (pinnum - 32));
} else if ((pinnum >= XMEGA_PORTF_PIN0) && (pinnum <= XMEGA_PORTF_PIN7)) {
port = &PORTF;
*pin_bm = (1 << (pinnum - 40));
}
return port;
}

View File

@@ -0,0 +1,86 @@
/*
* gpio_helper.h
*
* Created: 22/1/2016 15:29:12
* Author: akatran
*/
#ifndef GPIO_HELPER_H_
#define GPIO_HELPER_H_
#include <avr/io.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Defines */
#define XMEGA_PORTA_PIN0 0
#define XMEGA_PORTA_PIN1 1
#define XMEGA_PORTA_PIN2 2
#define XMEGA_PORTA_PIN3 3
#define XMEGA_PORTA_PIN4 4
#define XMEGA_PORTA_PIN5 5
#define XMEGA_PORTA_PIN6 6
#define XMEGA_PORTA_PIN7 7
#define XMEGA_PORTB_PIN0 8
#define XMEGA_PORTB_PIN1 9
#define XMEGA_PORTB_PIN2 10
#define XMEGA_PORTB_PIN3 11
#define XMEGA_PORTB_PIN4 12
#define XMEGA_PORTB_PIN5 13
#define XMEGA_PORTB_PIN6 14
#define XMEGA_PORTB_PIN7 15
#define XMEGA_PORTC_PIN0 16
#define XMEGA_PORTC_PIN1 17
#define XMEGA_PORTC_PIN2 18
#define XMEGA_PORTC_PIN3 19
#define XMEGA_PORTC_PIN4 20
#define XMEGA_PORTC_PIN5 21
#define XMEGA_PORTC_PIN6 22
#define XMEGA_PORTC_PIN7 23
#define XMEGA_PORTD_PIN0 24
#define XMEGA_PORTD_PIN1 25
#define XMEGA_PORTD_PIN2 26
#define XMEGA_PORTD_PIN3 27
#define XMEGA_PORTD_PIN4 28
#define XMEGA_PORTD_PIN5 29
#define XMEGA_PORTD_PIN6 30
#define XMEGA_PORTD_PIN7 31
#define XMEGA_PORTE_PIN0 32
#define XMEGA_PORTE_PIN1 33
#define XMEGA_PORTE_PIN2 34
#define XMEGA_PORTE_PIN3 35
#define XMEGA_PORTE_PIN4 36
#define XMEGA_PORTE_PIN5 37
#define XMEGA_PORTE_PIN6 38
#define XMEGA_PORTE_PIN7 39
#define XMEGA_PORTF_PIN0 40
#define XMEGA_PORTF_PIN1 41
#define XMEGA_PORTF_PIN2 42
#define XMEGA_PORTF_PIN3 43
#define XMEGA_PORTF_PIN4 44
#define XMEGA_PORTF_PIN5 45
#define XMEGA_PORTF_PIN6 46
#define XMEGA_PORTF_PIN7 47
#define XMEGA_SPI_PORT_C 20
#define XMEGA_SPI_PORT_D 28
//void GPIO_getPort(int pinnum, PORT_t * port, uint8_t pin);
//void GPIO_getPort(int pinnum, PORT_t * port, uint8_t * pin_bm);
PORT_t* GPIO_getPort(int pinnum, uint8_t* pin_bm);
#ifdef __cplusplus
}
#endif
#endif /* GPIO_HELPER_H_ */

View File

@@ -0,0 +1,30 @@
/**
* @file includes.h
* Configuration defines for RF24/Linux
*/
/**
* Example of includes.h for RF24 Linux portability
*
* @defgroup Porting_Includes Porting: Includes
*
*
* @{
*/
#ifndef __RF24_INCLUDES_H__
#define __RF24_INCLUDES_H__
/**
* Define a specific platform for this configuration
*/
// #define RF24_BBB
/**
* Load the correct configuration for this platform
*/
//#include "BBB/RF24_arch_config.h"
#endif
/*@}*/

View File

@@ -0,0 +1,64 @@
/*
* spi.cpp
*
* Created: 20/1/2016 10:10:39
* Author: akatran
*/
#include <avr/io.h>
#include "gpio_helper.h"
#include "spi.h"
using namespace std;
void SPI::begin(uint8_t _port)
{
if (_port == XMEGA_SPI_PORT_C) // Select SPI on PORTC
{
device = &SPIC;
port = &PORTC;
} else if (_port == XMEGA_SPI_PORT_D) // Select SPI on PORTD
{
device = &SPID;
port = &PORTD;
}
init();
}
uint8_t SPI::transfer(uint8_t tx_)
{
register8_t data;
device->DATA = tx_;
while (!(device->STATUS & (1 << 7))) {
}
data = device->DATA;
//PORTF.OUT = data;
return data;
}
void SPI::init()
{
port->DIRCLR = SPI_MISO_bm;
port->DIRSET = SPI_MOSI_bm | SPI_SCK_bm | SPI_SS_bm;
//device->CTRL = 0;
device->CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_0_gc | SPI_PRESCALER_DIV4_gc;
device->INTCTRL = 0; //Disable interrupts
}
SPI::SPI()
{
}
SPI::~SPI()
{
}
void operator delete(void* p) // or delete(void *, std::size_t)
{
}

View File

@@ -0,0 +1,88 @@
/**
* @file spi.h
* Class declaration for SPI helper files
*/
/**
* Example of spi.h class declaration for SPI portability
*
* @defgroup Porting_SPI Porting: SPI
*
*
* @{
*/
#ifndef __XMEGASPI_H__
#define __XMEGASPI_H__
#include <avr/io.h>
#include <stdint.h>
//#include <string.h>
//#include <unistd.h>
//#include <stdio.h>
//#include <stdlib.h>
//#include <getopt.h>
//#include <fcntl.h>
//#include <sys/ioctl.h>
//#include <inttypes.h>
//#include <linux/types.h>
//#include <linux/spi/spidev.h>
#define SPI_SS_bm (1<<4) /* SPI SS pin mask 4 */
#define SPI_MOSI_bm (1<<5) /* SPI MOSI pin mask 5 */
#define SPI_MISO_bm (1<<6) /* SPI MISO pin mask 6 */
#define SPI_SCK_bm (1<<7) /* SPI SCK pin mask 7 */
using namespace std;
class SPI {
public:
/**
* SPI constructor
*/
SPI();
/**
* Start SPI
* @param port is the SPI port (XMEGA_SPI_PORT_C for SPI on PORTC, XMEGA_SPI_PORT_D on PORTD etc).
*/
void begin(uint8_t port);
/**
* 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);
virtual ~SPI();
private:
/** Default SPI device */
SPI_t* device;
/* Port of the SPI */
PORT_t* port;
void init();
};
#endif /*__XMEGASPI_H__*/
/*@}*/

View File

@@ -0,0 +1,35 @@
/*
TMRh20 2015
RF24 Configuration file for Arduino Due
*/
#ifndef __RF24_ARCH_CONFIG_H__
#define __RF24_ARCH_CONFIG_H__
/*** USER DEFINES: ***/
//#define FAILURE_HANDLING
//#define SERIAL_DEBUG
//#define MINIMAL
/**********************/
#define rf24_max(a, b) (a>b?a:b)
#define rf24_min(a, b) (a<b?a:b)
#include <Arduino.h>
#include <SPI.h>
#define _BV(x) (1<<(x))
#define _SPI SPI
#ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({x;})
#else
#define IF_SERIAL_DEBUG(x)
#endif
#define printf_P printf
#define strlen_P strlen
#define PRIPSTR "%s"
#endif // __RF24_CONFIG_H__

View File

@@ -0,0 +1,39 @@
#ifndef __ARCH_CONFIG_H__
#define __ARCH_CONFIG_H__
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <stddef.h>
// Additional fixes for LittleWire
#include <LittleWireSPI/littlewirespi.h>
#include <LittleWireSPI/avr_fixes.h>
extern LittleWireSPI _SPI;
// 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)
#if defined(RF24_TINY)
#define printf_P(...)
#endif
#endif
#endif

View File

@@ -0,0 +1,30 @@
/**
* @file includes.h
* Configuration defines for RF24/Linux
*/
/**
* Example of includes.h for RF24 Linux portability
*
* @defgroup Porting_Includes Porting: Includes
*
*
* @{
*/
#ifndef __RF24_INCLUDES_H__
#define __RF24_INCLUDES_H__
/**
* Define a specific platform for this configuration
*/
#define LITTLEWIRE
/**
* Load the correct configuration for this platform
*/
#include "LittleWire/RF24_arch_config.h"
#endif
/*@}*/

View File

@@ -0,0 +1,64 @@
#ifndef __ARCH_CONFIG_H__
#define __ARCH_CONFIG_H__
#include "mraa.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>
#include <stddef.h>
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
//#include <UtilTime.h> // Precompiled arduino x86 based utiltime for timing functions
// GCC a Arduino Missing
#define HIGH 1
#define LOW 0
#define _BV(x) (1<<(x))
#define pgm_read_word(p) (*(p))
#define pgm_read_byte(p) (*(p))
#define pgm_read_ptr(p) (*(p))
#define _SPI spi
#define RF24_LINUX
//typedef uint16_t prog_uint16_t;
#define PSTR(x) (x)
#define printf_P printf
#define sprintf_P sprintf
#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) gpio.write(pin, value)
#define digitalRead(pin) GPIO::read(pin)
#define pinMode(pin, direction) gpio.open(pin, direction)
#ifndef __TIME_H__
// Prophet: Redefine time functions only if precompiled arduino time is not included
#define delay(milisec) __msleep(milisec)
#define delayMicroseconds(usec) __usleep(usec)
#define millis() __millis()
#endif
#define INPUT mraa::DIR_IN
#define OUTPUT mraa::DIR_OUT
// SPI defines for ARDUINO API
#define MSBFIRST 1
//#define SPI_MODE0 mraa::SPI_MODE0
#define SPI_CLOCK_DIV2 RF24_SPI_SPEED
#endif

View File

@@ -0,0 +1,47 @@
#include "compatibility.h"
static struct timeval start, end;
//static long mtime, seconds, useconds;
/**********************************************************************/
/**
* This function is added in order to simulate arduino delay() function
* @param milisec
*/
void __msleep(int milisec)
{
struct timespec req = {0};
req.tv_sec = 0;
req.tv_nsec = milisec * 1000000L;
nanosleep(&req, (struct timespec*) NULL);
//usleep(milisec*1000);
}
void __usleep(int milisec)
{
struct timespec req = {0};
req.tv_sec = 0;
req.tv_nsec = milisec * 1000L;
nanosleep(&req, (struct timespec*) NULL);
//usleep(milisec);
}
/**
* This function is added in order to simulate arduino millis() function
*/
void __start_timer()
{
gettimeofday(&start, NULL);
}
long __millis()
{
static long mtime, seconds, useconds;
gettimeofday(&end, NULL);
seconds = end.tv_sec - start.tv_sec;
useconds = end.tv_usec - start.tv_usec;
mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
return mtime;
}

View File

@@ -0,0 +1,32 @@
/*
* File: compatiblity.h
* Author: purinda
*
* Created on 24 June 2012, 3:08 PM
*/
#ifndef COMPATIBLITY_H
#define COMPATIBLITY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <time.h>
#include <sys/time.h>
void __msleep(int milisec);
void __usleep(int milisec);
void __start_timer();
long __millis();
#ifdef __cplusplus
}
#endif
#endif /* COMPATIBLITY_H */

View File

@@ -0,0 +1,86 @@
/*
* TMRh20 2015
*
*/
#include "gpio.h"
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*/);
}
void GPIO::open(int port, int DDR)
{
if (port == gpio_ce_pin) {
gpio_0 = new mraa::Gpio(port, 0);
gpio_0->useMmap(true);
gpio_0->dir((mraa::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)
{
// 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;
}
}
/*if(port == gpio_cs_pin) {
if (gpio_1 != NULL) {
delete gpio_1;
}
}*/
}
int GPIO::read(int port)
{
if (port == gpio_ce_pin) {
return gpio_0->read();
}/*else
if(port == gpio_cs_pin){
return gpio_1->read();
}*/
return -1;
}
void GPIO::write(int port, int value)
{
if (port == gpio_ce_pin) {
gpio_0->write(value);
}/*else
if(port == gpio_cs_pin){
gpio_1->write( value);
}*/
}

View File

@@ -0,0 +1,70 @@
/*
* TMRh20 2015
*
*/
#ifndef RF24_ARCH_GPIO_H
#define RF24_ARCH_GPIO_H
/**
* @file spi.h
* \cond HIDDEN_SYMBOLS
* Class declaration for GPIO helper files
*/
#include <cstdio>
#include <stdio.h>
#include "mraa.hpp"
class GPIO {
public:
/* Constants */
GPIO();
virtual ~GPIO();
/**
* Sets up GPIO on the CE & CS pins
* @param ce_pin
* @param cs_pin
*/
void begin(uint8_t ce_pin, uint8_t cs_pin);
/**
*
* @param port
* @param DDR
*/
void open(int port, int DDR);
/**
*
* @param port
*/
void close(int port);
/**
*
* @param port
* @param value
*/
int read(int port);
/**
*
* @param port
* @param value
*/
void write(int port, int value);
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 **/
};
/**
* \endcond
*/
#endif /* RF24_ARCH_GPIO_H */

View File

@@ -0,0 +1,10 @@
#ifndef __RF24_INCLUDES_H__
#define __RF24_INCLUDES_H__
#ifndef MRAA
#define MRAA
#endif
#include "MRAA/RF24_arch_config.h"
#endif

View File

@@ -0,0 +1,59 @@
#include "spi.h"
#include "mraa.h"
SPI::SPI()
{
mspi = NULL;
}
void SPI::begin(int busNo, uint32_t spi_speed)
{
mspi = new mraa::Spi(
busNo); // init mraa spi bus, it will handle chip select internally. For CS pin wiring user must check SPI details in hardware manual
mspi->mode(mraa::SPI_MODE0);
mspi->bitPerWord(8);
mspi->frequency(
spi_speed); // Prophet: this will try to set 8MHz, however MRAA will reset to max platform speed and syslog a message of it
}
void SPI::end()
{
// Prophet: we should check for existence of mspi before deleting it
if (mspi != NULL) {
delete mspi;
}
}
void SPI::setBitOrder(uint8_t bit_order)
{
if (mspi != NULL) {
mspi->lsbmode((mraa_boolean_t) bit_order);
} // Prophet: bit_order
}
void SPI::setDataMode(uint8_t data_mode)
{
if (mspi != NULL) {
mspi->mode((mraa::Spi_Mode) data_mode);
}
}
void SPI::setClockDivider(uint32_t spi_speed)
{
if (mspi != NULL) {
mspi->frequency(spi_speed);
}
}
void SPI::chipSelect(int csn_pin)
{
}
SPI::~SPI()
{
// Prophet: we should call end here to free used memory and unexport SPI interface
this->end();
}

View File

@@ -0,0 +1,66 @@
/*
* TMRh20 2015
* SPI layer for RF24
*/
#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED
/**
* @file spi.h
* \cond HIDDEN_SYMBOLS
* Class declaration for SPI helper files
*/
#include <stdio.h>
#include "mraa.h"
#include "mraa.hpp"
#include "../../RF24_config.h"
class SPI {
public:
SPI();
virtual ~SPI();
mraa::Spi* mspi;
inline uint8_t transfer(uint8_t _data);
inline void transfernb(char* tbuf, char* rbuf, uint32_t len);
inline void transfern(char* buf, uint32_t len);
void begin(int busNo, uint32_t spi_speed = RF24_SPI_SPEED);
void end();
void setBitOrder(uint8_t bit_order);
void setDataMode(uint8_t data_mode);
void setClockDivider(uint32_t spi_speed);
void chipSelect(int csn_pin);
};
uint8_t SPI::transfer(uint8_t _data)
{
return mspi->writeByte(_data);
}
void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
{
mspi->transfer((uint8_t*) tbuf, (uint8_t*) rbuf, len);
}
void SPI::transfern(char* buf, uint32_t len)
{
transfernb(buf, buf, len);
}
/**
* \endcond
*/
#endif

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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);
}

View 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

View 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

View 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);
}

View 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

View 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()
{
}

View 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

View 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

View 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;
}

View 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 */

View 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);*/
}

View 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 */

View 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

View 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);
}

View 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

View 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) &rx;
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);
}
}

View 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 */

View File

@@ -0,0 +1,33 @@
#if ARDUINO < 100
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <SPI.h>
#define _SPI SPI
#define printf Serial.printf
#ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({x;})
#else
#define IF_SERIAL_DEBUG(x)
#endif
#define PRIPSTR "%s"

View File

@@ -0,0 +1,83 @@
/*
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.
*/
/**
* @file RF24_arch_config.h
* General defines and includes for RF24/Linux
*/
/**
* Example of RF24_arch_config.h for RF24 portability
*
* @defgroup Porting_General Porting: General
*
*
* @{
*/
#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 _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))
// 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__
/*@}*/

View File

@@ -0,0 +1,47 @@
/*
* File: compatiblity.h
* Author: purinda
*
* Created on 24 June 2012, 3:08 PM
*/
/**
* @file compatibility.h
* Class declaration for SPI helper files
*/
/**
* Example of compatibility.h class declaration for timing functions portability
*
* @defgroup Porting_Timing Porting: Timing
*
*
* @{
*/
#ifndef COMPATIBLITY_H
#define COMPATIBLITY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <time.h>
#include <sys/time.h>
void __msleep(int milisec);
void __usleep(int milisec);
void __start_timer();
long __millis();
#ifdef __cplusplus
}
#endif
#endif /* COMPATIBLITY_H */
/*@}*/

View File

@@ -0,0 +1,63 @@
/**
* @file gpio.h
* Class declaration for SPI helper files
*/
/**
* Example of gpio.h class declaration for GPIO portability
*
* @defgroup Porting_GPIO Porting: GPIO
*
*
* @{
*/
#ifndef H
#define H
#include <cstdio>
//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();
};
/*@}*/

View File

@@ -0,0 +1,30 @@
/**
* @file includes.h
* Configuration defines for RF24/Linux
*/
/**
* Example of includes.h for RF24 Linux portability
*
* @defgroup Porting_Includes Porting: Includes
*
*
* @{
*/
#ifndef __RF24_INCLUDES_H__
#define __RF24_INCLUDES_H__
/**
* Define a specific platform for this configuration
*/
#define RF24_BBB
/**
* Load the correct configuration for this platform
*/
#include "BBB/RF24_arch_config.h"
#endif
/*@}*/

View File

@@ -0,0 +1,81 @@
/**
* @file spi.h
* Class declaration for SPI helper files
*/
/**
* Example of spi.h class declaration for SPI portability
*
* @defgroup Porting_SPI Porting: SPI
*
*
* @{
*/
#include <string>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <inttypes.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
using namespace std;
//class SPI {
public:
/**
* SPI constructor
*/
SPI();
/**
* Start SPI
*/
void begin(int busNo);
/**
* 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);
virtual ~ SPI();
private:
/** Default SPI device */
string device;
/** SPI Mode set */
uint8_t mode;
/** word size*/
uint8_t bits;
/** Set SPI speed*/
uint32_t speed;
int fd;
void init();
};
/*@}*/

View File

@@ -0,0 +1,55 @@
/*
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 "wiringPi.h"
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#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))
#endif // __ARCH_CONFIG_H__
/*@}*/

View File

@@ -0,0 +1,29 @@
/**
* @file includes.h
* Configuration defines for RF24/Linux
*/
/**
* Example of includes.h for RF24 Linux portability
*
* @defgroup Porting_Includes Porting: Includes
*
*
* @{
*/
#ifndef __RF24_INCLUDES_H__
#define __RF24_INCLUDES_H__
/**
* Define RF24_WIRINGPI configuration for RaspberryPi platform
*/
#define RF24_WIRINGPI
/**
* Load the correct configuration for this platform
*/
#include "wiringPi/RF24_arch_config.h"
#endif
/*@}*/

View File

@@ -0,0 +1,87 @@
/*
* File: spi.cpp
* Author:
*
* Created on
*
* Inspired from spi speed test from wiringPi
* wiringPi/examples/spiSpeed.c
*/
#include "spi.h"
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#define RF24_SPI_CHANNEL 0
SPI::SPI():fd(-1)
{
printf("wiringPi RF24 DRIVER\n");
}
void SPI::begin(int csn_pin, uint32_t spi_speed)
{
// initialize the wiringPiSPI
if ((this->fd = wiringPiSPISetup(RF24_SPI_CHANNEL, spi_speed)) < 0) {
printf("Cannot configure the SPI device!\n");
fflush(stdout);
abort();
} else {
printf("Configured SPI fd: %d - pin: %d\n", fd, csn_pin);
}
}
uint8_t SPI::transfer(uint8_t tx)
{
memset(&msgByte, 0, sizeof(msgByte));
memcpy(&msgByte, &tx, sizeof(tx));
if (wiringPiSPIDataRW(RF24_SPI_CHANNEL, &msgByte, sizeof(tx)) < 0) {
printf("transfer(): Cannot send data: %s\n", strerror(errno));
fflush(stdout);
abort();
}
return msgByte;
}
void SPI::transfern(char* buf, uint32_t len)
{
printf("transfern(tx: %s)\n", buf);
if (wiringPiSPIDataRW(RF24_SPI_CHANNEL, (uint8_t*) buf, len) < 0) {
printf("transfern(): Cannot send data %s\n", strerror(errno));
fflush(stdout);
abort();
}
}
void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
{
// using an auxiliary buffer to keep tx and rx different
memset(msg, 0, sizeof(msg));
memcpy(msg, tbuf, len);
if (wiringPiSPIDataRW(RF24_SPI_CHANNEL, msg, len) < 0) {
printf("transfernb() Cannot send data %s\n", strerror(errno));
fflush(stdout);
abort();
}
memcpy(rbuf, msg, len);
}
SPI::~SPI()
{
if (this->fd >= 0) {
close(this->fd);
this->fd = -1;
}
}

View File

@@ -0,0 +1,72 @@
/**
* @file spi.h
* Class declaration for SPI helper files
*/
#ifndef SPI_H
#define SPI_H
/**
* Example of spi.h class declaration for SPI portability
*
* @defgroup Porting_SPI Porting: SPI
*
* @{
*/
#include <stdio.h>
#include <inttypes.h>
#include "../../RF24_config.h"
using namespace std;
class SPI {
public:
/**
* SPI default constructor
*/
SPI();
/**
* Start SPI communication
* @param pin used for SPI
*/
void begin(int csn_pin, uint32_t spi_speed = RF24_SPI_SPEED);
/**
* Transfer a single byte of data
* @param tx Byte to send
* @return Data returned via spi
*/
uint8_t transfer(uint8_t);
/**
* Transfer a buffer of data using rx and tx buffer
* @param tbuf Transmit buffer
* @param rbuf Receive buffer
* @param len Length of the data
*/
void transfernb(char*, char*, uint32_t);
/**
* Transfer a buffer of data without using an rx buffer
* @param buf Pointer to a buffer of data
* @param len Length of the data
*/
void transfern(char*, const uint32_t);
/**
* SPI destructor
*/
virtual ~SPI();
private:
int fd;
uint8_t msg[32 + 1];
uint8_t msgByte;
};
/*@}*/
#endif /* SPI_H */