503 lines
15 KiB
C++
503 lines
15 KiB
C++
#include "hardwaresetup.h"
|
|
#include "sys/io.h"
|
|
// filecontrol
|
|
#include "datatypes.h"
|
|
#include <boost/asio/serial_port.hpp>
|
|
#include <cstdint>
|
|
#include <fcntl.h>
|
|
#include <fmt/format.h>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <qglobal.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
#ifdef ATMEGA
|
|
#include <libusb.h>
|
|
#endif
|
|
|
|
#define USB_LED_ON 1
|
|
#define USB_LED_OFF 0
|
|
#define USB_DATA_OUT 2
|
|
|
|
// #define DEMO_MODE 1 // no hardware required
|
|
|
|
#define HARDWARE_VERSION 3
|
|
// V1 Parallelport
|
|
// V2 USB Atmega8
|
|
// V3 STM32F07
|
|
|
|
#define LIGHT_BARRIERS 6u
|
|
|
|
// #define PORT_PATH "/dev/ttyACM0"
|
|
// #define PORT_PATH "/dev/pts/4"
|
|
|
|
using namespace std;
|
|
// not needed anymore -> usb
|
|
// #define BASEPORT 0xe050 /* lp1 */
|
|
// #define BASEPORT 0x378
|
|
// #define BASEPORT 0xd000
|
|
|
|
HardwareSetup::HardwareSetup(DataBase * db) {
|
|
// if (ioperm(BASEPORT, 3, 1)) {
|
|
// //perror("ioperm");
|
|
// }
|
|
this->db = db;
|
|
this->PORT_PATH =
|
|
this->db->getData("select interface from interface where id like 1", 1)
|
|
.at(0)
|
|
.at(0)
|
|
.toStdString();
|
|
this->stop = 0;
|
|
#ifdef ATMEGA
|
|
this->handle = nullptr;
|
|
|
|
#endif
|
|
this->fd = -1;
|
|
}
|
|
void HardwareSetup::setStop() {
|
|
this->stop = 1;
|
|
}
|
|
|
|
HardwareSetup::~HardwareSetup() {
|
|
/*if (ioperm(BASEPORT, 3, 0)) {
|
|
//perror("ioperm");
|
|
}*/
|
|
|
|
std::cout << "Destructor of Hardware" << std::endl;
|
|
this->stop = 1;
|
|
|
|
if (HARDWARE_VERSION == 2) {
|
|
#ifdef ATMEGA
|
|
if (this->handle) {
|
|
|
|
libusb_exit(nullptr);
|
|
|
|
libusb_close(this->handle);
|
|
}
|
|
this->handle = nullptr;
|
|
#endif
|
|
}
|
|
else if (HARDWARE_VERSION == 3) {
|
|
// close filedescriptor
|
|
if (this->fd < 0) {
|
|
// already closed
|
|
}
|
|
else {
|
|
close(this->fd);
|
|
}
|
|
}
|
|
}
|
|
#ifdef ATMEGA
|
|
|
|
libusb_device_handle * HardwareSetup::usbOpenDevice(int vendor, int product) {
|
|
|
|
libusb_device ** devs;
|
|
int r;
|
|
ssize_t cnt;
|
|
|
|
r = libusb_init(nullptr);
|
|
if (r < 0) {
|
|
// return r;
|
|
}
|
|
cnt = libusb_get_device_list(nullptr, &devs);
|
|
if (cnt < 0) {
|
|
libusb_exit(nullptr);
|
|
// return cnt;
|
|
}
|
|
|
|
libusb_device * dev;
|
|
this->handle = nullptr;
|
|
int i = 0;
|
|
|
|
while ((dev = devs[i++]) != nullptr) {
|
|
struct libusb_device_descriptor desc;
|
|
int r = libusb_get_device_descriptor(dev, &desc);
|
|
if (r < 0) {
|
|
fprintf(stderr, "failed to get device descriptor");
|
|
}
|
|
if (desc.idVendor == vendor && desc.idProduct == product) {
|
|
cout << "id vendor passt und id product auch" << endl;
|
|
libusb_open(dev, &this->handle);
|
|
|
|
cout << "handle: " << this->handle << endl;
|
|
return this->handle;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
#endif
|
|
|
|
void HardwareSetup::run() {
|
|
|
|
if (HARDWARE_VERSION == 2) {
|
|
#ifdef ATMEGA
|
|
struct TransStruct buffer[6];
|
|
int testmode = 0;
|
|
|
|
int nBytes = 0;
|
|
// char buffer[256];
|
|
|
|
// struct TransStruct *buffer = buffer1;
|
|
// cout << "thread started" << endl;
|
|
|
|
// if(argc < 2) {
|
|
// printf("Usage:\n");
|
|
// printf("usbtext.exe on\n");
|
|
// printf("usbtext.exe off\n");
|
|
// exit(1);
|
|
// }
|
|
if (!testmode) {
|
|
string vendorName = "test01";
|
|
string productName = "USBExample";
|
|
while (!this->handle) {
|
|
this->handle = usbOpenDevice(0x16C0, 0x05DC);
|
|
|
|
if (this->handle == nullptr) {
|
|
fprintf(stderr, "Could not find USB device!\n");
|
|
}
|
|
sleep(1);
|
|
}
|
|
}
|
|
|
|
while (!this->stop) {
|
|
|
|
// test mode
|
|
|
|
if (testmode) {
|
|
while (1) {
|
|
int validTimes = 0;
|
|
if (validTimes) {
|
|
Shell(1100, 1);
|
|
sleep(1);
|
|
Shell(1200, 2);
|
|
sleep(1);
|
|
Shell(1300, 3);
|
|
sleep(1);
|
|
Dea(1100, 1);
|
|
sleep(1);
|
|
Dea(1200, 2);
|
|
sleep(1);
|
|
Dea(1300, 3);
|
|
// this->stop = 0;
|
|
sleep(1);
|
|
}
|
|
else {
|
|
// invalid times
|
|
Shell(30, 1);
|
|
sleep(1);
|
|
Shell(700, 2);
|
|
sleep(1);
|
|
Shell(700, 3);
|
|
sleep(1);
|
|
Dea(500, 1);
|
|
sleep(1);
|
|
Dea(700, 2);
|
|
sleep(1);
|
|
Dea(3000, 3);
|
|
// this->stop = 0;
|
|
sleep(1);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// normal mode -> no testmode
|
|
usleep(150000); // 150ms
|
|
// while(1){
|
|
nBytes = libusb_control_transfer(
|
|
this->handle,
|
|
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE |
|
|
LIBUSB_ENDPOINT_IN,
|
|
USB_DATA_OUT, 0, 0,
|
|
static_cast<unsigned char *>(static_cast<void *>(buffer)),
|
|
sizeof(buffer), 5000);
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
if (buffer[i].update != 0) {
|
|
switch (buffer[i].id) {
|
|
case 0:
|
|
cout << "Shell Zeit 1: "
|
|
<< static_cast<int>(buffer[i].time) << endl;
|
|
emit Shell(static_cast<int>(buffer[i].time), 1);
|
|
break;
|
|
case 1:
|
|
cout << "Dea Zeit 1: "
|
|
<< static_cast<int>(buffer[i].time) << endl;
|
|
emit Dea(static_cast<int>(buffer[i].time), 1);
|
|
break;
|
|
case 2:
|
|
cout << "Shell Zeit 2: "
|
|
<< static_cast<int>(buffer[i].time) << endl;
|
|
emit Shell(static_cast<int>(buffer[i].time), 2);
|
|
break;
|
|
case 3:
|
|
cout << "Dea Zeit 2: "
|
|
<< static_cast<int>(buffer[i].time) << endl;
|
|
emit Dea(static_cast<int>(buffer[i].time), 2);
|
|
break;
|
|
case 4:
|
|
cout << "Shell Zeit 2: "
|
|
<< static_cast<int>(buffer[i].time) << endl;
|
|
emit Shell(static_cast<int>(buffer[i].time), 3);
|
|
break;
|
|
case 5:
|
|
cout << "Dea Zeit 3: "
|
|
<< static_cast<int>(buffer[i].time) << endl;
|
|
emit Dea(static_cast<int>(buffer[i].time), 3);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (buffer[0].update != 0) {
|
|
cout << "Got " << nBytes
|
|
<< " bytes: " << static_cast<int>(buffer[2].time)
|
|
<< ", " << static_cast<int>(buffer[2].id) << endl;
|
|
}
|
|
//}
|
|
|
|
if (nBytes < 0) {
|
|
// fprintf(stderr, "USB error: %sn", libusb_error());
|
|
// string vendorName = "test01";
|
|
string vendorName = "test01";
|
|
string productName = "USBExample";
|
|
while (!this->handle) {
|
|
this->handle = usbOpenDevice(0x16C0, 0x05DC);
|
|
|
|
if (this->handle == nullptr) {
|
|
fprintf(stderr, "Could not find USB device!\n");
|
|
}
|
|
sleep(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif // ATMEGA
|
|
} // end HARDWARE_VERSION 2
|
|
|
|
else if (HARDWARE_VERSION == 3) {
|
|
|
|
#ifndef DEMO_MODE
|
|
TransCheck * received;
|
|
sport = std::make_unique<serial_port>(PORT_PATH);
|
|
TransCheck buffer = sport->read_frame();
|
|
#else
|
|
uint ctr = 0;
|
|
#endif
|
|
|
|
while (!this->stop) {
|
|
|
|
#ifndef DEMO_MODE
|
|
usleep(100000); // 150ms
|
|
buffer = sport->read_frame();
|
|
received = &buffer;
|
|
#else
|
|
usleep(1000000); // 1s
|
|
#endif
|
|
#ifndef DEMO_MODE
|
|
for (uint8_t i = 0; i < LIGHT_BARRIERS; i++) {
|
|
|
|
// fmt::print("{} ", TransStruct{buffer.data[i]}); // removed
|
|
// because build fails :(
|
|
cout << "i: " << i
|
|
<< " time: " << static_cast<int>(received->data[i].time)
|
|
<< " update: "
|
|
<< static_cast<int>(received->data[i].update) << endl;
|
|
if (received->data[i].update != NO_UPDATE) {
|
|
switch (received->data[i].id) {
|
|
|
|
case SHELL_SECTOR_1:
|
|
cout << "Shell Zeit 1: "
|
|
<< static_cast<int>(received->data[i].time)
|
|
<< endl;
|
|
emit Shell(static_cast<int>(received->data[i].time),
|
|
SECTOR_1);
|
|
break;
|
|
case DEA_SECTOR_1:
|
|
cout << "Dea Zeit 1: "
|
|
<< static_cast<int>(received->data[i].time)
|
|
<< endl;
|
|
emit Dea(static_cast<int>(received->data[i].time),
|
|
SECTOR_1);
|
|
break;
|
|
case SHELL_SECTOR_2:
|
|
cout << "Shell Zeit 2: "
|
|
<< static_cast<int>(received->data[i].time)
|
|
<< endl;
|
|
emit Shell(static_cast<int>(received->data[i].time),
|
|
SECTOR_2);
|
|
break;
|
|
case DEA_SECTOR_2:
|
|
cout << "Dea Zeit 2: "
|
|
<< static_cast<int>(received->data[i].time)
|
|
<< endl;
|
|
emit Dea(static_cast<int>(received->data[i].time),
|
|
SECTOR_2);
|
|
break;
|
|
case SHELL_SECTOR_3:
|
|
cout << "Shell Zeit 3: "
|
|
<< static_cast<int>(received->data[i].time)
|
|
<< endl;
|
|
emit Shell(static_cast<int>(received->data[i].time),
|
|
SECTOR_3);
|
|
break;
|
|
case DEA_SECTOR_3:
|
|
cout << "Dea Zeit 3: "
|
|
<< static_cast<int>(received->data[i].time)
|
|
<< endl;
|
|
emit Dea(static_cast<int>(received->data[i].time),
|
|
SECTOR_3);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
|
|
switch (ctr) {
|
|
|
|
case SHELL_SECTOR_1:
|
|
|
|
emit Shell((ctr + 1) * 1000, SECTOR_1);
|
|
break;
|
|
case DEA_SECTOR_1:
|
|
emit Dea((ctr + 1) * 1000, SECTOR_1);
|
|
break;
|
|
case SHELL_SECTOR_2:
|
|
|
|
emit Shell((ctr + 1) * 1000, SECTOR_2);
|
|
break;
|
|
case DEA_SECTOR_2:
|
|
emit Dea((ctr + 1) * 1000, SECTOR_2);
|
|
break;
|
|
case SHELL_SECTOR_3:
|
|
|
|
emit Shell((ctr + 1) * 1000, SECTOR_3);
|
|
break;
|
|
case DEA_SECTOR_3:
|
|
emit Dea((ctr + 1) * 1000, SECTOR_3);
|
|
break;
|
|
}
|
|
ctr += 1;
|
|
ctr = ctr % LIGHT_BARRIERS;
|
|
|
|
#endif
|
|
|
|
// overwrite received data to prevent same data gets read one more
|
|
// time; dummy data is array of zeros
|
|
}
|
|
}
|
|
else {
|
|
cout << "unknown hardware version" << endl;
|
|
}
|
|
}
|
|
/*
|
|
void HardwareSetup::connectSTM32Boost() {
|
|
// serialPort.
|
|
boost::asio::serial_port port(this->context);
|
|
try {
|
|
port.open(PORT_PATH);
|
|
port.set_option(boost::asio::serial_port::baud_rate(9600));
|
|
port.set_option(boost::asio::serial_port::service_type());
|
|
} catch (boost::system::system_error & e) {
|
|
Q_UNUSED(e);
|
|
cout << "port could not be opened" << endl;
|
|
}
|
|
}
|
|
*/
|
|
void HardwareSetup::connectSTM32() {
|
|
if (fd >= 0) { // fd is already in use
|
|
close(fd);
|
|
}
|
|
usleep(10000);
|
|
fd = open(this->PORT_PATH.c_str(), O_RDONLY);
|
|
while (this->fd < 0) {
|
|
// wait 1 second
|
|
sleep(1);
|
|
cout << "Port can't be opened" << endl;
|
|
fd = open(PORT_PATH.c_str(), O_RDONLY);
|
|
if (this->stop) {
|
|
break;
|
|
}
|
|
}
|
|
// prepare buffer
|
|
std::shared_ptr<struct TransCheck> received =
|
|
std::make_shared<struct TransCheck>();
|
|
uint8_t uintBuf[sizeof(struct TransCheck)];
|
|
// void * voidBuf;
|
|
// configure among others non-canonical mode (important)
|
|
struct termios config;
|
|
tcgetattr(fd, &config);
|
|
config.c_lflag = 0; // standard value is bad choosen
|
|
tcsetattr(fd, TCSANOW, &config);
|
|
|
|
// read raw data to buffer
|
|
ssize_t length = read(fd, uintBuf, sizeof(struct TransCheck));
|
|
|
|
if (this->stop == 0) {
|
|
cout << "Port opened" << endl;
|
|
// flush existing data
|
|
if (static_cast<unsigned long>(length) < sizeof(struct TransCheck)) {
|
|
tcflush(fd, TCIFLUSH);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool HardwareSetup::getShell() {
|
|
|
|
// int zahl[8] = {0};
|
|
|
|
// if(findBit(zahl, inb(BASEPORT + 1))[7] == 1){
|
|
|
|
// return true;
|
|
// }
|
|
return false;
|
|
}
|
|
bool HardwareSetup::getDea() {
|
|
|
|
// int zahl[8] = {0};
|
|
|
|
// if(findBit(zahl, inb(BASEPORT + 1))[6] == 0 ){
|
|
// return true;
|
|
// }
|
|
return false;
|
|
}
|
|
|
|
int * HardwareSetup::findBit(int * array, int zahl) {
|
|
if (zahl >= 128) {
|
|
array[7] = 1;
|
|
zahl -= 128;
|
|
}
|
|
if (zahl >= 64) {
|
|
array[6] = 1;
|
|
zahl -= 64;
|
|
}
|
|
if (zahl >= 32) {
|
|
array[5] = 1;
|
|
zahl -= 32;
|
|
}
|
|
if (zahl >= 16) {
|
|
array[4] = 1;
|
|
zahl -= 16;
|
|
}
|
|
if (zahl >= 8) {
|
|
array[3] = 1;
|
|
zahl -= 8;
|
|
}
|
|
if (zahl >= 4) {
|
|
array[2] = 1;
|
|
zahl -= 4;
|
|
}
|
|
if (zahl >= 2) {
|
|
array[1] = 1;
|
|
zahl -= 2;
|
|
}
|
|
if (zahl >= 1) {
|
|
array[0] = 1;
|
|
zahl -= 1;
|
|
}
|
|
|
|
return array;
|
|
}
|