Skip to content

Commit

Permalink
User space shock detection (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
skaupper authored Jan 14, 2020
1 parent 378074f commit f039f11
Show file tree
Hide file tree
Showing 16 changed files with 1,111 additions and 0 deletions.
29 changes: 29 additions & 0 deletions user/event_sensors/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
APP_NAME=event_sensors

# DEFINES=NO_SENSORS
CPPFLAGS=-Wall -Werror -pedantic -std=c++17 -O2 -g -Wno-psabi $(addprefix -D,$(DEFINES))
# Attention: the lib diretory where the MQTT is installed into may not be in the LD path!
LDFLAGS=-lpaho-mqtt3as -lpaho-mqttpp3 -lfpgaregion -lpthread -lz

SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)


all: $(APP_NAME)

$(APP_NAME): $(OBJECTS)
$(CXX) $^ $(LDFLAGS) -o $@

%.o: %.cpp
$(CXX) -c $< $(CPPFLAGS) -o $@

clean:
rm -rf $(OBJECTS)
rm -rf $(APP_NAME)

deploy: all
scp $(APP_NAME) $(DEPLOYSSH):$(DEPLOYSSHPATH)/$(APP_NAME)
ssh $(DEPLOYSSH) $(DEPLOYSSHPATH)/$(APP_NAME)


.PHONY: all clean deploy
126 changes: 126 additions & 0 deletions user/event_sensors/apds9301.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include "apds9301.h"

#include <cstring>
#include <iostream>
#include <sstream>

#include "fpga.h"
#include "tsu.h"

struct APDS9301POD {
uint32_t timestamp_lo;
uint32_t timestamp_hi;
uint16_t value;
} __attribute__((packed));


std::string APDS9301::getTopic() const {
static const std::string TOPIC_NAME = "compressed/sensors/apds9301";
return TOPIC_NAME;
}


void APDS9301::doProcess(APDS9301Data const &data) {
#ifdef NO_SENSORS
// nothing to process here
return;
#endif

//
// dimm 7-segment display according to the latest light intensity
//

static const int SEGMENT_COUNT = 6;
static const std::string CHARACTER_DEVICE = "/dev/sevensegment";

uint8_t brightness = data.value >> 8;
uint8_t values[SEGMENT_COUNT] = {0};

auto _lck = lockFPGA();

// open character device
auto fd = fopen(CHARACTER_DEVICE.c_str(), "wb");
if (!fd) {
std::cerr << "Failed to open character device '" << CHARACTER_DEVICE << "'" << std::endl;
return;
}

// write display values
for (int i = 0; i < SEGMENT_COUNT; ++i) {
if (fputc(values[i], fd) == EOF) {
std::cerr << "Failed to write character (index " << i << ")" << std::endl;
fclose(fd);
return;
}
}

// write brightness level
if (fputc(brightness, fd) == EOF) {
std::cerr << "Failed to write brightness level" << std::endl;
fclose(fd);
return;
}

// write enable bits
if (fputc(0xff, fd) == EOF) {
std::cerr << "Failed to write enable bits" << std::endl;
fclose(fd);
return;
}

(void) fclose(fd);
}

std::optional<APDS9301Data> APDS9301::doPoll() {
#ifdef NO_SENSORS
static int c = 0;

APDS9301Data data{};
data.timeStamp = TimeStampingUnit::getCurrentTimeStamp();
data.value = 10 * c;

c = (c + 1) % 100;
return data;
#endif

static const std::string CHARACTER_DEVICE = "/dev/apds9301";

static const int READ_SIZE = sizeof(APDS9301POD);
APDS9301Data results {};
APDS9301POD pod = {};


// lock fpga device using a lock guard
// the result is never used, but it keeps the mutex locked until it goes out of scope
auto _lck = lockFPGA();

// open character device
auto fd = fopen(CHARACTER_DEVICE.c_str(), "rb");
if (!fd) {
std::cerr << "Failed to open character device '" << CHARACTER_DEVICE << "'" << std::endl;
return {};
}

if (fread(&pod, READ_SIZE, 1, fd) != 1) {
std::cerr << "Failed to read sensor values" << std::endl;
return {};
}

auto timestamp = (((uint64_t) pod.timestamp_hi) << 32) | pod.timestamp_lo;
results.timeStamp = TimeStampingUnit::getResolvedTimeStamp(timestamp);
results.value = pod.value;

// close character device
(void) fclose(fd);

return std::make_optional(results);
}

std::string APDS9301Data::toJsonString() const {
std::stringstream ss;
ss << "{";
ss << "\"ambient_light\":" << value << ",";
ss << "\"timestamp\":" << timeStamp;
ss << "}";
return ss.str();
}
25 changes: 25 additions & 0 deletions user/event_sensors/apds9301.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef APDS9301_H
#define APDS9301_H

#include "sensors.h"


struct APDS9301Data : public Serializable {
std::string toJsonString() const override;

uint64_t timeStamp;
uint16_t value;
};

class APDS9301 : public StreamingSensor<APDS9301Data> {
public:
using StreamingSensor::StreamingSensor;

std::string getTopic() const override;

protected:
std::optional<APDS9301Data> doPoll() override;
void doProcess(APDS9301Data const &data) override;
};

#endif // APDS9301_H
24 changes: 24 additions & 0 deletions user/event_sensors/ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEBTCCAu2gAwIBAgIUdpw+vK5pmaDJIzpinZAe9owU45gwDQYJKoZIhvcNAQEL
BQAwgZExCzAJBgNVBAYTAkFVMRgwFgYDVQQIDA9PYmVyb2VzdGVycmVpY2gxEjAQ
BgNVBAcMCUhhZ2VuYmVyZzEMMAoGA1UECgwDU1NMMQ4wDAYDVQQLDAVGSE9PRTEY
MBYGA1UEAwwPMTkzLjE3MC4xOTIuMjI0MRwwGgYJKoZIhvcNAQkBFg1mcmFuekB0
ZXN0LmF0MB4XDTIwMDEwODA5MDgzNVoXDTI1MDEwNzA5MDgzNVowgZExCzAJBgNV
BAYTAkFVMRgwFgYDVQQIDA9PYmVyb2VzdGVycmVpY2gxEjAQBgNVBAcMCUhhZ2Vu
YmVyZzEMMAoGA1UECgwDU1NMMQ4wDAYDVQQLDAVGSE9PRTEYMBYGA1UEAwwPMTkz
LjE3MC4xOTIuMjI0MRwwGgYJKoZIhvcNAQkBFg1mcmFuekB0ZXN0LmF0MIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8lOPnJCOuOIMMZMkHXipDVTmpGDS
X+PIktJBn2buwHb5UcOq5HyyhVu6l0b1LLKPfF4wyEW3TbueShME58UMg2+xigrN
hrgHA/XUi/FhhOE1jcqaIlxZ/yVouANtiVVSGx6X1c0va0aSznp4Eo7Up7Lj2Eh8
ksWhk/r6/ylRjbyhpAJVnUkdKY2hAk72zfarAjTSpOivgfl3QoqR0ZENSkEs2Ztd
2D2L05eqndEmxQTOOvIQxTCcFujTwqQFskhDpaG0cWvcgE9TzP+T9t1o1g5aTCb7
LPvdeCuGOdPkSKFXF2+YFrL1vBiKgdq5FZRBLPsIO5vq9jJND0ijP666uQIDAQAB
o1MwUTAdBgNVHQ4EFgQUp8+SKO6i3q1IQrWC2Uj6KGyv6WEwHwYDVR0jBBgwFoAU
p8+SKO6i3q1IQrWC2Uj6KGyv6WEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEANTdqsNfWWebI+DG9QtERaXu1p+9Vv2LjYLA6mS7Z6YrFpqBYorRf
EOc99RzSn4QGyvJgNAzEtM9qDNcmIzG3iKrXy+//WFkDwQu33U89SqjRBj/4T5RS
Lt2xVMtcXN47vqsBZzLgkP90D7Mt7OMeh1NaOxiy3Q2QP8qQ2XXl01ZR/Q8rGelp
JoEcwhgkuIni/3D9J3jjE0T4GQ0o53LJGBoAJKoIdq6FPTHK00YUMSTGC7twicKg
kvD3qd/tDYnjN7azGjmJfNdG6sIj3OwYHc+2C29GbRBNWplUUHW3nmzonOgOOhak
d7rPsop1H0XVXMFEWw7iBK97DcyVBChrQQ==
-----END CERTIFICATE-----
38 changes: 38 additions & 0 deletions user/event_sensors/fpga.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "fpga.h"

#include <libfpgaregion.h>

#include <cassert>
#include <iostream>
#include <memory>


static std::mutex fpgaMutex;
static std::unique_ptr<FpgaRegion> fpga;


static void ReconfigRequested() {
std::cout << "Reconfiguration in progres" << std::endl;
fpgaMutex.lock();
fpga->Release();
std::cout << "Reconfiguration requested" << std::endl;
}

static void ReconfigDone() {
std::cout << "Reconfiguration done" << std::endl;
fpga->Acquire();
fpgaMutex.unlock();
}



void initFPGA(std::string name) {
fpga = std::make_unique<FpgaRegion>(name, ReconfigRequested, ReconfigDone);
fpga->Acquire();
}


std::lock_guard<std::mutex> lockFPGA() {
assert(fpga);
return std::lock_guard(fpgaMutex);
}
11 changes: 11 additions & 0 deletions user/event_sensors/fpga.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef FPGA_H
#define FPGA_H

#include <mutex>
#include <string>


void initFPGA(std::string name);
std::lock_guard<std::mutex> lockFPGA();

#endif
84 changes: 84 additions & 0 deletions user/event_sensors/hdc1000.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include "hdc1000.h"

#include <cstring>
#include <iostream>
#include <sstream>

#include "fpga.h"
#include "tsu.h"


std::string HDC1000::getTopic() const {
static const std::string TOPIC_NAME = "compressed/sensors/hdc1000";
return TOPIC_NAME;
}

std::optional<HDC1000Data> HDC1000::doPoll() {
#ifdef NO_SENSORS
static int c = 0;

HDC1000Data data{};
data.timeStamp = TimeStampingUnit::getCurrentTimeStamp();
data.temperature = 1 * c;
data.humidity = 1 * (100 - c);

c = (c + 1) % 100;
return data;
#endif

static const std::string CHARACTER_DEVICE = "/dev/hdc1000";

static const int READ_SIZE = 12;
static const int OFFSET_TEMPERATURE = 0;
static const int OFFSET_HUMIDITY = OFFSET_TEMPERATURE + 2;
static const int OFFSET_TIMESTAMP = OFFSET_HUMIDITY + 2;

HDC1000Data results;
uint16_t temperature;
uint16_t humidity;
uint32_t timeStamp;
uint8_t readBuf[READ_SIZE];

// lock fpga device using a lock guard
// the result is never used, but it keeps the mutex locked until it goes out of scope
auto _lck = lockFPGA();

// open character device
auto fd = fopen(CHARACTER_DEVICE.c_str(), "rb");
if (!fd) {
std::cerr << "Failed to open character device '" << CHARACTER_DEVICE << "'" << std::endl;
return {};
}

if (fread(readBuf, READ_SIZE, 1, fd) != 1) {
std::cerr << "Failed to read sensor values" << std::endl;
return {};
}

// copy sensor values to struct
memcpy(&temperature, readBuf + OFFSET_TEMPERATURE, sizeof(temperature));
memcpy(&humidity, readBuf + OFFSET_HUMIDITY, sizeof(humidity));
memcpy(&timeStamp, readBuf + OFFSET_TIMESTAMP, sizeof(timeStamp));



results.timeStamp = TimeStampingUnit::getResolvedTimeStamp(timeStamp);
// calculations according to the datasheet
results.humidity = (humidity * 100) / 65536.;
results.temperature = (temperature * 165) / 65536. - 40;

// close character device
(void) fclose(fd);

return std::make_optional(results);
}

std::string HDC1000Data::toJsonString() const {
std::stringstream ss;
ss << "{";
ss << "\"tmp\":" << temperature << ",";
ss << "\"hum\":" << humidity << ",";
ss << "\"timestamp\":" << timeStamp;
ss << "}";
return ss.str();
}
25 changes: 25 additions & 0 deletions user/event_sensors/hdc1000.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef HDC1000_H
#define HDC1000_H

#include "sensors.h"


struct HDC1000Data : public Serializable {
std::string toJsonString() const override;

uint64_t timeStamp;
double temperature;
double humidity;
};

class HDC1000 : public StreamingSensor<HDC1000Data> {
public:
using StreamingSensor::StreamingSensor;

std::string getTopic() const override;

protected:
std::optional<HDC1000Data> doPoll() override;
};

#endif // HDC1000_H
Loading

0 comments on commit f039f11

Please sign in to comment.