Restructure RPi files (#827)

- Restructure SPi files for linux and RPi
- Update RPi revision detection (#826)
This commit is contained in:
Marcelo Aquino
2017-04-19 22:03:10 +02:00
committed by Henrik Ekblad
parent 26c237adad
commit 4c31e22d6f
19 changed files with 345 additions and 505 deletions
+4 -20
View File
@@ -26,30 +26,14 @@ GATEWAY_OBJECTS=$(patsubst %.c,$(BUILDDIR)/%.o,$(GATEWAY_C_SOURCES)) $(patsubst
INCLUDES=-I. -I./core -I./drivers/Linux
ifeq ($(SOC),$(filter $(SOC),BCM2835 BCM2836))
RPI_C_SOURCES=$(wildcard drivers/RPi/*.c)
RPI_CPP_SOURCES=$(wildcard drivers/RPi/*.cpp)
GATEWAY_OBJECTS+=$(patsubst %.c,$(BUILDDIR)/%.o,$(RPI_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(RPI_CPP_SOURCES))
INCLUDES+=-I./drivers/RPi
endif
ifeq ($(SPI_DRIVER), BCM)
SPI_DRIVER_C_SOURCES=$(wildcard drivers/BCM/*.c)
SPI_DRIVER_CPP_SOURCES=$(wildcard drivers/BCM/*.cpp)
GATEWAY_OBJECTS+=$(patsubst %.c,$(BUILDDIR)/%.o,$(SPI_DRIVER_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(SPI_DRIVER_CPP_SOURCES))
ifeq ($(SOC),$(filter $(SOC),BCM2835 BCM2836 BCM2837))
BCM_C_SOURCES=$(wildcard drivers/BCM/*.c)
BCM_CPP_SOURCES=$(wildcard drivers/BCM/*.cpp)
GATEWAY_OBJECTS+=$(patsubst %.c,$(BUILDDIR)/%.o,$(BCM_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(BCM_CPP_SOURCES))
INCLUDES+=-I./drivers/BCM
endif
ifeq ($(SPI_DRIVER), SPIDEV)
SPI_DRIVER_C_SOURCES=$(wildcard drivers/SPIDEV/*.c)
SPI_DRIVER_CPP_SOURCES=$(wildcard drivers/SPIDEV/*.cpp)
GATEWAY_OBJECTS+=$(patsubst %.c,$(BUILDDIR)/%.o,$(SPI_DRIVER_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(SPI_DRIVER_CPP_SOURCES))
INCLUDES+=-I./drivers/SPIDEV
endif
# Gets include flags for library
get_library_includes = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.properties)), \
-I$(1)/src, \
Vendored
+36 -16
View File
@@ -17,7 +17,7 @@ SPI driver options:
Device path. [/dev/spidev0.0]
Building options:
--soc=[BCM2835|BCM2836|AM33XX|A10|A13|A20|H3]
--soc=[BCM2835|BCM2836|BCM2837|AM33XX|A10|A13|A20|H3]
SoC type to be used. [configure autodetected]
--cpu-flags=<CPUFLAGS> CPU defining/optimizing flags to be used. [configure autodetected]
--extra-cflags=<CFLAGS> Extra C flags passed to C compilation. []
@@ -126,21 +126,38 @@ function detect_machine {
fi
case $hardware in
BCM2708)
soc="BCM2835"
BCM*)
if [[ $machine == "Raspberry"* ]]; then
tp="RPi"
fi
;;
BCM2709)
soc="BCM2836"
if [[ $machine == "Raspberry"* ]]; then
local rev=($(detect_rpi_revision))
if [[ $rev == "a02082" || $rev == "a22082" ]]; then
tp="RPi3"
# Calculation done by joolswills(https://github.com/joolswills) for the RetroPie-Setup project
# and based on information from https://github.com/AndrewFromMelbourne/raspberry_pi_revision
local rev="0x$(sed -n '/^Revision/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo)"
# if bit 23 is not set, we are on a rpi1 (bit 23 means the revision is a bitfield)
if [[ $((($rev >> 23) & 1)) -eq 0 ]]; then
soc="BCM2835"
tp="rpi1"
else
tp="Rpi2"
# if bit 23 is set, get the cpu from bits 12-15
case "$((($rev >> 12) & 15))" in
0)
soc="BCM2835"
tp="rpi1"
;;
1)
soc="BCM2836"
tp="rpi2"
;;
2)
soc="BCM2837"
tp="rpi3"
;;
esac
fi
elif [[ $hardware == "BCM2708"* ]]; then
soc="BCM2835"
elif [[ $hardware == "BCM2709"* ]]; then
soc="BCM2836"
elif [[ $hardware == "BCM2710"* ]]; then
soc="BCM2837"
fi
;;
sun4i|Sun4iw1p1)
@@ -208,6 +225,9 @@ function gcc_cpu_flags {
BCM2836)
flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"
;;
BCM2837)
flags="-march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard"
;;
AM33XX)
flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard"
;;
@@ -446,8 +466,8 @@ if [ -z "${CPUFLAGS}" ]; then
CPUFLAGS=$(gcc_cpu_flags $SOC)
fi
if [[ $SOC == "BCM2835" || $SOC == "BCM2836" ]]; then
CPPFLAGS="-DLINUX_ARCH_RASPBERRYPI $CPPFLAGS"
if [[ $SOC == "BCM2835" || $SOC == "BCM2836" || $SOC == "BCM2837" ]]; then
CPPFLAGS="-DLINUX_ARCH_RASPBERRYPI -DRPI_TYPE=\\\"$TYPE\\\" $CPPFLAGS"
else
echo "[SECTION] Checking GPIO Sysfs."
if [[ $(eval 'ls /sys/class/gpio/export 2>/dev/null') ]]; then
@@ -459,7 +479,7 @@ fi
if [ -z "${SPI_DRIVER}" ]; then
echo "[SECTION] Detecting SPI driver."
if [[ $SOC == "BCM2835" || $SOC == "BCM2836" ]]; then
if [[ $SOC == "BCM2835" || $SOC == "BCM2836" || $SOC == "BCM2837" ]]; then
SPI_DRIVER=BCM
elif [[ $(eval 'ls /dev/spidev* 2>/dev/null') ]]; then
SPI_DRIVER=SPIDEV
+76
View File
@@ -0,0 +1,76 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2017 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* 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.
*/
#include "BCM.h"
#include <stdlib.h>
#include "log.h"
// Declare a single default instance
BCMClass BCM = BCMClass();
uint8_t BCMClass::initialized = 0;
BCMClass::~BCMClass()
{
if (initialized) {
bcm2835_close();
initialized = 0;
}
}
void BCMClass::pinMode(uint8_t gpio, uint8_t mode)
{
if (!initialized) {
if (!bcm2835_init()) {
logError("Failed to initialized bcm2835.\n");
exit(1);
}
initialized = 1;
}
bcm2835_gpio_fsel(gpio, mode);
}
void BCMClass::digitalWrite(uint8_t gpio, uint8_t value)
{
if (!initialized) {
if (!bcm2835_init()) {
logError("Failed to initialized bcm2835.\n");
exit(1);
}
initialized = 1;
}
bcm2835_gpio_write(gpio, value);
// Delay to allow any change in state to be reflected in the LEVn, register bit.
delayMicroseconds(1);
}
uint8_t BCMClass::digitalRead(uint8_t gpio)
{
if (!initialized) {
if (!bcm2835_init()) {
logError("Failed to initialized bcm2835.\n");
exit(1);
}
initialized = 1;
}
return bcm2835_gpio_lev(gpio);
}
+80
View File
@@ -0,0 +1,80 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2017 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* 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 BCM_h
#define BCM_h
#include <stdint.h>
#include "bcm2835.h"
#define INPUT BCM2835_GPIO_FSEL_INPT
#define OUTPUT BCM2835_GPIO_FSEL_OUTP
/**
* @brief BCM class
*/
class BCMClass
{
public:
/**
* @brief BCMClass destructor.
*/
~BCMClass();
/**
* @brief Configures the specified pin to behave either as an input or an output.
*
* @param gpio The GPIO pin number.
* @param mode INPUT or OUTPUT.
*/
void pinMode(uint8_t gpio, uint8_t mode);
/**
* @brief Write a high or a low value for the given pin.
*
* @param gpio The GPIO pin number.
* @param value HIGH or LOW.
*/
void digitalWrite(uint8_t gpio, uint8_t value);
/**
* @brief Reads the value from a specified pin.
*
* @param gpio The GPIO pin number.
* @return HIGH or LOW.
*/
uint8_t digitalRead(uint8_t gpio);
/**
* @brief Returns the same GPIO, no conversion is required.
*
* @param gpio The GPIO pin number.
* @return The GPIO pin number.
*/
inline uint8_t digitalPinToInterrupt(uint8_t gpio);
private:
static uint8_t initialized; //!< @brief BCM initialized flag.
};
uint8_t BCMClass::digitalPinToInterrupt(uint8_t gpio)
{
return gpio;
}
extern BCMClass BCM;
#endif
+31 -45
View File
@@ -19,6 +19,7 @@
#include "RPi.h"
#include <stdlib.h>
#include <string.h>
#include "log.h"
const static int pin_to_gpio_rev1[41] = {-1, -1, -1, 0, -1, 1, -1, 4, 14, -1, 15, 17, 18, 21, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
@@ -26,67 +27,55 @@ const static int pin_to_gpio_rev2[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15
const static int pin_to_gpio_rev3[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 26, 20, -1, 21 };
// Declare a single default instance
RPi rpi = RPi();
RPiClass RPi = RPiClass();
const int* RPi::pin_to_gpio = NULL;
rpi_info RPi::rpiinfo;
const int* RPiClass::pin_to_gpio = NULL;
#ifndef RPI_TYPE
#error Raspberry Pi type not set
#endif
const char* RPiClass::type = RPI_TYPE;
RPi::RPi()
{
if (!bcm2835_init()) {
logError("Failed to initialized bcm2835.\n");
exit(1);
}
}
RPi::~RPi()
{
bcm2835_close();
}
void RPi::pinMode(uint8_t physPin, uint8_t mode)
void RPiClass::pinMode(uint8_t physPin, uint8_t mode)
{
uint8_t gpioPin;
if (physToGPIO(physPin, &gpioPin)) {
if (physToGPIO(physPin, &gpioPin) != 0) {
logError("pinMode: invalid pin: %d\n", physPin);
return;
}
bcm2835_gpio_fsel(gpioPin, mode);
BCM.pinMode(gpioPin, mode);
}
void RPi::digitalWrite(uint8_t physPin, uint8_t value)
void RPiClass::digitalWrite(uint8_t physPin, uint8_t value)
{
uint8_t gpioPin;
if (physToGPIO(physPin, &gpioPin)) {
if (physToGPIO(physPin, &gpioPin) != 0) {
logError("digitalWrite: invalid pin: %d\n", physPin);
return;
}
bcm2835_gpio_write(gpioPin, value);
// Delay to allow any change in state to be reflected in the LEVn, register bit.
delayMicroseconds(1);
BCM.digitalWrite(gpioPin, value);
}
uint8_t RPi::digitalRead(uint8_t physPin)
uint8_t RPiClass::digitalRead(uint8_t physPin)
{
uint8_t gpioPin;
if (physToGPIO(physPin, &gpioPin)) {
if (physToGPIO(physPin, &gpioPin) != 0) {
logError("digitalRead: invalid pin: %d\n", physPin);
return 0;
}
return bcm2835_gpio_lev(gpioPin);
return BCM.digitalRead(gpioPin);
}
uint8_t RPi::digitalPinToInterrupt(uint8_t physPin)
uint8_t RPiClass::digitalPinToInterrupt(uint8_t physPin)
{
uint8_t gpioPin;
if (physToGPIO(physPin, &gpioPin)) {
if (physToGPIO(physPin, &gpioPin) != 0) {
logError("digitalPinToInterrupt: invalid pin: %d\n", physPin);
return 0;
}
@@ -94,33 +83,30 @@ uint8_t RPi::digitalPinToInterrupt(uint8_t physPin)
return gpioPin;
}
int RPi::physToGPIO(uint8_t physPin, uint8_t *gpio)
int RPiClass::physToGPIO(uint8_t physPin, uint8_t *gpio)
{
if (pin_to_gpio == NULL) {
// detect board revision and set up accordingly
if (get_rpi_info(&rpiinfo)) {
logError("This module can only be run on a Raspberry Pi!\n");
if (strncmp(type,"rpi1", 4) == 0) {
pin_to_gpio = &pin_to_gpio_rev1[0];
} else if (strncmp(type,"rpi2", 4) == 0) {
pin_to_gpio = &pin_to_gpio_rev2[0];
} else if (strncmp(type,"rpi3", 4) == 0) {
pin_to_gpio = &pin_to_gpio_rev3[0];
} else {
logError("Invalid Raspberry Pi type!\n");
exit(1);
}
if (rpiinfo.p1_revision == 1) {
pin_to_gpio = &pin_to_gpio_rev1[0];
} else if (rpiinfo.p1_revision == 2) {
pin_to_gpio = &pin_to_gpio_rev2[0];
} else { // assume model B+ or A+ or 2B
pin_to_gpio = &pin_to_gpio_rev3[0];
}
}
if ((rpiinfo.p1_revision != 3 && physPin > 26)
|| (rpiinfo.p1_revision == 3 && physPin > 40)) {
if (gpio == NULL || physPin > 40) {
return -1;
}
if (*(pin_to_gpio+physPin) == -1) {
int pin = *(pin_to_gpio+physPin);
if (pin == -1) {
return -1;
} else {
*gpio = *(pin_to_gpio+physPin);
*gpio = pin;
}
return 0;
+4 -16
View File
@@ -21,27 +21,15 @@
#define RPi_h
#include <stdint.h>
#include "bcm2835.h"
#include "cpuinfo.h"
#define INPUT BCM2835_GPIO_FSEL_INPT
#define OUTPUT BCM2835_GPIO_FSEL_OUTP
#include "BCM.h"
/**
* @brief RPi class
*/
class RPi
class RPiClass
{
public:
/**
* @brief RPi constructor.
*/
RPi();
/**
* @brief RPi destructor.
*/
~RPi();
/**
* @brief Configures the specified pin to behave either as an input or an output.
*
@@ -81,9 +69,9 @@ public:
private:
static const int *pin_to_gpio; //!< @brief Pointer to array of GPIO pins numbers.
static rpi_info rpiinfo; //!< @brief Board information.
static const char *type; //!< @brief Raspberry Pi type.
};
extern RPi rpi;
extern RPiClass RPi;
#endif
+13 -13
View File
@@ -19,7 +19,7 @@
* Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
*/
#include "SPI.h"
#include "SPIBCM.h"
#include <pthread.h>
#include <stdlib.h>
#include "log.h"
@@ -27,11 +27,11 @@
static pthread_mutex_t spiMutex = PTHREAD_MUTEX_INITIALIZER;
// Declare a single default instance
SPIClass SPI = SPIClass();
SPIBCMClass SPIBCM = SPIBCMClass();
uint8_t SPIClass::initialized = 0;
uint8_t SPIBCMClass::initialized = 0;
void SPIClass::begin()
void SPIBCMClass::begin()
{
if (!initialized) {
if (!bcm2835_spi_begin()) {
@@ -43,7 +43,7 @@ void SPIClass::begin()
initialized++; // reference count
}
void SPIClass::end()
void SPIBCMClass::end()
{
if (initialized) {
initialized--;
@@ -55,22 +55,22 @@ void SPIClass::end()
}
}
void SPIClass::setBitOrder(uint8_t bit_order)
void SPIBCMClass::setBitOrder(uint8_t bit_order)
{
bcm2835_spi_setBitOrder(bit_order);
}
void SPIClass::setDataMode(uint8_t data_mode)
void SPIBCMClass::setDataMode(uint8_t data_mode)
{
bcm2835_spi_setDataMode(data_mode);
}
void SPIClass::setClockDivider(uint16_t divider)
void SPIBCMClass::setClockDivider(uint16_t divider)
{
bcm2835_spi_setClockDivider(divider);
}
void SPIClass::chipSelect(int csn_pin)
void SPIBCMClass::chipSelect(int csn_pin)
{
if (csn_pin == RPI_GPIO_P1_26) {
csn_pin = BCM2835_SPI_CS1;
@@ -83,7 +83,7 @@ void SPIClass::chipSelect(int csn_pin)
delayMicroseconds(5);
}
void SPIClass::beginTransaction(SPISettings settings)
void SPIBCMClass::beginTransaction(SPISettings settings)
{
pthread_mutex_lock(&spiMutex);
setBitOrder(settings.border);
@@ -91,17 +91,17 @@ void SPIClass::beginTransaction(SPISettings settings)
setClockDivider(settings.cdiv);
}
void SPIClass::endTransaction()
void SPIBCMClass::endTransaction()
{
pthread_mutex_unlock(&spiMutex);
}
void SPIClass::usingInterrupt(uint8_t interruptNumber)
void SPIBCMClass::usingInterrupt(uint8_t interruptNumber)
{
(void)interruptNumber;
}
void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
void SPIBCMClass::notUsingInterrupt(uint8_t interruptNumber)
{
(void)interruptNumber;
}
+10 -10
View File
@@ -19,12 +19,12 @@
* Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
*/
#ifndef _SPI_H_
#define _SPI_H_
#ifndef SPIBCM_h
#define SPIBCM_h
#include <stdio.h>
#include "bcm2835.h"
#include "RPi.h"
#include "BCM.h"
#define SPI_HAS_TRANSACTION
@@ -151,13 +151,13 @@ private:
dmode = dataMode;
}
friend class SPIClass;
friend class SPIBCMClass;
};
/**
* SPIClass class
* SPIBCM class
*/
class SPIClass
class SPIBCMClass
{
public:
@@ -242,21 +242,21 @@ private:
static uint8_t initialized; //!< @brief SPI initialized flag.
};
uint8_t SPIClass::transfer(uint8_t data)
uint8_t SPIBCMClass::transfer(uint8_t data)
{
return bcm2835_spi_transfer(data);
}
void SPIClass::transfernb(char* tbuf, char* rbuf, uint32_t len)
void SPIBCMClass::transfernb(char* tbuf, char* rbuf, uint32_t len)
{
bcm2835_spi_transfernb( tbuf, rbuf, len);
}
void SPIClass::transfern(char* buf, uint32_t len)
void SPIBCMClass::transfern(char* buf, uint32_t len)
{
transfernb(buf, buf, len);
}
extern SPIClass SPI;
extern SPIBCMClass SPIBCM;
#endif
+1 -1
View File
@@ -28,7 +28,7 @@
#if !DOXYGEN
#include <stdint.h>
#include "Stream.h"
#include "RPi.h"
#include "BCM.h"
#define BUFFER_LENGTH 32
+8 -8
View File
@@ -34,16 +34,16 @@
#ifdef LINUX_ARCH_RASPBERRYPI
#include "RPi.h"
#define pinMode(pin, direction) rpi.pinMode(pin, direction)
#define digitalWrite(pin, value) rpi.digitalWrite(pin, value)
#define digitalRead(pin) rpi.digitalRead(pin)
#define digitalPinToInterrupt(pin) rpi.digitalPinToInterrupt(pin)
#define pinMode(pin, direction) RPi.pinMode(pin, direction)
#define digitalWrite(pin, value) RPi.digitalWrite(pin, value)
#define digitalRead(pin) RPi.digitalRead(pin)
#define digitalPinToInterrupt(pin) RPi.digitalPinToInterrupt(pin)
#else
#include "GPIO.h"
#define pinMode(pin, direction) gpio.pinMode(pin, direction)
#define digitalWrite(pin, value) gpio.digitalWrite(pin, value)
#define digitalRead(pin) gpio.digitalRead(pin)
#define digitalPinToInterrupt(pin) gpio.digitalPinToInterrupt(pin)
#define pinMode(pin, direction) GPIO.pinMode(pin, direction)
#define digitalWrite(pin, value) GPIO.digitalWrite(pin, value)
#define digitalRead(pin) GPIO.digitalRead(pin)
#define digitalPinToInterrupt(pin) GPIO.digitalPinToInterrupt(pin)
#endif
#include "interrupt.h"
+9 -9
View File
@@ -27,9 +27,9 @@
#include "log.h"
// Declare a single default instance
GPIO gpio = GPIO();
GPIOClass GPIO = GPIOClass();
GPIO::GPIO()
GPIOClass::GPIOClass()
{
FILE *f;
DIR* dp;
@@ -83,7 +83,7 @@ GPIO::GPIO()
}
}
GPIO::GPIO(const GPIO& other)
GPIOClass::GPIOClass(const GPIOClass& other)
{
lastPinNum = other.lastPinNum;
@@ -93,7 +93,7 @@ GPIO::GPIO(const GPIO& other)
}
}
GPIO::~GPIO()
GPIOClass::~GPIOClass()
{
FILE *f;
@@ -108,7 +108,7 @@ GPIO::~GPIO()
delete [] exportedPins;
}
void GPIO::pinMode(uint8_t pin, uint8_t mode)
void GPIOClass::pinMode(uint8_t pin, uint8_t mode)
{
FILE *f;
@@ -144,7 +144,7 @@ void GPIO::pinMode(uint8_t pin, uint8_t mode)
fclose(f);
}
void GPIO::digitalWrite(uint8_t pin, uint8_t value)
void GPIOClass::digitalWrite(uint8_t pin, uint8_t value)
{
FILE *f;
char file[128];
@@ -168,7 +168,7 @@ void GPIO::digitalWrite(uint8_t pin, uint8_t value)
fclose(f);
}
uint8_t GPIO::digitalRead(uint8_t pin)
uint8_t GPIOClass::digitalRead(uint8_t pin)
{
FILE *f;
char file[128];
@@ -192,12 +192,12 @@ uint8_t GPIO::digitalRead(uint8_t pin)
return i;
}
uint8_t GPIO::digitalPinToInterrupt(uint8_t pin)
uint8_t GPIOClass::digitalPinToInterrupt(uint8_t pin)
{
return pin;
}
GPIO& GPIO::operator=(const GPIO& other)
GPIOClass& GPIOClass::operator=(const GPIOClass& other)
{
if (this != &other) {
lastPinNum = other.lastPinNum;
+9 -9
View File
@@ -31,22 +31,22 @@
/**
* @brief GPIO class
*/
class GPIO
class GPIOClass
{
public:
/**
* @brief GPIO constructor.
* @brief GPIOClass constructor.
*/
GPIO();
GPIOClass();
/**
* @brief GPIO copy constructor.
* @brief GPIOClass copy constructor.
*/
GPIO(const GPIO& other);
GPIOClass(const GPIOClass& other);
/**
* @brief GPIO destructor.
* @brief GPIOClass destructor.
*/
~GPIO();
~GPIOClass();
/**
* @brief Configures the specified pin to behave either as an input or an output.
*
@@ -79,13 +79,13 @@ public:
* @brief Overloaded assign operator.
*
*/
GPIO& operator=(const GPIO& other);
GPIOClass& operator=(const GPIOClass& other);
private:
int lastPinNum; //!< @brief Highest pin number supported.
uint8_t *exportedPins; //!< @brief Array with information of which pins were exported.
};
extern GPIO gpio;
extern GPIOClass GPIO;
#endif
+31
View File
@@ -0,0 +1,31 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2017 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* 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 _SPI_H_
#define _SPI_H_
#ifdef LINUX_SPI_BCM
#include "SPIBCM.h"
#define SPI SPIBCM
#elif LINUX_SPI_SPIDEV
#include "SPIDEV.h"
#define SPI SPIDEV
#endif
#endif
@@ -19,7 +19,7 @@
* Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
*/
#include "SPI.h"
#include "SPIDEV.h"
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>
@@ -32,22 +32,22 @@ static pthread_mutex_t spiMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutexattr_t attr;
// Declare a single default instance
SPIClass SPI = SPIClass();
SPIDEVClass SPIDEV = SPIDEVClass();
uint8_t SPIClass::initialized = 0;
int SPIClass::fd = -1;
std::string SPIClass::device = SPI_SPIDEV_DEVICE;
uint32_t SPIClass::speed = SPI_CLOCK_BASE;
uint32_t SPIClass::speed_temp = SPI_CLOCK_BASE;
struct spi_ioc_transfer SPIClass::tr = {0,0,0,0,0,8,1,0,0,0}; // 8 bits_per_word, 1 cs_change
uint8_t SPIDEVClass::initialized = 0;
int SPIDEVClass::fd = -1;
std::string SPIDEVClass::device = SPI_SPIDEV_DEVICE;
uint32_t SPIDEVClass::speed = SPI_CLOCK_BASE;
uint32_t SPIDEVClass::speed_temp = SPI_CLOCK_BASE;
struct spi_ioc_transfer SPIDEVClass::tr = {0,0,0,0,0,8,1,0,0,0}; // 8 bits_per_word, 1 cs_change
SPIClass::SPIClass()
SPIDEVClass::SPIDEVClass()
{
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&spiMutex, &attr);
}
void SPIClass::begin(int busNo)
void SPIDEVClass::begin(int busNo)
{
if (!initialized) {
/* set spidev accordingly to busNo like:
@@ -64,7 +64,7 @@ void SPIClass::begin(int busNo)
initialized++; // reference count
}
void SPIClass::end()
void SPIDEVClass::end()
{
if (initialized) {
initialized--;
@@ -78,7 +78,7 @@ void SPIClass::end()
}
}
void SPIClass::setBitOrder(uint8_t bit_order)
void SPIDEVClass::setBitOrder(uint8_t bit_order)
{
pthread_mutex_lock(&spiMutex);
@@ -95,7 +95,7 @@ void SPIClass::setBitOrder(uint8_t bit_order)
pthread_mutex_unlock(&spiMutex);
}
void SPIClass::setDataMode(uint8_t data_mode)
void SPIDEVClass::setDataMode(uint8_t data_mode)
{
pthread_mutex_lock(&spiMutex);
@@ -111,7 +111,7 @@ void SPIClass::setDataMode(uint8_t data_mode)
pthread_mutex_unlock(&spiMutex);
}
void SPIClass::setClockDivider(uint16_t divider)
void SPIDEVClass::setClockDivider(uint16_t divider)
{
pthread_mutex_lock(&spiMutex);
@@ -128,7 +128,7 @@ void SPIClass::setClockDivider(uint16_t divider)
pthread_mutex_unlock(&spiMutex);
}
void SPIClass::chipSelect(int csn_chip)
void SPIDEVClass::chipSelect(int csn_chip)
{
if (csn_chip >= 0 && csn_chip <= 9) {
device[13] = '0' + (csn_chip % 10);
@@ -137,7 +137,7 @@ void SPIClass::chipSelect(int csn_chip)
}
}
uint8_t SPIClass::transfer(uint8_t data)
uint8_t SPIDEVClass::transfer(uint8_t data)
{
int ret;
uint8_t tx[1] = {data};
@@ -161,7 +161,7 @@ uint8_t SPIClass::transfer(uint8_t data)
return rx[0];
}
void SPIClass::transfernb(char* tbuf, char* rbuf, uint32_t len)
void SPIDEVClass::transfernb(char* tbuf, char* rbuf, uint32_t len)
{
int ret;
@@ -181,12 +181,12 @@ void SPIClass::transfernb(char* tbuf, char* rbuf, uint32_t len)
pthread_mutex_unlock(&spiMutex);
}
void SPIClass::transfern(char* buf, uint32_t len)
void SPIDEVClass::transfern(char* buf, uint32_t len)
{
transfernb(buf, buf, len);
}
void SPIClass::beginTransaction(SPISettings settings)
void SPIDEVClass::beginTransaction(SPISettings settings)
{
int ret;
@@ -215,23 +215,23 @@ void SPIClass::beginTransaction(SPISettings settings)
}
}
void SPIClass::endTransaction()
void SPIDEVClass::endTransaction()
{
speed = speed_temp;
pthread_mutex_unlock(&spiMutex);
}
void SPIClass::usingInterrupt(uint8_t interruptNumber)
void SPIDEVClass::usingInterrupt(uint8_t interruptNumber)
{
(void)interruptNumber;
}
void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
void SPIDEVClass::notUsingInterrupt(uint8_t interruptNumber)
{
(void)interruptNumber;
}
void SPIClass::init()
void SPIDEVClass::init()
{
pthread_mutex_lock(&spiMutex);
@@ -19,8 +19,8 @@
* Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
*/
#ifndef SPI_H
#define SPI_H
#ifndef SPIDEV_h
#define SPIDEV_h
#include <stdint.h>
#include <string>
@@ -102,17 +102,20 @@ private:
dmode = dataMode;
}
friend class SPIClass;
friend class SPIDEVClass;
};
class SPIClass
/**
* SPIDEV class
*/
class SPIDEVClass
{
public:
/**
* @brief SPIClass constructor.
* @brief SPIDEVClass constructor.
*/
SPIClass();
SPIDEVClass();
/**
* @brief Start SPI operations.
*/
@@ -201,6 +204,6 @@ private:
static void init();
};
extern SPIClass SPI;
extern SPIDEVClass SPIDEV;
#endif
-281
View File
@@ -1,281 +0,0 @@
/*
Copyright (c) 2012-2016 Ben Croston
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "cpuinfo.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int get_rpi_info(rpi_info *info)
{
FILE *fp;
char buffer[1024];
char hardware[1024];
char revision[1024];
char *rev;
int found = 0;
int len;
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL) {
return -1;
}
while(!feof(fp)) {
fgets(buffer, sizeof(buffer), fp);
sscanf(buffer, "Hardware : %s", hardware);
if (strcmp(hardware, "BCM2708") == 0 ||
strcmp(hardware, "BCM2709") == 0 ||
strcmp(hardware, "BCM2835") == 0 ||
strcmp(hardware, "BCM2836") == 0 ||
strcmp(hardware, "BCM2837") == 0 ) {
found = 1;
}
sscanf(buffer, "Revision : %s", revision);
}
fclose(fp);
if (!found) {
return -1;
}
if ((len = strlen(revision)) == 0) {
return -1;
}
if (len >= 6 && strtol((char[]) {
revision[len-6],0
}, NULL, 16) & 8) {
// new scheme
//info->rev = revision[len-1]-'0';
strcpy(info->revision, revision);
switch (revision[len-2]) {
case '0':
info->type = "Model A";
info->p1_revision = 2;
break;
case '1':
info->type = "Model B";
info->p1_revision = 2;
break;
case '2':
info->type = "Model A+";
info->p1_revision = 3;
break;
case '3':
info->type = "Model B+";
info->p1_revision = 3;
break;
case '4':
info->type = "Pi 2 Model B";
info->p1_revision = 3;
break;
case '5':
info->type = "Alpha";
info->p1_revision = 3;
break;
case '6':
info->type = "Compute";
info->p1_revision = 0;
break;
case '8':
info->type = "Pi 3 Model B";
info->p1_revision = 3;
break;
case '9':
info->type = "Zero";
info->p1_revision = 3;
break;
default :
info->type = "Unknown";
info->p1_revision = 3;
break;
}
switch (revision[len-4]) {
case '0':
info->processor = "BCM2835";
break;
case '1':
info->processor = "BCM2836";
break;
case '2':
info->processor = "BCM2837";
break;
default :
info->processor = "Unknown";
break;
}
switch (revision[len-5]) {
case '0':
info->manufacturer = "Sony";
break;
case '1':
info->manufacturer = "Egoman";
break;
case '2':
info->manufacturer = "Embest";
break;
case '4':
info->manufacturer = "Embest";
break;
default :
info->manufacturer = "Unknown";
break;
}
switch (strtol((char[]) {
revision[len-6],0
}, NULL, 16) & 7) {
case 0:
info->ram = "256M";
break;
case 1:
info->ram = "512M";
break;
case 2:
info->ram = "1024M";
break;
default:
info->ram = "Unknown";
break;
}
}
else {
// old scheme
info->ram = "Unknown";
info->manufacturer = "Unknown";
info->processor = "Unknown";
info->type = "Unknown";
strcpy(info->revision, revision);
// get last four characters (ignore preceeding 1000 for overvolt)
if (len > 4) {
rev = (char *)&revision+len-4;
} else {
rev = revision;
}
if ((strcmp(rev, "0002") == 0) ||
(strcmp(rev, "0003") == 0)) {
info->type = "Model B";
info->p1_revision = 1;
info->ram = "256M";
info->processor = "BCM2835";
} else if (strcmp(rev, "0004") == 0) {
info->type = "Model B";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Sony";
info->processor = "BCM2835";
} else if (strcmp(rev, "0005") == 0) {
info->type = "Model B";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Qisda";
info->processor = "BCM2835";
} else if (strcmp(rev, "0006") == 0) {
info->type = "Model B";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Egoman";
info->processor = "BCM2835";
} else if (strcmp(rev, "0007") == 0) {
info->type = "Model A";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Egoman";
info->processor = "BCM2835";
} else if (strcmp(rev, "0008") == 0) {
info->type = "Model A";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Sony";
info->processor = "BCM2835";
} else if (strcmp(rev, "0009") == 0) {
info->type = "Model A";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Qisda";
info->processor = "BCM2835";
} else if (strcmp(rev, "000d") == 0) {
info->type = "Model B";
info->p1_revision = 2;
info->ram = "512M";
info->manufacturer = "Egoman";
info->processor = "BCM2835";
} else if (strcmp(rev, "000e") == 0) {
info->type = "Model B";
info->p1_revision = 2;
info->ram = "512M";
info->manufacturer = "Sony";
info->processor = "BCM2835";
} else if (strcmp(rev, "000f") == 0) {
info->type = "Model B";
info->p1_revision = 2;
info->ram = "512M";
info->manufacturer = "Qisda";
info->processor = "BCM2835";
} else if ((strcmp(rev, "0011") == 0) ||
(strcmp(rev, "0014") == 0)) {
info->type = "Compute Module";
info->p1_revision = 0;
info->ram = "512M";
info->processor = "BCM2835";
} else if (strcmp(rev, "0012") == 0) {
info->type = "Model A+";
info->p1_revision = 3;
info->ram = "256M";
info->processor = "BCM2835";
} else if ((strcmp(rev, "0010") == 0) ||
(strcmp(rev, "0013") == 0)) {
info->type = "Model B+";
info->p1_revision = 3;
info->ram = "512M";
info->processor = "BCM2835";
} else { // don't know - assume revision 3 p1 connector
info->p1_revision = 3;
}
}
return 0;
}
/*
32 bits
NEW 23: will be 1 for the new scheme, 0 for the old scheme
MEMSIZE 20: 0=256M 1=512M 2=1G
MANUFACTURER 16: 0=SONY 1=EGOMAN
PROCESSOR 12: 0=2835 1=2836
TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODEL B 5=ALPHA 6=CM
REV 00: 0=REV0 1=REV1 2=REV2
pi2 = 1<<23 | 2<<20 | 1<<12 | 4<<4 = 0xa01040
--------------------
SRRR MMMM PPPP TTTT TTTT VVVV
S scheme (0=old, 1=new)
R RAM (0=256, 1=512, 2=1024)
M manufacturer (0='SONY',1='EGOMAN',2='EMBEST',3='UNKNOWN',4='EMBEST')
P processor (0=2835, 1=2836 2=2837)
T type (0='A', 1='B', 2='A+', 3='B+', 4='Pi 2 B', 5='Alpha', 6='Compute Module')
V revision (0-15)
*/
-47
View File
@@ -1,47 +0,0 @@
/*
Copyright (c) 2012-2015 Ben Croston
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef CPUINFO_H
#define CPUINFO_H
#if !DOXYGEN
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int p1_revision;
char *ram;
char *manufacturer;
char *processor;
char *type;
char revision[1024];
} rpi_info;
int get_rpi_info(rpi_info *info);
#ifdef __cplusplus
}
#endif
#endif
#endif /* CPUINFO_H */