mirror of
https://github.com/thelsing/knx.git
synced 2026-02-23 13:50:35 +01:00
include linux and samd versions here
This commit is contained in:
7
src/arch_config.h
Normal file
7
src/arch_config.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
#ifndef USE_STATES
|
||||
#define USE_STATES
|
||||
#endif
|
||||
#endif
|
||||
@@ -2,9 +2,19 @@
|
||||
#include "state.h"
|
||||
#include "knx_facade.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
unsigned long buttonTimestamp = 0;
|
||||
|
||||
void buttonDown()
|
||||
{
|
||||
buttonTimestamp = millis();
|
||||
attachInterrupt(knx.buttonPin(), buttonUp, RISING);
|
||||
}
|
||||
#endif
|
||||
|
||||
void buttonUp()
|
||||
{
|
||||
#ifdef USE_STATES
|
||||
if (millis() - buttonTimestamp > 1000)
|
||||
{
|
||||
Serial.println("long button press");
|
||||
@@ -16,10 +26,15 @@ void buttonUp()
|
||||
currentState->shortButtonPress();
|
||||
}
|
||||
attachInterrupt(knx.buttonPin(), buttonDown, FALLING);
|
||||
}
|
||||
|
||||
void buttonDown()
|
||||
{
|
||||
buttonTimestamp = millis();
|
||||
attachInterrupt(knx.buttonPin(), buttonUp, RISING);
|
||||
#else
|
||||
if (knx.progMode())
|
||||
{
|
||||
digitalWrite(knx.ledPin(), LOW);
|
||||
knx.progMode(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(knx.ledPin(), HIGH);
|
||||
knx.progMode(true);
|
||||
}
|
||||
#endif
|
||||
@@ -1,4 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch_config.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
void buttonDown();
|
||||
#endif
|
||||
void buttonUp();
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "esp_platform.h"
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
#include <user_interface.h>
|
||||
#include <Arduino.h>
|
||||
#include <EEPROM.h>
|
||||
@@ -169,3 +171,4 @@ size_t EspPlatform::readBytesUart(uint8_t *buffer, size_t length)
|
||||
printHex("p>", buffer, length);
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
@@ -1,7 +1,10 @@
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
#include "knx/platform.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WifiUDP.h>
|
||||
|
||||
#define SerialDBG Serial
|
||||
|
||||
class EspPlatform : public Platform
|
||||
{
|
||||
public:
|
||||
@@ -43,3 +46,4 @@ private:
|
||||
WiFiUDP _udp;
|
||||
};
|
||||
|
||||
#endif
|
||||
2
src/knx
2
src/knx
Submodule src/knx updated: 0762e753f7...aaf6c27584
@@ -4,9 +4,17 @@
|
||||
#include "led.h"
|
||||
#include "nowifistate.h"
|
||||
|
||||
KnxFacade knx;
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
SamdPlatform platform;
|
||||
Bau07B0 bau(platform);
|
||||
#else
|
||||
EspPlatform platform;
|
||||
Bau57B0 bau(platform);
|
||||
#endif
|
||||
KnxFacade knx(bau);
|
||||
|
||||
KnxFacade::KnxFacade() : _bau(_platform)
|
||||
|
||||
KnxFacade::KnxFacade(BauSystemB& bau) : _bau(bau)
|
||||
{
|
||||
manufacturerId(0xfa);
|
||||
_bau.addSaveRestore(this);
|
||||
@@ -69,8 +77,12 @@ void KnxFacade::writeMemory()
|
||||
|
||||
void KnxFacade::loop()
|
||||
{
|
||||
#ifdef USE_STATES
|
||||
if (currentState)
|
||||
currentState->loop();
|
||||
#else
|
||||
knxLoop();
|
||||
#endif
|
||||
}
|
||||
|
||||
void KnxFacade::knxLoop()
|
||||
@@ -112,12 +124,17 @@ void KnxFacade::start()
|
||||
{
|
||||
pinMode(_ledPin, OUTPUT);
|
||||
|
||||
pinMode(_buttonPin, INPUT);
|
||||
attachInterrupt(_buttonPin, buttonDown, FALLING);
|
||||
pinMode(_buttonPin, INPUT_PULLUP);
|
||||
|
||||
#ifdef USE_STATES
|
||||
attachInterrupt(_buttonPin, buttonDown, FALLING);
|
||||
switchToSate(noWifiState);
|
||||
checkStates();
|
||||
_ticker.attach_ms(100, doLed);
|
||||
#else
|
||||
attachInterrupt(knx.buttonPin(), buttonUp, RISING);
|
||||
enabled(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t* KnxFacade::paramData(uint32_t addr)
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch_config.h"
|
||||
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
#include "samd_platform.h"
|
||||
#include "knx/bau07B0.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
#include <Ticker.h>
|
||||
#include "esp_platform.h"
|
||||
#include "knx/bau57B0.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_STATES
|
||||
class RunningState;
|
||||
#endif
|
||||
|
||||
typedef uint8_t* (*saveRestoreCallback)(uint8_t* buffer);
|
||||
|
||||
class KnxFacade : private SaveRestore
|
||||
{
|
||||
public:
|
||||
KnxFacade();
|
||||
KnxFacade(BauSystemB& bau);
|
||||
bool enabled();
|
||||
void enabled(bool value);
|
||||
bool progMode();
|
||||
@@ -38,11 +50,12 @@ public:
|
||||
uint16_t paramWord(uint32_t addr);
|
||||
uint32_t paramInt(uint32_t addr);
|
||||
private:
|
||||
EspPlatform _platform;
|
||||
Bau57B0 _bau;
|
||||
BauSystemB& _bau;
|
||||
uint32_t _ledPin = 16;
|
||||
uint32_t _buttonPin = 0;
|
||||
#ifdef USE_STATES
|
||||
Ticker _ticker;
|
||||
#endif
|
||||
saveRestoreCallback _saveCallback = 0;
|
||||
saveRestoreCallback _restoreCallback = 0;
|
||||
|
||||
|
||||
174
src/knx_facade_samd.cpp
Normal file
174
src/knx_facade_samd.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "knx_facade.h"
|
||||
#if 0
|
||||
KnxFacade knx;
|
||||
|
||||
|
||||
#define SerialDBG SerialUSB
|
||||
|
||||
void buttonUp();
|
||||
long buttonTimestamp = 0;
|
||||
void buttonDown()
|
||||
{
|
||||
buttonTimestamp = millis();
|
||||
attachInterrupt(knx.buttonPin(), buttonUp, RISING);
|
||||
}
|
||||
|
||||
void buttonUp()
|
||||
{
|
||||
// keep short/long for now
|
||||
if (millis() - buttonTimestamp > 1000)
|
||||
{
|
||||
SerialDBG.println("long button press");
|
||||
}
|
||||
else
|
||||
{
|
||||
SerialDBG.println("short button press");
|
||||
}
|
||||
|
||||
if (knx.progMode())
|
||||
{
|
||||
digitalWrite(knx.ledPin(), LOW);
|
||||
knx.progMode(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(knx.ledPin(), HIGH);
|
||||
knx.progMode(true);
|
||||
}
|
||||
|
||||
attachInterrupt(knx.buttonPin(), buttonDown, FALLING);
|
||||
}
|
||||
|
||||
KnxFacade::KnxFacade() : _bau(_platform)
|
||||
{
|
||||
manufacturerId(0xfa);
|
||||
}
|
||||
|
||||
bool KnxFacade::enabled()
|
||||
{
|
||||
return _bau.enabled();
|
||||
}
|
||||
|
||||
void KnxFacade::enabled(bool value)
|
||||
{
|
||||
_bau.enabled(true);
|
||||
}
|
||||
|
||||
bool KnxFacade::progMode()
|
||||
{
|
||||
return _bau.deviceObject().progMode();
|
||||
}
|
||||
|
||||
void KnxFacade::progMode(bool value)
|
||||
{
|
||||
_bau.deviceObject().progMode(value);
|
||||
}
|
||||
|
||||
bool KnxFacade::configured()
|
||||
{
|
||||
return _bau.configured();
|
||||
}
|
||||
|
||||
uint32_t KnxFacade::ledPin()
|
||||
{
|
||||
return _ledPin;
|
||||
}
|
||||
|
||||
void KnxFacade::ledPin(uint32_t value)
|
||||
{
|
||||
_ledPin = value;
|
||||
}
|
||||
|
||||
uint32_t KnxFacade::buttonPin()
|
||||
{
|
||||
return _buttonPin;
|
||||
}
|
||||
|
||||
void KnxFacade::buttonPin(uint32_t value)
|
||||
{
|
||||
_buttonPin = value;
|
||||
}
|
||||
|
||||
void KnxFacade::readMemory()
|
||||
{
|
||||
_bau.readMemory();
|
||||
}
|
||||
|
||||
void KnxFacade::loop()
|
||||
{
|
||||
_bau.loop();
|
||||
}
|
||||
|
||||
void KnxFacade::registerGroupObjects(GroupObject* groupObjects, uint16_t count)
|
||||
{
|
||||
_bau.groupObjectTable().groupObjects(groupObjects, count);
|
||||
}
|
||||
|
||||
void KnxFacade::manufacturerId(uint16_t value)
|
||||
{
|
||||
_bau.deviceObject().manufacturerId(value);
|
||||
}
|
||||
|
||||
void KnxFacade::bauNumber(uint32_t value)
|
||||
{
|
||||
_bau.deviceObject().bauNumber(value);
|
||||
}
|
||||
|
||||
void KnxFacade::orderNumber(const char* value)
|
||||
{
|
||||
_bau.deviceObject().orderNumber(value);
|
||||
}
|
||||
|
||||
void KnxFacade::hardwareType(uint8_t* value)
|
||||
{
|
||||
_bau.deviceObject().hardwareType(value);
|
||||
}
|
||||
|
||||
void KnxFacade::version(uint16_t value)
|
||||
{
|
||||
_bau.deviceObject().version(value);
|
||||
}
|
||||
|
||||
void KnxFacade::start()
|
||||
{
|
||||
pinMode(_ledPin, OUTPUT);
|
||||
|
||||
pinMode(_buttonPin, INPUT_PULLUP);
|
||||
attachInterrupt(_buttonPin, buttonDown, FALLING);
|
||||
enabled(true);
|
||||
}
|
||||
|
||||
uint8_t* KnxFacade::paramData(uint32_t addr)
|
||||
{
|
||||
if (!_bau.configured())
|
||||
return nullptr;
|
||||
|
||||
return _bau.parameters().data(addr);
|
||||
}
|
||||
|
||||
uint8_t KnxFacade::paramByte(uint32_t addr)
|
||||
{
|
||||
if (!_bau.configured())
|
||||
return 0;
|
||||
|
||||
return _bau.parameters().getByte(addr);
|
||||
}
|
||||
|
||||
uint16_t KnxFacade::paramWord(uint32_t addr)
|
||||
{
|
||||
if (!_bau.configured())
|
||||
return 0;
|
||||
|
||||
return _bau.parameters().getWord(addr);
|
||||
}
|
||||
|
||||
uint32_t KnxFacade::paramInt(uint32_t addr)
|
||||
{
|
||||
if (!_bau.configured())
|
||||
return 0;
|
||||
|
||||
return _bau.parameters().getInt(addr);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "knx_facade.h"
|
||||
#include "state.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
void doLed()
|
||||
{
|
||||
if (!currentState)
|
||||
@@ -25,4 +26,5 @@ void doLed()
|
||||
digitalWrite(knx.ledPin(), HIGH);
|
||||
else
|
||||
digitalWrite(knx.ledPin(), LOW);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,3 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
void doLed();
|
||||
#include "arch_config.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
void doLed();
|
||||
#endif
|
||||
279
src/linux_platform.cpp
Normal file
279
src/linux_platform.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
#include "linux_platform.h"
|
||||
#ifdef __linux__
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <math.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "knx/device_object.h"
|
||||
#include "knx/address_table_object.h"
|
||||
#include "knx/association_table_object.h"
|
||||
#include "knx/group_object_table_object.h"
|
||||
#include "knx/application_program_object.h"
|
||||
#include "knx/ip_parameter_object.h"
|
||||
|
||||
LinuxPlatform::LinuxPlatform()
|
||||
{
|
||||
doMemoryMapping();
|
||||
}
|
||||
|
||||
uint32_t LinuxPlatform::currentIpAddress()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t LinuxPlatform::currentSubnetMask()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t LinuxPlatform::currentDefaultGateway()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t LinuxPlatform::millis()
|
||||
{
|
||||
struct timespec spec;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||
return spec.tv_sec * 1000 + round(spec.tv_nsec / 1.0e6);
|
||||
}
|
||||
|
||||
void LinuxPlatform::mdelay(uint32_t millis)
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = millis / 1000;
|
||||
ts.tv_nsec = (millis % 1000) * 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
void LinuxPlatform::macAddress(uint8_t* data)
|
||||
{
|
||||
// hardcode some address
|
||||
data[0] = 0x08;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x27;
|
||||
data[3] = 0x6c;
|
||||
data[4] = 0xa8;
|
||||
data[5] = 0x2a;
|
||||
}
|
||||
|
||||
void LinuxPlatform::restart()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void LinuxPlatform::fatalError()
|
||||
{
|
||||
printf("A fatal error occured. Stopping.\n");
|
||||
while (true)
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port)
|
||||
{
|
||||
_multicastAddr = addr;
|
||||
_port = port;
|
||||
|
||||
struct ip_mreq command;
|
||||
uint32_t loop = 1;
|
||||
|
||||
struct sockaddr_in sin;
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
sin.sin_port = htons(port);
|
||||
|
||||
_socketFd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_socketFd == -1) {
|
||||
perror("socket()");
|
||||
fatalError();
|
||||
}
|
||||
|
||||
/* Mehr Prozessen erlauben, denselben Port zu nutzen */
|
||||
loop = 1;
|
||||
if (setsockopt(_socketFd, SOL_SOCKET, SO_REUSEADDR, &loop, sizeof(loop)) < 0)
|
||||
{
|
||||
perror("setsockopt:SO_REUSEADDR");
|
||||
fatalError();
|
||||
}
|
||||
|
||||
if (bind(_socketFd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
||||
{
|
||||
perror("bind");
|
||||
fatalError();
|
||||
}
|
||||
|
||||
/* Broadcast auf dieser Maschine zulassen */
|
||||
loop = 1;
|
||||
if (setsockopt(_socketFd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
|
||||
{
|
||||
perror("setsockopt:IP_MULTICAST_LOOP");
|
||||
fatalError();
|
||||
}
|
||||
|
||||
/* Join the broadcast group: */
|
||||
command.imr_multiaddr.s_addr = htonl(addr);
|
||||
command.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (setsockopt(_socketFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0)
|
||||
{
|
||||
perror("setsockopt:IP_ADD_MEMBERSHIP");
|
||||
fatalError();
|
||||
}
|
||||
|
||||
uint32_t flags = fcntl(_socketFd, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(_socketFd, F_SETFL, flags);
|
||||
}
|
||||
|
||||
void LinuxPlatform::closeMultiCast()
|
||||
{
|
||||
struct ip_mreq command;
|
||||
command.imr_multiaddr.s_addr = htonl(_multicastAddr);
|
||||
command.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (setsockopt(_socketFd,
|
||||
IPPROTO_IP,
|
||||
IP_DROP_MEMBERSHIP,
|
||||
&command, sizeof(command)) < 0) {
|
||||
perror("setsockopt:IP_DROP_MEMBERSHIP");
|
||||
}
|
||||
close(_socketFd);
|
||||
}
|
||||
|
||||
bool LinuxPlatform::sendBytes(uint8_t* buffer, uint16_t len)
|
||||
{
|
||||
struct sockaddr_in address = { 0 };
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = htonl(_multicastAddr);
|
||||
address.sin_port = htons(_port);
|
||||
|
||||
ssize_t retVal = 0;
|
||||
do
|
||||
{
|
||||
retVal = sendto(_socketFd, buffer, len, 0, (struct sockaddr *) &address, sizeof(address));
|
||||
if (retVal == -1)
|
||||
{
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
return false;
|
||||
}
|
||||
} while (retVal == -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
int LinuxPlatform::readBytes(uint8_t * buffer, uint16_t maxLen)
|
||||
{
|
||||
uint32_t sin_len;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
sin_len = sizeof(sin);
|
||||
ssize_t len = recvfrom(_socketFd, buffer, maxLen, 0, (struct sockaddr *) &sin, &sin_len);
|
||||
return len;
|
||||
}
|
||||
|
||||
uint8_t * LinuxPlatform::getEepromBuffer(uint16_t size)
|
||||
{
|
||||
return _mappedFile + 2;
|
||||
}
|
||||
|
||||
void LinuxPlatform::commitToEeprom()
|
||||
{
|
||||
fsync(_fd);
|
||||
}
|
||||
|
||||
#define FLASHSIZE 0x10000
|
||||
void LinuxPlatform::doMemoryMapping()
|
||||
{
|
||||
_fd = open("flash.bin", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
if (_fd < 0)
|
||||
{
|
||||
perror("Error in file opening");
|
||||
//exit(-1);
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
uint32_t ret = fstat(_fd, &st);
|
||||
if (ret < 0)
|
||||
{
|
||||
perror("Error in fstat");
|
||||
//exit(-1);
|
||||
}
|
||||
|
||||
size_t len_file = st.st_size;
|
||||
if (len_file < FLASHSIZE)
|
||||
{
|
||||
if (ftruncate(_fd, FLASHSIZE) != 0)
|
||||
{
|
||||
perror("Error extending file");
|
||||
//exit(-1);
|
||||
}
|
||||
len_file = FLASHSIZE;
|
||||
}
|
||||
unsigned char* addr = (unsigned char*)mmap(NULL, len_file, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
|
||||
if (addr[0] != 0xAF || addr[1] != 0xFE)
|
||||
{
|
||||
memset(addr, 0, FLASHSIZE);
|
||||
addr[0] = 0xAF;
|
||||
addr[1] = 0xFE;
|
||||
}
|
||||
|
||||
if (addr == MAP_FAILED)
|
||||
{
|
||||
perror("Error in mmap");
|
||||
//exit(-1);
|
||||
}
|
||||
_mappedFile = addr;
|
||||
}
|
||||
|
||||
size_t LinuxPlatform::readBytesUart(uint8_t *buffer, size_t length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int LinuxPlatform::readUart()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
size_t LinuxPlatform::writeUart(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
size_t LinuxPlatform::writeUart(const uint8_t data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int LinuxPlatform::uartAvailable()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void LinuxPlatform::closeUart()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LinuxPlatform::setupUart()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
51
src/linux_platform.h
Normal file
51
src/linux_platform.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#include "knx/platform.h"
|
||||
|
||||
class LinuxPlatform: public Platform
|
||||
{
|
||||
public:
|
||||
LinuxPlatform();
|
||||
|
||||
// ip stuff
|
||||
uint32_t currentIpAddress();
|
||||
uint32_t currentSubnetMask();
|
||||
uint32_t currentDefaultGateway();
|
||||
void macAddress(uint8_t* addr);
|
||||
|
||||
// basic stuff
|
||||
uint32_t millis();
|
||||
void mdelay(uint32_t millis);
|
||||
void restart();
|
||||
void fatalError();
|
||||
|
||||
//multicast
|
||||
void setupMultiCast(uint32_t addr, uint16_t port);
|
||||
void closeMultiCast();
|
||||
bool sendBytes(uint8_t* buffer, uint16_t len);
|
||||
int readBytes(uint8_t* buffer, uint16_t maxLen);
|
||||
|
||||
//uart
|
||||
void setupUart();
|
||||
void closeUart();
|
||||
int uartAvailable();
|
||||
size_t writeUart(const uint8_t data);
|
||||
size_t writeUart(const uint8_t *buffer, size_t size);
|
||||
int readUart();
|
||||
size_t readBytesUart(uint8_t *buffer, size_t length);
|
||||
|
||||
//memory
|
||||
uint8_t* getEepromBuffer(uint16_t size);
|
||||
void commitToEeprom();
|
||||
private:
|
||||
uint32_t _multicastAddr;
|
||||
uint16_t _port;
|
||||
int _socketFd = -1;
|
||||
void doMemoryMapping();
|
||||
uint8_t* _mappedFile;
|
||||
int _fd;
|
||||
};
|
||||
|
||||
#endif
|
||||
116
src/main.cpp
Normal file
116
src/main.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifdef __linux__
|
||||
|
||||
#include "linux_platform.h"
|
||||
#include "knx/bau57B0.h"
|
||||
#include "knx/group_object_table_object.h"
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
LinuxPlatform platfrom;
|
||||
Bau57B0 bau(platfrom);
|
||||
|
||||
float currentValue = 0;
|
||||
float maxValue = 0;
|
||||
float minValue = RAND_MAX;
|
||||
long lastsend = 0;
|
||||
|
||||
GroupObject groupObjects[]
|
||||
{
|
||||
GroupObject(2),
|
||||
GroupObject(2),
|
||||
GroupObject(2),
|
||||
GroupObject(1)
|
||||
};
|
||||
#define CURR groupObjects[0]
|
||||
#define MAX groupObjects[1]
|
||||
#define MIN groupObjects[2]
|
||||
#define RESET groupObjects[3]
|
||||
|
||||
void measureTemp()
|
||||
{
|
||||
long now = platfrom.millis();
|
||||
if ((now - lastsend) < 2000)
|
||||
return;
|
||||
|
||||
lastsend = now;
|
||||
int r = rand();
|
||||
currentValue = (r * 1.0) / (RAND_MAX * 1.0);
|
||||
currentValue *= 100 * 100;
|
||||
|
||||
CURR.objectWrite(currentValue);
|
||||
|
||||
if (currentValue > maxValue)
|
||||
{
|
||||
maxValue = currentValue;
|
||||
MAX.objectWrite(maxValue);
|
||||
}
|
||||
|
||||
if (currentValue < minValue)
|
||||
{
|
||||
minValue = currentValue;
|
||||
MIN.objectWrite(minValue);
|
||||
}
|
||||
}
|
||||
|
||||
void resetCallback(GroupObject& go)
|
||||
{
|
||||
if (go.objectReadBool())
|
||||
{
|
||||
maxValue = 0;
|
||||
minValue = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
void appLoop()
|
||||
{
|
||||
if (!bau.configured())
|
||||
return;
|
||||
|
||||
measureTemp();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
srand((unsigned int)time(NULL));
|
||||
bau.readMemory();
|
||||
|
||||
uint8_t hwType[] = { 0x0, 0x0, 0x8, 0x0, 0x0, 0x2 };
|
||||
GroupObjectTableObject& got(bau.groupObjectTable());
|
||||
got.groupObjects(groupObjects, 4);
|
||||
|
||||
DeviceObject& devObj(bau.deviceObject());
|
||||
devObj.manufacturerId(0xfa);
|
||||
devObj.bauNumber(0xdeadbeef);
|
||||
devObj.orderNumber("Coolstuff");
|
||||
devObj.hardwareType(hwType);
|
||||
devObj.version(0x0020);
|
||||
|
||||
RESET.updateHandler = resetCallback;
|
||||
|
||||
if (bau.deviceObject().induvidualAddress() == 0)
|
||||
bau.deviceObject().progMode(true);
|
||||
|
||||
if (bau.parameters().loadState() == LS_LOADED)
|
||||
{
|
||||
printf("Timeout: %d\n", bau.parameters().getWord(0));
|
||||
printf("Zykl. senden: %d\n", bau.parameters().getByte(2));
|
||||
printf("Min/Max senden: %d\n", bau.parameters().getByte(3));
|
||||
printf("Aenderung senden: %d\n", bau.parameters().getByte(4));
|
||||
printf("Abgleich %d\n", bau.parameters().getByte(5));
|
||||
}
|
||||
bau.enabled(true);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
setup();
|
||||
|
||||
while (1)
|
||||
{
|
||||
bau.loop();
|
||||
appLoop();
|
||||
platfrom.mdelay(100);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,9 +1,11 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
#include "nowifistate.h"
|
||||
#include "wpsstate.h"
|
||||
#include "runningstate.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
NoWifiState noWifiState = NoWifiState();
|
||||
|
||||
void NoWifiState::shortButtonPress()
|
||||
@@ -32,4 +34,6 @@ void NoWifiState::enterState()
|
||||
Serial.printf("\nConnected successful to SSID '%s'\n", WiFi.SSID().c_str());
|
||||
switchToSate(runningState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "state.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
|
||||
class NoWifiState : public State
|
||||
{
|
||||
public:
|
||||
@@ -13,4 +15,6 @@ public:
|
||||
virtual const char* name() { return "NoWifi"; }
|
||||
};
|
||||
|
||||
extern NoWifiState noWifiState;
|
||||
extern NoWifiState noWifiState;
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "runningstate.h"
|
||||
#include "knx_facade.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
ProgramModeState programModeState = ProgramModeState();
|
||||
|
||||
void ProgramModeState::enterState()
|
||||
@@ -24,3 +25,4 @@ void ProgramModeState::loop()
|
||||
State::loop();
|
||||
knx.knxLoop();
|
||||
}
|
||||
#endif
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "state.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
|
||||
class ProgramModeState : public State
|
||||
{
|
||||
public:
|
||||
@@ -14,4 +16,6 @@ public:
|
||||
virtual const char* name() { return "ProgramMode"; }
|
||||
};
|
||||
|
||||
extern ProgramModeState programModeState;
|
||||
extern ProgramModeState programModeState;
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "wpsstate.h"
|
||||
#include "knx_facade.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
|
||||
RunningState runningState = RunningState();
|
||||
|
||||
void RunningState::shortButtonPress()
|
||||
@@ -38,3 +40,4 @@ void RunningState::loop()
|
||||
State::loop();
|
||||
knx.knxLoop();
|
||||
}
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "state.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
class RunningState : public State
|
||||
{
|
||||
public:
|
||||
@@ -17,4 +17,5 @@ private:
|
||||
bool _initialized = false;
|
||||
};
|
||||
|
||||
extern RunningState runningState;
|
||||
extern RunningState runningState;
|
||||
#endif
|
||||
157
src/samd_platform.cpp
Normal file
157
src/samd_platform.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
#include "samd_platform.h"
|
||||
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
#include <knx/bits.h>
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <FlashAsEEPROM.h>
|
||||
|
||||
SamdPlatform::SamdPlatform()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t SamdPlatform::currentIpAddress()
|
||||
{
|
||||
// not needed
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t SamdPlatform::currentSubnetMask()
|
||||
{
|
||||
// not needed
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t SamdPlatform::currentDefaultGateway()
|
||||
{
|
||||
// not needed
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SamdPlatform::macAddress(uint8_t * addr)
|
||||
{
|
||||
// not needed
|
||||
}
|
||||
|
||||
uint32_t SamdPlatform::millis()
|
||||
{
|
||||
return::millis();
|
||||
}
|
||||
|
||||
void SamdPlatform::mdelay(uint32_t millis)
|
||||
{
|
||||
delay(millis);
|
||||
}
|
||||
|
||||
void SamdPlatform::restart()
|
||||
{
|
||||
SerialUSB.println("restart");
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void SamdPlatform::fatalError()
|
||||
{
|
||||
const int period = 200;
|
||||
while (true)
|
||||
{
|
||||
if ((millis() % period) > (period / 2))
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
else
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void SamdPlatform::setupMultiCast(uint32_t addr, uint16_t port)
|
||||
{
|
||||
//not needed
|
||||
}
|
||||
|
||||
void SamdPlatform::closeMultiCast()
|
||||
{
|
||||
//not needed
|
||||
}
|
||||
|
||||
bool SamdPlatform::sendBytes(uint8_t * buffer, uint16_t len)
|
||||
{
|
||||
//not needed
|
||||
}
|
||||
|
||||
int SamdPlatform::readBytes(uint8_t * buffer, uint16_t maxLen)
|
||||
{
|
||||
//not needed
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t * SamdPlatform::getEepromBuffer(uint16_t size)
|
||||
{
|
||||
//EEPROM.begin(size);
|
||||
if(size > EEPROM_EMULATION_SIZE)
|
||||
fatalError();
|
||||
|
||||
return EEPROM.getDataPtr();
|
||||
}
|
||||
|
||||
void SamdPlatform::commitToEeprom()
|
||||
{
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
|
||||
void SamdPlatform::setupUart()
|
||||
{
|
||||
SerialKNX.begin(19200, SERIAL_8E1);
|
||||
while (!SerialKNX)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void SamdPlatform::closeUart()
|
||||
{
|
||||
SerialKNX.end();
|
||||
}
|
||||
|
||||
|
||||
int SamdPlatform::uartAvailable()
|
||||
{
|
||||
return SerialKNX.available();
|
||||
}
|
||||
|
||||
|
||||
size_t SamdPlatform::writeUart(const uint8_t data)
|
||||
{
|
||||
//printHex("<p", &data, 1);
|
||||
return SerialKNX.write(data);
|
||||
}
|
||||
|
||||
|
||||
size_t SamdPlatform::writeUart(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
//printHex("<p", buffer, size);
|
||||
return SerialKNX.write(buffer, size);
|
||||
}
|
||||
|
||||
|
||||
int SamdPlatform::readUart()
|
||||
{
|
||||
int val = SerialKNX.read();
|
||||
//if(val > 0)
|
||||
// printHex("p>", (uint8_t*)&val, 1);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
size_t SamdPlatform::readBytesUart(uint8_t *buffer, size_t length)
|
||||
{
|
||||
size_t toRead = length;
|
||||
uint8_t* pos = buffer;
|
||||
while (toRead > 0)
|
||||
{
|
||||
size_t val = SerialKNX.readBytes(pos, toRead);
|
||||
pos += val;
|
||||
toRead -= val;
|
||||
}
|
||||
//printHex("p>", buffer, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
#endif
|
||||
50
src/samd_platform.h
Normal file
50
src/samd_platform.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "knx/platform.h"
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
|
||||
#define SerialDBG SerialUSB
|
||||
#define SerialKNX Serial1
|
||||
|
||||
class SamdPlatform : public Platform
|
||||
{
|
||||
public:
|
||||
SamdPlatform();
|
||||
|
||||
// ip stuff
|
||||
uint32_t currentIpAddress();
|
||||
uint32_t currentSubnetMask();
|
||||
uint32_t currentDefaultGateway();
|
||||
void macAddress(uint8_t* addr);
|
||||
|
||||
// basic stuff
|
||||
uint32_t millis();
|
||||
void mdelay(uint32_t millis);
|
||||
void restart();
|
||||
void fatalError();
|
||||
|
||||
//multicast
|
||||
void setupMultiCast(uint32_t addr, uint16_t port);
|
||||
void closeMultiCast();
|
||||
bool sendBytes(uint8_t* buffer, uint16_t len);
|
||||
int readBytes(uint8_t* buffer, uint16_t maxLen);
|
||||
|
||||
//uart
|
||||
virtual void setupUart();
|
||||
virtual void closeUart();
|
||||
virtual int uartAvailable();
|
||||
virtual size_t writeUart(const uint8_t data);
|
||||
virtual size_t writeUart(const uint8_t *buffer, size_t size);
|
||||
virtual int readUart();
|
||||
virtual size_t readBytesUart(uint8_t *buffer, size_t length);
|
||||
|
||||
//memory
|
||||
uint8_t* getEepromBuffer(uint16_t size);
|
||||
void commitToEeprom();
|
||||
private:
|
||||
uint32_t _mulitcastAddr;
|
||||
uint16_t _mulitcastPort;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "state.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
|
||||
State* volatile currentState = 0;
|
||||
State* volatile nextState = 0;
|
||||
|
||||
@@ -51,3 +53,5 @@ void State::loop()
|
||||
{
|
||||
checkStates();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
#include "arch_config.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
|
||||
class State
|
||||
{
|
||||
@@ -26,4 +29,6 @@ void switchToSate(State& state);
|
||||
void checkStates();
|
||||
|
||||
extern State* volatile currentState;
|
||||
extern State* volatile nextState;
|
||||
extern State* volatile nextState;
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,6 @@
|
||||
#include "arch_config.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
#include "wpsstate.h"
|
||||
@@ -26,3 +29,5 @@ void WpsState::enterState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "state.h"
|
||||
|
||||
#ifdef USE_STATES
|
||||
class WpsState : public State
|
||||
{
|
||||
public:
|
||||
@@ -12,3 +13,5 @@ public:
|
||||
};
|
||||
|
||||
extern WpsState wpsState;
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user