Add support for RaspberryPi
This commit is contained in:
committed by
Marcelo Aquino
parent
c7efee31dd
commit
35cab8c26d
@@ -0,0 +1,67 @@
|
||||
##########################################################################
|
||||
# Configurable options #
|
||||
##########################################################################
|
||||
# Install Base location
|
||||
PREFIX=/usr/local
|
||||
# Bin Dir
|
||||
BINDIR=$(PREFIX)/sbin
|
||||
|
||||
##########################################################################
|
||||
# Please do not change anything below this line #
|
||||
##########################################################################
|
||||
CXX ?= g++
|
||||
|
||||
ifeq "$(shell uname -m)" "armv6l"
|
||||
ARCH=armv6zk
|
||||
endif
|
||||
ifeq "$(shell uname -m)" "armv7l"
|
||||
ARCH=armv7-a
|
||||
endif
|
||||
ifdef ARCH
|
||||
# The recommended compiler flags for the Raspberry Pi
|
||||
CXXFLAGS+=-Ofast -mfpu=vfp -mfloat-abi=hard -march=$(ARCH) -mtune=arm1176jzf-s -DRASPBERRYPI_ARCH $(OPTFLAGS)
|
||||
LDFLAGS+=-lrf24-bcm
|
||||
endif
|
||||
|
||||
CXXFLAGS+=-g -Wall -Wextra
|
||||
CXXFLAGS+=-DLINUX_ARCH_GENERIC $(OPTFLAGS)
|
||||
|
||||
# get PI Revision from cpuinfo
|
||||
PIREV := $(shell cat /proc/cpuinfo | grep Revision | cut -f 2 -d ":" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$$//')
|
||||
ifeq ($(PIREV),$(filter $(PIREV),a01041 a21041 0010))
|
||||
# a01041 and a21041 are PI 2 Model B with BPLUS Layout and 0010 is Pi Model B+ with BPLUS Layout
|
||||
CXXFLAGS+=-D__PI_BPLUS
|
||||
endif
|
||||
|
||||
GATEWAY=examples_RPi/PiGateway
|
||||
GATEWAY_SOURCES=examples_RPi/PiGateway.cpp $(wildcard ./utility/*.cpp)
|
||||
GATEWAY_OBJECTS=$(patsubst %.cpp,%.o,$(GATEWAY_SOURCES))
|
||||
DEPS+=$(patsubst %.cpp,%.d,$(GATEWAY_SOURCES))
|
||||
|
||||
RF24H = /usr/local/include/RF24
|
||||
CINCLUDE=-I. -I./core -I$(RF24H)
|
||||
|
||||
.PHONY: all clean install uninstall
|
||||
|
||||
all: $(GATEWAY)
|
||||
|
||||
# Basic Gateway Build
|
||||
$(GATEWAY): LDFLAGS += -pthread
|
||||
$(GATEWAY): $(GATEWAY_OBJECTS)
|
||||
$(CXX) $(LDFLAGS) -o $@ $(GATEWAY_OBJECTS)
|
||||
|
||||
# Include all .d files
|
||||
-include $(DEPS)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(CINCLUDE) -MMD -c -o $@ $<
|
||||
|
||||
# The Cleaner
|
||||
clean:
|
||||
rm -rf build $(GATEWAY_OBJECTS) $(GATEWAY) $(DEPS)
|
||||
|
||||
install: all install-gatewaybasic install-gatewayserial install-gatewayethernet install-initscripts
|
||||
|
||||
install-gatewaybasic:
|
||||
@echo "Installing $(GATEWAY) to $(BINDIR)"
|
||||
@install -m 0755 $(GATEWAY) $(BINDIR)
|
||||
@@ -342,6 +342,17 @@
|
||||
#define MY_RF24_CE_PIN 4
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#define MY_RF24_CE_PIN 27
|
||||
#elif defined(RASPBERRYPI_ARCH)
|
||||
#include <RF24.h>
|
||||
#include <RF24_config.h>
|
||||
#ifdef __PI_BPLUS
|
||||
#define MY_RF24_CE_PIN RPI_BPLUS_GPIO_J8_22
|
||||
#define MY_RF24_CS_PIN RPI_BPLUS_GPIO_J8_24
|
||||
#else
|
||||
#define MY_RF24_CE_PIN RPI_V2_GPIO_P1_22
|
||||
#define MY_RF24_CS_PIN BCM2835_SPI_CS0
|
||||
#endif
|
||||
#define MY_RF24_SPI_SPEED BCM2835_SPI_SPEED_8MHZ
|
||||
#else
|
||||
#define MY_RF24_CE_PIN 9
|
||||
#endif
|
||||
@@ -509,6 +520,8 @@
|
||||
//#define MY_GATEWAY_W5100
|
||||
//#define MY_GATEWAY_ENC28J60
|
||||
//#define MY_GATEWAY_ESP8266
|
||||
//#define MY_GATEWAY_RASPBERRYPI
|
||||
//#define MY_GATEWAY_LINUX
|
||||
|
||||
/**
|
||||
* @def MY_PORT
|
||||
@@ -546,6 +559,10 @@
|
||||
// If MY_CONTROLLER_IP_ADDRESS is left un-defined, gateway acts as server allowing incoming connections.
|
||||
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254
|
||||
|
||||
/**************************************
|
||||
* Node Locking
|
||||
***************************************/
|
||||
|
||||
/**
|
||||
* @defgroup MyLockgrp MyNodeLock
|
||||
* @ingroup internals
|
||||
@@ -604,6 +621,27 @@
|
||||
|
||||
#endif
|
||||
|
||||
/**************************************
|
||||
* RaspberryPi Settings
|
||||
***************************************/
|
||||
|
||||
/**
|
||||
* @def MY_RASPBERRYPI_TTY_NAME
|
||||
* @brief Set the name of predictable tty
|
||||
*/
|
||||
#ifndef MY_RASPBERRYPI_TTY_NAME
|
||||
#define MY_RASPBERRYPI_TTY_NAME /dev/ttyMySensorsGateway
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def MY_RASPBERRYPI_TTY_GROUPNAME
|
||||
* @brief Set the group name for the raw tty
|
||||
*/
|
||||
#ifndef MY_RASPBERRYPI_TTY_GROUPNAME
|
||||
#define MY_RASPBERRYPI_TTY_GROUPNAME tty
|
||||
#endif
|
||||
|
||||
|
||||
// Doxygen specific constructs, not included when built normally
|
||||
// This is used to enable disabled macros/definitions to be included in the documentation as well.
|
||||
#if DOXYGEN
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
* @def MY_NODE_TYPE
|
||||
* @brief Contain a string describing the class of sketch/node (gateway/repeater/sensor).
|
||||
*/
|
||||
#if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100) || defined(MY_GATEWAY_ENC28J60) || defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_MQTT_CLIENT)
|
||||
#if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100) || defined(MY_GATEWAY_ENC28J60) || defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_RASPBERRYPI) || defined(MY_GATEWAY_LINUX) || defined(MY_GATEWAY_MQTT_CLIENT)
|
||||
#define MY_GATEWAY_FEATURE
|
||||
#define MY_IS_GATEWAY (true)
|
||||
#define MY_NODE_TYPE "gateway"
|
||||
@@ -68,7 +68,19 @@
|
||||
#elif defined(ARDUINO_ARCH_AVR)
|
||||
#include "core/MyHwATMega328.cpp"
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#include "core/MyHwSAMD.cpp"
|
||||
#include "core/MyHwSAMD.cpp"
|
||||
#elif defined(LINUX_ARCH_GENERIC)
|
||||
// Remove PSTR macros from debug prints
|
||||
#undef PSTR
|
||||
#define PSTR(x) (x)
|
||||
//#undef F
|
||||
//#define F(x) (x)
|
||||
#define PROGMEM
|
||||
#define vsnprintf_P(...) vsnprintf( __VA_ARGS__ )
|
||||
#define snprintf_P(...) snprintf( __VA_ARGS__ )
|
||||
#define memcpy_P memcpy
|
||||
#define pgm_read_dword(x) (*x)
|
||||
#include "core/MyHwLinuxGeneric.cpp"
|
||||
#endif
|
||||
|
||||
// LEDS
|
||||
@@ -208,6 +220,9 @@
|
||||
// We assume that a gateway having a radio also should act as repeater
|
||||
#define MY_REPEATER_FEATURE
|
||||
#endif
|
||||
#if defined(MY_GATEWAY_RASPBERRYPI)
|
||||
#define MY_GATEWAY_LINUX
|
||||
#endif
|
||||
#if defined(MY_CONTROLLER_IP_ADDRESS)
|
||||
#define MY_GATEWAY_CLIENT_MODE
|
||||
#endif
|
||||
@@ -217,6 +232,9 @@
|
||||
#if defined(MY_GATEWAY_ESP8266)
|
||||
// GATEWAY - ESP8266
|
||||
#include "core/MyGatewayTransportEthernet.cpp"
|
||||
#elif defined(MY_GATEWAY_LINUX)
|
||||
// GATEWAY - Generic Linux (RaspberryPi, BBB)
|
||||
#include "core/MyGatewayTransportEthernetLinux.cpp"
|
||||
#elif defined(MY_GATEWAY_W5100)
|
||||
// GATEWAY - W5100
|
||||
#include "core/MyGatewayTransportEthernet.cpp"
|
||||
@@ -229,6 +247,7 @@
|
||||
#elif defined(MY_GATEWAY_SERIAL)
|
||||
// GATEWAY - SERIAL
|
||||
#include "core/MyGatewayTransportSerial.cpp"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -256,7 +275,9 @@
|
||||
#if defined(MY_RF24_ENABLE_ENCRYPTION)
|
||||
#include "drivers/AES/AES.cpp"
|
||||
#endif
|
||||
#include "drivers/RF24/RF24.cpp"
|
||||
#if !defined(RASPBERRYPI_ARCH)
|
||||
#include "drivers/RF24/RF24.cpp"
|
||||
#endif
|
||||
#include "core/MyTransportNRF24.cpp"
|
||||
#elif defined(MY_RS485)
|
||||
#include "drivers/AltSoftSerial/AltSoftSerial.cpp"
|
||||
@@ -295,6 +316,8 @@
|
||||
#if !defined(MY_CORE_ONLY)
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
#include "core/MyMainESP8266.cpp"
|
||||
#elif defined(LINUX_ARCH_GENERIC)
|
||||
#include "core/MyMainLinux.cpp"
|
||||
#else
|
||||
#include "core/MyMainDefault.cpp"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
* 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>
|
||||
* Copyleft (c) 2016, Marcelo Aquino
|
||||
* 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 "MyGatewayTransport.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <list>
|
||||
|
||||
//TODO
|
||||
#ifdef MY_USE_UDP
|
||||
#error UDP not supported for this type of gateway
|
||||
#endif
|
||||
|
||||
union _addrIPv4{
|
||||
uint8_t bytes[4];
|
||||
uint32_t dword;
|
||||
};
|
||||
|
||||
static int controllers[MY_GATEWAY_MAX_CLIENTS];
|
||||
static MyMessage _ethernetMsg;
|
||||
static std::list<struct MyMessage> ethernetMsg_q;
|
||||
static pthread_mutex_t ethernetMsg_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// Prototypes
|
||||
int open_listen(char *ip, uint16_t port);
|
||||
uint32_t getAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
|
||||
void *get_in_addr(struct sockaddr *sa);
|
||||
void *waiting_controllers(void* thread_arg);
|
||||
void *connected_controller(void* thread_arg);
|
||||
|
||||
bool gatewayTransportInit() {
|
||||
long int sockfd;
|
||||
pthread_t thread_id;
|
||||
pthread_attr_t attr;
|
||||
char *ip = NULL;
|
||||
|
||||
// ignore SIGPIPE generated by send() to a disconnected client
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
for (uint8_t i = 0; i < MY_GATEWAY_MAX_CLIENTS; i++) {
|
||||
controllers[i] = -1;
|
||||
}
|
||||
|
||||
#ifdef MY_CONTROLLER_IP_ADDRESS
|
||||
//TODO
|
||||
return false;
|
||||
#else
|
||||
#ifdef MY_IP_ADDRESS
|
||||
char ipstr[INET_ADDRSTRLEN];
|
||||
union _addrIPv4 addrIPv4 = getAddress(MY_IP_ADDRESS);
|
||||
sprintf(ipstr, "%d.%d.%d.%d", addrIPv4.bytes[0], addrIPv4.bytes[1],
|
||||
addrIPv4.bytes[2], addrIPv4.bytes[3]);
|
||||
ip = ipstr;
|
||||
#endif
|
||||
|
||||
sockfd = open_listen(ip, MY_PORT);
|
||||
if (sockfd < 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&thread_id, &attr, &waiting_controllers, (void *)sockfd);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gatewayTransportSend(MyMessage &message)
|
||||
{
|
||||
char *ethernetMsg = protocolFormat(message);
|
||||
|
||||
for (uint8_t i = 0; i < MY_GATEWAY_MAX_CLIENTS; i++) {
|
||||
if (controllers[i] == -1)
|
||||
continue;
|
||||
if (send(controllers[i], ethernetMsg, strlen(ethernetMsg), 0) == -1)
|
||||
perror("send");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gatewayTransportAvailable()
|
||||
{
|
||||
bool empty;
|
||||
|
||||
pthread_mutex_lock(ðernetMsg_mutex);
|
||||
empty = ethernetMsg_q.empty();
|
||||
pthread_mutex_unlock(ðernetMsg_mutex);
|
||||
|
||||
return !empty;
|
||||
}
|
||||
|
||||
MyMessage& gatewayTransportReceive()
|
||||
{
|
||||
// Return the last parsed message
|
||||
pthread_mutex_lock(ðernetMsg_mutex);
|
||||
_ethernetMsg = ethernetMsg_q.front();
|
||||
ethernetMsg_q.pop_front();
|
||||
pthread_mutex_unlock(ðernetMsg_mutex);
|
||||
|
||||
return _ethernetMsg;
|
||||
}
|
||||
|
||||
int open_listen(char *address, uint16_t port)
|
||||
{
|
||||
int sockfd;
|
||||
struct addrinfo hints, *servinfo, *p;
|
||||
int yes=1;
|
||||
int rv;
|
||||
char ipstr[INET_ADDRSTRLEN];
|
||||
char portstr[6];
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_INET; // IPv4
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
sprintf(portstr, "%d", port);
|
||||
if ((rv = getaddrinfo(address, portstr, &hints, &servinfo)) != 0) {
|
||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// loop through all the results and bind to the first we can
|
||||
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
|
||||
perror("socket");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
|
||||
perror("setsockopt");
|
||||
freeaddrinfo(servinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
|
||||
close(sockfd);
|
||||
perror("bind");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
fprintf(stderr, "failed to bind\n");
|
||||
freeaddrinfo(servinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(sockfd, MY_GATEWAY_MAX_CLIENTS) == -1) {
|
||||
perror("listen");
|
||||
freeaddrinfo(servinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
|
||||
void *addr = &(ipv4->sin_addr);
|
||||
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
|
||||
debug("Eth: Listening for connections on %s:%s\n", ipstr, portstr);
|
||||
|
||||
freeaddrinfo(servinfo);
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
uint32_t getAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
|
||||
{
|
||||
union _addrIPv4 addrIPv4;
|
||||
|
||||
addrIPv4.bytes[0] = first_octet;
|
||||
addrIPv4.bytes[1] = second_octet;
|
||||
addrIPv4.bytes[2] = third_octet;
|
||||
addrIPv4.bytes[3] = fourth_octet;
|
||||
|
||||
return addrIPv4.dword;
|
||||
}
|
||||
|
||||
void *get_in_addr(struct sockaddr *sa)
|
||||
{
|
||||
if (sa->sa_family == AF_INET) {
|
||||
return &(((struct sockaddr_in*)sa)->sin_addr);
|
||||
}
|
||||
|
||||
return &(((struct sockaddr_in6*)sa)->sin6_addr);
|
||||
}
|
||||
|
||||
void *waiting_controllers(void* thread_arg)
|
||||
{
|
||||
long int sockfd = (long int) thread_arg;
|
||||
long int new_fd; // new connection on new_fd
|
||||
struct sockaddr_storage client_addr; // connector's address information
|
||||
socklen_t sin_size;
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
pthread_t thread_id;
|
||||
pthread_attr_t attr;
|
||||
uint8_t i;
|
||||
|
||||
while (1) { // accept() loop
|
||||
sin_size = sizeof client_addr;
|
||||
new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
|
||||
if (new_fd == -1) {
|
||||
perror("accept");
|
||||
continue;
|
||||
}
|
||||
|
||||
inet_ntop(client_addr.ss_family,
|
||||
get_in_addr((struct sockaddr *)&client_addr), s, sizeof s);
|
||||
debug("Eth: New connection from %s\n", s);
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&thread_id, &attr, &connected_controller, (void *)new_fd);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
for (i = 0; i < MY_GATEWAY_MAX_CLIENTS; i++) {
|
||||
if (controllers[i] == -1) {
|
||||
controllers[i] = new_fd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MY_GATEWAY_MAX_CLIENTS) {
|
||||
// no free/disconnected spot so reject
|
||||
close(new_fd);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *connected_controller(void* thread_arg)
|
||||
{
|
||||
long int sockfd = (long int) thread_arg;
|
||||
char inputString[MY_GATEWAY_MAX_RECEIVE_LENGTH];
|
||||
char *ptr = inputString;
|
||||
int nbytes = 0;
|
||||
MyMessage ethernetMsg;
|
||||
|
||||
while (1) {
|
||||
if (recv(sockfd, ptr, 1, 0) > 0) {
|
||||
if (*ptr == '\n' || *ptr == '\r') {
|
||||
// String terminator
|
||||
*ptr = 0;
|
||||
debug("Eth: %s\n", inputString);
|
||||
if (protocolParse(ethernetMsg, inputString)) {
|
||||
pthread_mutex_lock(ðernetMsg_mutex);
|
||||
ethernetMsg_q.push_back(ethernetMsg);
|
||||
pthread_mutex_unlock(ðernetMsg_mutex);
|
||||
}
|
||||
|
||||
// Prepare for the next message
|
||||
ptr = inputString;
|
||||
nbytes = 0;
|
||||
continue;
|
||||
}
|
||||
nbytes++;
|
||||
if (nbytes == MY_GATEWAY_MAX_RECEIVE_LENGTH) {
|
||||
// Incoming message too long. Throw away
|
||||
debug("Eth: Message too long\n");
|
||||
ptr = inputString;
|
||||
nbytes = 0;
|
||||
} else {
|
||||
ptr++;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nbytes == -1)
|
||||
perror("recv");
|
||||
|
||||
for (uint8_t i = 0; i < MY_GATEWAY_MAX_CLIENTS; i++) {
|
||||
if (controllers[i] == sockfd) {
|
||||
controllers[i] = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* 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>
|
||||
* Copyleft (c) 2016, Marcelo Aquino
|
||||
* 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 "MyHwLinuxGeneric.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
static const size_t _length = 1024; // ATMega328 has 1024 bytes
|
||||
//TODO store _config to a file
|
||||
static uint8_t _config[_length];
|
||||
static unsigned long millis_at_start;
|
||||
|
||||
void hwInit()
|
||||
{
|
||||
timeval curTime;
|
||||
|
||||
for (size_t i = 0; i < _length; i++)
|
||||
_config[i] = 0xFF;
|
||||
|
||||
gettimeofday(&curTime, NULL);
|
||||
millis_at_start = curTime.tv_sec;
|
||||
}
|
||||
|
||||
void hwReadConfigBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(buf, _config+offs, length);
|
||||
}
|
||||
}
|
||||
|
||||
void hwWriteConfigBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(_config+offs, buf, length);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t hwReadConfig(int addr)
|
||||
{
|
||||
if (addr >= 0 && (unsigned)addr < _length)
|
||||
return _config[addr];
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void hwWriteConfig(int addr, uint8_t value)
|
||||
{
|
||||
if (addr >= 0 && (unsigned)addr < _length)
|
||||
_config[addr] = value;
|
||||
}
|
||||
|
||||
unsigned long hwMillis()
|
||||
{
|
||||
timeval curTime;
|
||||
|
||||
gettimeofday(&curTime, NULL);
|
||||
return ((curTime.tv_sec - millis_at_start) * 1000) + (curTime.tv_usec / 1000);
|
||||
}
|
||||
|
||||
int8_t hwSleep(unsigned long ms)
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return -2;
|
||||
}
|
||||
|
||||
int8_t hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms)
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return -2;
|
||||
}
|
||||
|
||||
int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms)
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ... )
|
||||
{
|
||||
va_list arglist;
|
||||
va_start(arglist, fmt);
|
||||
vprintf(fmt, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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>
|
||||
* Copyleft (c) 2016, Marcelo Aquino
|
||||
* 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 MyHwLinuxGeneric_h
|
||||
#define MyHwLinuxGeneric_h
|
||||
|
||||
#include "MyHw.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MY_SERIALDEVICE Serial
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
// Define these as macros (do nothing)
|
||||
#define hwDigitalWrite(__pin, __value)
|
||||
#define hwWatchdogReset()
|
||||
#define hwReboot()
|
||||
|
||||
void hwInit();
|
||||
void hwReadConfigBlock(void* buf, void* adr, size_t length);
|
||||
void hwWriteConfigBlock(void* buf, void* adr, size_t length);
|
||||
void hwWriteConfig(int adr, uint8_t value);
|
||||
uint8_t hwReadConfig(int adr);
|
||||
unsigned long hwMillis();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
// Initialize library and handle sketch functions like we want to
|
||||
|
||||
#include "MySensorCore.h"
|
||||
|
||||
int main(void) {
|
||||
_begin(); // Startup MySensors library
|
||||
|
||||
for(;;) {
|
||||
_process(); // Process incoming data
|
||||
if (loop) loop(); // Call sketch loop
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -51,6 +51,11 @@ void _process() {
|
||||
#if defined(MY_RADIO_FEATURE)
|
||||
transportProcess();
|
||||
#endif
|
||||
|
||||
#if defined(LINUX_ARCH_GENERIC)
|
||||
// To avoid high cpu usage
|
||||
usleep(10000); // 10ms
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MY_RADIO_FEATURE)
|
||||
|
||||
@@ -20,8 +20,10 @@
|
||||
#include "MyConfig.h"
|
||||
#include "MyTransport.h"
|
||||
#include <stdint.h>
|
||||
#include "drivers/RF24/RF24.h"
|
||||
#include "drivers/RF24/RF24_config.h"
|
||||
#ifndef RASPBERRYPI_ARCH
|
||||
#include "drivers/RF24/RF24.h"
|
||||
#include "drivers/RF24/RF24_config.h"
|
||||
#endif
|
||||
#if defined(MY_RF24_ENABLE_ENCRYPTION)
|
||||
#include "drivers/AES/AES.h"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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>
|
||||
* Copyleft (c) 2016, Marcelo Aquino
|
||||
* 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 <iostream>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enables and select radio type (if attached)
|
||||
#define MY_RADIO_NRF24
|
||||
|
||||
#define MY_GATEWAY_RASPBERRYPI
|
||||
|
||||
// Enable MY_IP_ADDRESS here if you want to listen for incoming network
|
||||
// connections on the specified IP address/hostname only
|
||||
//#define MY_IP_ADDRESS 192,168,178,87
|
||||
|
||||
// The port to keep open on node server mode
|
||||
#define MY_PORT 5003
|
||||
|
||||
// How many clients should be able to connect to this gateway (default 1)
|
||||
#define MY_GATEWAY_MAX_CLIENTS 2
|
||||
|
||||
#include <MySensor.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors here
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Send locally attached sensors data here
|
||||
}
|
||||
Reference in New Issue
Block a user