Linux: Add support for SPIDEV (#734)
RPi and Linux refactor. Add GPIO Sysfs for GPIO operations. Update configure script. Fix some cppcheck warnings. Add serial emulation that prints to stdout. Fix some file headers.
This commit is contained in:
committed by
Henrik Ekblad
parent
aa5cecfca1
commit
2e0f6b6229
+39
-4
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* 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 Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
@@ -14,10 +33,21 @@
|
||||
#include "stdlib_noniso.h"
|
||||
|
||||
#ifdef LINUX_ARCH_RASPBERRYPI
|
||||
#include "rpi_util.h"
|
||||
using namespace rpi_util;
|
||||
#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)
|
||||
#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)
|
||||
#endif
|
||||
|
||||
#include "interrupt.h"
|
||||
|
||||
#undef PSTR
|
||||
#define PSTR(x) (x)
|
||||
#undef F
|
||||
@@ -57,7 +87,11 @@ using namespace rpi_util;
|
||||
#define random(...) GET_MACRO(_0, ##__VA_ARGS__, randMinMax, randMax, rand)(__VA_ARGS__)
|
||||
|
||||
#ifndef delay
|
||||
#define delay _delay_ms
|
||||
#define delay _delay_milliseconds
|
||||
#endif
|
||||
|
||||
#ifndef delayMicroseconds
|
||||
#define delayMicroseconds _delay_microseconds
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
@@ -73,7 +107,8 @@ typedef char __FlashStringHelper;
|
||||
void yield(void);
|
||||
unsigned long millis(void);
|
||||
unsigned long micros(void);
|
||||
void _delay_ms(unsigned int millis);
|
||||
void _delay_milliseconds(unsigned int millis);
|
||||
void _delay_microseconds(unsigned int micro);
|
||||
void randomSeed(unsigned long seed);
|
||||
long randMax(long howbig);
|
||||
long randMinMax(long howsmall, long howbig);
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
@@ -103,7 +103,6 @@ size_t EthernetClient::write(uint8_t b)
|
||||
|
||||
size_t EthernetClient::write(const uint8_t *buf, size_t size)
|
||||
{
|
||||
int rc = 0;
|
||||
int bytes = 0;
|
||||
|
||||
if (_sock == -1) {
|
||||
@@ -111,7 +110,7 @@ size_t EthernetClient::write(const uint8_t *buf, size_t size)
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
rc = send(_sock, buf + bytes, size, MSG_NOSIGNAL | MSG_DONTWAIT);
|
||||
int rc = send(_sock, buf + bytes, size, MSG_NOSIGNAL | MSG_DONTWAIT);
|
||||
if (rc == -1) {
|
||||
logError("send: %s\n", strerror(errno));
|
||||
close(_sock);
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
@@ -43,9 +43,6 @@
|
||||
class EthernetClient : public Client
|
||||
{
|
||||
|
||||
private:
|
||||
int _sock; //!< @brief Network socket.
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief EthernetClient constructor.
|
||||
@@ -56,7 +53,7 @@ public:
|
||||
*
|
||||
* @param sock Network socket.
|
||||
*/
|
||||
EthernetClient(int sock);
|
||||
explicit EthernetClient(int sock);
|
||||
/**
|
||||
* @brief Initiate a connection with host:port.
|
||||
*
|
||||
@@ -196,6 +193,9 @@ public:
|
||||
};
|
||||
|
||||
friend class EthernetServer;
|
||||
|
||||
private:
|
||||
int _sock; //!< @brief Network socket.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "EthernetServer.h"
|
||||
|
||||
EthernetServer::EthernetServer(uint16_t port, uint16_t max_clients) : port(port),
|
||||
max_clients(max_clients)
|
||||
max_clients(max_clients), sockfd(-1)
|
||||
{
|
||||
clients.reserve(max_clients);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
@@ -42,19 +42,6 @@ class EthernetClient;
|
||||
class EthernetServer : public Server
|
||||
{
|
||||
|
||||
private:
|
||||
uint16_t port; //!< @brief Port number for the network socket.
|
||||
std::list<int> new_clients; //!< Socket list of new clients.
|
||||
std::vector<int> clients; //!< @brief Socket list of clients.
|
||||
uint16_t max_clients; //!< @brief The maximum number of allowed clients.
|
||||
int sockfd; //!< @brief Network socket used to accept connections.
|
||||
|
||||
/**
|
||||
* @brief Accept new clients if the total of connected clients is below max_clients.
|
||||
*
|
||||
*/
|
||||
void _accept();
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief EthernetServer constructor.
|
||||
@@ -116,6 +103,19 @@ public:
|
||||
* @return 0 if FAILURE else the number of characters sent.
|
||||
*/
|
||||
size_t write(const char *buffer, size_t size);
|
||||
|
||||
private:
|
||||
uint16_t port; //!< @brief Port number for the network socket.
|
||||
std::list<int> new_clients; //!< Socket list of new clients.
|
||||
std::vector<int> clients; //!< @brief Socket list of clients.
|
||||
uint16_t max_clients; //!< @brief The maximum number of allowed clients.
|
||||
int sockfd; //!< @brief Network socket used to accept connections.
|
||||
|
||||
/**
|
||||
* @brief Accept new clients if the total of connected clients is below max_clients.
|
||||
*
|
||||
*/
|
||||
void _accept();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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 "GPIO.h"
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "log.h"
|
||||
|
||||
// Declare a single default instance
|
||||
GPIO gpio = GPIO();
|
||||
|
||||
GPIO::GPIO()
|
||||
{
|
||||
FILE *f;
|
||||
DIR* dp;
|
||||
char file[64];
|
||||
|
||||
dp = opendir("/sys/class/gpio");
|
||||
if (dp == NULL) {
|
||||
logError("Could not open /sys/class/gpio directory");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lastPinNum = 0;
|
||||
|
||||
while (true) {
|
||||
dirent *de = readdir(dp);
|
||||
if (de == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp("gpiochip", de->d_name, 8) == 0) {
|
||||
sprintf(file, "/sys/class/gpio/%s/base", de->d_name);
|
||||
f = fopen(file, "r");
|
||||
int base;
|
||||
if (fscanf(f, "%d", &base) == EOF) {
|
||||
logError("Failed to open %s\n", file);
|
||||
base = 0;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
sprintf(file, "/sys/class/gpio/%s/ngpio", de->d_name);
|
||||
f = fopen(file, "r");
|
||||
int ngpio;
|
||||
if (fscanf(f, "%d", &ngpio) == EOF) {
|
||||
logError("Failed to open %s\n", file);
|
||||
ngpio = 0;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
int max = ngpio + base - 1;
|
||||
if (lastPinNum < max) {
|
||||
lastPinNum = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
|
||||
exportedPins = new uint8_t[lastPinNum + 1];
|
||||
|
||||
for (int i = 0; i < lastPinNum + 1; ++i) {
|
||||
exportedPins[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GPIO::GPIO(const GPIO& other)
|
||||
{
|
||||
lastPinNum = other.lastPinNum;
|
||||
|
||||
exportedPins = new uint8_t[lastPinNum + 1];
|
||||
for (int i = 0; i < lastPinNum + 1; ++i) {
|
||||
exportedPins[i] = other.exportedPins[i];
|
||||
}
|
||||
}
|
||||
|
||||
GPIO::~GPIO()
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
for (int i = 0; i < lastPinNum + 1; ++i) {
|
||||
if (exportedPins[i]) {
|
||||
f = fopen("/sys/class/gpio/unexport", "w");
|
||||
fprintf(f, "%d\n", i);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
delete [] exportedPins;
|
||||
}
|
||||
|
||||
void GPIO::pinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if (pin > lastPinNum) {
|
||||
return;
|
||||
}
|
||||
|
||||
f = fopen("/sys/class/gpio/export", "w");
|
||||
fprintf(f, "%d\n", pin);
|
||||
fclose(f);
|
||||
|
||||
int counter = 0;
|
||||
char file[128];
|
||||
sprintf(file, "/sys/class/gpio/gpio%d/direction", pin);
|
||||
|
||||
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) {
|
||||
logError("Could not open /sys/class/gpio/gpio%u/direction", pin);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (mode == INPUT) {
|
||||
fprintf(f, "in\n");
|
||||
} else {
|
||||
fprintf(f, "out\n");
|
||||
}
|
||||
|
||||
exportedPins[pin] = 1;
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void GPIO::digitalWrite(uint8_t pin, uint8_t value)
|
||||
{
|
||||
FILE *f;
|
||||
char file[128];
|
||||
|
||||
if (pin > lastPinNum) {
|
||||
return;
|
||||
}
|
||||
if (0 == exportedPins[pin]) {
|
||||
pinMode(pin, OUTPUT);
|
||||
}
|
||||
|
||||
sprintf(file, "/sys/class/gpio/gpio%d/value", pin);
|
||||
f = fopen(file, "w");
|
||||
|
||||
if (value == 0) {
|
||||
fprintf(f, "0\n");
|
||||
} else {
|
||||
fprintf(f, "1\n");
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
uint8_t GPIO::digitalRead(uint8_t pin)
|
||||
{
|
||||
FILE *f;
|
||||
char file[128];
|
||||
|
||||
if (pin > lastPinNum) {
|
||||
return 0;
|
||||
}
|
||||
if (0 == exportedPins[pin]) {
|
||||
pinMode(pin, INPUT);
|
||||
}
|
||||
|
||||
sprintf(file, "/sys/class/gpio/gpio%d/value", pin);
|
||||
f = fopen(file, "r");
|
||||
|
||||
int i;
|
||||
if (fscanf(f, "%d", &i) == EOF) {
|
||||
logError("digitalRead: failed to read pin %u\n", pin);
|
||||
i = 0;
|
||||
}
|
||||
fclose(f);
|
||||
return i;
|
||||
}
|
||||
|
||||
uint8_t GPIO::digitalPinToInterrupt(uint8_t pin)
|
||||
{
|
||||
return pin;
|
||||
}
|
||||
|
||||
GPIO& GPIO::operator=(const GPIO& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
lastPinNum = other.lastPinNum;
|
||||
|
||||
exportedPins = new uint8_t[lastPinNum + 1];
|
||||
for (int i = 0; i < lastPinNum + 1; ++i) {
|
||||
exportedPins[i] = other.exportedPins[i];
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 GPIO_h
|
||||
#define GPIO_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define INPUT 0
|
||||
#define OUTPUT 1
|
||||
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
|
||||
/**
|
||||
* @brief GPIO class
|
||||
*/
|
||||
class GPIO
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief GPIO constructor.
|
||||
*/
|
||||
GPIO();
|
||||
/**
|
||||
* @brief GPIO copy constructor.
|
||||
*/
|
||||
GPIO(const GPIO& other);
|
||||
/**
|
||||
* @brief GPIO destructor.
|
||||
*/
|
||||
~GPIO();
|
||||
/**
|
||||
* @brief Configures the specified pin to behave either as an input or an output.
|
||||
*
|
||||
* @param pin The number of the pin.
|
||||
* @param mode INPUT or OUTPUT.
|
||||
*/
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
/**
|
||||
* @brief Write a high or a low value for the given pin.
|
||||
*
|
||||
* @param pin number.
|
||||
* @param value HIGH or LOW.
|
||||
*/
|
||||
void digitalWrite(uint8_t pin, uint8_t value);
|
||||
/**
|
||||
* @brief Reads the value from a specified pin.
|
||||
*
|
||||
* @param pin The number of the pin.
|
||||
* @return HIGH or LOW.
|
||||
*/
|
||||
uint8_t digitalRead(uint8_t pin);
|
||||
/**
|
||||
* @brief Arduino compatibility function, returns the same given pin.
|
||||
*
|
||||
* @param pin The number of the pin.
|
||||
* @return The same parameter pin number.
|
||||
*/
|
||||
uint8_t digitalPinToInterrupt(uint8_t pin);
|
||||
/**
|
||||
* @brief Overloaded assign operator.
|
||||
*
|
||||
*/
|
||||
GPIO& operator=(const GPIO& other);
|
||||
|
||||
private:
|
||||
int lastPinNum; //!< @brief Highest pin number supported.
|
||||
uint8_t *exportedPins; //!< @brief Array with information of which pins were exported.
|
||||
};
|
||||
|
||||
extern GPIO gpio;
|
||||
|
||||
#endif
|
||||
@@ -70,13 +70,13 @@ public:
|
||||
*
|
||||
* @param address to be set from a 32 bits integer.
|
||||
*/
|
||||
IPAddress(uint32_t address);
|
||||
explicit IPAddress(uint32_t address);
|
||||
/**
|
||||
* @brief IPAddress constructor.
|
||||
*
|
||||
* @param address to be set from a byte array.
|
||||
*/
|
||||
IPAddress(const uint8_t *address);
|
||||
explicit IPAddress(const uint8_t *address);
|
||||
/**
|
||||
* @brief Set the IP from a array of characters.
|
||||
*
|
||||
|
||||
@@ -210,9 +210,9 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
|
||||
}
|
||||
|
||||
do {
|
||||
unsigned long m = n;
|
||||
char c = n % base;
|
||||
n /= base;
|
||||
char c = m - base * n;
|
||||
|
||||
*--str = c < 10 ? c + '0' : c + 'A' - 10;
|
||||
} while(n);
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
@@ -179,25 +179,23 @@ bool SerialPort::open(int bauds)
|
||||
|
||||
bool SerialPort::setGroupPerm(const char *groupName)
|
||||
{
|
||||
struct group* devGrp;
|
||||
const mode_t ttyPermissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||
const char *dev;
|
||||
int ret;
|
||||
|
||||
if (sd != -1 && groupName != NULL) {
|
||||
devGrp = getgrnam(groupName);
|
||||
struct group *devGrp = getgrnam(groupName);
|
||||
if (devGrp == NULL) {
|
||||
logError("getgrnam: %s failed. (%d) %s\n", groupName, errno, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *dev;
|
||||
if (isPty) {
|
||||
dev = ptsname(sd);
|
||||
} else {
|
||||
dev = serialPort.c_str();
|
||||
}
|
||||
|
||||
ret = chown(dev, -1, devGrp->gr_gid);
|
||||
int ret = chown(dev, -1, devGrp->gr_gid);
|
||||
if (ret == -1) {
|
||||
logError("Could not change PTY owner! (%d) %s\n", errno, strerror(errno));
|
||||
return false;
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include "SerialSimulator.h"
|
||||
|
||||
void SerialSimulator::begin(int baud)
|
||||
{
|
||||
(void)baud;
|
||||
}
|
||||
|
||||
int SerialSimulator::available()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SerialSimulator::read()
|
||||
{
|
||||
return getchar();
|
||||
}
|
||||
|
||||
size_t SerialSimulator::write(uint8_t b)
|
||||
{
|
||||
return (size_t)::printf("%c", b);
|
||||
}
|
||||
|
||||
int SerialSimulator::peek()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SerialSimulator::flush()
|
||||
{
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void SerialSimulator::end()
|
||||
{
|
||||
flush();
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#ifndef SerialSimulator_h
|
||||
#define SerialSimulator_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "Stream.h"
|
||||
|
||||
/**
|
||||
* @brief A class equivalent to Serial in Arduino but outputs to stdout
|
||||
*/
|
||||
class SerialSimulator : public Stream
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief This function does nothing.
|
||||
*
|
||||
* @param baud Ignored parameter.
|
||||
*/
|
||||
void begin(int baud);
|
||||
/**
|
||||
* @brief This function does nothing.
|
||||
*
|
||||
* @return always returns 1.
|
||||
*/
|
||||
int available();
|
||||
/**
|
||||
* @brief Reads 1 key pressed from the keyboard.
|
||||
*
|
||||
* @return key character pressed cast to an int.
|
||||
*/
|
||||
int read();
|
||||
/**
|
||||
* @brief Writes a single byte to stdout.
|
||||
*
|
||||
* @param b byte to write.
|
||||
* @return -1 if error else, number of bytes written.
|
||||
*/
|
||||
size_t write(uint8_t b);
|
||||
/**
|
||||
* @brief Not supported.
|
||||
*
|
||||
* @return always returns -1.
|
||||
*/
|
||||
int peek();
|
||||
/**
|
||||
* @brief Flush stdout.
|
||||
*/
|
||||
void flush();
|
||||
/**
|
||||
* @brief Nothing to do, flush stdout.
|
||||
*/
|
||||
void end();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
/*
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
/*
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
* 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
|
||||
@@ -33,11 +33,6 @@
|
||||
class SoftEeprom
|
||||
{
|
||||
|
||||
private:
|
||||
size_t _length; //!< @brief Eeprom max size.
|
||||
char *_fileName; //!< @brief file where the eeprom values are stored.
|
||||
uint8_t *_values; //!< @brief copy of the eeprom values held in memory for a faster reading.
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief SoftEeprom constructor.
|
||||
@@ -86,6 +81,11 @@ public:
|
||||
*
|
||||
*/
|
||||
SoftEeprom& operator=(const SoftEeprom& other);
|
||||
|
||||
private:
|
||||
size_t _length; //!< @brief Eeprom max size.
|
||||
char *_fileName; //!< @brief file where the eeprom values are stored.
|
||||
uint8_t *_values; //!< @brief copy of the eeprom values held in memory for a faster reading.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
Stream()
|
||||
{
|
||||
_timeout = 1000;
|
||||
_startMillis = 0;
|
||||
}
|
||||
|
||||
// parsing methods
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* 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 <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
@@ -34,7 +53,7 @@ unsigned long micros()
|
||||
return ((curTime.tv_sec - millis_at_start) * 1000000) + (curTime.tv_usec);
|
||||
}
|
||||
|
||||
void _delay_ms(unsigned int millis)
|
||||
void _delay_milliseconds(unsigned int millis)
|
||||
{
|
||||
struct timespec sleeper;
|
||||
|
||||
@@ -43,6 +62,15 @@ void _delay_ms(unsigned int millis)
|
||||
nanosleep(&sleeper, NULL);
|
||||
}
|
||||
|
||||
void _delay_microseconds(unsigned int micro)
|
||||
{
|
||||
struct timespec sleeper;
|
||||
|
||||
sleeper.tv_sec = (time_t)(micro / 1000000);
|
||||
sleeper.tv_nsec = (long)(micro % 1000000) * 1000;
|
||||
nanosleep(&sleeper, NULL);
|
||||
}
|
||||
|
||||
void randomSeed(unsigned long seed)
|
||||
{
|
||||
if (seed != 0) {
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Based on wiringPi Copyright (c) 2012 Gordon Henderson.
|
||||
*/
|
||||
|
||||
#include "interrupt.h"
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stropts.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include "log.h"
|
||||
|
||||
struct ThreadArgs {
|
||||
void (*func)();
|
||||
int gpioPin;
|
||||
};
|
||||
|
||||
volatile bool interruptsEnabled = true;
|
||||
static pthread_mutex_t intMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static pthread_t *threadIds[64] = {NULL};
|
||||
|
||||
// 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,
|
||||
};
|
||||
|
||||
/*
|
||||
* Part of wiringPi: Simple way to get your program running at high priority
|
||||
* with realtime schedulling.
|
||||
*/
|
||||
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 *args)
|
||||
{
|
||||
int fd;
|
||||
struct pollfd polls;
|
||||
char c;
|
||||
struct ThreadArgs *arguments = (struct ThreadArgs *)args;
|
||||
int gpioPin = arguments->gpioPin;
|
||||
void (*func)() = arguments->func;
|
||||
delete arguments;
|
||||
|
||||
(void)piHiPri(55); // Only effective if we run as root
|
||||
|
||||
if ((fd = sysFds[gpioPin]) == -1) {
|
||||
logError("Failed to attach interrupt for pin %d\n", gpioPin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Setup poll structure
|
||||
polls.fd = fd;
|
||||
polls.events = POLLPRI;
|
||||
|
||||
while (1) {
|
||||
// Wait for it ...
|
||||
int ret = poll(&polls, 1, -1);
|
||||
if (ret < 0) {
|
||||
logError("Error waiting for interrupt: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
// Do a dummy read to clear the interrupt
|
||||
// A one character read appars to be enough.
|
||||
// Followed by a seek to reset it.
|
||||
if (read (fd, &c, 1) < 0) {
|
||||
logError("Interrupt handler error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if (lseek (fd, 0, SEEK_SET) < 0) {
|
||||
logError("Interrupt handler error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
// Call user function.
|
||||
pthread_mutex_lock(&intMutex);
|
||||
if (interruptsEnabled) {
|
||||
pthread_mutex_unlock(&intMutex);
|
||||
func();
|
||||
} else {
|
||||
pthread_mutex_unlock(&intMutex);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void attachInterrupt(uint8_t gpioPin, void (*func)(), uint8_t mode)
|
||||
{
|
||||
FILE *fd;
|
||||
char fName[40];
|
||||
char c;
|
||||
int count, i;
|
||||
|
||||
if (threadIds[gpioPin] == NULL) {
|
||||
threadIds[gpioPin] = new pthread_t;
|
||||
} else {
|
||||
// Cancel the existing thread for that pin
|
||||
pthread_cancel(*threadIds[gpioPin]);
|
||||
// Wait a bit
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
// Export pin for interrupt
|
||||
if ((fd = fopen("/sys/class/gpio/export", "w")) == NULL) {
|
||||
logError("attachInterrupt: Unable to export pin %d for interrupt: %s\n", gpioPin, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
fprintf(fd, "%d\n", gpioPin);
|
||||
fclose(fd);
|
||||
|
||||
// Wait a bit the system to create /sys/class/gpio/gpio<GPIO number>
|
||||
usleep(1000);
|
||||
|
||||
snprintf(fName, sizeof(fName), "/sys/class/gpio/gpio%d/direction", gpioPin) ;
|
||||
if ((fd = fopen (fName, "w")) == NULL) {
|
||||
logError("attachInterrupt: Unable to open GPIO direction interface for pin %d: %s\n",
|
||||
gpioPin, strerror(errno));
|
||||
exit(1) ;
|
||||
}
|
||||
fprintf(fd, "in\n") ;
|
||||
fclose(fd) ;
|
||||
|
||||
snprintf(fName, sizeof(fName), "/sys/class/gpio/gpio%d/edge", gpioPin) ;
|
||||
if ((fd = fopen(fName, "w")) == NULL) {
|
||||
logError("attachInterrupt: Unable to open GPIO edge interface for pin %d: %s\n", gpioPin,
|
||||
strerror(errno));
|
||||
exit(1) ;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case CHANGE:
|
||||
fprintf(fd, "both\n");
|
||||
break;
|
||||
case FALLING:
|
||||
fprintf(fd, "falling\n");
|
||||
break;
|
||||
case RISING:
|
||||
fprintf(fd, "rising\n");
|
||||
break;
|
||||
case NONE:
|
||||
fprintf(fd, "none\n");
|
||||
break;
|
||||
default:
|
||||
logError("attachInterrupt: Invalid mode\n");
|
||||
fclose(fd);
|
||||
return;
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
if (sysFds[gpioPin] == -1) {
|
||||
snprintf(fName, sizeof(fName), "/sys/class/gpio/gpio%d/value", gpioPin);
|
||||
if ((sysFds[gpioPin] = open(fName, O_RDWR)) < 0) {
|
||||
logError("Error reading pin %d: %s\n", gpioPin, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear any initial pending interrupt
|
||||
ioctl(sysFds[gpioPin], FIONREAD, &count);
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (read(sysFds[gpioPin], &c, 1) == -1) {
|
||||
logError("attachInterrupt: failed to read pin status: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
struct ThreadArgs *threadArgs = new struct ThreadArgs;
|
||||
threadArgs->func = func;
|
||||
threadArgs->gpioPin = gpioPin;
|
||||
|
||||
// Create a thread passing the pin and function
|
||||
pthread_create(threadIds[gpioPin], NULL, interruptHandler, (void *)threadArgs);
|
||||
}
|
||||
|
||||
void detachInterrupt(uint8_t gpioPin)
|
||||
{
|
||||
// Cancel the thread
|
||||
if (threadIds[gpioPin] != NULL) {
|
||||
pthread_cancel(*threadIds[gpioPin]);
|
||||
delete threadIds[gpioPin];
|
||||
threadIds[gpioPin] = NULL;
|
||||
}
|
||||
|
||||
// Close filehandle
|
||||
if (sysFds[gpioPin] != -1) {
|
||||
close(sysFds[gpioPin]);
|
||||
sysFds[gpioPin] = -1;
|
||||
}
|
||||
|
||||
FILE *fp = fopen("/sys/class/gpio/unexport", "w");
|
||||
if (fp == NULL) {
|
||||
logError("Unable to unexport pin %d for interrupt\n", gpioPin);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(fp, "%d", gpioPin);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void interrupts()
|
||||
{
|
||||
pthread_mutex_lock(&intMutex);
|
||||
interruptsEnabled = true;
|
||||
pthread_mutex_unlock(&intMutex);
|
||||
}
|
||||
|
||||
void noInterrupts()
|
||||
{
|
||||
pthread_mutex_lock(&intMutex);
|
||||
interruptsEnabled = false;
|
||||
pthread_mutex_unlock(&intMutex);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Based on wiringPi Copyright (c) 2012 Gordon Henderson.
|
||||
*/
|
||||
|
||||
#ifndef interrupt_h
|
||||
#define interrupt_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CHANGE 1
|
||||
#define FALLING 2
|
||||
#define RISING 3
|
||||
#define NONE 4
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void attachInterrupt(uint8_t gpioPin, void(*func)(), uint8_t mode);
|
||||
void detachInterrupt(uint8_t gpioPin);
|
||||
void interrupts();
|
||||
void noInterrupts();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* 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 "log.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* 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 LOG_H
|
||||
#define LOG_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user