Skip to content

Show IP with event_sensors. #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ drivers/**/.tmp_versions/

user/**/*.o
user/show_ip/show_ip
user/event_sensors/event_sensors
user/streaming_sensors/streaming_sensors

# ModelSim temporary files
Expand Down
66 changes: 44 additions & 22 deletions user/event_sensors/apds9301.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,23 @@

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

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


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


void APDS9301::doProcess(APDS9301Data const &data) {
void APDS9301::doProcess(APDS9301Data const &data)
{
#ifdef NO_SENSORS
// nothing to process here
return;
Expand All @@ -30,48 +32,66 @@ void APDS9301::doProcess(APDS9301Data const &data) {
// dimm 7-segment display according to the latest light intensity
//

static const int SEGMENT_COUNT = 6;
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};
float scale = (float)data.value / UINT16_MAX;
uint8_t brightness = (uint8_t)(scale * UINT8_MAX);
if (brightness < 3)
brightness = 3;

getIPdata_t getIPdata = {0};
if (mIP_octet < 3)
mIP_octet++;
else
mIP_octet = 0;
memcpy(&getIPdata, get_ip(mIP_octet), sizeof(getIPdata_t));

auto _lck = lockFPGA();

// open character device
auto fd = fopen(CHARACTER_DEVICE.c_str(), "wb");
if (!fd) {
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) {
for (int i = 0; i < SEGMENT_COUNT; ++i)
{
// Convert to binary for driver
getIPdata.hex_values[i] -= '0';

if (fputc(getIPdata.hex_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) {
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) {
if (fputc(getIPdata.hex_enable, fd) == EOF)
{
std::cerr << "Failed to write enable bits" << std::endl;
fclose(fd);
return;
}

(void) fclose(fd);
(void)fclose(fd);
}

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

Expand All @@ -86,37 +106,39 @@ std::optional<APDS9301Data> APDS9301::doPoll() {
static const std::string CHARACTER_DEVICE = "/dev/apds9301";

static const int READ_SIZE = sizeof(APDS9301POD);
APDS9301Data results {};
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) {
if (!fd)
{
std::cerr << "Failed to open character device '" << CHARACTER_DEVICE << "'" << std::endl;
return {};
}

if (fread(&pod, READ_SIZE, 1, fd) != 1) {
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;
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);
(void)fclose(fd);

return std::make_optional(results);
}

std::string APDS9301Data::toJsonString() const {
std::string APDS9301Data::toJsonString() const
{
std::stringstream ss;
ss << "{";
ss << "\"ambient_light\":" << value << ",";
Expand Down
12 changes: 8 additions & 4 deletions user/event_sensors/apds9301.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@

#include "sensors.h"


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

uint64_t timeStamp;
uint16_t value;
};

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

Expand All @@ -20,6 +21,9 @@ class APDS9301 : public StreamingSensor<APDS9301Data> {
protected:
std::optional<APDS9301Data> doPoll() override;
void doProcess(APDS9301Data const &data) override;

private:
int mIP_octet = 0;
};

#endif // APDS9301_H
#endif // APDS9301_H
89 changes: 89 additions & 0 deletions user/event_sensors/get_ip.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <cstdio>
#include <cstdint>
#include <cstring>

#include <iostream>
#include <string>
#include <thread>
#include <chrono>

#include "get_ip.h"

using namespace std::literals::chrono_literals;

struct IPv4Address
{
uint8_t segments[4];
};

IPv4Address getIPfromSystem()
{
// drop 127.0.0.1
static const uint32_t LOCAL_IP = 16777343;
IPv4Address result;

struct ifaddrs *ifAddrStruct = NULL;
getifaddrs(&ifAddrStruct);

for (auto ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
{
if (!ifa->ifa_addr)
{
continue;
}

if (ifa->ifa_addr->sa_family == AF_INET)
{
auto ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
if (ip == LOCAL_IP)
{
continue;
}

// use the first non-local IP
for (int i = 0; i < 4; ++i)
{
result.segments[i] = static_cast<uint8_t>((ip >> (i * 8)) & 0xff);
}
break;
}
}

if (ifAddrStruct)
{
freeifaddrs(ifAddrStruct);
}

return result;
}

getIPdata_t *get_ip(int hex_index)
{
auto ip = getIPfromSystem();

char chars[7] = {0};
auto s = ip.segments[hex_index];
snprintf(chars, 6, "%d", s);

static getIPdata_t data = {0};

for (int i = 0; i < SEGMENT_COUNT; ++i)
{
bool isValidChar = (chars[i] >= '0' && chars[i] <= '9');
data.hex_enable |= (((int)isValidChar) & 1) << (SEGMENT_COUNT - i - 1);

if (isValidChar)
{
data.hex_values[i] = chars[i];
}
else
{
data.hex_values[i] = '0';
}
}
return &data;
}
15 changes: 15 additions & 0 deletions user/event_sensors/get_ip.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef GET_IP_H
#define GET_IP_H

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

struct getIPdata_t
{
uint8_t hex_values[SEGMENT_COUNT];
uint8_t hex_enable;
};

getIPdata_t *get_ip(int hex_index);

#endif // GET_IP_H
Loading