diff --git a/Makefile b/Makefile index a0a4bd9..66f31ae 100644 --- a/Makefile +++ b/Makefile @@ -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, \ diff --git a/configure b/configure index e80113e..f4a15eb 100755 --- a/configure +++ b/configure @@ -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= CPU defining/optimizing flags to be used. [configure autodetected] --extra-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 diff --git a/drivers/BCM/BCM.cpp b/drivers/BCM/BCM.cpp new file mode 100644 index 0000000..cb9acd9 --- /dev/null +++ b/drivers/BCM/BCM.cpp @@ -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 + * 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 +#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); +} diff --git a/drivers/BCM/BCM.h b/drivers/BCM/BCM.h new file mode 100644 index 0000000..c591968 --- /dev/null +++ b/drivers/BCM/BCM.h @@ -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 + * 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 +#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 diff --git a/drivers/RPi/RPi.cpp b/drivers/BCM/RPi.cpp similarity index 63% rename from drivers/RPi/RPi.cpp rename to drivers/BCM/RPi.cpp index 566eb44..86a792c 100644 --- a/drivers/RPi/RPi.cpp +++ b/drivers/BCM/RPi.cpp @@ -19,6 +19,7 @@ #include "RPi.h" #include +#include #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; diff --git a/drivers/RPi/RPi.h b/drivers/BCM/RPi.h similarity index 88% rename from drivers/RPi/RPi.h rename to drivers/BCM/RPi.h index 5173c1f..2c6b32c 100644 --- a/drivers/RPi/RPi.h +++ b/drivers/BCM/RPi.h @@ -21,27 +21,15 @@ #define RPi_h #include -#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 diff --git a/drivers/BCM/SPI.cpp b/drivers/BCM/SPIBCM.cpp similarity index 78% rename from drivers/BCM/SPI.cpp rename to drivers/BCM/SPIBCM.cpp index ea8273b..cc0180c 100644 --- a/drivers/BCM/SPI.cpp +++ b/drivers/BCM/SPIBCM.cpp @@ -19,7 +19,7 @@ * Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard */ -#include "SPI.h" +#include "SPIBCM.h" #include #include #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; } diff --git a/drivers/BCM/SPI.h b/drivers/BCM/SPIBCM.h similarity index 95% rename from drivers/BCM/SPI.h rename to drivers/BCM/SPIBCM.h index bcb2c4e..1d353ad 100644 --- a/drivers/BCM/SPI.h +++ b/drivers/BCM/SPIBCM.h @@ -19,12 +19,12 @@ * Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard */ -#ifndef _SPI_H_ -#define _SPI_H_ +#ifndef SPIBCM_h +#define SPIBCM_h #include #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 diff --git a/drivers/BCM/Wire.h b/drivers/BCM/Wire.h index 065ab79..3b129da 100644 --- a/drivers/BCM/Wire.h +++ b/drivers/BCM/Wire.h @@ -28,7 +28,7 @@ #if !DOXYGEN #include #include "Stream.h" -#include "RPi.h" +#include "BCM.h" #define BUFFER_LENGTH 32 diff --git a/drivers/RPi/bcm2835.c b/drivers/BCM/bcm2835.c similarity index 100% rename from drivers/RPi/bcm2835.c rename to drivers/BCM/bcm2835.c diff --git a/drivers/RPi/bcm2835.h b/drivers/BCM/bcm2835.h similarity index 100% rename from drivers/RPi/bcm2835.h rename to drivers/BCM/bcm2835.h diff --git a/drivers/Linux/Arduino.h b/drivers/Linux/Arduino.h index 54c0765..dd736ac 100644 --- a/drivers/Linux/Arduino.h +++ b/drivers/Linux/Arduino.h @@ -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" diff --git a/drivers/Linux/GPIO.cpp b/drivers/Linux/GPIO.cpp index d8fba28..c8e44c7 100644 --- a/drivers/Linux/GPIO.cpp +++ b/drivers/Linux/GPIO.cpp @@ -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; diff --git a/drivers/Linux/GPIO.h b/drivers/Linux/GPIO.h index e3d9a40..1a962d1 100644 --- a/drivers/Linux/GPIO.h +++ b/drivers/Linux/GPIO.h @@ -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 diff --git a/drivers/Linux/SPI.h b/drivers/Linux/SPI.h new file mode 100644 index 0000000..8efbcc3 --- /dev/null +++ b/drivers/Linux/SPI.h @@ -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 + * 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 diff --git a/drivers/SPIDEV/SPI.cpp b/drivers/Linux/SPIDEV.cpp similarity index 81% rename from drivers/SPIDEV/SPI.cpp rename to drivers/Linux/SPIDEV.cpp index 2f6c5b3..5e77303 100644 --- a/drivers/SPIDEV/SPI.cpp +++ b/drivers/Linux/SPIDEV.cpp @@ -19,7 +19,7 @@ * Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard */ -#include "SPI.h" +#include "SPIDEV.h" #include #include #include @@ -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); diff --git a/drivers/SPIDEV/SPI.h b/drivers/Linux/SPIDEV.h similarity index 96% rename from drivers/SPIDEV/SPI.h rename to drivers/Linux/SPIDEV.h index 8e40034..fa89525 100644 --- a/drivers/SPIDEV/SPI.h +++ b/drivers/Linux/SPIDEV.h @@ -19,8 +19,8 @@ * Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard */ -#ifndef SPI_H -#define SPI_H +#ifndef SPIDEV_h +#define SPIDEV_h #include #include @@ -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 diff --git a/drivers/RPi/cpuinfo.c b/drivers/RPi/cpuinfo.c deleted file mode 100644 index 8c16a0d..0000000 --- a/drivers/RPi/cpuinfo.c +++ /dev/null @@ -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 -#include -#include - -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) - -*/ diff --git a/drivers/RPi/cpuinfo.h b/drivers/RPi/cpuinfo.h deleted file mode 100644 index dc32f44..0000000 --- a/drivers/RPi/cpuinfo.h +++ /dev/null @@ -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 */